1 /*-------------------------------------------------------------------------
5 * Copyright (c) 2021 The Khronos Group Inc.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 *-------------------------------------------------------------------------*/
21 #include "vksServices.hpp"
22 #include "vksJson.hpp"
23 #include "vksCacheBuilder.hpp"
24 #include "vksStore.hpp"
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"
42 tcu::Platform* createPlatform (void);
46 const vk::PlatformInterface& vkp;
47 vk::VkInstance instance;
48 const vk::InstanceInterface& vki;
49 vk::VkPhysicalDevice physicalDevice;
51 const vk::VkPhysicalDeviceFeatures2& enabledFeatures;
54 VkscServer* createServerVKSC(const std::string& logFile);
55 std::unique_ptr<VkscServer> vkscServer;
64 bool LoadPhysicalFile (const string& path, vector<u8>& content)
66 std::ifstream file(path, std::ios::binary);
67 if (!file) return false;
69 content.assign((std::istreambuf_iterator<char>(file)),
70 std::istreambuf_iterator<char>());
75 bool StoreFile (const string& uniqueFilename, const vector<u8>& content)
77 return ServiceStore.Set(uniqueFilename, content);
80 bool GetFile (const string& path, vector<u8>& content, bool removeAfter)
82 return ServiceStore.Get(path, content, removeAfter) || LoadPhysicalFile(path, content);
85 bool AppendFile (const string& path, const vector<u8>& content, bool clear)
87 auto mode = clear ? std::ios::binary : std::ios::binary | std::ios::app;
89 std::ofstream file(path, mode);
90 if (!file) return false;
92 std::copy(content.begin(), content.end(), std::ostream_iterator<u8>{file});
97 void CreateVulkanSCCache (const VulkanPipelineCacheInput& input, int caseFraction, vector<u8>& binary, const CmdLineParams& cmdLineParams, const std::string& logFile)
99 if (!cmdLineParams.compilerPath.empty())
101 std::stringstream prefix;
102 if (caseFraction >= 0)
103 prefix << "sub_" << caseFraction << "_";
107 binary = vksc_server::buildOfflinePipelineCache(input,
108 cmdLineParams.compilerPath,
109 cmdLineParams.compilerDataDir,
110 cmdLineParams.compilerArgs,
111 cmdLineParams.compilerPipelineCacheFile,
112 cmdLineParams.compilerLogFile,
117 if (vkscServer.get() == DE_NULL)
118 vkscServer.reset(createServerVKSC(logFile));
120 binary = buildPipelineCache(input,
122 vkscServer->instance,
124 vkscServer->physicalDevice,
125 vkscServer->queueIndex);
129 bool CompileShader (const SourceVariant& source, const string& commandLine, vector<u8>& binary)
131 glu::ShaderProgramInfo programInfo;
132 vk::SpirVProgramInfo programInfoSpirv;
133 tcu::CommandLine cmd(commandLine);
135 std::unique_ptr<vk::ProgramBinary> programBinary;
137 if (source.active == "glsl") programBinary.reset( vk::buildProgram(source.glsl, &programInfo, cmd) );
138 else if (source.active == "hlsl") programBinary.reset( vk::buildProgram(source.hlsl, &programInfo, cmd) );
139 else if (source.active == "spirv") programBinary.reset( vk::assembleProgram(source.spirv, &programInfoSpirv, cmd) );
142 if (!programBinary || programBinary->getBinary() == nullptr)
147 if (programBinary->getFormat() != vk::PROGRAM_FORMAT_SPIRV)
149 throw std::runtime_error("CompileShader supports only PROGRAM_FORMAT_SPIRV binary output");
152 binary.assign( programBinary->getBinary(),
153 programBinary->getBinary() + programBinary->getSize() );
160 VkscServer* createServerVKSC(const std::string& logFile)
162 tcu::CommandLine cmdLine {"--deqp-vk-device-id=0"};
163 tcu::DirArchive archive {""};
164 tcu::TestLog log { logFile.c_str() }; log.supressLogging(true);
165 tcu::Platform* platform {createPlatform()};
166 vk::Library* library {platform->getVulkanPlatform().createLibrary(vk::Platform::LIBRARY_TYPE_VULKAN, DE_NULL)};
167 tcu::TestContext* tcx = new tcu::TestContext{*platform, archive, log, cmdLine, nullptr};
168 vk::ResourceInterface* resource = new vk::ResourceInterfaceStandard{*tcx};
169 vk::BinaryCollection* collection = new vk::BinaryCollection{};
170 vkt::Context* context = new vkt::Context(*tcx, library->getPlatformInterface(), *collection, de::SharedPtr<vk::ResourceInterface>{resource});
172 VkscServer* result = new VkscServer
174 library->getPlatformInterface(),
175 context->getInstance(),
176 context->getInstanceInterface(),
177 context->getPhysicalDevice(),
178 context->getUniversalQueueFamilyIndex(),
179 context->getDeviceFeatures2()