• 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 	deUint32										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) return false;
68 
69 	content.assign((std::istreambuf_iterator<char>(file)),
70 					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) return false;
91 
92 	std::copy(content.begin(), content.end(), std::ostream_iterator<u8>{file});
93 
94 	return true;
95 }
96 
CreateVulkanSCCache(const VulkanPipelineCacheInput & input,int caseFraction,vector<u8> & binary,const CmdLineParams & cmdLineParams,const std::string & logFile)97 void CreateVulkanSCCache (const VulkanPipelineCacheInput& input, int caseFraction, vector<u8>& binary, const CmdLineParams& cmdLineParams, const std::string& logFile)
98 {
99 	if (!cmdLineParams.compilerPath.empty())
100 	{
101 		std::stringstream prefix;
102 		if (caseFraction >= 0)
103 			prefix << "sub_" << caseFraction << "_";
104 		else
105 			prefix << "";
106 
107 		binary = vksc_server::buildOfflinePipelineCache(input,
108 														cmdLineParams.compilerPath,
109 														cmdLineParams.compilerDataDir,
110 														cmdLineParams.compilerArgs,
111 														cmdLineParams.compilerPipelineCacheFile,
112 														cmdLineParams.compilerLogFile,
113 														prefix.str());
114 	}
115 	else
116 	{
117 		if (vkscServer.get() == DE_NULL)
118 			vkscServer.reset(createServerVKSC(logFile));
119 
120 		binary = buildPipelineCache(input,
121 									vkscServer->vkp,
122 									vkscServer->instance,
123 									vkscServer->vki,
124 									vkscServer->physicalDevice,
125 									vkscServer->queueIndex);
126 	}
127 }
128 
CompileShader(const SourceVariant & source,const string & commandLine,vector<u8> & binary)129 bool CompileShader (const SourceVariant& source, const string& commandLine, vector<u8>& binary)
130 {
131 	glu::ShaderProgramInfo programInfo;
132 	vk::SpirVProgramInfo programInfoSpirv;
133 	tcu::CommandLine cmd(commandLine);
134 
135 	std::unique_ptr<vk::ProgramBinary> programBinary;
136 
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) );
140 	else return false;
141 
142 	if (!programBinary || programBinary->getBinary() == nullptr)
143 	{
144 		return false;
145 	}
146 
147 	if (programBinary->getFormat() != vk::PROGRAM_FORMAT_SPIRV)
148 	{
149 		throw std::runtime_error("CompileShader supports only PROGRAM_FORMAT_SPIRV binary output");
150 	}
151 
152 	binary.assign(	programBinary->getBinary(),
153 					programBinary->getBinary() + programBinary->getSize()	);
154 
155 	return true;
156 }
157 
158 } // vksc_server
159 
createServerVKSC(const std::string & logFile)160 VkscServer* createServerVKSC(const std::string& logFile)
161 {
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 #ifdef DE_PLATFORM_USE_LIBRARY_TYPE
167 	vk::Library*					library		{platform->getVulkanPlatform().createLibrary(vk::Platform::LIBRARY_TYPE_VULKAN, DE_NULL)};
168 #else
169 	vk::Library*					library		{platform->getVulkanPlatform().createLibrary(DE_NULL)};
170 #endif
171 	tcu::TestContext*				tcx			= new tcu::TestContext{*platform, archive, log, cmdLine, nullptr};
172 	vk::ResourceInterface*			resource	= new vk::ResourceInterfaceStandard{*tcx};
173 	vk::BinaryCollection*			collection  = new vk::BinaryCollection{};
174 	vkt::Context*					context		= new vkt::Context(*tcx, library->getPlatformInterface(), *collection, de::SharedPtr<vk::ResourceInterface>{resource});
175 
176 	VkscServer* result = new VkscServer
177 	{
178 		library->getPlatformInterface(),
179 		context->getInstance(),
180 		context->getInstanceInterface(),
181 		context->getPhysicalDevice(),
182 		context->getUniversalQueueFamilyIndex(),
183 		context->getDeviceFeatures2()
184 	};
185 
186 	return result;
187 }
188