• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * Vulkan CTS Framework
3  * --------------------
4  *
5  * Copyright (c) 2021 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *-------------------------------------------------------------------------*/
20 
21 #include "vksServices.hpp"
22 #include "vksJson.hpp"
23 #include "vksCacheBuilder.hpp"
24 #include "vksStore.hpp"
25 
26 #include <map>
27 #include <mutex>
28 #include <fstream>
29 #include <iostream>
30 
31 #include "deUniquePtr.hpp"
32 #include "vkPrograms.hpp"
33 #include "vkPlatform.hpp"
34 #include "vkDeviceUtil.hpp"
35 #include "vktTestCase.hpp"
36 #include "tcuCommandLine.hpp"
37 #include "tcuPlatform.hpp"
38 #include "tcuTestContext.hpp"
39 #include "tcuResource.hpp"
40 #include "tcuTestLog.hpp"
41 
42 tcu::Platform *createPlatform(void);
43 
44 struct VkscServer
45 {
46     const vk::PlatformInterface &vkp;
47     vk::VkInstance instance;
48     const vk::InstanceInterface &vki;
49     vk::VkPhysicalDevice physicalDevice;
50     uint32_t queueIndex;
51     const vk::VkPhysicalDeviceFeatures2 &enabledFeatures;
52 };
53 
54 VkscServer *createServerVKSC(const std::string &logFile);
55 std::unique_ptr<VkscServer> vkscServer;
56 
57 namespace vksc_server
58 {
59 
60 using namespace json;
61 
62 Store ServiceStore;
63 
LoadPhysicalFile(const string & path,vector<u8> & content)64 bool LoadPhysicalFile(const string &path, vector<u8> &content)
65 {
66     std::ifstream file(path, std::ios::binary);
67     if (!file)
68         return false;
69 
70     content.assign((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
71 
72     return true;
73 }
74 
StoreFile(const string & uniqueFilename,const vector<u8> & content)75 bool StoreFile(const string &uniqueFilename, const vector<u8> &content)
76 {
77     return ServiceStore.Set(uniqueFilename, content);
78 }
79 
GetFile(const string & path,vector<u8> & content,bool removeAfter)80 bool GetFile(const string &path, vector<u8> &content, bool removeAfter)
81 {
82     return ServiceStore.Get(path, content, removeAfter) || LoadPhysicalFile(path, content);
83 }
84 
AppendFile(const string & path,const vector<u8> & content,bool clear)85 bool AppendFile(const string &path, const vector<u8> &content, bool clear)
86 {
87     auto mode = clear ? std::ios::binary : std::ios::binary | std::ios::app;
88 
89     std::ofstream file(path, mode);
90     if (!file)
91         return false;
92 
93     std::copy(content.begin(), content.end(), std::ostream_iterator<u8>{file});
94 
95     return true;
96 }
97 
CreateVulkanSCCache(const VulkanPipelineCacheInput & input,int caseFraction,vector<u8> & binary,const CmdLineParams & cmdLineParams,const std::string & logFile)98 void CreateVulkanSCCache(const VulkanPipelineCacheInput &input, int caseFraction, vector<u8> &binary,
99                          const CmdLineParams &cmdLineParams, const std::string &logFile)
100 {
101     if (!cmdLineParams.compilerPath.empty())
102     {
103         std::stringstream prefix;
104         if (caseFraction >= 0)
105             prefix << "sub_" << caseFraction << "_";
106         else
107             prefix << "";
108 
109         binary = vksc_server::buildOfflinePipelineCache(
110             input, cmdLineParams.compilerPath, cmdLineParams.compilerDataDir, cmdLineParams.compilerArgs,
111             cmdLineParams.compilerPipelineCacheFile, cmdLineParams.compilerLogFile, prefix.str());
112     }
113     else
114     {
115         if (vkscServer.get() == DE_NULL)
116             vkscServer.reset(createServerVKSC(logFile));
117 
118         binary = buildPipelineCache(input, vkscServer->vkp, vkscServer->instance, vkscServer->vki,
119                                     vkscServer->physicalDevice, vkscServer->queueIndex);
120     }
121 }
122 
CompileShader(const SourceVariant & source,const string & commandLine,vector<u8> & binary)123 bool CompileShader(const SourceVariant &source, const string &commandLine, vector<u8> &binary)
124 {
125     glu::ShaderProgramInfo programInfo;
126     vk::SpirVProgramInfo programInfoSpirv;
127     tcu::CommandLine cmd(commandLine);
128 
129     std::unique_ptr<vk::ProgramBinary> programBinary;
130 
131     if (source.active == "glsl")
132         programBinary.reset(vk::buildProgram(source.glsl, &programInfo, cmd));
133     else if (source.active == "hlsl")
134         programBinary.reset(vk::buildProgram(source.hlsl, &programInfo, cmd));
135     else if (source.active == "spirv")
136         programBinary.reset(vk::assembleProgram(source.spirv, &programInfoSpirv, cmd));
137     else
138         return false;
139 
140     if (!programBinary || programBinary->getBinary() == nullptr)
141     {
142         return false;
143     }
144 
145     if (programBinary->getFormat() != vk::PROGRAM_FORMAT_SPIRV)
146     {
147         throw std::runtime_error("CompileShader supports only PROGRAM_FORMAT_SPIRV binary output");
148     }
149 
150     binary.assign(programBinary->getBinary(), programBinary->getBinary() + programBinary->getSize());
151 
152     return true;
153 }
154 
155 } // namespace vksc_server
156 
createServerVKSC(const std::string & logFile)157 VkscServer *createServerVKSC(const std::string &logFile)
158 {
159     tcu::CommandLine cmdLine{"--deqp-vk-device-id=0"};
160     tcu::DirArchive archive{""};
161     tcu::TestLog log{logFile.c_str()};
162     log.supressLogging(true);
163     tcu::Platform *platform{createPlatform()};
164 #ifdef DE_PLATFORM_USE_LIBRARY_TYPE
165     vk::Library *library{platform->getVulkanPlatform().createLibrary(vk::Platform::LIBRARY_TYPE_VULKAN, DE_NULL)};
166 #else
167     vk::Library *library{platform->getVulkanPlatform().createLibrary(DE_NULL)};
168 #endif
169     tcu::TestContext *tcx            = new tcu::TestContext{*platform, archive, log, cmdLine, nullptr};
170     vk::ResourceInterface *resource  = new vk::ResourceInterfaceStandard{*tcx};
171     vk::BinaryCollection *collection = new vk::BinaryCollection{};
172     vkt::Context *context            = new vkt::Context(*tcx, library->getPlatformInterface(), *collection,
173                                                         de::SharedPtr<vk::ResourceInterface>{resource});
174 
175     VkscServer *result = new VkscServer{library->getPlatformInterface(),         context->getInstance(),
176                                         context->getInstanceInterface(),         context->getPhysicalDevice(),
177                                         context->getUniversalQueueFamilyIndex(), context->getDeviceFeatures2()};
178 
179     return result;
180 }
181