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 * \file
21e5c31af7Sopenharmony_ci * \brief Defines class for handling resources ( programs, pipelines, files, etc. )
22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/
23e5c31af7Sopenharmony_ci
24e5c31af7Sopenharmony_ci#include "vkResourceInterface.hpp"
25e5c31af7Sopenharmony_ci#include "vkQueryUtil.hpp"
26e5c31af7Sopenharmony_ci
27e5c31af7Sopenharmony_ci#ifdef CTS_USES_VULKANSC
28e5c31af7Sopenharmony_ci	#include <functional>
29e5c31af7Sopenharmony_ci	#include <fstream>
30e5c31af7Sopenharmony_ci	#include "vkSafetyCriticalUtil.hpp"
31e5c31af7Sopenharmony_ci	#include "vkRefUtil.hpp"
32e5c31af7Sopenharmony_ci	#include "tcuCommandLine.hpp"
33e5c31af7Sopenharmony_ci	#include "vksCacheBuilder.hpp"
34e5c31af7Sopenharmony_ci	#include "vksSerializer.hpp"
35e5c31af7Sopenharmony_ci	#include "vkApiVersion.hpp"
36e5c31af7Sopenharmony_ci	using namespace vksc_server::json;
37e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC
38e5c31af7Sopenharmony_ci
39e5c31af7Sopenharmony_cinamespace vk
40e5c31af7Sopenharmony_ci{
41e5c31af7Sopenharmony_ci
42e5c31af7Sopenharmony_ciResourceInterface::ResourceInterface (tcu::TestContext& testCtx)
43e5c31af7Sopenharmony_ci	: m_testCtx			(testCtx)
44e5c31af7Sopenharmony_ci#ifdef CTS_USES_VULKANSC
45e5c31af7Sopenharmony_ci	, m_commandPoolIndex		(0u)
46e5c31af7Sopenharmony_ci	, m_resourceCounter			(0u)
47e5c31af7Sopenharmony_ci	, m_statCurrent				(resetDeviceObjectReservationCreateInfo())
48e5c31af7Sopenharmony_ci	, m_statMax					(resetDeviceObjectReservationCreateInfo())
49e5c31af7Sopenharmony_ci	, m_enabledHandleDestroy	(true)
50e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC
51e5c31af7Sopenharmony_ci{
52e5c31af7Sopenharmony_ci#ifdef CTS_USES_VULKANSC
53e5c31af7Sopenharmony_ci	// pipelineCacheRequestCount does not contain one instance of createPipelineCache call that happens only in subprocess
54e5c31af7Sopenharmony_ci	m_statCurrent.pipelineCacheRequestCount		= 1u;
55e5c31af7Sopenharmony_ci	m_statMax.pipelineCacheRequestCount			= 1u;
56e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC
57e5c31af7Sopenharmony_ci}
58e5c31af7Sopenharmony_ci
59e5c31af7Sopenharmony_ciResourceInterface::~ResourceInterface ()
60e5c31af7Sopenharmony_ci{
61e5c31af7Sopenharmony_ci}
62e5c31af7Sopenharmony_ci
63e5c31af7Sopenharmony_civoid ResourceInterface::initTestCase (const std::string& casePath)
64e5c31af7Sopenharmony_ci{
65e5c31af7Sopenharmony_ci	m_currentTestPath = casePath;
66e5c31af7Sopenharmony_ci}
67e5c31af7Sopenharmony_ci
68e5c31af7Sopenharmony_ciconst std::string& ResourceInterface::getCasePath() const
69e5c31af7Sopenharmony_ci{
70e5c31af7Sopenharmony_ci	return m_currentTestPath;
71e5c31af7Sopenharmony_ci}
72e5c31af7Sopenharmony_ci
73e5c31af7Sopenharmony_ci#ifdef CTS_USES_VULKANSC
74e5c31af7Sopenharmony_civoid ResourceInterface::initApiVersion (const deUint32 version)
75e5c31af7Sopenharmony_ci{
76e5c31af7Sopenharmony_ci	const ApiVersion	apiVersion	= unpackVersion(version);
77e5c31af7Sopenharmony_ci	const bool			vulkanSC	= (apiVersion.variantNum == 1);
78e5c31af7Sopenharmony_ci
79e5c31af7Sopenharmony_ci	m_version	= tcu::Maybe<deUint32>(version);
80e5c31af7Sopenharmony_ci	m_vulkanSC	= vulkanSC;
81e5c31af7Sopenharmony_ci}
82e5c31af7Sopenharmony_ci
83e5c31af7Sopenharmony_cibool ResourceInterface::isVulkanSC (void) const
84e5c31af7Sopenharmony_ci{
85e5c31af7Sopenharmony_ci	return m_vulkanSC.get();
86e5c31af7Sopenharmony_ci}
87e5c31af7Sopenharmony_ci
88e5c31af7Sopenharmony_cideUint64 ResourceInterface::incResourceCounter ()
89e5c31af7Sopenharmony_ci{
90e5c31af7Sopenharmony_ci	return ++m_resourceCounter;
91e5c31af7Sopenharmony_ci}
92e5c31af7Sopenharmony_ci
93e5c31af7Sopenharmony_cistd::mutex& ResourceInterface::getStatMutex ()
94e5c31af7Sopenharmony_ci{
95e5c31af7Sopenharmony_ci	return m_mutex;
96e5c31af7Sopenharmony_ci}
97e5c31af7Sopenharmony_ci
98e5c31af7Sopenharmony_ciVkDeviceObjectReservationCreateInfo& ResourceInterface::getStatCurrent ()
99e5c31af7Sopenharmony_ci{
100e5c31af7Sopenharmony_ci	return m_statCurrent;
101e5c31af7Sopenharmony_ci}
102e5c31af7Sopenharmony_ci
103e5c31af7Sopenharmony_ciVkDeviceObjectReservationCreateInfo&	ResourceInterface::getStatMax ()
104e5c31af7Sopenharmony_ci{
105e5c31af7Sopenharmony_ci	return m_statMax;
106e5c31af7Sopenharmony_ci}
107e5c31af7Sopenharmony_ci
108e5c31af7Sopenharmony_ciconst VkDeviceObjectReservationCreateInfo&	ResourceInterface::getStatMax () const
109e5c31af7Sopenharmony_ci{
110e5c31af7Sopenharmony_ci	return m_statMax;
111e5c31af7Sopenharmony_ci}
112e5c31af7Sopenharmony_ci
113e5c31af7Sopenharmony_civoid ResourceInterface::setHandleDestroy(bool value)
114e5c31af7Sopenharmony_ci{
115e5c31af7Sopenharmony_ci	m_enabledHandleDestroy = value;
116e5c31af7Sopenharmony_ci}
117e5c31af7Sopenharmony_ci
118e5c31af7Sopenharmony_cibool ResourceInterface::isEnabledHandleDestroy() const
119e5c31af7Sopenharmony_ci{
120e5c31af7Sopenharmony_ci	return m_enabledHandleDestroy;
121e5c31af7Sopenharmony_ci}
122e5c31af7Sopenharmony_ci
123e5c31af7Sopenharmony_civoid ResourceInterface::removeRedundantObjects ()
124e5c31af7Sopenharmony_ci{
125e5c31af7Sopenharmony_ci	// At the end of the day we only need to export objects used in pipelines.
126e5c31af7Sopenharmony_ci	// Rest of the objects may be removed from m_json* structures as redundant
127e5c31af7Sopenharmony_ci	std::set<VkSamplerYcbcrConversion>	samplerYcbcrConversionsInPipeline;
128e5c31af7Sopenharmony_ci	std::set<VkSampler>					samplersInPipeline;
129e5c31af7Sopenharmony_ci	std::set<VkShaderModule>			shadersInPipeline;
130e5c31af7Sopenharmony_ci	std::set<VkRenderPass>				renderPassesInPipeline;
131e5c31af7Sopenharmony_ci	std::set<VkPipelineLayout>			pipelineLayoutsInPipeline;
132e5c31af7Sopenharmony_ci	std::set<VkDescriptorSetLayout>		descriptorSetLayoutsInPipeline;
133e5c31af7Sopenharmony_ci
134e5c31af7Sopenharmony_ci	Context jsonReader;
135e5c31af7Sopenharmony_ci
136e5c31af7Sopenharmony_ci	for (auto it = begin(m_pipelineInput.pipelines); it != end(m_pipelineInput.pipelines); ++it)
137e5c31af7Sopenharmony_ci	{
138e5c31af7Sopenharmony_ci		if (it->pipelineContents.find("VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO") != std::string::npos)
139e5c31af7Sopenharmony_ci		{
140e5c31af7Sopenharmony_ci			VkGraphicsPipelineCreateInfo	gpCI;
141e5c31af7Sopenharmony_ci			deMemset(&gpCI, 0, sizeof(gpCI));
142e5c31af7Sopenharmony_ci			readJSON_VkGraphicsPipelineCreateInfo(jsonReader, it->pipelineContents, gpCI);
143e5c31af7Sopenharmony_ci
144e5c31af7Sopenharmony_ci			for (deUint32 i = 0; i < gpCI.stageCount; ++i)
145e5c31af7Sopenharmony_ci				shadersInPipeline.insert(gpCI.pStages[i].module);
146e5c31af7Sopenharmony_ci			renderPassesInPipeline.insert(gpCI.renderPass);
147e5c31af7Sopenharmony_ci			pipelineLayoutsInPipeline.insert(gpCI.layout);
148e5c31af7Sopenharmony_ci		}
149e5c31af7Sopenharmony_ci		else if (it->pipelineContents.find("VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO") != std::string::npos)
150e5c31af7Sopenharmony_ci		{
151e5c31af7Sopenharmony_ci			VkComputePipelineCreateInfo	cpCI;
152e5c31af7Sopenharmony_ci			deMemset(&cpCI, 0, sizeof(cpCI));
153e5c31af7Sopenharmony_ci			readJSON_VkComputePipelineCreateInfo(jsonReader, it->pipelineContents, cpCI);
154e5c31af7Sopenharmony_ci
155e5c31af7Sopenharmony_ci			shadersInPipeline.insert(cpCI.stage.module);
156e5c31af7Sopenharmony_ci			pipelineLayoutsInPipeline.insert(cpCI.layout);
157e5c31af7Sopenharmony_ci		}
158e5c31af7Sopenharmony_ci		else
159e5c31af7Sopenharmony_ci			TCU_THROW(InternalError, "Could not recognize pipeline type");
160e5c31af7Sopenharmony_ci	}
161e5c31af7Sopenharmony_ci	for (auto it = begin(m_pipelineInput.shaderModules); it != end(m_pipelineInput.shaderModules); )
162e5c31af7Sopenharmony_ci	{
163e5c31af7Sopenharmony_ci		if (shadersInPipeline.find(it->first) == end(shadersInPipeline))
164e5c31af7Sopenharmony_ci			it = m_pipelineInput.shaderModules.erase(it);
165e5c31af7Sopenharmony_ci		else
166e5c31af7Sopenharmony_ci			++it;
167e5c31af7Sopenharmony_ci	}
168e5c31af7Sopenharmony_ci	for (auto it = begin(m_pipelineInput.renderPasses); it != end(m_pipelineInput.renderPasses); )
169e5c31af7Sopenharmony_ci	{
170e5c31af7Sopenharmony_ci		if (renderPassesInPipeline.find(it->first) == end(renderPassesInPipeline))
171e5c31af7Sopenharmony_ci			it = m_pipelineInput.renderPasses.erase(it);
172e5c31af7Sopenharmony_ci		else
173e5c31af7Sopenharmony_ci			++it;
174e5c31af7Sopenharmony_ci	}
175e5c31af7Sopenharmony_ci	for (auto it = begin(m_pipelineInput.pipelineLayouts); it != end(m_pipelineInput.pipelineLayouts); )
176e5c31af7Sopenharmony_ci	{
177e5c31af7Sopenharmony_ci		if (pipelineLayoutsInPipeline.find(it->first) == end(pipelineLayoutsInPipeline))
178e5c31af7Sopenharmony_ci		{
179e5c31af7Sopenharmony_ci			it = m_pipelineInput.pipelineLayouts.erase(it);
180e5c31af7Sopenharmony_ci		}
181e5c31af7Sopenharmony_ci		else
182e5c31af7Sopenharmony_ci		{
183e5c31af7Sopenharmony_ci			VkPipelineLayoutCreateInfo	plCI;
184e5c31af7Sopenharmony_ci			deMemset(&plCI, 0, sizeof(plCI));
185e5c31af7Sopenharmony_ci			readJSON_VkPipelineLayoutCreateInfo(jsonReader, it->second, plCI);
186e5c31af7Sopenharmony_ci			for (deUint32 i = 0; i < plCI.setLayoutCount; ++i)
187e5c31af7Sopenharmony_ci				descriptorSetLayoutsInPipeline.insert(plCI.pSetLayouts[i]);
188e5c31af7Sopenharmony_ci			++it;
189e5c31af7Sopenharmony_ci		}
190e5c31af7Sopenharmony_ci	}
191e5c31af7Sopenharmony_ci	for (auto it = begin(m_pipelineInput.descriptorSetLayouts); it != end(m_pipelineInput.descriptorSetLayouts); )
192e5c31af7Sopenharmony_ci	{
193e5c31af7Sopenharmony_ci		if (descriptorSetLayoutsInPipeline.find(it->first) == end(descriptorSetLayoutsInPipeline))
194e5c31af7Sopenharmony_ci			it = m_pipelineInput.descriptorSetLayouts.erase(it);
195e5c31af7Sopenharmony_ci		else
196e5c31af7Sopenharmony_ci		{
197e5c31af7Sopenharmony_ci			VkDescriptorSetLayoutCreateInfo	dsCI;
198e5c31af7Sopenharmony_ci			deMemset(&dsCI, 0, sizeof(dsCI));
199e5c31af7Sopenharmony_ci			readJSON_VkDescriptorSetLayoutCreateInfo(jsonReader, it->second, dsCI);
200e5c31af7Sopenharmony_ci
201e5c31af7Sopenharmony_ci			for (deUint32 i = 0; i < dsCI.bindingCount; ++i)
202e5c31af7Sopenharmony_ci			{
203e5c31af7Sopenharmony_ci				if (dsCI.pBindings[i].pImmutableSamplers == NULL)
204e5c31af7Sopenharmony_ci					continue;
205e5c31af7Sopenharmony_ci				for (deUint32 j = 0; j < dsCI.pBindings[i].descriptorCount; ++j)
206e5c31af7Sopenharmony_ci				{
207e5c31af7Sopenharmony_ci					if (dsCI.pBindings[i].pImmutableSamplers[j] == DE_NULL)
208e5c31af7Sopenharmony_ci						continue;
209e5c31af7Sopenharmony_ci					samplersInPipeline.insert(dsCI.pBindings[i].pImmutableSamplers[j]);
210e5c31af7Sopenharmony_ci				}
211e5c31af7Sopenharmony_ci			}
212e5c31af7Sopenharmony_ci			++it;
213e5c31af7Sopenharmony_ci		}
214e5c31af7Sopenharmony_ci	}
215e5c31af7Sopenharmony_ci
216e5c31af7Sopenharmony_ci	for (auto it = begin(m_pipelineInput.samplers); it != end(m_pipelineInput.samplers); )
217e5c31af7Sopenharmony_ci	{
218e5c31af7Sopenharmony_ci		if (samplersInPipeline.find(it->first) == end(samplersInPipeline))
219e5c31af7Sopenharmony_ci			it = m_pipelineInput.samplers.erase(it);
220e5c31af7Sopenharmony_ci		else
221e5c31af7Sopenharmony_ci		{
222e5c31af7Sopenharmony_ci			VkSamplerCreateInfo	sCI;
223e5c31af7Sopenharmony_ci			deMemset(&sCI, 0, sizeof(sCI));
224e5c31af7Sopenharmony_ci			readJSON_VkSamplerCreateInfo(jsonReader, it->second, sCI);
225e5c31af7Sopenharmony_ci
226e5c31af7Sopenharmony_ci			if (sCI.pNext != DE_NULL)
227e5c31af7Sopenharmony_ci			{
228e5c31af7Sopenharmony_ci				VkSamplerYcbcrConversionInfo* info = (VkSamplerYcbcrConversionInfo*)(sCI.pNext);
229e5c31af7Sopenharmony_ci				if (info->sType == VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO)
230e5c31af7Sopenharmony_ci					samplerYcbcrConversionsInPipeline.insert(info->conversion);
231e5c31af7Sopenharmony_ci			}
232e5c31af7Sopenharmony_ci			++it;
233e5c31af7Sopenharmony_ci		}
234e5c31af7Sopenharmony_ci	}
235e5c31af7Sopenharmony_ci	for (auto it = begin(m_pipelineInput.samplerYcbcrConversions); it != end(m_pipelineInput.samplerYcbcrConversions); )
236e5c31af7Sopenharmony_ci	{
237e5c31af7Sopenharmony_ci		if (samplerYcbcrConversionsInPipeline.find(it->first) == end(samplerYcbcrConversionsInPipeline))
238e5c31af7Sopenharmony_ci			it = m_pipelineInput.samplerYcbcrConversions.erase(it);
239e5c31af7Sopenharmony_ci		else
240e5c31af7Sopenharmony_ci			++it;
241e5c31af7Sopenharmony_ci	}
242e5c31af7Sopenharmony_ci}
243e5c31af7Sopenharmony_ci
244e5c31af7Sopenharmony_civoid ResourceInterface::finalizeCommandBuffers ()
245e5c31af7Sopenharmony_ci{
246e5c31af7Sopenharmony_ci	// We have information about command buffer sizes
247e5c31af7Sopenharmony_ci	// Now we have to convert it into command pool sizes
248e5c31af7Sopenharmony_ci	std::map<deUint64, std::size_t> cpToIndex;
249e5c31af7Sopenharmony_ci	for (std::size_t i = 0; i < m_commandPoolMemoryConsumption.size(); ++i)
250e5c31af7Sopenharmony_ci		cpToIndex.insert({ m_commandPoolMemoryConsumption[i].commandPool, i });
251e5c31af7Sopenharmony_ci	for (const auto& memC : m_commandBufferMemoryConsumption)
252e5c31af7Sopenharmony_ci	{
253e5c31af7Sopenharmony_ci		std::size_t j = cpToIndex[memC.second.commandPool];
254e5c31af7Sopenharmony_ci		m_commandPoolMemoryConsumption[j].updateValues
255e5c31af7Sopenharmony_ci		(
256e5c31af7Sopenharmony_ci			memC.second.maxCommandPoolAllocated,
257e5c31af7Sopenharmony_ci			memC.second.maxCommandPoolReservedSize,
258e5c31af7Sopenharmony_ci			memC.second.maxCommandBufferAllocated
259e5c31af7Sopenharmony_ci		);
260e5c31af7Sopenharmony_ci		m_commandPoolMemoryConsumption[j].commandBufferCount++;
261e5c31af7Sopenharmony_ci	}
262e5c31af7Sopenharmony_ci	// Each m_commandPoolMemoryConsumption element must have at least one command buffer ( see DeviceDriverSC::createCommandPoolHandlerNorm() )
263e5c31af7Sopenharmony_ci	// As a result we have to ensure that commandBufferRequestCount is not less than the number of command pools
264e5c31af7Sopenharmony_ci	m_statMax.commandBufferRequestCount = de::max(deUint32(m_commandPoolMemoryConsumption.size()), m_statMax.commandBufferRequestCount);
265e5c31af7Sopenharmony_ci}
266e5c31af7Sopenharmony_ci
267e5c31af7Sopenharmony_cistd::vector<deUint8> ResourceInterface::exportData () const
268e5c31af7Sopenharmony_ci{
269e5c31af7Sopenharmony_ci	vksc_server::VulkanDataTransmittedFromMainToSubprocess vdtfmtsp(m_pipelineInput, m_statMax, m_commandPoolMemoryConsumption, m_pipelineSizes);
270e5c31af7Sopenharmony_ci
271e5c31af7Sopenharmony_ci	return vksc_server::Serialize(vdtfmtsp);
272e5c31af7Sopenharmony_ci}
273e5c31af7Sopenharmony_ci
274e5c31af7Sopenharmony_civoid ResourceInterface::importData (std::vector<deUint8>& importText) const
275e5c31af7Sopenharmony_ci{
276e5c31af7Sopenharmony_ci	vksc_server::VulkanDataTransmittedFromMainToSubprocess vdtfmtsp = vksc_server::Deserialize<vksc_server::VulkanDataTransmittedFromMainToSubprocess>(importText);
277e5c31af7Sopenharmony_ci
278e5c31af7Sopenharmony_ci	m_pipelineInput					= vdtfmtsp.pipelineCacheInput;
279e5c31af7Sopenharmony_ci	m_statMax						= vdtfmtsp.memoryReservation;
280e5c31af7Sopenharmony_ci	m_commandPoolMemoryConsumption	= vdtfmtsp.commandPoolMemoryConsumption;
281e5c31af7Sopenharmony_ci	m_pipelineSizes					= vdtfmtsp.pipelineSizes;
282e5c31af7Sopenharmony_ci}
283e5c31af7Sopenharmony_ci
284e5c31af7Sopenharmony_civoid ResourceInterface::registerObjectHash (deUint64 handle, std::size_t hashValue) const
285e5c31af7Sopenharmony_ci{
286e5c31af7Sopenharmony_ci	m_objectHashes[handle] =  hashValue;
287e5c31af7Sopenharmony_ci}
288e5c31af7Sopenharmony_ci
289e5c31af7Sopenharmony_ciconst std::map<deUint64,std::size_t>& ResourceInterface::getObjectHashes () const
290e5c31af7Sopenharmony_ci{
291e5c31af7Sopenharmony_ci	return m_objectHashes;
292e5c31af7Sopenharmony_ci}
293e5c31af7Sopenharmony_ci
294e5c31af7Sopenharmony_cistruct PipelinePoolSizeInfo
295e5c31af7Sopenharmony_ci{
296e5c31af7Sopenharmony_ci	deUint32					maxTestCount;
297e5c31af7Sopenharmony_ci	deUint32					size;
298e5c31af7Sopenharmony_ci};
299e5c31af7Sopenharmony_ci
300e5c31af7Sopenharmony_civoid ResourceInterface::preparePipelinePoolSizes()
301e5c31af7Sopenharmony_ci{
302e5c31af7Sopenharmony_ci	std::map<std::string, std::vector<PipelinePoolSizeInfo>> pipelineInfoPerTest;
303e5c31af7Sopenharmony_ci
304e5c31af7Sopenharmony_ci	// Step 1: collect information about all pipelines in each test, group by size
305e5c31af7Sopenharmony_ci	for (const auto& pipeline : m_pipelineInput.pipelines)
306e5c31af7Sopenharmony_ci	{
307e5c31af7Sopenharmony_ci		auto it = std::find_if(begin(m_pipelineSizes), end(m_pipelineSizes), vksc_server::PipelineIdentifierEqual(pipeline.id));
308e5c31af7Sopenharmony_ci		if (it == end(m_pipelineSizes))
309e5c31af7Sopenharmony_ci			TCU_THROW(InternalError, "VkPipelinePoolEntrySizeCreateInfo not created for pipelineIdentifier");
310e5c31af7Sopenharmony_ci
311e5c31af7Sopenharmony_ci		PipelinePoolSizeInfo ppsi
312e5c31af7Sopenharmony_ci		{
313e5c31af7Sopenharmony_ci			it->count,
314e5c31af7Sopenharmony_ci			it->size
315e5c31af7Sopenharmony_ci		};
316e5c31af7Sopenharmony_ci
317e5c31af7Sopenharmony_ci		for (const auto& test : pipeline.tests)
318e5c31af7Sopenharmony_ci		{
319e5c31af7Sopenharmony_ci			auto pit = pipelineInfoPerTest.find(test);
320e5c31af7Sopenharmony_ci			if (pit == end(pipelineInfoPerTest))
321e5c31af7Sopenharmony_ci				pit = pipelineInfoPerTest.insert({ test, std::vector<PipelinePoolSizeInfo>() }).first;
322e5c31af7Sopenharmony_ci			// group by the same sizes in a test
323e5c31af7Sopenharmony_ci			bool found = false;
324e5c31af7Sopenharmony_ci			for (size_t i = 0; i<pit->second.size(); ++i)
325e5c31af7Sopenharmony_ci			{
326e5c31af7Sopenharmony_ci				if (pit->second[i].size == ppsi.size)
327e5c31af7Sopenharmony_ci				{
328e5c31af7Sopenharmony_ci					pit->second[i].maxTestCount += ppsi.maxTestCount;
329e5c31af7Sopenharmony_ci					found = true;
330e5c31af7Sopenharmony_ci					break;
331e5c31af7Sopenharmony_ci				}
332e5c31af7Sopenharmony_ci			}
333e5c31af7Sopenharmony_ci			if(!found)
334e5c31af7Sopenharmony_ci				pit->second.push_back(ppsi);
335e5c31af7Sopenharmony_ci		}
336e5c31af7Sopenharmony_ci	}
337e5c31af7Sopenharmony_ci
338e5c31af7Sopenharmony_ci	// Step 2: choose pipeline pool sizes
339e5c31af7Sopenharmony_ci	std::vector<PipelinePoolSizeInfo> finalPoolSizes;
340e5c31af7Sopenharmony_ci	for (const auto& pInfo : pipelineInfoPerTest)
341e5c31af7Sopenharmony_ci	{
342e5c31af7Sopenharmony_ci		for (const auto& ppsi1 : pInfo.second)
343e5c31af7Sopenharmony_ci		{
344e5c31af7Sopenharmony_ci			auto it = std::find_if(begin(finalPoolSizes), end(finalPoolSizes), [&ppsi1](const PipelinePoolSizeInfo& x) { return (x.size == ppsi1.size); });
345e5c31af7Sopenharmony_ci			if (it != end(finalPoolSizes))
346e5c31af7Sopenharmony_ci				it->maxTestCount = de::max(it->maxTestCount, ppsi1.maxTestCount);
347e5c31af7Sopenharmony_ci			else
348e5c31af7Sopenharmony_ci				finalPoolSizes.push_back(ppsi1);
349e5c31af7Sopenharmony_ci		}
350e5c31af7Sopenharmony_ci	}
351e5c31af7Sopenharmony_ci
352e5c31af7Sopenharmony_ci	// Step 3: convert results to VkPipelinePoolSize
353e5c31af7Sopenharmony_ci	m_pipelinePoolSizes.clear();
354e5c31af7Sopenharmony_ci	for (const auto& ppsi : finalPoolSizes)
355e5c31af7Sopenharmony_ci	{
356e5c31af7Sopenharmony_ci		VkPipelinePoolSize poolSize =
357e5c31af7Sopenharmony_ci		{
358e5c31af7Sopenharmony_ci			VK_STRUCTURE_TYPE_PIPELINE_POOL_SIZE,	// VkStructureType	sType;
359e5c31af7Sopenharmony_ci			DE_NULL,								// const void*		pNext;
360e5c31af7Sopenharmony_ci			ppsi.size,								// VkDeviceSize		poolEntrySize;
361e5c31af7Sopenharmony_ci			ppsi.maxTestCount						// deUint32			poolEntryCount;
362e5c31af7Sopenharmony_ci		};
363e5c31af7Sopenharmony_ci		m_pipelinePoolSizes.emplace_back(poolSize);
364e5c31af7Sopenharmony_ci	}
365e5c31af7Sopenharmony_ci}
366e5c31af7Sopenharmony_ci
367e5c31af7Sopenharmony_cistd::vector<VkPipelinePoolSize> ResourceInterface::getPipelinePoolSizes () const
368e5c31af7Sopenharmony_ci{
369e5c31af7Sopenharmony_ci	return m_pipelinePoolSizes;
370e5c31af7Sopenharmony_ci}
371e5c31af7Sopenharmony_ci
372e5c31af7Sopenharmony_civoid ResourceInterface::fillPoolEntrySize (vk::VkPipelineOfflineCreateInfo&	pipelineIdentifier) const
373e5c31af7Sopenharmony_ci{
374e5c31af7Sopenharmony_ci	auto it = std::find_if(begin(m_pipelineSizes), end(m_pipelineSizes), vksc_server::PipelineIdentifierEqual(pipelineIdentifier));
375e5c31af7Sopenharmony_ci	if( it == end(m_pipelineSizes) )
376e5c31af7Sopenharmony_ci		TCU_THROW(InternalError, "VkPipelinePoolEntrySizeCreateInfo not created for pipelineIdentifier");
377e5c31af7Sopenharmony_ci	pipelineIdentifier.poolEntrySize = it->size;
378e5c31af7Sopenharmony_ci}
379e5c31af7Sopenharmony_ci
380e5c31af7Sopenharmony_civksc_server::VulkanCommandMemoryConsumption ResourceInterface::getNextCommandPoolSize ()
381e5c31af7Sopenharmony_ci{
382e5c31af7Sopenharmony_ci	if (m_commandPoolMemoryConsumption.empty())
383e5c31af7Sopenharmony_ci		return vksc_server::VulkanCommandMemoryConsumption();
384e5c31af7Sopenharmony_ci
385e5c31af7Sopenharmony_ci	vksc_server::VulkanCommandMemoryConsumption result	= m_commandPoolMemoryConsumption[m_commandPoolIndex];
386e5c31af7Sopenharmony_ci	// modulo operation is just a safeguard against excessive number of requests
387e5c31af7Sopenharmony_ci	m_commandPoolIndex									= (m_commandPoolIndex + 1) % deUint32(m_commandPoolMemoryConsumption.size());
388e5c31af7Sopenharmony_ci	return result;
389e5c31af7Sopenharmony_ci}
390e5c31af7Sopenharmony_ci
391e5c31af7Sopenharmony_cistd::size_t	ResourceInterface::getCacheDataSize () const
392e5c31af7Sopenharmony_ci{
393e5c31af7Sopenharmony_ci	return m_cacheData.size();
394e5c31af7Sopenharmony_ci}
395e5c31af7Sopenharmony_ci
396e5c31af7Sopenharmony_ciconst deUint8* ResourceInterface::getCacheData () const
397e5c31af7Sopenharmony_ci{
398e5c31af7Sopenharmony_ci	return m_cacheData.data();
399e5c31af7Sopenharmony_ci}
400e5c31af7Sopenharmony_ci
401e5c31af7Sopenharmony_ciVkPipelineCache ResourceInterface::getPipelineCache(VkDevice device) const
402e5c31af7Sopenharmony_ci{
403e5c31af7Sopenharmony_ci	auto pit = m_pipelineCache.find(device);
404e5c31af7Sopenharmony_ci	if (pit == end(m_pipelineCache))
405e5c31af7Sopenharmony_ci		TCU_THROW(InternalError, "m_pipelineCache not found for this device");
406e5c31af7Sopenharmony_ci	return pit->second.get()->get();
407e5c31af7Sopenharmony_ci}
408e5c31af7Sopenharmony_ci
409e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC
410e5c31af7Sopenharmony_ci
411e5c31af7Sopenharmony_ciResourceInterfaceStandard::ResourceInterfaceStandard (tcu::TestContext& testCtx)
412e5c31af7Sopenharmony_ci	: ResourceInterface(testCtx)
413e5c31af7Sopenharmony_ci{
414e5c31af7Sopenharmony_ci}
415e5c31af7Sopenharmony_ci
416e5c31af7Sopenharmony_civoid ResourceInterfaceStandard::initDevice (DeviceInterface& deviceInterface, VkDevice device)
417e5c31af7Sopenharmony_ci{
418e5c31af7Sopenharmony_ci	// ResourceInterfaceStandard is a class for running VulkanSC tests on normal Vulkan driver.
419e5c31af7Sopenharmony_ci	// CTS does not have vkCreateShaderModule function defined for Vulkan SC driver, but we need this function
420e5c31af7Sopenharmony_ci	// So ResourceInterfaceStandard class must have its own vkCreateShaderModule function pointer
421e5c31af7Sopenharmony_ci	// Moreover - we create additional function pointers for vkCreateGraphicsPipelines, vkCreateComputePipelines, etc.
422e5c31af7Sopenharmony_ci	// BTW: although ResourceInterfaceStandard exists in normal Vulkan tests - only initDevice and buildProgram functions are used by Vulkan tests
423e5c31af7Sopenharmony_ci	// Other functions are called from within DeviceDriverSC which does not exist in these tests ( DeviceDriver class is used instead )
424e5c31af7Sopenharmony_ci	m_createShaderModuleFunc[device]				= (CreateShaderModuleFunc)				deviceInterface.getDeviceProcAddr(device, "vkCreateShaderModule");
425e5c31af7Sopenharmony_ci	m_createGraphicsPipelinesFunc[device]			= (CreateGraphicsPipelinesFunc)			deviceInterface.getDeviceProcAddr(device, "vkCreateGraphicsPipelines");
426e5c31af7Sopenharmony_ci	m_createComputePipelinesFunc[device]			= (CreateComputePipelinesFunc)			deviceInterface.getDeviceProcAddr(device, "vkCreateComputePipelines");
427e5c31af7Sopenharmony_ci#ifdef CTS_USES_VULKANSC
428e5c31af7Sopenharmony_ci	if (m_testCtx.getCommandLine().isSubProcess())
429e5c31af7Sopenharmony_ci	{
430e5c31af7Sopenharmony_ci		if (m_cacheData.size() > 0)
431e5c31af7Sopenharmony_ci		{
432e5c31af7Sopenharmony_ci			VkPipelineCacheCreateInfo pCreateInfo =
433e5c31af7Sopenharmony_ci			{
434e5c31af7Sopenharmony_ci				VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,				// VkStructureType				sType;
435e5c31af7Sopenharmony_ci				DE_NULL,													// const void*					pNext;
436e5c31af7Sopenharmony_ci				VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT |
437e5c31af7Sopenharmony_ci					VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT,	// VkPipelineCacheCreateFlags	flags;
438e5c31af7Sopenharmony_ci				m_cacheData.size(),											// deUintptr					initialDataSize;
439e5c31af7Sopenharmony_ci				m_cacheData.data()											// const void*					pInitialData;
440e5c31af7Sopenharmony_ci			};
441e5c31af7Sopenharmony_ci			m_pipelineCache[device] = de::SharedPtr<Move<VkPipelineCache>>(new Move<VkPipelineCache>(createPipelineCache(deviceInterface, device, &pCreateInfo, DE_NULL)));
442e5c31af7Sopenharmony_ci		}
443e5c31af7Sopenharmony_ci	}
444e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC
445e5c31af7Sopenharmony_ci}
446e5c31af7Sopenharmony_ci
447e5c31af7Sopenharmony_civoid ResourceInterfaceStandard::deinitDevice (VkDevice device)
448e5c31af7Sopenharmony_ci{
449e5c31af7Sopenharmony_ci#ifdef CTS_USES_VULKANSC
450e5c31af7Sopenharmony_ci	if (m_testCtx.getCommandLine().isSubProcess())
451e5c31af7Sopenharmony_ci	{
452e5c31af7Sopenharmony_ci		m_pipelineCache.erase(device);
453e5c31af7Sopenharmony_ci	}
454e5c31af7Sopenharmony_ci#else
455e5c31af7Sopenharmony_ci	DE_UNREF(device);
456e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC
457e5c31af7Sopenharmony_ci}
458e5c31af7Sopenharmony_ci
459e5c31af7Sopenharmony_ci#ifdef CTS_USES_VULKANSC
460e5c31af7Sopenharmony_ci
461e5c31af7Sopenharmony_civoid ResourceInterfaceStandard::registerDeviceFeatures (VkDevice							device,
462e5c31af7Sopenharmony_ci														const VkDeviceCreateInfo*			pCreateInfo) const
463e5c31af7Sopenharmony_ci{
464e5c31af7Sopenharmony_ci	VkPhysicalDeviceFeatures2* chainedFeatures		= (VkPhysicalDeviceFeatures2*)findStructureInChain(pCreateInfo->pNext, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2);
465e5c31af7Sopenharmony_ci	if (chainedFeatures != NULL)
466e5c31af7Sopenharmony_ci	{
467e5c31af7Sopenharmony_ci		m_deviceFeatures[device]					= writeJSON_pNextChain(pCreateInfo->pNext);
468e5c31af7Sopenharmony_ci	}
469e5c31af7Sopenharmony_ci	else
470e5c31af7Sopenharmony_ci	{
471e5c31af7Sopenharmony_ci		VkPhysicalDeviceFeatures2 deviceFeatures2	= initVulkanStructure();
472e5c31af7Sopenharmony_ci		if (pCreateInfo->pEnabledFeatures != NULL)
473e5c31af7Sopenharmony_ci			deviceFeatures2.features = *(pCreateInfo->pEnabledFeatures);
474e5c31af7Sopenharmony_ci
475e5c31af7Sopenharmony_ci		deviceFeatures2.pNext						= (void *)pCreateInfo->pNext;
476e5c31af7Sopenharmony_ci		m_deviceFeatures[device]					= writeJSON_VkPhysicalDeviceFeatures2(deviceFeatures2);
477e5c31af7Sopenharmony_ci	}
478e5c31af7Sopenharmony_ci
479e5c31af7Sopenharmony_ci	std::vector<std::string> extensions;
480e5c31af7Sopenharmony_ci	for (deUint32 i = 0; i < pCreateInfo->enabledExtensionCount; ++i)
481e5c31af7Sopenharmony_ci		extensions.push_back(pCreateInfo->ppEnabledExtensionNames[i]);
482e5c31af7Sopenharmony_ci	m_deviceExtensions[device]					= extensions;
483e5c31af7Sopenharmony_ci}
484e5c31af7Sopenharmony_ci
485e5c31af7Sopenharmony_civoid ResourceInterfaceStandard::unregisterDeviceFeatures(VkDevice							device) const
486e5c31af7Sopenharmony_ci{
487e5c31af7Sopenharmony_ci	m_deviceFeatures.erase(device);
488e5c31af7Sopenharmony_ci	m_deviceExtensions.erase(device);
489e5c31af7Sopenharmony_ci}
490e5c31af7Sopenharmony_ci
491e5c31af7Sopenharmony_ciVkResult ResourceInterfaceStandard::createShaderModule (VkDevice							device,
492e5c31af7Sopenharmony_ci														const VkShaderModuleCreateInfo*		pCreateInfo,
493e5c31af7Sopenharmony_ci														const VkAllocationCallbacks*		pAllocator,
494e5c31af7Sopenharmony_ci														VkShaderModule*						pShaderModule,
495e5c31af7Sopenharmony_ci														bool								normalMode) const
496e5c31af7Sopenharmony_ci{
497e5c31af7Sopenharmony_ci	if (normalMode)
498e5c31af7Sopenharmony_ci	{
499e5c31af7Sopenharmony_ci		if (isVulkanSC())
500e5c31af7Sopenharmony_ci		{
501e5c31af7Sopenharmony_ci			*pShaderModule = VkShaderModule(++m_resourceCounter);
502e5c31af7Sopenharmony_ci			registerObjectHash(pShaderModule->getInternal(), calculateShaderModuleHash(*pCreateInfo, getObjectHashes()));
503e5c31af7Sopenharmony_ci			return VK_SUCCESS;
504e5c31af7Sopenharmony_ci		}
505e5c31af7Sopenharmony_ci		else
506e5c31af7Sopenharmony_ci		{
507e5c31af7Sopenharmony_ci			const auto it = m_createShaderModuleFunc.find(device);
508e5c31af7Sopenharmony_ci			if (it != end(m_createShaderModuleFunc))
509e5c31af7Sopenharmony_ci			{
510e5c31af7Sopenharmony_ci				VkResult result = it->second(device, pCreateInfo, pAllocator, pShaderModule);
511e5c31af7Sopenharmony_ci				registerObjectHash(pShaderModule->getInternal(), calculateShaderModuleHash(*pCreateInfo, getObjectHashes()));
512e5c31af7Sopenharmony_ci				return result;
513e5c31af7Sopenharmony_ci			}
514e5c31af7Sopenharmony_ci			TCU_THROW(InternalError, "vkCreateShaderModule not defined");
515e5c31af7Sopenharmony_ci		}
516e5c31af7Sopenharmony_ci	}
517e5c31af7Sopenharmony_ci
518e5c31af7Sopenharmony_ci	// main process: store VkShaderModuleCreateInfo in JSON format. Shaders will be sent later for m_pipelineCache creation ( and sent through file to another process )
519e5c31af7Sopenharmony_ci	*pShaderModule = VkShaderModule(++m_resourceCounter);
520e5c31af7Sopenharmony_ci	registerObjectHash(pShaderModule->getInternal(), calculateShaderModuleHash(*pCreateInfo, getObjectHashes()));
521e5c31af7Sopenharmony_ci	m_pipelineInput.shaderModules.insert({ *pShaderModule, writeJSON_VkShaderModuleCreateInfo(*pCreateInfo) });
522e5c31af7Sopenharmony_ci	return VK_SUCCESS;
523e5c31af7Sopenharmony_ci}
524e5c31af7Sopenharmony_ci
525e5c31af7Sopenharmony_ciVkPipelineOfflineCreateInfo makeGraphicsPipelineIdentifier (const std::string& testPath, const VkGraphicsPipelineCreateInfo& gpCI, const std::map<deUint64, std::size_t>& objectHashes)
526e5c31af7Sopenharmony_ci{
527e5c31af7Sopenharmony_ci	DE_UNREF(testPath);
528e5c31af7Sopenharmony_ci	VkPipelineOfflineCreateInfo	pipelineID		= resetPipelineOfflineCreateInfo();
529e5c31af7Sopenharmony_ci	std::size_t					hashValue		= calculateGraphicsPipelineHash(gpCI, objectHashes);
530e5c31af7Sopenharmony_ci	memcpy(pipelineID.pipelineIdentifier, &hashValue, sizeof(std::size_t));
531e5c31af7Sopenharmony_ci	return pipelineID;
532e5c31af7Sopenharmony_ci}
533e5c31af7Sopenharmony_ci
534e5c31af7Sopenharmony_ciVkPipelineOfflineCreateInfo makeComputePipelineIdentifier (const std::string& testPath, const VkComputePipelineCreateInfo& cpCI, const std::map<deUint64, std::size_t>& objectHashes)
535e5c31af7Sopenharmony_ci{
536e5c31af7Sopenharmony_ci	DE_UNREF(testPath);
537e5c31af7Sopenharmony_ci	VkPipelineOfflineCreateInfo	pipelineID		= resetPipelineOfflineCreateInfo();
538e5c31af7Sopenharmony_ci	std::size_t					hashValue		= calculateComputePipelineHash(cpCI, objectHashes);
539e5c31af7Sopenharmony_ci	memcpy(pipelineID.pipelineIdentifier, &hashValue, sizeof(std::size_t));
540e5c31af7Sopenharmony_ci	return pipelineID;
541e5c31af7Sopenharmony_ci}
542e5c31af7Sopenharmony_ci
543e5c31af7Sopenharmony_ciVkResult ResourceInterfaceStandard::createGraphicsPipelines (VkDevice								device,
544e5c31af7Sopenharmony_ci															 VkPipelineCache						pipelineCache,
545e5c31af7Sopenharmony_ci															 deUint32								createInfoCount,
546e5c31af7Sopenharmony_ci															 const VkGraphicsPipelineCreateInfo*	pCreateInfos,
547e5c31af7Sopenharmony_ci															 const VkAllocationCallbacks*			pAllocator,
548e5c31af7Sopenharmony_ci															 VkPipeline*							pPipelines,
549e5c31af7Sopenharmony_ci															 bool									normalMode) const
550e5c31af7Sopenharmony_ci{
551e5c31af7Sopenharmony_ci	DE_UNREF(pipelineCache);
552e5c31af7Sopenharmony_ci
553e5c31af7Sopenharmony_ci	// build pipeline identifiers (if required), make a copy of pCreateInfos
554e5c31af7Sopenharmony_ci	std::vector<VkPipelineOfflineCreateInfo>		pipelineIDs;
555e5c31af7Sopenharmony_ci	std::vector<deUint8>							idInPNextChain;
556e5c31af7Sopenharmony_ci	std::vector<VkGraphicsPipelineCreateInfo>		pCreateInfoCopies;
557e5c31af7Sopenharmony_ci
558e5c31af7Sopenharmony_ci	for (deUint32 i = 0; i < createInfoCount; ++i)
559e5c31af7Sopenharmony_ci	{
560e5c31af7Sopenharmony_ci		pCreateInfoCopies.push_back(pCreateInfos[i]);
561e5c31af7Sopenharmony_ci
562e5c31af7Sopenharmony_ci		// Check if test added pipeline identifier on its own
563e5c31af7Sopenharmony_ci		VkPipelineOfflineCreateInfo* idInfo = (VkPipelineOfflineCreateInfo*)findStructureInChain(pCreateInfos[i].pNext, VK_STRUCTURE_TYPE_PIPELINE_OFFLINE_CREATE_INFO);
564e5c31af7Sopenharmony_ci		if (idInfo == DE_NULL)
565e5c31af7Sopenharmony_ci		{
566e5c31af7Sopenharmony_ci			pipelineIDs.push_back(makeGraphicsPipelineIdentifier(m_currentTestPath, pCreateInfos[i], getObjectHashes()));
567e5c31af7Sopenharmony_ci			idInPNextChain.push_back(0);
568e5c31af7Sopenharmony_ci		}
569e5c31af7Sopenharmony_ci		else
570e5c31af7Sopenharmony_ci		{
571e5c31af7Sopenharmony_ci			pipelineIDs.push_back(*idInfo);
572e5c31af7Sopenharmony_ci			idInPNextChain.push_back(1);
573e5c31af7Sopenharmony_ci		}
574e5c31af7Sopenharmony_ci
575e5c31af7Sopenharmony_ci		if (normalMode)
576e5c31af7Sopenharmony_ci			fillPoolEntrySize(pipelineIDs.back());
577e5c31af7Sopenharmony_ci	}
578e5c31af7Sopenharmony_ci
579e5c31af7Sopenharmony_ci	// reset not used pointers, so that JSON generation does not crash
580e5c31af7Sopenharmony_ci	std::vector<VkPipelineViewportStateCreateInfo>	viewportStateCopies	(createInfoCount);
581e5c31af7Sopenharmony_ci	if (!normalMode)
582e5c31af7Sopenharmony_ci	{
583e5c31af7Sopenharmony_ci		for (deUint32 i = 0; i < createInfoCount; ++i)
584e5c31af7Sopenharmony_ci		{
585e5c31af7Sopenharmony_ci			bool vertexInputStateRequired		= false;
586e5c31af7Sopenharmony_ci			bool inputAssemblyStateRequired		= false;
587e5c31af7Sopenharmony_ci			bool tessellationStateRequired		= false;
588e5c31af7Sopenharmony_ci			bool viewportStateRequired			= false;
589e5c31af7Sopenharmony_ci			bool viewportStateViewportsRequired	= false;
590e5c31af7Sopenharmony_ci			bool viewportStateScissorsRequired	= false;
591e5c31af7Sopenharmony_ci			bool multiSampleStateRequired		= false;
592e5c31af7Sopenharmony_ci			bool depthStencilStateRequired		= false;
593e5c31af7Sopenharmony_ci			bool colorBlendStateRequired		= false;
594e5c31af7Sopenharmony_ci
595e5c31af7Sopenharmony_ci			if (pCreateInfoCopies[i].pStages != DE_NULL)
596e5c31af7Sopenharmony_ci			{
597e5c31af7Sopenharmony_ci				for (deUint32 j = 0; j < pCreateInfoCopies[i].stageCount; ++j)
598e5c31af7Sopenharmony_ci				{
599e5c31af7Sopenharmony_ci					if (pCreateInfoCopies[i].pStages[j].stage == VK_SHADER_STAGE_VERTEX_BIT)
600e5c31af7Sopenharmony_ci					{
601e5c31af7Sopenharmony_ci						vertexInputStateRequired	= true;
602e5c31af7Sopenharmony_ci						inputAssemblyStateRequired	= true;
603e5c31af7Sopenharmony_ci					}
604e5c31af7Sopenharmony_ci					if (pCreateInfoCopies[i].pStages[j].stage == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
605e5c31af7Sopenharmony_ci					{
606e5c31af7Sopenharmony_ci						tessellationStateRequired	= true;
607e5c31af7Sopenharmony_ci					}
608e5c31af7Sopenharmony_ci				}
609e5c31af7Sopenharmony_ci			}
610e5c31af7Sopenharmony_ci			if (pCreateInfoCopies[i].pDynamicState != DE_NULL)
611e5c31af7Sopenharmony_ci			{
612e5c31af7Sopenharmony_ci				if (pCreateInfoCopies[i].pDynamicState->pDynamicStates != DE_NULL)
613e5c31af7Sopenharmony_ci					for (deUint32 j = 0; j < pCreateInfoCopies[i].pDynamicState->dynamicStateCount; ++j)
614e5c31af7Sopenharmony_ci					{
615e5c31af7Sopenharmony_ci						if (pCreateInfoCopies[i].pDynamicState->pDynamicStates[j] == VK_DYNAMIC_STATE_VIEWPORT || pCreateInfoCopies[i].pDynamicState->pDynamicStates[j] == VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT)
616e5c31af7Sopenharmony_ci						{
617e5c31af7Sopenharmony_ci							viewportStateRequired			= true;
618e5c31af7Sopenharmony_ci							viewportStateViewportsRequired	= true;
619e5c31af7Sopenharmony_ci						}
620e5c31af7Sopenharmony_ci						if (pCreateInfoCopies[i].pDynamicState->pDynamicStates[j] == VK_DYNAMIC_STATE_SCISSOR || pCreateInfoCopies[i].pDynamicState->pDynamicStates[j] == VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT)
621e5c31af7Sopenharmony_ci						{
622e5c31af7Sopenharmony_ci							viewportStateRequired			= true;
623e5c31af7Sopenharmony_ci							viewportStateScissorsRequired	= true;
624e5c31af7Sopenharmony_ci						}
625e5c31af7Sopenharmony_ci						if (pCreateInfoCopies[i].pDynamicState->pDynamicStates[j] == VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT)
626e5c31af7Sopenharmony_ci							viewportStateRequired = true;
627e5c31af7Sopenharmony_ci					}
628e5c31af7Sopenharmony_ci			}
629e5c31af7Sopenharmony_ci			if (pCreateInfoCopies[i].pRasterizationState != DE_NULL)
630e5c31af7Sopenharmony_ci			{
631e5c31af7Sopenharmony_ci				if (pCreateInfoCopies[i].pRasterizationState->rasterizerDiscardEnable == VK_FALSE)
632e5c31af7Sopenharmony_ci				{
633e5c31af7Sopenharmony_ci					viewportStateRequired			= true;
634e5c31af7Sopenharmony_ci					viewportStateViewportsRequired	= true;
635e5c31af7Sopenharmony_ci					viewportStateScissorsRequired	= true;
636e5c31af7Sopenharmony_ci					multiSampleStateRequired		= true;
637e5c31af7Sopenharmony_ci					depthStencilStateRequired		= true;
638e5c31af7Sopenharmony_ci					colorBlendStateRequired			= true;
639e5c31af7Sopenharmony_ci				}
640e5c31af7Sopenharmony_ci			}
641e5c31af7Sopenharmony_ci			if (pCreateInfoCopies[i].pVertexInputState != DE_NULL && !vertexInputStateRequired)
642e5c31af7Sopenharmony_ci				pCreateInfoCopies[i].pVertexInputState = DE_NULL;
643e5c31af7Sopenharmony_ci			if (pCreateInfoCopies[i].pInputAssemblyState != DE_NULL && !inputAssemblyStateRequired)
644e5c31af7Sopenharmony_ci				pCreateInfoCopies[i].pInputAssemblyState = DE_NULL;
645e5c31af7Sopenharmony_ci			if (pCreateInfoCopies[i].pTessellationState != DE_NULL && !tessellationStateRequired)
646e5c31af7Sopenharmony_ci				pCreateInfoCopies[i].pTessellationState = DE_NULL;
647e5c31af7Sopenharmony_ci			if (pCreateInfoCopies[i].pViewportState != DE_NULL)
648e5c31af7Sopenharmony_ci			{
649e5c31af7Sopenharmony_ci				if (viewportStateRequired)
650e5c31af7Sopenharmony_ci				{
651e5c31af7Sopenharmony_ci					viewportStateCopies[i]		= *(pCreateInfoCopies[i].pViewportState);
652e5c31af7Sopenharmony_ci					bool exchangeVP				= false;
653e5c31af7Sopenharmony_ci					if (pCreateInfoCopies[i].pViewportState->pViewports != DE_NULL && !viewportStateViewportsRequired)
654e5c31af7Sopenharmony_ci					{
655e5c31af7Sopenharmony_ci						viewportStateCopies[i].pViewports		= DE_NULL;
656e5c31af7Sopenharmony_ci						viewportStateCopies[i].viewportCount	= 0u;
657e5c31af7Sopenharmony_ci						exchangeVP = true;
658e5c31af7Sopenharmony_ci					}
659e5c31af7Sopenharmony_ci					if (pCreateInfoCopies[i].pViewportState->pScissors != DE_NULL && !viewportStateScissorsRequired)
660e5c31af7Sopenharmony_ci					{
661e5c31af7Sopenharmony_ci						viewportStateCopies[i].pScissors	= DE_NULL;
662e5c31af7Sopenharmony_ci						viewportStateCopies[i].scissorCount	= 0u;
663e5c31af7Sopenharmony_ci						exchangeVP = true;
664e5c31af7Sopenharmony_ci					}
665e5c31af7Sopenharmony_ci					if (exchangeVP)
666e5c31af7Sopenharmony_ci						pCreateInfoCopies[i].pViewportState = &(viewportStateCopies[i]);
667e5c31af7Sopenharmony_ci				}
668e5c31af7Sopenharmony_ci				else
669e5c31af7Sopenharmony_ci					pCreateInfoCopies[i].pViewportState = DE_NULL;
670e5c31af7Sopenharmony_ci			}
671e5c31af7Sopenharmony_ci			if (pCreateInfoCopies[i].pMultisampleState != DE_NULL && !multiSampleStateRequired)
672e5c31af7Sopenharmony_ci				pCreateInfoCopies[i].pMultisampleState = DE_NULL;
673e5c31af7Sopenharmony_ci			if (pCreateInfoCopies[i].pDepthStencilState != DE_NULL && !depthStencilStateRequired)
674e5c31af7Sopenharmony_ci				pCreateInfoCopies[i].pDepthStencilState = DE_NULL;
675e5c31af7Sopenharmony_ci			if (pCreateInfoCopies[i].pColorBlendState != DE_NULL && !colorBlendStateRequired)
676e5c31af7Sopenharmony_ci				pCreateInfoCopies[i].pColorBlendState = DE_NULL;
677e5c31af7Sopenharmony_ci		}
678e5c31af7Sopenharmony_ci	}
679e5c31af7Sopenharmony_ci
680e5c31af7Sopenharmony_ci	// Include pipelineIdentifiers into pNext chain of pCreateInfoCopies - skip this operation if pipeline identifier was created inside test
681e5c31af7Sopenharmony_ci	for (deUint32 i = 0; i < createInfoCount; ++i)
682e5c31af7Sopenharmony_ci	{
683e5c31af7Sopenharmony_ci		if (idInPNextChain[i] == 0)
684e5c31af7Sopenharmony_ci		{
685e5c31af7Sopenharmony_ci			pipelineIDs[i].pNext				= pCreateInfoCopies[i].pNext;
686e5c31af7Sopenharmony_ci			pCreateInfoCopies[i].pNext			= &pipelineIDs[i];
687e5c31af7Sopenharmony_ci		}
688e5c31af7Sopenharmony_ci	}
689e5c31af7Sopenharmony_ci
690e5c31af7Sopenharmony_ci	// subprocess: load graphics pipelines from OUR m_pipelineCache cache
691e5c31af7Sopenharmony_ci	if (normalMode)
692e5c31af7Sopenharmony_ci	{
693e5c31af7Sopenharmony_ci		const auto it = m_createGraphicsPipelinesFunc.find(device);
694e5c31af7Sopenharmony_ci		if (it != end(m_createGraphicsPipelinesFunc))
695e5c31af7Sopenharmony_ci		{
696e5c31af7Sopenharmony_ci			auto pit = m_pipelineCache.find(device);
697e5c31af7Sopenharmony_ci			if ( pit != end(m_pipelineCache) )
698e5c31af7Sopenharmony_ci			{
699e5c31af7Sopenharmony_ci				VkPipelineCache pCache = pit->second->get();
700e5c31af7Sopenharmony_ci				return it->second(device, pCache, createInfoCount, pCreateInfoCopies.data(), pAllocator, pPipelines);
701e5c31af7Sopenharmony_ci			}
702e5c31af7Sopenharmony_ci			TCU_THROW(InternalError, "m_pipelineCache not initialized for this device");
703e5c31af7Sopenharmony_ci		}
704e5c31af7Sopenharmony_ci		TCU_THROW(InternalError, "vkCreateGraphicsPipelines not defined");
705e5c31af7Sopenharmony_ci	}
706e5c31af7Sopenharmony_ci
707e5c31af7Sopenharmony_ci	// main process: store pipelines in JSON format. Pipelines will be sent later for m_pipelineCache creation ( and sent through file to another process )
708e5c31af7Sopenharmony_ci	for (deUint32 i = 0; i < createInfoCount; ++i)
709e5c31af7Sopenharmony_ci	{
710e5c31af7Sopenharmony_ci		m_pipelineIdentifiers.insert({ pPipelines[i], pipelineIDs[i] });
711e5c31af7Sopenharmony_ci
712e5c31af7Sopenharmony_ci		auto it = std::find_if(begin(m_pipelineInput.pipelines), end(m_pipelineInput.pipelines), vksc_server::PipelineIdentifierEqual(pipelineIDs[i]));
713e5c31af7Sopenharmony_ci		pipelineIDs[i].pNext = DE_NULL;
714e5c31af7Sopenharmony_ci		if (it == end(m_pipelineInput.pipelines))
715e5c31af7Sopenharmony_ci		{
716e5c31af7Sopenharmony_ci			const auto& featIt = m_deviceFeatures.find(device);
717e5c31af7Sopenharmony_ci			if(featIt == end(m_deviceFeatures))
718e5c31af7Sopenharmony_ci				TCU_THROW(InternalError, "Can't find device features for this pipeline");
719e5c31af7Sopenharmony_ci			const auto& extIt = m_deviceExtensions.find(device);
720e5c31af7Sopenharmony_ci			if (extIt == end(m_deviceExtensions))
721e5c31af7Sopenharmony_ci				TCU_THROW(InternalError, "Can't find device extensions for this pipeline");
722e5c31af7Sopenharmony_ci
723e5c31af7Sopenharmony_ci			m_pipelineInput.pipelines.push_back(vksc_server::VulkanJsonPipelineDescription(
724e5c31af7Sopenharmony_ci				pipelineIDs[i],
725e5c31af7Sopenharmony_ci				writeJSON_VkGraphicsPipelineCreateInfo(pCreateInfoCopies[i]),
726e5c31af7Sopenharmony_ci				featIt->second,
727e5c31af7Sopenharmony_ci				extIt->second,
728e5c31af7Sopenharmony_ci				m_currentTestPath));
729e5c31af7Sopenharmony_ci		}
730e5c31af7Sopenharmony_ci		else
731e5c31af7Sopenharmony_ci			it->add(m_currentTestPath);
732e5c31af7Sopenharmony_ci	}
733e5c31af7Sopenharmony_ci	return VK_SUCCESS;
734e5c31af7Sopenharmony_ci}
735e5c31af7Sopenharmony_ci
736e5c31af7Sopenharmony_ciVkResult ResourceInterfaceStandard::createComputePipelines (VkDevice								device,
737e5c31af7Sopenharmony_ci															VkPipelineCache							pipelineCache,
738e5c31af7Sopenharmony_ci															deUint32								createInfoCount,
739e5c31af7Sopenharmony_ci															const VkComputePipelineCreateInfo*		pCreateInfos,
740e5c31af7Sopenharmony_ci															const VkAllocationCallbacks*			pAllocator,
741e5c31af7Sopenharmony_ci															VkPipeline*								pPipelines,
742e5c31af7Sopenharmony_ci															bool									normalMode) const
743e5c31af7Sopenharmony_ci{
744e5c31af7Sopenharmony_ci	DE_UNREF(pipelineCache);
745e5c31af7Sopenharmony_ci
746e5c31af7Sopenharmony_ci	// build pipeline identifiers (if required), make a copy of pCreateInfos
747e5c31af7Sopenharmony_ci	std::vector<VkPipelineOfflineCreateInfo>		pipelineIDs;
748e5c31af7Sopenharmony_ci	std::vector<deUint8>							idInPNextChain;
749e5c31af7Sopenharmony_ci	std::vector<VkComputePipelineCreateInfo>		pCreateInfoCopies;
750e5c31af7Sopenharmony_ci
751e5c31af7Sopenharmony_ci	for (deUint32 i = 0; i < createInfoCount; ++i)
752e5c31af7Sopenharmony_ci	{
753e5c31af7Sopenharmony_ci		pCreateInfoCopies.push_back(pCreateInfos[i]);
754e5c31af7Sopenharmony_ci
755e5c31af7Sopenharmony_ci		// Check if test added pipeline identifier on its own
756e5c31af7Sopenharmony_ci		VkPipelineOfflineCreateInfo* idInfo = (VkPipelineOfflineCreateInfo*)findStructureInChain(pCreateInfos[i].pNext, VK_STRUCTURE_TYPE_PIPELINE_OFFLINE_CREATE_INFO);
757e5c31af7Sopenharmony_ci		if (idInfo == DE_NULL)
758e5c31af7Sopenharmony_ci		{
759e5c31af7Sopenharmony_ci			pipelineIDs.push_back(makeComputePipelineIdentifier(m_currentTestPath, pCreateInfos[i], getObjectHashes()));
760e5c31af7Sopenharmony_ci			idInPNextChain.push_back(0);
761e5c31af7Sopenharmony_ci		}
762e5c31af7Sopenharmony_ci		else
763e5c31af7Sopenharmony_ci		{
764e5c31af7Sopenharmony_ci			pipelineIDs.push_back(*idInfo);
765e5c31af7Sopenharmony_ci			idInPNextChain.push_back(1);
766e5c31af7Sopenharmony_ci		}
767e5c31af7Sopenharmony_ci
768e5c31af7Sopenharmony_ci		if (normalMode)
769e5c31af7Sopenharmony_ci			fillPoolEntrySize(pipelineIDs.back());
770e5c31af7Sopenharmony_ci	}
771e5c31af7Sopenharmony_ci
772e5c31af7Sopenharmony_ci	// Include pipelineIdentifiers into pNext chain of pCreateInfoCopies - skip this operation if pipeline identifier was created inside test
773e5c31af7Sopenharmony_ci	for (deUint32 i = 0; i < createInfoCount; ++i)
774e5c31af7Sopenharmony_ci	{
775e5c31af7Sopenharmony_ci		if (idInPNextChain[i] == 0)
776e5c31af7Sopenharmony_ci		{
777e5c31af7Sopenharmony_ci			pipelineIDs[i].pNext				= pCreateInfoCopies[i].pNext;
778e5c31af7Sopenharmony_ci			pCreateInfoCopies[i].pNext			= &pipelineIDs[i];
779e5c31af7Sopenharmony_ci		}
780e5c31af7Sopenharmony_ci	}
781e5c31af7Sopenharmony_ci
782e5c31af7Sopenharmony_ci	// subprocess: load compute pipelines from OUR pipeline cache
783e5c31af7Sopenharmony_ci	if (normalMode)
784e5c31af7Sopenharmony_ci	{
785e5c31af7Sopenharmony_ci		const auto it = m_createComputePipelinesFunc.find(device);
786e5c31af7Sopenharmony_ci		if (it != end(m_createComputePipelinesFunc))
787e5c31af7Sopenharmony_ci		{
788e5c31af7Sopenharmony_ci			auto pit = m_pipelineCache.find(device);
789e5c31af7Sopenharmony_ci			if ( pit != end(m_pipelineCache) )
790e5c31af7Sopenharmony_ci			{
791e5c31af7Sopenharmony_ci				VkPipelineCache pCache = pit->second->get();
792e5c31af7Sopenharmony_ci				return it->second(device, pCache, createInfoCount, pCreateInfoCopies.data(), pAllocator, pPipelines);
793e5c31af7Sopenharmony_ci			}
794e5c31af7Sopenharmony_ci			TCU_THROW(InternalError, "m_pipelineCache not initialized for this device");
795e5c31af7Sopenharmony_ci		}
796e5c31af7Sopenharmony_ci		TCU_THROW(InternalError, "vkCreateComputePipelines not defined");
797e5c31af7Sopenharmony_ci	}
798e5c31af7Sopenharmony_ci
799e5c31af7Sopenharmony_ci	// main process: store pipelines in JSON format. Pipelines will be sent later for m_pipelineCache creation ( and sent through file to another process )
800e5c31af7Sopenharmony_ci	for (deUint32 i = 0; i < createInfoCount; ++i)
801e5c31af7Sopenharmony_ci	{
802e5c31af7Sopenharmony_ci		m_pipelineIdentifiers.insert({ pPipelines[i], pipelineIDs[i] });
803e5c31af7Sopenharmony_ci
804e5c31af7Sopenharmony_ci		auto it = std::find_if(begin(m_pipelineInput.pipelines), end(m_pipelineInput.pipelines), vksc_server::PipelineIdentifierEqual(pipelineIDs[i]));
805e5c31af7Sopenharmony_ci		pipelineIDs[i].pNext = DE_NULL;
806e5c31af7Sopenharmony_ci		if (it == end(m_pipelineInput.pipelines))
807e5c31af7Sopenharmony_ci		{
808e5c31af7Sopenharmony_ci			const auto& featIt = m_deviceFeatures.find(device);
809e5c31af7Sopenharmony_ci			if (featIt == end(m_deviceFeatures))
810e5c31af7Sopenharmony_ci				TCU_THROW(InternalError, "Can't find device features for this pipeline");
811e5c31af7Sopenharmony_ci			const auto& extIt = m_deviceExtensions.find(device);
812e5c31af7Sopenharmony_ci			if (extIt == end(m_deviceExtensions))
813e5c31af7Sopenharmony_ci				TCU_THROW(InternalError, "Can't find device extensions for this pipeline");
814e5c31af7Sopenharmony_ci
815e5c31af7Sopenharmony_ci			m_pipelineInput.pipelines.push_back(vksc_server::VulkanJsonPipelineDescription(
816e5c31af7Sopenharmony_ci				pipelineIDs[i],
817e5c31af7Sopenharmony_ci				writeJSON_VkComputePipelineCreateInfo(pCreateInfoCopies[i]),
818e5c31af7Sopenharmony_ci				featIt->second,
819e5c31af7Sopenharmony_ci				extIt->second,
820e5c31af7Sopenharmony_ci				m_currentTestPath));
821e5c31af7Sopenharmony_ci		}
822e5c31af7Sopenharmony_ci		else
823e5c31af7Sopenharmony_ci			it->add(m_currentTestPath);
824e5c31af7Sopenharmony_ci	}
825e5c31af7Sopenharmony_ci	return VK_SUCCESS;
826e5c31af7Sopenharmony_ci}
827e5c31af7Sopenharmony_ci
828e5c31af7Sopenharmony_civoid ResourceInterfaceStandard::destroyPipeline (VkDevice								device,
829e5c31af7Sopenharmony_ci												 VkPipeline								pipeline,
830e5c31af7Sopenharmony_ci												 const VkAllocationCallbacks*			pAllocator) const
831e5c31af7Sopenharmony_ci{
832e5c31af7Sopenharmony_ci	DE_UNREF(device);
833e5c31af7Sopenharmony_ci	DE_UNREF(pAllocator);
834e5c31af7Sopenharmony_ci
835e5c31af7Sopenharmony_ci	auto it = m_pipelineIdentifiers.find(pipeline);
836e5c31af7Sopenharmony_ci	if(it==end(m_pipelineIdentifiers))
837e5c31af7Sopenharmony_ci		TCU_THROW(InternalError, "Can't find pipeline");
838e5c31af7Sopenharmony_ci
839e5c31af7Sopenharmony_ci	auto pit = std::find_if(begin(m_pipelineInput.pipelines), end(m_pipelineInput.pipelines), vksc_server::PipelineIdentifierEqual(it->second));
840e5c31af7Sopenharmony_ci	if (pit == end(m_pipelineInput.pipelines))
841e5c31af7Sopenharmony_ci		TCU_THROW(InternalError, "Can't find pipeline identifier");
842e5c31af7Sopenharmony_ci	pit->remove();
843e5c31af7Sopenharmony_ci}
844e5c31af7Sopenharmony_ci
845e5c31af7Sopenharmony_civoid ResourceInterfaceStandard::createRenderPass (VkDevice								device,
846e5c31af7Sopenharmony_ci												  const VkRenderPassCreateInfo*			pCreateInfo,
847e5c31af7Sopenharmony_ci												  const VkAllocationCallbacks*			pAllocator,
848e5c31af7Sopenharmony_ci												  VkRenderPass*							pRenderPass) const
849e5c31af7Sopenharmony_ci{
850e5c31af7Sopenharmony_ci	DE_UNREF(device);
851e5c31af7Sopenharmony_ci	DE_UNREF(pAllocator);
852e5c31af7Sopenharmony_ci	m_pipelineInput.renderPasses.insert({ *pRenderPass,  writeJSON_VkRenderPassCreateInfo(*pCreateInfo) });
853e5c31af7Sopenharmony_ci}
854e5c31af7Sopenharmony_ci
855e5c31af7Sopenharmony_civoid ResourceInterfaceStandard::createRenderPass2 (VkDevice								device,
856e5c31af7Sopenharmony_ci												   const VkRenderPassCreateInfo2*		pCreateInfo,
857e5c31af7Sopenharmony_ci												   const VkAllocationCallbacks*			pAllocator,
858e5c31af7Sopenharmony_ci												   VkRenderPass*						pRenderPass) const
859e5c31af7Sopenharmony_ci{
860e5c31af7Sopenharmony_ci	DE_UNREF(device);
861e5c31af7Sopenharmony_ci	DE_UNREF(pAllocator);
862e5c31af7Sopenharmony_ci	m_pipelineInput.renderPasses.insert({ *pRenderPass,  writeJSON_VkRenderPassCreateInfo2(*pCreateInfo) });
863e5c31af7Sopenharmony_ci}
864e5c31af7Sopenharmony_ci
865e5c31af7Sopenharmony_civoid ResourceInterfaceStandard::createPipelineLayout (VkDevice								device,
866e5c31af7Sopenharmony_ci													  const VkPipelineLayoutCreateInfo*		pCreateInfo,
867e5c31af7Sopenharmony_ci													  const VkAllocationCallbacks*			pAllocator,
868e5c31af7Sopenharmony_ci													  VkPipelineLayout*						pPipelineLayout) const
869e5c31af7Sopenharmony_ci{
870e5c31af7Sopenharmony_ci	DE_UNREF(device);
871e5c31af7Sopenharmony_ci	DE_UNREF(pAllocator);
872e5c31af7Sopenharmony_ci	m_pipelineInput.pipelineLayouts.insert({*pPipelineLayout, writeJSON_VkPipelineLayoutCreateInfo(*pCreateInfo) });
873e5c31af7Sopenharmony_ci}
874e5c31af7Sopenharmony_ci
875e5c31af7Sopenharmony_civoid ResourceInterfaceStandard::createDescriptorSetLayout (VkDevice									device,
876e5c31af7Sopenharmony_ci														   const VkDescriptorSetLayoutCreateInfo*	pCreateInfo,
877e5c31af7Sopenharmony_ci														   const VkAllocationCallbacks*				pAllocator,
878e5c31af7Sopenharmony_ci														   VkDescriptorSetLayout*					pSetLayout) const
879e5c31af7Sopenharmony_ci{
880e5c31af7Sopenharmony_ci	DE_UNREF(device);
881e5c31af7Sopenharmony_ci	DE_UNREF(pAllocator);
882e5c31af7Sopenharmony_ci	m_pipelineInput.descriptorSetLayouts.insert({ *pSetLayout, writeJSON_VkDescriptorSetLayoutCreateInfo(*pCreateInfo) });
883e5c31af7Sopenharmony_ci}
884e5c31af7Sopenharmony_ci
885e5c31af7Sopenharmony_civoid ResourceInterfaceStandard::createSampler (VkDevice							device,
886e5c31af7Sopenharmony_ci											   const VkSamplerCreateInfo*		pCreateInfo,
887e5c31af7Sopenharmony_ci											   const VkAllocationCallbacks*		pAllocator,
888e5c31af7Sopenharmony_ci											   VkSampler*						pSampler) const
889e5c31af7Sopenharmony_ci{
890e5c31af7Sopenharmony_ci	DE_UNREF(device);
891e5c31af7Sopenharmony_ci	DE_UNREF(pAllocator);
892e5c31af7Sopenharmony_ci	m_pipelineInput.samplers.insert({ *pSampler,  writeJSON_VkSamplerCreateInfo(*pCreateInfo) });
893e5c31af7Sopenharmony_ci}
894e5c31af7Sopenharmony_ci
895e5c31af7Sopenharmony_civoid ResourceInterfaceStandard::createSamplerYcbcrConversion (VkDevice									device,
896e5c31af7Sopenharmony_ci															  const VkSamplerYcbcrConversionCreateInfo*	pCreateInfo,
897e5c31af7Sopenharmony_ci															  const VkAllocationCallbacks*				pAllocator,
898e5c31af7Sopenharmony_ci															  VkSamplerYcbcrConversion*					pYcbcrConversion) const
899e5c31af7Sopenharmony_ci{
900e5c31af7Sopenharmony_ci	DE_UNREF(device);
901e5c31af7Sopenharmony_ci	DE_UNREF(pAllocator);
902e5c31af7Sopenharmony_ci	m_pipelineInput.samplerYcbcrConversions.insert({ *pYcbcrConversion,  writeJSON_VkSamplerYcbcrConversionCreateInfo(*pCreateInfo) });
903e5c31af7Sopenharmony_ci}
904e5c31af7Sopenharmony_ci
905e5c31af7Sopenharmony_civoid ResourceInterfaceStandard::createCommandPool (VkDevice										device,
906e5c31af7Sopenharmony_ci												   const VkCommandPoolCreateInfo*				pCreateInfo,
907e5c31af7Sopenharmony_ci												   const VkAllocationCallbacks*					pAllocator,
908e5c31af7Sopenharmony_ci												   VkCommandPool*								pCommandPool) const
909e5c31af7Sopenharmony_ci{
910e5c31af7Sopenharmony_ci	DE_UNREF(device);
911e5c31af7Sopenharmony_ci	DE_UNREF(pCreateInfo);
912e5c31af7Sopenharmony_ci	DE_UNREF(pAllocator);
913e5c31af7Sopenharmony_ci	m_commandPoolMemoryConsumption.push_back(vksc_server::VulkanCommandMemoryConsumption(pCommandPool->getInternal()));
914e5c31af7Sopenharmony_ci}
915e5c31af7Sopenharmony_ci
916e5c31af7Sopenharmony_civoid ResourceInterfaceStandard::allocateCommandBuffers (VkDevice								device,
917e5c31af7Sopenharmony_ci														const VkCommandBufferAllocateInfo*		pAllocateInfo,
918e5c31af7Sopenharmony_ci														VkCommandBuffer*						pCommandBuffers) const
919e5c31af7Sopenharmony_ci{
920e5c31af7Sopenharmony_ci	DE_UNREF(device);
921e5c31af7Sopenharmony_ci	for (deUint32 i = 0; i < pAllocateInfo->commandBufferCount; ++i)
922e5c31af7Sopenharmony_ci	{
923e5c31af7Sopenharmony_ci		m_commandBufferMemoryConsumption.insert({ pCommandBuffers[i], vksc_server::VulkanCommandMemoryConsumption(pAllocateInfo->commandPool.getInternal()) });
924e5c31af7Sopenharmony_ci	}
925e5c31af7Sopenharmony_ci}
926e5c31af7Sopenharmony_ci
927e5c31af7Sopenharmony_civoid ResourceInterfaceStandard::increaseCommandBufferSize (VkCommandBuffer						commandBuffer,
928e5c31af7Sopenharmony_ci														   VkDeviceSize							commandSize) const
929e5c31af7Sopenharmony_ci{
930e5c31af7Sopenharmony_ci	auto it = m_commandBufferMemoryConsumption.find(commandBuffer);
931e5c31af7Sopenharmony_ci	if (it == end(m_commandBufferMemoryConsumption))
932e5c31af7Sopenharmony_ci		TCU_THROW(InternalError, "Unregistered command buffer");
933e5c31af7Sopenharmony_ci
934e5c31af7Sopenharmony_ci	it->second.updateValues(commandSize, commandSize, commandSize);
935e5c31af7Sopenharmony_ci}
936e5c31af7Sopenharmony_ci
937e5c31af7Sopenharmony_civoid ResourceInterfaceStandard::resetCommandPool (VkDevice								device,
938e5c31af7Sopenharmony_ci												  VkCommandPool							commandPool,
939e5c31af7Sopenharmony_ci												  VkCommandPoolResetFlags				flags) const
940e5c31af7Sopenharmony_ci{
941e5c31af7Sopenharmony_ci	DE_UNREF(device);
942e5c31af7Sopenharmony_ci	DE_UNREF(flags);
943e5c31af7Sopenharmony_ci
944e5c31af7Sopenharmony_ci	for (auto& memC : m_commandBufferMemoryConsumption)
945e5c31af7Sopenharmony_ci	{
946e5c31af7Sopenharmony_ci		if (memC.second.commandPool == commandPool.getInternal())
947e5c31af7Sopenharmony_ci			memC.second.resetValues();
948e5c31af7Sopenharmony_ci	}
949e5c31af7Sopenharmony_ci}
950e5c31af7Sopenharmony_ci
951e5c31af7Sopenharmony_civoid ResourceInterfaceStandard::importPipelineCacheData (const PlatformInterface&			vkp,
952e5c31af7Sopenharmony_ci														 VkInstance							instance,
953e5c31af7Sopenharmony_ci														 const InstanceInterface&			vki,
954e5c31af7Sopenharmony_ci														 VkPhysicalDevice					physicalDevice,
955e5c31af7Sopenharmony_ci														 deUint32							queueIndex)
956e5c31af7Sopenharmony_ci{
957e5c31af7Sopenharmony_ci	if(!std::string(m_testCtx.getCommandLine().getPipelineCompilerPath()).empty())
958e5c31af7Sopenharmony_ci	{
959e5c31af7Sopenharmony_ci		m_cacheData = vksc_server::buildOfflinePipelineCache(m_pipelineInput,
960e5c31af7Sopenharmony_ci															 std::string( m_testCtx.getCommandLine().getPipelineCompilerPath()),
961e5c31af7Sopenharmony_ci															 std::string( m_testCtx.getCommandLine().getPipelineCompilerDataDir()),
962e5c31af7Sopenharmony_ci															 std::string( m_testCtx.getCommandLine().getPipelineCompilerArgs()),
963e5c31af7Sopenharmony_ci															 std::string( m_testCtx.getCommandLine().getPipelineCompilerOutputFile()),
964e5c31af7Sopenharmony_ci															 std::string( m_testCtx.getCommandLine().getPipelineCompilerLogFile()),
965e5c31af7Sopenharmony_ci															 std::string( m_testCtx.getCommandLine().getPipelineCompilerFilePrefix()) );
966e5c31af7Sopenharmony_ci	}
967e5c31af7Sopenharmony_ci	else
968e5c31af7Sopenharmony_ci	{
969e5c31af7Sopenharmony_ci		m_cacheData = vksc_server::buildPipelineCache(m_pipelineInput, vkp, instance, vki, physicalDevice, queueIndex);
970e5c31af7Sopenharmony_ci	}
971e5c31af7Sopenharmony_ci
972e5c31af7Sopenharmony_ci	VkPhysicalDeviceVulkanSC10Properties	vulkanSC10Properties	= initVulkanStructure();
973e5c31af7Sopenharmony_ci	VkPhysicalDeviceProperties2				deviceProperties2		= initVulkanStructure(&vulkanSC10Properties);
974e5c31af7Sopenharmony_ci	vki.getPhysicalDeviceProperties2(physicalDevice, &deviceProperties2);
975e5c31af7Sopenharmony_ci
976e5c31af7Sopenharmony_ci	m_pipelineSizes	= vksc_server::extractSizesFromPipelineCache( m_pipelineInput, m_cacheData, deUint32(m_testCtx.getCommandLine().getPipelineDefaultSize()), vulkanSC10Properties.recyclePipelineMemory == VK_TRUE);
977e5c31af7Sopenharmony_ci	preparePipelinePoolSizes();
978e5c31af7Sopenharmony_ci}
979e5c31af7Sopenharmony_ci
980e5c31af7Sopenharmony_civoid ResourceInterfaceStandard::resetObjects ()
981e5c31af7Sopenharmony_ci{
982e5c31af7Sopenharmony_ci	m_pipelineInput							= {};
983e5c31af7Sopenharmony_ci	m_objectHashes.clear();
984e5c31af7Sopenharmony_ci	m_commandPoolMemoryConsumption.clear();
985e5c31af7Sopenharmony_ci	m_commandPoolIndex						= 0u;
986e5c31af7Sopenharmony_ci	m_commandBufferMemoryConsumption.clear();
987e5c31af7Sopenharmony_ci	m_resourceCounter						= 0u;
988e5c31af7Sopenharmony_ci	m_statCurrent							= resetDeviceObjectReservationCreateInfo();
989e5c31af7Sopenharmony_ci	m_statMax								= resetDeviceObjectReservationCreateInfo();
990e5c31af7Sopenharmony_ci	// pipelineCacheRequestCount does not contain one instance of createPipelineCache call that happens only in subprocess
991e5c31af7Sopenharmony_ci	m_statCurrent.pipelineCacheRequestCount	= 1u;
992e5c31af7Sopenharmony_ci	m_statMax.pipelineCacheRequestCount		= 1u;
993e5c31af7Sopenharmony_ci	m_cacheData.clear();
994e5c31af7Sopenharmony_ci	m_pipelineIdentifiers.clear();
995e5c31af7Sopenharmony_ci	m_pipelineSizes.clear();
996e5c31af7Sopenharmony_ci	m_pipelinePoolSizes.clear();
997e5c31af7Sopenharmony_ci	runGarbageCollection();
998e5c31af7Sopenharmony_ci}
999e5c31af7Sopenharmony_ci
1000e5c31af7Sopenharmony_civoid ResourceInterfaceStandard::resetPipelineCaches ()
1001e5c31af7Sopenharmony_ci{
1002e5c31af7Sopenharmony_ci	if (m_testCtx.getCommandLine().isSubProcess())
1003e5c31af7Sopenharmony_ci	{
1004e5c31af7Sopenharmony_ci		m_pipelineCache.clear();
1005e5c31af7Sopenharmony_ci	}
1006e5c31af7Sopenharmony_ci}
1007e5c31af7Sopenharmony_ci
1008e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC
1009e5c31af7Sopenharmony_ci
1010e5c31af7Sopenharmony_civk::ProgramBinary* ResourceInterfaceStandard::compileProgram (const vk::ProgramIdentifier&	progId,
1011e5c31af7Sopenharmony_ci															  const vk::GlslSource&			source,
1012e5c31af7Sopenharmony_ci															  glu::ShaderProgramInfo*		buildInfo,
1013e5c31af7Sopenharmony_ci															  const tcu::CommandLine&		commandLine)
1014e5c31af7Sopenharmony_ci{
1015e5c31af7Sopenharmony_ci	DE_UNREF(progId);
1016e5c31af7Sopenharmony_ci	return vk::buildProgram(source, buildInfo, commandLine);
1017e5c31af7Sopenharmony_ci}
1018e5c31af7Sopenharmony_ci
1019e5c31af7Sopenharmony_civk::ProgramBinary* ResourceInterfaceStandard::compileProgram (const vk::ProgramIdentifier&	progId,
1020e5c31af7Sopenharmony_ci															  const vk::HlslSource&			source,
1021e5c31af7Sopenharmony_ci															  glu::ShaderProgramInfo*		buildInfo,
1022e5c31af7Sopenharmony_ci															  const tcu::CommandLine&		commandLine)
1023e5c31af7Sopenharmony_ci{
1024e5c31af7Sopenharmony_ci	DE_UNREF(progId);
1025e5c31af7Sopenharmony_ci	return vk::buildProgram(source, buildInfo, commandLine);
1026e5c31af7Sopenharmony_ci}
1027e5c31af7Sopenharmony_ci
1028e5c31af7Sopenharmony_civk::ProgramBinary* ResourceInterfaceStandard::compileProgram (const vk::ProgramIdentifier&	progId,
1029e5c31af7Sopenharmony_ci															  const vk::SpirVAsmSource&		source,
1030e5c31af7Sopenharmony_ci															  vk::SpirVProgramInfo*			buildInfo,
1031e5c31af7Sopenharmony_ci															  const tcu::CommandLine&		commandLine)
1032e5c31af7Sopenharmony_ci{
1033e5c31af7Sopenharmony_ci	DE_UNREF(progId);
1034e5c31af7Sopenharmony_ci	return vk::assembleProgram(source, buildInfo, commandLine);
1035e5c31af7Sopenharmony_ci}
1036e5c31af7Sopenharmony_ci
1037e5c31af7Sopenharmony_ci#ifdef CTS_USES_VULKANSC
1038e5c31af7Sopenharmony_ci
1039e5c31af7Sopenharmony_ciResourceInterfaceVKSC::ResourceInterfaceVKSC (tcu::TestContext& testCtx)
1040e5c31af7Sopenharmony_ci	: ResourceInterfaceStandard(testCtx)
1041e5c31af7Sopenharmony_ci{
1042e5c31af7Sopenharmony_ci		m_address = std::string(testCtx.getCommandLine().getServerAddress());
1043e5c31af7Sopenharmony_ci}
1044e5c31af7Sopenharmony_ci
1045e5c31af7Sopenharmony_civksc_server::Server* ResourceInterfaceVKSC::getServer ()
1046e5c31af7Sopenharmony_ci{
1047e5c31af7Sopenharmony_ci	if (!m_server)
1048e5c31af7Sopenharmony_ci	{
1049e5c31af7Sopenharmony_ci		m_server = std::make_shared<vksc_server::Server>(m_address);
1050e5c31af7Sopenharmony_ci	}
1051e5c31af7Sopenharmony_ci	return m_server.get();
1052e5c31af7Sopenharmony_ci}
1053e5c31af7Sopenharmony_ci
1054e5c31af7Sopenharmony_cibool ResourceInterfaceVKSC::noServer () const
1055e5c31af7Sopenharmony_ci{
1056e5c31af7Sopenharmony_ci	return m_address.empty();
1057e5c31af7Sopenharmony_ci}
1058e5c31af7Sopenharmony_ci
1059e5c31af7Sopenharmony_civk::ProgramBinary* ResourceInterfaceVKSC::compileProgram (const vk::ProgramIdentifier&	progId,
1060e5c31af7Sopenharmony_ci														  const vk::GlslSource&			source,
1061e5c31af7Sopenharmony_ci														  glu::ShaderProgramInfo*		buildInfo,
1062e5c31af7Sopenharmony_ci														  const tcu::CommandLine&		commandLine)
1063e5c31af7Sopenharmony_ci{
1064e5c31af7Sopenharmony_ci	if (noServer()) return ResourceInterfaceStandard::compileProgram(progId, source, buildInfo, commandLine);
1065e5c31af7Sopenharmony_ci
1066e5c31af7Sopenharmony_ci	DE_UNREF(progId);
1067e5c31af7Sopenharmony_ci	DE_UNREF(buildInfo);
1068e5c31af7Sopenharmony_ci
1069e5c31af7Sopenharmony_ci	vksc_server::CompileShaderRequest request;
1070e5c31af7Sopenharmony_ci	request.source.active = "glsl";
1071e5c31af7Sopenharmony_ci	request.source.glsl = source;
1072e5c31af7Sopenharmony_ci	request.commandLine = commandLine.getInitialCmdLine();
1073e5c31af7Sopenharmony_ci	vksc_server::CompileShaderResponse response;
1074e5c31af7Sopenharmony_ci	getServer()->SendRequest(request, response);
1075e5c31af7Sopenharmony_ci
1076e5c31af7Sopenharmony_ci	return new ProgramBinary(PROGRAM_FORMAT_SPIRV, response.binary.size(), response.binary.data());
1077e5c31af7Sopenharmony_ci}
1078e5c31af7Sopenharmony_ci
1079e5c31af7Sopenharmony_civk::ProgramBinary* ResourceInterfaceVKSC::compileProgram (const vk::ProgramIdentifier&	progId,
1080e5c31af7Sopenharmony_ci														  const vk::HlslSource&			source,
1081e5c31af7Sopenharmony_ci														  glu::ShaderProgramInfo*		buildInfo,
1082e5c31af7Sopenharmony_ci														  const tcu::CommandLine&		commandLine)
1083e5c31af7Sopenharmony_ci{
1084e5c31af7Sopenharmony_ci	if (noServer()) return ResourceInterfaceStandard::compileProgram(progId, source, buildInfo, commandLine);
1085e5c31af7Sopenharmony_ci
1086e5c31af7Sopenharmony_ci	DE_UNREF(progId);
1087e5c31af7Sopenharmony_ci	DE_UNREF(buildInfo);
1088e5c31af7Sopenharmony_ci
1089e5c31af7Sopenharmony_ci	vksc_server::CompileShaderRequest request;
1090e5c31af7Sopenharmony_ci	request.source.active = "hlsl";
1091e5c31af7Sopenharmony_ci	request.source.hlsl = source;
1092e5c31af7Sopenharmony_ci	request.commandLine = commandLine.getInitialCmdLine();
1093e5c31af7Sopenharmony_ci	vksc_server::CompileShaderResponse response;
1094e5c31af7Sopenharmony_ci	getServer()->SendRequest(request, response);
1095e5c31af7Sopenharmony_ci
1096e5c31af7Sopenharmony_ci	return new ProgramBinary(PROGRAM_FORMAT_SPIRV, response.binary.size(), response.binary.data());
1097e5c31af7Sopenharmony_ci}
1098e5c31af7Sopenharmony_ci
1099e5c31af7Sopenharmony_civk::ProgramBinary* ResourceInterfaceVKSC::compileProgram (const vk::ProgramIdentifier&	progId,
1100e5c31af7Sopenharmony_ci														  const vk::SpirVAsmSource&		source,
1101e5c31af7Sopenharmony_ci														  vk::SpirVProgramInfo*			buildInfo,
1102e5c31af7Sopenharmony_ci														  const tcu::CommandLine&		commandLine)
1103e5c31af7Sopenharmony_ci{
1104e5c31af7Sopenharmony_ci	if (noServer()) return ResourceInterfaceStandard::compileProgram(progId, source, buildInfo, commandLine);
1105e5c31af7Sopenharmony_ci
1106e5c31af7Sopenharmony_ci	DE_UNREF(progId);
1107e5c31af7Sopenharmony_ci	DE_UNREF(buildInfo);
1108e5c31af7Sopenharmony_ci
1109e5c31af7Sopenharmony_ci	vksc_server::CompileShaderRequest request;
1110e5c31af7Sopenharmony_ci	request.source.active = "spirv";
1111e5c31af7Sopenharmony_ci	request.source.spirv = source;
1112e5c31af7Sopenharmony_ci	request.commandLine = commandLine.getInitialCmdLine();
1113e5c31af7Sopenharmony_ci	vksc_server::CompileShaderResponse response;
1114e5c31af7Sopenharmony_ci	getServer()->SendRequest(request, response);
1115e5c31af7Sopenharmony_ci
1116e5c31af7Sopenharmony_ci	return new ProgramBinary(PROGRAM_FORMAT_SPIRV, response.binary.size(), response.binary.data());
1117e5c31af7Sopenharmony_ci}
1118e5c31af7Sopenharmony_ci
1119e5c31af7Sopenharmony_ciVkResult ResourceInterfaceVKSC::createShaderModule (VkDevice							device,
1120e5c31af7Sopenharmony_ci													const VkShaderModuleCreateInfo*		pCreateInfo,
1121e5c31af7Sopenharmony_ci													const VkAllocationCallbacks*		pAllocator,
1122e5c31af7Sopenharmony_ci													VkShaderModule*						pShaderModule,
1123e5c31af7Sopenharmony_ci													bool								normalMode) const
1124e5c31af7Sopenharmony_ci{
1125e5c31af7Sopenharmony_ci	if (noServer() || !normalMode || !isVulkanSC())
1126e5c31af7Sopenharmony_ci		return ResourceInterfaceStandard::createShaderModule(device, pCreateInfo, pAllocator, pShaderModule, normalMode);
1127e5c31af7Sopenharmony_ci
1128e5c31af7Sopenharmony_ci	// We will reach this place only in one case:
1129e5c31af7Sopenharmony_ci	// - server exists
1130e5c31af7Sopenharmony_ci	// - subprocess asks for creation of VkShaderModule which will be later ignored, because it will receive the whole pipeline from server
1131e5c31af7Sopenharmony_ci	// ( Are there any tests which receive VkShaderModule and do not use it in any pipeline ? )
1132e5c31af7Sopenharmony_ci	*pShaderModule = VkShaderModule(++m_resourceCounter);
1133e5c31af7Sopenharmony_ci	registerObjectHash(pShaderModule->getInternal(), calculateShaderModuleHash(*pCreateInfo, getObjectHashes()));
1134e5c31af7Sopenharmony_ci	return VK_SUCCESS;
1135e5c31af7Sopenharmony_ci}
1136e5c31af7Sopenharmony_ci
1137e5c31af7Sopenharmony_ci
1138e5c31af7Sopenharmony_civoid ResourceInterfaceVKSC::importPipelineCacheData (const PlatformInterface&			vkp,
1139e5c31af7Sopenharmony_ci													 VkInstance							instance,
1140e5c31af7Sopenharmony_ci													 const InstanceInterface&			vki,
1141e5c31af7Sopenharmony_ci													 VkPhysicalDevice					physicalDevice,
1142e5c31af7Sopenharmony_ci													 deUint32							queueIndex)
1143e5c31af7Sopenharmony_ci{
1144e5c31af7Sopenharmony_ci	if (noServer())
1145e5c31af7Sopenharmony_ci	{
1146e5c31af7Sopenharmony_ci		ResourceInterfaceStandard::importPipelineCacheData(vkp, instance, vki, physicalDevice, queueIndex);
1147e5c31af7Sopenharmony_ci		return;
1148e5c31af7Sopenharmony_ci	}
1149e5c31af7Sopenharmony_ci
1150e5c31af7Sopenharmony_ci	vksc_server::CreateCacheRequest request;
1151e5c31af7Sopenharmony_ci	request.input						= m_pipelineInput;
1152e5c31af7Sopenharmony_ci	std::vector<int>	caseFraction	= m_testCtx.getCommandLine().getCaseFraction();
1153e5c31af7Sopenharmony_ci	request.caseFraction				= caseFraction.empty() ? -1 : caseFraction[0];
1154e5c31af7Sopenharmony_ci
1155e5c31af7Sopenharmony_ci	vksc_server::CreateCacheResponse response;
1156e5c31af7Sopenharmony_ci	getServer()->SendRequest(request, response);
1157e5c31af7Sopenharmony_ci
1158e5c31af7Sopenharmony_ci	if (response.status)
1159e5c31af7Sopenharmony_ci	{
1160e5c31af7Sopenharmony_ci		m_cacheData = std::move(response.binary);
1161e5c31af7Sopenharmony_ci
1162e5c31af7Sopenharmony_ci		VkPhysicalDeviceVulkanSC10Properties	vulkanSC10Properties	= initVulkanStructure();
1163e5c31af7Sopenharmony_ci		VkPhysicalDeviceProperties2				deviceProperties2		= initVulkanStructure(&vulkanSC10Properties);
1164e5c31af7Sopenharmony_ci		vki.getPhysicalDeviceProperties2(physicalDevice, &deviceProperties2);
1165e5c31af7Sopenharmony_ci
1166e5c31af7Sopenharmony_ci		m_pipelineSizes	= vksc_server::extractSizesFromPipelineCache( m_pipelineInput, m_cacheData, deUint32(m_testCtx.getCommandLine().getPipelineDefaultSize()), vulkanSC10Properties.recyclePipelineMemory == VK_TRUE);
1167e5c31af7Sopenharmony_ci		preparePipelinePoolSizes();
1168e5c31af7Sopenharmony_ci	}
1169e5c31af7Sopenharmony_ci	else { TCU_THROW(InternalError, "Server did not return pipeline cache data when requested (check server log for details)"); }
1170e5c31af7Sopenharmony_ci}
1171e5c31af7Sopenharmony_ci
1172e5c31af7Sopenharmony_ciMultithreadedDestroyGuard::MultithreadedDestroyGuard (de::SharedPtr<vk::ResourceInterface> resourceInterface)
1173e5c31af7Sopenharmony_ci	: m_resourceInterface{ resourceInterface }
1174e5c31af7Sopenharmony_ci{
1175e5c31af7Sopenharmony_ci	if (m_resourceInterface.get() != DE_NULL)
1176e5c31af7Sopenharmony_ci		m_resourceInterface->setHandleDestroy(false);
1177e5c31af7Sopenharmony_ci}
1178e5c31af7Sopenharmony_ci
1179e5c31af7Sopenharmony_ciMultithreadedDestroyGuard::~MultithreadedDestroyGuard ()
1180e5c31af7Sopenharmony_ci{
1181e5c31af7Sopenharmony_ci	if (m_resourceInterface.get() != DE_NULL)
1182e5c31af7Sopenharmony_ci		m_resourceInterface->setHandleDestroy(true);
1183e5c31af7Sopenharmony_ci}
1184e5c31af7Sopenharmony_ci
1185e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC
1186e5c31af7Sopenharmony_ci
1187e5c31af7Sopenharmony_ci
1188e5c31af7Sopenharmony_ci} // namespace vk
1189