1e5c31af7Sopenharmony_ci/*-------------------------------------------------------------------------
2e5c31af7Sopenharmony_ci * Vulkan CTS Framework
3e5c31af7Sopenharmony_ci * --------------------
4e5c31af7Sopenharmony_ci *
5e5c31af7Sopenharmony_ci * Copyright (c) 2021 The Khronos Group Inc.
6e5c31af7Sopenharmony_ci *
7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License.
9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at
10e5c31af7Sopenharmony_ci *
11e5c31af7Sopenharmony_ci *      http://www.apache.org/licenses/LICENSE-2.0
12e5c31af7Sopenharmony_ci *
13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and
17e5c31af7Sopenharmony_ci * limitations under the License.
18e5c31af7Sopenharmony_ci *
19e5c31af7Sopenharmony_ci *-------------------------------------------------------------------------*/
20e5c31af7Sopenharmony_ci
21e5c31af7Sopenharmony_ci#include <iostream>
22e5c31af7Sopenharmony_ci#include <fstream>
23e5c31af7Sopenharmony_ci#include <sstream>
24e5c31af7Sopenharmony_ci#include <json/json.h>
25e5c31af7Sopenharmony_ci#include "deCommandLine.hpp"
26e5c31af7Sopenharmony_ci#include "deDirectoryIterator.hpp"
27e5c31af7Sopenharmony_ci#include "tcuCommandLine.hpp"
28e5c31af7Sopenharmony_ci#include "tcuPlatform.hpp"
29e5c31af7Sopenharmony_ci#include "tcuTestContext.hpp"
30e5c31af7Sopenharmony_ci#include "tcuResource.hpp"
31e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp"
32e5c31af7Sopenharmony_ci#include "vkPlatform.hpp"
33e5c31af7Sopenharmony_ci#include "vktTestCase.hpp"
34e5c31af7Sopenharmony_ci#include "vksStructsVKSC.hpp"
35e5c31af7Sopenharmony_ci#include "vksCacheBuilder.hpp"
36e5c31af7Sopenharmony_ci
37e5c31af7Sopenharmony_cinamespace opt
38e5c31af7Sopenharmony_ci{
39e5c31af7Sopenharmony_ci
40e5c31af7Sopenharmony_ciDE_DECLARE_COMMAND_LINE_OPT(CompilerDataPath,	std::string);
41e5c31af7Sopenharmony_ciDE_DECLARE_COMMAND_LINE_OPT(CompilerOutputFile,	std::string);
42e5c31af7Sopenharmony_ciDE_DECLARE_COMMAND_LINE_OPT(LogFile,			std::string);
43e5c31af7Sopenharmony_ciDE_DECLARE_COMMAND_LINE_OPT(FilePrefix,			std::string);
44e5c31af7Sopenharmony_ci
45e5c31af7Sopenharmony_civoid registerOptions (de::cmdline::Parser& parser)
46e5c31af7Sopenharmony_ci{
47e5c31af7Sopenharmony_ci	using de::cmdline::Option;
48e5c31af7Sopenharmony_ci	using de::cmdline::NamedValue;
49e5c31af7Sopenharmony_ci
50e5c31af7Sopenharmony_ci	parser << Option<CompilerDataPath>		("p", "path",		"Offline pipeline data directory",		"");
51e5c31af7Sopenharmony_ci	parser << Option<CompilerOutputFile>	("o", "out",		"Output file with pipeline cache",		"");
52e5c31af7Sopenharmony_ci	parser << Option<LogFile>				("l", "log",		"Log file",								"dummy.log");
53e5c31af7Sopenharmony_ci	parser << Option<FilePrefix>			("x", "prefix",		"Prefix for input files",				"");
54e5c31af7Sopenharmony_ci}
55e5c31af7Sopenharmony_ci
56e5c31af7Sopenharmony_ci}
57e5c31af7Sopenharmony_ci
58e5c31af7Sopenharmony_cienum PipelineType
59e5c31af7Sopenharmony_ci{
60e5c31af7Sopenharmony_ci	PT_UNDEFINED_PIPELINE = 0,
61e5c31af7Sopenharmony_ci	PT_GRAPHICS_PIPELINE,
62e5c31af7Sopenharmony_ci	PT_COMPUTE_PIPELINE,
63e5c31af7Sopenharmony_ci};
64e5c31af7Sopenharmony_ci
65e5c31af7Sopenharmony_civoid importFilesForExternalCompiler (vksc_server::VulkanPipelineCacheInput&	input,
66e5c31af7Sopenharmony_ci									 const std::string&						path,
67e5c31af7Sopenharmony_ci									 const std::string&						filePrefix)
68e5c31af7Sopenharmony_ci{
69e5c31af7Sopenharmony_ci	vksc_server::json::Context context;
70e5c31af7Sopenharmony_ci
71e5c31af7Sopenharmony_ci	for (de::DirectoryIterator iter(path); iter.hasItem(); iter.next())
72e5c31af7Sopenharmony_ci	{
73e5c31af7Sopenharmony_ci		const de::FilePath							filePath					= iter.getItem();
74e5c31af7Sopenharmony_ci		if (filePath.getType() != de::FilePath::TYPE_FILE)
75e5c31af7Sopenharmony_ci			continue;
76e5c31af7Sopenharmony_ci		if (filePath.getFileExtension() != "json")
77e5c31af7Sopenharmony_ci			continue;
78e5c31af7Sopenharmony_ci		if (!filePrefix.empty() && filePath.getBaseName().find(filePrefix) != 0)
79e5c31af7Sopenharmony_ci			continue;
80e5c31af7Sopenharmony_ci
81e5c31af7Sopenharmony_ci		std::string									fileContents;
82e5c31af7Sopenharmony_ci		{
83e5c31af7Sopenharmony_ci			std::ifstream file(filePath.getPath());
84e5c31af7Sopenharmony_ci			std::stringstream buffer;
85e5c31af7Sopenharmony_ci			buffer << file.rdbuf();
86e5c31af7Sopenharmony_ci			fileContents = buffer.str();
87e5c31af7Sopenharmony_ci		}
88e5c31af7Sopenharmony_ci
89e5c31af7Sopenharmony_ci		Json::Value									jsonRoot;
90e5c31af7Sopenharmony_ci		std::string									errors;
91e5c31af7Sopenharmony_ci		bool										parsingSuccessful			= context.reader->parse(fileContents.c_str(), fileContents.c_str() + fileContents.size(), &jsonRoot, &errors);
92e5c31af7Sopenharmony_ci		if (!parsingSuccessful)
93e5c31af7Sopenharmony_ci			TCU_THROW(InternalError, (std::string("JSON parsing error. File ") + filePath.getPath() + " Error : " + errors).c_str());
94e5c31af7Sopenharmony_ci
95e5c31af7Sopenharmony_ci		// decide what pipeline type will be created later
96e5c31af7Sopenharmony_ci		PipelineType pipelineType = PT_UNDEFINED_PIPELINE;
97e5c31af7Sopenharmony_ci		if (jsonRoot.isMember("GraphicsPipelineState"))
98e5c31af7Sopenharmony_ci			pipelineType = PT_GRAPHICS_PIPELINE;
99e5c31af7Sopenharmony_ci		else if (jsonRoot.isMember("ComputePipelineState"))
100e5c31af7Sopenharmony_ci			pipelineType = PT_COMPUTE_PIPELINE;
101e5c31af7Sopenharmony_ci		if(pipelineType == PT_UNDEFINED_PIPELINE)
102e5c31af7Sopenharmony_ci			TCU_THROW(InternalError, (std::string("JSON - unknown pipeline. File ") + filePath.getPath()).c_str());
103e5c31af7Sopenharmony_ci
104e5c31af7Sopenharmony_ci		const Json::Value&							jsonGraphicsPipelineState	= jsonRoot["GraphicsPipelineState"];
105e5c31af7Sopenharmony_ci		const Json::Value&							jsonComputePipelineState	= jsonRoot["ComputePipelineState"];
106e5c31af7Sopenharmony_ci		const Json::Value&							jsonPipelineState			= (pipelineType == PT_GRAPHICS_PIPELINE ) ? jsonGraphicsPipelineState : jsonComputePipelineState;
107e5c31af7Sopenharmony_ci		vksc_server::VulkanJsonPipelineDescription	pipelineDescription;
108e5c31af7Sopenharmony_ci
109e5c31af7Sopenharmony_ci		{
110e5c31af7Sopenharmony_ci			const Json::Value&	jsonSamplerYcbcrConversions		= jsonPipelineState["YcbcrSamplers"];
111e5c31af7Sopenharmony_ci			if (!jsonSamplerYcbcrConversions.isNull())
112e5c31af7Sopenharmony_ci			{
113e5c31af7Sopenharmony_ci				for (Json::ArrayIndex i = 0; i < jsonSamplerYcbcrConversions.size(); ++i)
114e5c31af7Sopenharmony_ci				{
115e5c31af7Sopenharmony_ci					const Json::Value::Members	membersNames	= jsonSamplerYcbcrConversions[i].getMemberNames();
116e5c31af7Sopenharmony_ci					const Json::Value&			value			= jsonSamplerYcbcrConversions[i][membersNames[0]];
117e5c31af7Sopenharmony_ci					deUint64					index;
118e5c31af7Sopenharmony_ci					std::istringstream(membersNames[0]) >> index;
119e5c31af7Sopenharmony_ci					input.samplerYcbcrConversions[vk::VkSamplerYcbcrConversion(index)] =  std::string(fileContents.begin() + value.getOffsetStart(), fileContents.begin() + value.getOffsetLimit());
120e5c31af7Sopenharmony_ci				}
121e5c31af7Sopenharmony_ci			}
122e5c31af7Sopenharmony_ci
123e5c31af7Sopenharmony_ci			const Json::Value&	jsonSamplers					= jsonPipelineState["ImmutableSamplers"];
124e5c31af7Sopenharmony_ci			if (!jsonSamplers.isNull())
125e5c31af7Sopenharmony_ci			{
126e5c31af7Sopenharmony_ci				for (Json::ArrayIndex i = 0; i < jsonSamplers.size(); ++i)
127e5c31af7Sopenharmony_ci				{
128e5c31af7Sopenharmony_ci					const Json::Value::Members	membersNames	= jsonSamplers[i].getMemberNames();
129e5c31af7Sopenharmony_ci					const Json::Value&			value			= jsonSamplers[i][membersNames[0]];
130e5c31af7Sopenharmony_ci					deUint64					index;
131e5c31af7Sopenharmony_ci					std::istringstream(membersNames[0]) >> index;
132e5c31af7Sopenharmony_ci					input.samplers[vk::VkSampler(index)] = std::string(fileContents.begin() + value.getOffsetStart(), fileContents.begin() + value.getOffsetLimit());
133e5c31af7Sopenharmony_ci				}
134e5c31af7Sopenharmony_ci			}
135e5c31af7Sopenharmony_ci
136e5c31af7Sopenharmony_ci			const Json::Value&	jsonDescriptorSetLayouts		= jsonPipelineState["DescriptorSetLayouts"];
137e5c31af7Sopenharmony_ci			if (!jsonDescriptorSetLayouts.isNull())
138e5c31af7Sopenharmony_ci			{
139e5c31af7Sopenharmony_ci				for (Json::ArrayIndex i = 0; i < jsonDescriptorSetLayouts.size(); ++i)
140e5c31af7Sopenharmony_ci				{
141e5c31af7Sopenharmony_ci					const Json::Value::Members	membersNames	= jsonDescriptorSetLayouts[i].getMemberNames();
142e5c31af7Sopenharmony_ci					const Json::Value&			value			= jsonDescriptorSetLayouts[i][membersNames[0]];
143e5c31af7Sopenharmony_ci					deUint64					index;
144e5c31af7Sopenharmony_ci					std::istringstream(membersNames[0]) >> index;
145e5c31af7Sopenharmony_ci					input.descriptorSetLayouts[vk::VkDescriptorSetLayout(index)] = std::string(fileContents.begin() + value.getOffsetStart(), fileContents.begin() + value.getOffsetLimit());
146e5c31af7Sopenharmony_ci				}
147e5c31af7Sopenharmony_ci			}
148e5c31af7Sopenharmony_ci
149e5c31af7Sopenharmony_ci			deUint64						pipelineLayoutHandle	= 0u;
150e5c31af7Sopenharmony_ci			deUint64						renderPassHandle		= 0u;
151e5c31af7Sopenharmony_ci			std::map<std::string, deUint64>	stages;
152e5c31af7Sopenharmony_ci
153e5c31af7Sopenharmony_ci			const Json::Value&	jsonComputePipeline				= jsonPipelineState["ComputePipeline"];
154e5c31af7Sopenharmony_ci			if (!jsonComputePipeline.isNull())
155e5c31af7Sopenharmony_ci			{
156e5c31af7Sopenharmony_ci				pipelineDescription.pipelineContents			= std::string(fileContents.begin() + jsonComputePipeline.getOffsetStart(), fileContents.begin() + jsonComputePipeline.getOffsetLimit());
157e5c31af7Sopenharmony_ci				pipelineLayoutHandle							= jsonComputePipeline["layout"].asUInt64();
158e5c31af7Sopenharmony_ci
159e5c31af7Sopenharmony_ci				const Json::Value&	jsonStage					= jsonComputePipeline["stage"];
160e5c31af7Sopenharmony_ci				stages[jsonStage["stage"].asString()]			= jsonStage["module"].asUInt64();
161e5c31af7Sopenharmony_ci			}
162e5c31af7Sopenharmony_ci
163e5c31af7Sopenharmony_ci			const Json::Value&	jsonGraphicsPipeline			= jsonPipelineState["GraphicsPipeline"];
164e5c31af7Sopenharmony_ci			if (!jsonGraphicsPipeline.isNull())
165e5c31af7Sopenharmony_ci			{
166e5c31af7Sopenharmony_ci				pipelineDescription.pipelineContents			= std::string(fileContents.begin() + jsonGraphicsPipeline.getOffsetStart(), fileContents.begin() + jsonGraphicsPipeline.getOffsetLimit());
167e5c31af7Sopenharmony_ci				pipelineLayoutHandle							= jsonGraphicsPipeline["layout"].asUInt64();
168e5c31af7Sopenharmony_ci				renderPassHandle								= jsonGraphicsPipeline["renderPass"].asUInt64();
169e5c31af7Sopenharmony_ci
170e5c31af7Sopenharmony_ci				const Json::Value&	jsonStages = jsonGraphicsPipeline["pStages"];
171e5c31af7Sopenharmony_ci				for (Json::ArrayIndex i = 0; i < jsonStages.size(); ++i)
172e5c31af7Sopenharmony_ci					stages[jsonStages[i]["stage"].asString()] = jsonStages[i]["module"].asUInt64();
173e5c31af7Sopenharmony_ci			}
174e5c31af7Sopenharmony_ci
175e5c31af7Sopenharmony_ci			const Json::Value&	jsonPipelineLayout				= jsonPipelineState["PipelineLayout"];
176e5c31af7Sopenharmony_ci			if (!jsonPipelineLayout.isNull() && pipelineLayoutHandle != 0u)
177e5c31af7Sopenharmony_ci			{
178e5c31af7Sopenharmony_ci				input.pipelineLayouts[vk::VkPipelineLayout(pipelineLayoutHandle)] = std::string(fileContents.begin() + jsonPipelineLayout.getOffsetStart(), fileContents.begin() + jsonPipelineLayout.getOffsetLimit());
179e5c31af7Sopenharmony_ci			}
180e5c31af7Sopenharmony_ci
181e5c31af7Sopenharmony_ci			const Json::Value&	jsonRenderPass					= jsonPipelineState["Renderpass"];
182e5c31af7Sopenharmony_ci			if (!jsonRenderPass.isNull() && renderPassHandle != 0u)
183e5c31af7Sopenharmony_ci			{
184e5c31af7Sopenharmony_ci				input.renderPasses[vk::VkRenderPass(renderPassHandle)] = std::string(fileContents.begin() + jsonRenderPass.getOffsetStart(), fileContents.begin() + jsonRenderPass.getOffsetLimit());
185e5c31af7Sopenharmony_ci			}
186e5c31af7Sopenharmony_ci
187e5c31af7Sopenharmony_ci			const Json::Value&	jsonRenderPass2					= jsonPipelineState["Renderpass2"];
188e5c31af7Sopenharmony_ci			if (!jsonRenderPass2.isNull() && renderPassHandle != 0u)
189e5c31af7Sopenharmony_ci			{
190e5c31af7Sopenharmony_ci				input.renderPasses[vk::VkRenderPass(renderPassHandle)] = std::string(fileContents.begin() + jsonRenderPass.getOffsetStart(), fileContents.begin() + jsonRenderPass.getOffsetLimit());
191e5c31af7Sopenharmony_ci			}
192e5c31af7Sopenharmony_ci
193e5c31af7Sopenharmony_ci			const Json::Value&	jsonShaderFileNames				= jsonPipelineState["ShaderFileNames"];
194e5c31af7Sopenharmony_ci			if (!jsonShaderFileNames.isNull())
195e5c31af7Sopenharmony_ci			{
196e5c31af7Sopenharmony_ci				for (Json::ArrayIndex i = 0; i < jsonShaderFileNames.size(); ++i)
197e5c31af7Sopenharmony_ci				{
198e5c31af7Sopenharmony_ci					std::string				stageName	= jsonShaderFileNames[i]["stage"].asString();
199e5c31af7Sopenharmony_ci					std::string				fileName	= jsonShaderFileNames[i]["filename"].asString();
200e5c31af7Sopenharmony_ci					auto it = stages.find(stageName);
201e5c31af7Sopenharmony_ci					if(it == end(stages))
202e5c31af7Sopenharmony_ci						TCU_THROW(InternalError, (std::string("JSON - missing shader stage. File ") + filePath.getPath()).c_str());
203e5c31af7Sopenharmony_ci
204e5c31af7Sopenharmony_ci					de::FilePath			shaderPath	(path);
205e5c31af7Sopenharmony_ci					shaderPath.join(de::FilePath(fileName));
206e5c31af7Sopenharmony_ci					std::ifstream			iFile		(shaderPath.getPath(), std::ios::in | std::ios::binary);
207e5c31af7Sopenharmony_ci					if(!iFile)
208e5c31af7Sopenharmony_ci						TCU_THROW(InternalError, (std::string("JSON - missing shader file ") + fileName + ". File " + filePath.getPath()).c_str());
209e5c31af7Sopenharmony_ci
210e5c31af7Sopenharmony_ci					auto					fileBegin	= iFile.tellg();
211e5c31af7Sopenharmony_ci					iFile.seekg(0, std::ios::end);
212e5c31af7Sopenharmony_ci					auto					fileEnd		= iFile.tellg();
213e5c31af7Sopenharmony_ci					iFile.seekg(0, std::ios::beg);
214e5c31af7Sopenharmony_ci					std::size_t				fileSize	= static_cast<std::size_t>(fileEnd - fileBegin);
215e5c31af7Sopenharmony_ci					std::vector<deUint8>	shaderData	(fileSize);
216e5c31af7Sopenharmony_ci
217e5c31af7Sopenharmony_ci					iFile.read(reinterpret_cast<char*>(shaderData.data()), fileSize);
218e5c31af7Sopenharmony_ci					if (iFile.fail())
219e5c31af7Sopenharmony_ci						TCU_THROW(InternalError, (std::string("JSON - error reading shader file ") + fileName + ". File " + filePath.getPath()).c_str());
220e5c31af7Sopenharmony_ci
221e5c31af7Sopenharmony_ci					vk::VkShaderModuleCreateInfo smCI
222e5c31af7Sopenharmony_ci					{
223e5c31af7Sopenharmony_ci						VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,		// VkStructureType				sType;
224e5c31af7Sopenharmony_ci						DE_NULL,											// const void*					pNext;
225e5c31af7Sopenharmony_ci						vk::VkShaderModuleCreateFlags(0u),					// VkShaderModuleCreateFlags	flags;
226e5c31af7Sopenharmony_ci						fileSize,											// deUintptr					codeSize;
227e5c31af7Sopenharmony_ci						reinterpret_cast<deUint32*>(shaderData.data())		// const deUint32*				pCode;
228e5c31af7Sopenharmony_ci					};
229e5c31af7Sopenharmony_ci
230e5c31af7Sopenharmony_ci					input.shaderModules[vk::VkShaderModule(it->second)] = vksc_server::json::writeJSON_VkShaderModuleCreateInfo(smCI);
231e5c31af7Sopenharmony_ci				}
232e5c31af7Sopenharmony_ci			}
233e5c31af7Sopenharmony_ci
234e5c31af7Sopenharmony_ci			const Json::Value&	jsonPhysicalDeviceFeatures		= jsonPipelineState["PhysicalDeviceFeatures"];
235e5c31af7Sopenharmony_ci			if (!jsonPhysicalDeviceFeatures.isNull())
236e5c31af7Sopenharmony_ci			{
237e5c31af7Sopenharmony_ci				pipelineDescription.deviceFeatures				= std::string(fileContents.begin() + jsonPhysicalDeviceFeatures.getOffsetStart(), fileContents.begin() + jsonPhysicalDeviceFeatures.getOffsetLimit());
238e5c31af7Sopenharmony_ci			}
239e5c31af7Sopenharmony_ci		}
240e5c31af7Sopenharmony_ci
241e5c31af7Sopenharmony_ci		const Json::Value&	jsonEnabledExtensions				= jsonRoot["EnabledExtensions"];
242e5c31af7Sopenharmony_ci		if (!jsonEnabledExtensions.isNull())
243e5c31af7Sopenharmony_ci		{
244e5c31af7Sopenharmony_ci			for (Json::ArrayIndex i = 0; i < jsonEnabledExtensions.size(); ++i)
245e5c31af7Sopenharmony_ci				pipelineDescription.deviceExtensions.push_back(jsonEnabledExtensions[i].asString());
246e5c31af7Sopenharmony_ci		}
247e5c31af7Sopenharmony_ci
248e5c31af7Sopenharmony_ci		const Json::Value&	jsonPipelineUUID					= jsonRoot["PipelineUUID"];
249e5c31af7Sopenharmony_ci		if (!jsonPipelineUUID.isNull())
250e5c31af7Sopenharmony_ci		{
251e5c31af7Sopenharmony_ci			pipelineDescription.id.sType			= VK_STRUCTURE_TYPE_PIPELINE_OFFLINE_CREATE_INFO;
252e5c31af7Sopenharmony_ci			pipelineDescription.id.pNext			= DE_NULL;
253e5c31af7Sopenharmony_ci			for (Json::ArrayIndex i = 0; i < jsonPipelineUUID.size(); ++i)
254e5c31af7Sopenharmony_ci				pipelineDescription.id.pipelineIdentifier[i] = deUint8(jsonPipelineUUID[i].asUInt());
255e5c31af7Sopenharmony_ci			pipelineDescription.id.matchControl		= VK_PIPELINE_MATCH_CONTROL_APPLICATION_UUID_EXACT_MATCH;
256e5c31af7Sopenharmony_ci			pipelineDescription.id.poolEntrySize	= 0u;
257e5c31af7Sopenharmony_ci		}
258e5c31af7Sopenharmony_ci		input.pipelines.push_back(pipelineDescription);
259e5c31af7Sopenharmony_ci	}
260e5c31af7Sopenharmony_ci}
261e5c31af7Sopenharmony_ci
262e5c31af7Sopenharmony_citcu::Platform* createPlatform(void);
263e5c31af7Sopenharmony_ci
264e5c31af7Sopenharmony_ciint main (int argc, char** argv)
265e5c31af7Sopenharmony_ci{
266e5c31af7Sopenharmony_ci	de::cmdline::CommandLine	cmdLine;
267e5c31af7Sopenharmony_ci
268e5c31af7Sopenharmony_ci	// Parse command line.
269e5c31af7Sopenharmony_ci	{
270e5c31af7Sopenharmony_ci		de::cmdline::Parser	parser;
271e5c31af7Sopenharmony_ci		opt::registerOptions(parser);
272e5c31af7Sopenharmony_ci
273e5c31af7Sopenharmony_ci		if (!parser.parse(argc, argv, &cmdLine, std::cerr))
274e5c31af7Sopenharmony_ci		{
275e5c31af7Sopenharmony_ci			parser.help(std::cout);
276e5c31af7Sopenharmony_ci			return EXIT_FAILURE;
277e5c31af7Sopenharmony_ci		}
278e5c31af7Sopenharmony_ci	}
279e5c31af7Sopenharmony_ci
280e5c31af7Sopenharmony_ci	try
281e5c31af7Sopenharmony_ci	{
282e5c31af7Sopenharmony_ci		// load JSON files into VulkanPipelineCacheInput
283e5c31af7Sopenharmony_ci		vksc_server::VulkanPipelineCacheInput			input;
284e5c31af7Sopenharmony_ci		importFilesForExternalCompiler(input, cmdLine.getOption<opt::CompilerDataPath>(), cmdLine.getOption<opt::FilePrefix>());
285e5c31af7Sopenharmony_ci
286e5c31af7Sopenharmony_ci		// create Vulkan instance
287e5c31af7Sopenharmony_ci		tcu::CommandLine				cmdLineDummy	{"--deqp-vk-device-id=0"};
288e5c31af7Sopenharmony_ci		tcu::DirArchive					archive			{""};
289e5c31af7Sopenharmony_ci		tcu::TestLog					log				{ cmdLine.getOption<opt::LogFile>().c_str() }; log.supressLogging(true);
290e5c31af7Sopenharmony_ci		de::SharedPtr<tcu::Platform>	platform		{createPlatform()};
291e5c31af7Sopenharmony_ci#ifdef DE_PLATFORM_USE_LIBRARY_TYPE
292e5c31af7Sopenharmony_ci		de::SharedPtr<vk::Library>		library			{platform->getVulkanPlatform().createLibrary(vk::Platform::LIBRARY_TYPE_VULKAN, DE_NULL)};
293e5c31af7Sopenharmony_ci#else
294e5c31af7Sopenharmony_ci		de::SharedPtr<vk::Library>		library			{platform->getVulkanPlatform().createLibrary(DE_NULL)};
295e5c31af7Sopenharmony_ci#endif
296e5c31af7Sopenharmony_ci		tcu::TestContext				tcx				{*platform, archive, log, cmdLineDummy, nullptr};
297e5c31af7Sopenharmony_ci		vk::BinaryCollection			collection		{};
298e5c31af7Sopenharmony_ci		vkt::Context					context			(tcx, library->getPlatformInterface(), collection, de::SharedPtr<vk::ResourceInterface>{new vk::ResourceInterfaceStandard{ tcx }});
299e5c31af7Sopenharmony_ci
300e5c31af7Sopenharmony_ci		// create pipeline cache
301e5c31af7Sopenharmony_ci		std::vector<deUint8>			binary			= vksc_server::buildPipelineCache(
302e5c31af7Sopenharmony_ci															input,
303e5c31af7Sopenharmony_ci															library->getPlatformInterface(),
304e5c31af7Sopenharmony_ci															context.getInstance(),
305e5c31af7Sopenharmony_ci															context.getInstanceInterface(),
306e5c31af7Sopenharmony_ci															context.getPhysicalDevice(),
307e5c31af7Sopenharmony_ci															context.getUniversalQueueFamilyIndex());
308e5c31af7Sopenharmony_ci
309e5c31af7Sopenharmony_ci		// write pipeline cache to output file
310e5c31af7Sopenharmony_ci		std::ofstream					oFile			(cmdLine.getOption<opt::CompilerOutputFile>().c_str(), std::ios::out | std::ios::binary);
311e5c31af7Sopenharmony_ci		if (!oFile)
312e5c31af7Sopenharmony_ci			TCU_THROW(InternalError, (std::string("Cannot create file : ") + cmdLine.getOption<opt::CompilerOutputFile>().c_str()));
313e5c31af7Sopenharmony_ci		oFile.write(reinterpret_cast<char*>(binary.data()), binary.size());
314e5c31af7Sopenharmony_ci	}
315e5c31af7Sopenharmony_ci	catch (const std::exception& e)
316e5c31af7Sopenharmony_ci	{
317e5c31af7Sopenharmony_ci		std::cout << e.what() << std::endl;
318e5c31af7Sopenharmony_ci	}
319e5c31af7Sopenharmony_ci
320e5c31af7Sopenharmony_ci	return EXIT_SUCCESS;
321e5c31af7Sopenharmony_ci}
322