• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * Vulkan CTS Framework
3  * --------------------
4  *
5  * Copyright (c) 2021 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Vulkan SC utilities
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vkSafetyCriticalUtil.hpp"
25 #include <set>
26 
27 #ifdef CTS_USES_VULKANSC
28 
29 namespace vk
30 {
31 struct MemoryArea
32 {
MemoryAreavk::MemoryArea33 	MemoryArea(const void* data_, std::size_t size_)
34 		: data(data_), size(size_)
35 	{
36 	}
37 
38 	const void*		data;
39 	std::size_t		size;
40 };
41 } // vk
42 
43 namespace std
44 {
45 	template<>
46 	struct hash<vk::MemoryArea>
47 	{
operator ()std::hash48 		std::size_t operator()(const vk::MemoryArea& s) const noexcept
49 		{
50 			std::size_t seed = 0;
51 			std::hash<unsigned char> hasher;
52 			for (std::size_t i = 0; i < s.size; ++i)
53 			{
54 				unsigned char* v = (unsigned char*)s.data + i;
55 				seed ^= hasher(*v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
56 			}
57 			return seed;
58 		}
59 	};
60 }// std
61 
62 namespace vk
63 {
64 
resetDeviceObjectReservationCreateInfo()65 VkDeviceObjectReservationCreateInfo resetDeviceObjectReservationCreateInfo ()
66 {
67 	VkDeviceObjectReservationCreateInfo result =
68 	{
69 		VK_STRUCTURE_TYPE_DEVICE_OBJECT_RESERVATION_CREATE_INFO,	// VkStructureType					sType;
70 		DE_NULL,													// const void*						pNext;
71 		0u,															// deUint32							pipelineCacheCreateInfoCount;
72 		DE_NULL,													// const VkPipelineCacheCreateInfo*	pPipelineCacheCreateInfos;
73 		0u,															// deUint32							pipelinePoolSizeCount;
74 		DE_NULL,													// const VkPipelinePoolSize*		pPipelinePoolSizes;
75 		0u,															// deUint32							semaphoreRequestCount;
76 		0u,															// deUint32							commandBufferRequestCount;
77 		0u,															// deUint32							fenceRequestCount;
78 		0u,															// deUint32							deviceMemoryRequestCount;
79 		0u,															// deUint32							bufferRequestCount;
80 		0u,															// deUint32							imageRequestCount;
81 		0u,															// deUint32							eventRequestCount;
82 		0u,															// deUint32							queryPoolRequestCount;
83 		0u,															// deUint32							bufferViewRequestCount;
84 		0u,															// deUint32							imageViewRequestCount;
85 		0u,															// deUint32							layeredImageViewRequestCount;
86 		0u,															// deUint32							pipelineCacheRequestCount;
87 		0u,															// deUint32							pipelineLayoutRequestCount;
88 		0u,															// deUint32							renderPassRequestCount;
89 		0u,															// deUint32							graphicsPipelineRequestCount;
90 		0u,															// deUint32							computePipelineRequestCount;
91 		0u,															// deUint32							descriptorSetLayoutRequestCount;
92 		0u,															// deUint32							samplerRequestCount;
93 		0u,															// deUint32							descriptorPoolRequestCount;
94 		0u,															// deUint32							descriptorSetRequestCount;
95 		0u,															// deUint32							framebufferRequestCount;
96 		0u,															// deUint32							commandPoolRequestCount;
97 		0u,															// deUint32							samplerYcbcrConversionRequestCount;
98 		0u,															// deUint32							surfaceRequestCount;
99 		0u,															// deUint32							swapchainRequestCount;
100 		0u,															// deUint32							displayModeRequestCount;
101 		0u,															// deUint32							subpassDescriptionRequestCount;
102 		0u,															// deUint32							attachmentDescriptionRequestCount;
103 		0u,															// deUint32							descriptorSetLayoutBindingRequestCount;
104 		0u,															// deUint32							descriptorSetLayoutBindingLimit;
105 		0u,															// deUint32							maxImageViewMipLevels;
106 		0u,															// deUint32							maxImageViewArrayLayers;
107 		0u,															// deUint32							maxLayeredImageViewMipLevels;
108 		0u,															// deUint32							maxOcclusionQueriesPerPool;
109 		0u,															// deUint32							maxPipelineStatisticsQueriesPerPool;
110 		0u,															// deUint32							maxTimestampQueriesPerPool;
111 		0u,															// deUint32							maxImmutableSamplersPerDescriptorSetLayout;
112 	};
113 	return result;
114 }
115 
resetPipelineOfflineCreateInfo()116 VkPipelineOfflineCreateInfo resetPipelineOfflineCreateInfo()
117 {
118 	VkPipelineOfflineCreateInfo pipelineID =
119 	{
120 		VK_STRUCTURE_TYPE_PIPELINE_OFFLINE_CREATE_INFO,			// VkStructureType			sType;
121 		DE_NULL,												// const void*				pNext;
122 		{0},													// deUint8					pipelineIdentifier[VK_UUID_SIZE];
123 		VK_PIPELINE_MATCH_CONTROL_APPLICATION_UUID_EXACT_MATCH,	// VkPipelineMatchControl	matchControl;
124 		0u														// VkDeviceSize				poolEntrySize;
125 
126 	};
127 	for (deUint32 i = 0; i < VK_UUID_SIZE; ++i)
128 		pipelineID.pipelineIdentifier[i] = 0U;
129 
130 	return pipelineID;
131 }
132 
applyPipelineIdentifier(VkPipelineOfflineCreateInfo & pipelineID,const std::string & value)133 void applyPipelineIdentifier (VkPipelineOfflineCreateInfo& pipelineID, const std::string& value)
134 {
135 	for (deUint32 i = 0; i < VK_UUID_SIZE && i < value.size(); ++i)
136 		pipelineID.pipelineIdentifier[i] = deUint8(value[i]);
137 }
138 
createDefaultSC10Features()139 VkPhysicalDeviceVulkanSC10Features createDefaultSC10Features ()
140 {
141 	VkPhysicalDeviceVulkanSC10Features result =
142 	{
143 		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_SC_1_0_FEATURES,	// VkStructureType	sType;
144 		DE_NULL,													// void*			pNext;
145 		VK_FALSE													// VkBool32			shaderAtomicInstructions;
146 	};
147 	return result;
148 }
149 
hashPNextChain(std::size_t & seed,const void * pNext,const std::map<deUint64,std::size_t> & objectHashes)150 void hashPNextChain (std::size_t& seed, const void* pNext, const std::map<deUint64, std::size_t>& objectHashes)
151 {
152 	VkBaseInStructure* pBase = (VkBaseInStructure*)pNext;
153 	if (pNext != DE_NULL)
154 	{
155 		switch (pBase->sType)
156 		{
157 			case VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT:
158 			{
159 				VkAttachmentDescriptionStencilLayout* ptr = (VkAttachmentDescriptionStencilLayout *)pNext;
160 				hash_combine(seed, deUint32(ptr->stencilInitialLayout), deUint32(ptr->stencilFinalLayout));
161 				break;
162 			}
163 			case VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO:
164 			{
165 				VkDescriptorSetLayoutBindingFlagsCreateInfo* ptr = (VkDescriptorSetLayoutBindingFlagsCreateInfo *)pNext;
166 				if (ptr->pBindingFlags != DE_NULL)
167 					for (deUint32 i = 0; i < ptr->bindingCount; ++i)
168 						hash_combine(seed, ptr->pBindingFlags[i]);
169 				break;
170 			}
171 			case VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_EXT:
172 			{
173 				VkPipelineColorBlendAdvancedStateCreateInfoEXT* ptr = (VkPipelineColorBlendAdvancedStateCreateInfoEXT *)pNext;
174 				hash_combine(seed, ptr->srcPremultiplied, ptr->dstPremultiplied, deUint32(ptr->blendOverlap));
175 				break;
176 			}
177 			case VK_STRUCTURE_TYPE_PIPELINE_COLOR_WRITE_CREATE_INFO_EXT:
178 			{
179 				VkPipelineColorWriteCreateInfoEXT* ptr = (VkPipelineColorWriteCreateInfoEXT *)pNext;
180 				if (ptr->pColorWriteEnables != DE_NULL)
181 					for (deUint32 i = 0; i < ptr->attachmentCount; ++i)
182 						hash_combine(seed, ptr->pColorWriteEnables[i]);
183 				break;
184 			}
185 			case VK_STRUCTURE_TYPE_PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT:
186 			{
187 				VkPipelineDiscardRectangleStateCreateInfoEXT* ptr = (VkPipelineDiscardRectangleStateCreateInfoEXT *)pNext;
188 				hash_combine(seed, ptr->flags, deUint32(ptr->discardRectangleMode));
189 				if (ptr->pDiscardRectangles != DE_NULL)
190 					for (deUint32 i = 0; i < ptr->discardRectangleCount; ++i)
191 						hash_combine(seed, ptr->pDiscardRectangles[i].offset.x, ptr->pDiscardRectangles[i].offset.y, ptr->pDiscardRectangles[i].extent.width, ptr->pDiscardRectangles[i].extent.height);
192 				break;
193 			}
194 			case VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR:
195 			{
196 				VkPipelineFragmentShadingRateStateCreateInfoKHR* ptr = (VkPipelineFragmentShadingRateStateCreateInfoKHR *)pNext;
197 				hash_combine(seed, ptr->fragmentSize.width, ptr->fragmentSize.height, deUint32(ptr->combinerOps[0]), deUint32(ptr->combinerOps[1]));
198 				break;
199 			}
200 			case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT:
201 			{
202 				VkPipelineRasterizationConservativeStateCreateInfoEXT* ptr = (VkPipelineRasterizationConservativeStateCreateInfoEXT *)pNext;
203 				hash_combine(seed, ptr->flags, deUint32(ptr->conservativeRasterizationMode), ptr->extraPrimitiveOverestimationSize);
204 				break;
205 			}
206 			case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT:
207 			{
208 				VkPipelineRasterizationDepthClipStateCreateInfoEXT* ptr = (VkPipelineRasterizationDepthClipStateCreateInfoEXT *)pNext;
209 				hash_combine(seed, ptr->flags, ptr->depthClipEnable);
210 				break;
211 			}
212 			case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT:
213 			{
214 				VkPipelineRasterizationLineStateCreateInfoEXT* ptr = (VkPipelineRasterizationLineStateCreateInfoEXT *)pNext;
215 				hash_combine(seed, deUint32(ptr->lineRasterizationMode), ptr->stippledLineEnable, ptr->lineStippleFactor, ptr->lineStipplePattern);
216 				break;
217 			}
218 			case VK_STRUCTURE_TYPE_PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT:
219 			{
220 				VkPipelineSampleLocationsStateCreateInfoEXT* ptr = (VkPipelineSampleLocationsStateCreateInfoEXT *)pNext;
221 				hash_combine(seed, ptr->sampleLocationsEnable, deUint32(ptr->sampleLocationsInfo.sampleLocationsPerPixel), ptr->sampleLocationsInfo.sampleLocationGridSize.width, ptr->sampleLocationsInfo.sampleLocationGridSize.height);
222 				if (ptr->sampleLocationsInfo.pSampleLocations != DE_NULL)
223 					for (deUint32 i = 0; i < ptr->sampleLocationsInfo.sampleLocationsCount; ++i)
224 						hash_combine(seed, ptr->sampleLocationsInfo.pSampleLocations[i].x, ptr->sampleLocationsInfo.pSampleLocations[i].y);
225 				break;
226 			}
227 			case VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT:
228 			{
229 				VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT* ptr = (VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT *)pNext;
230 				hash_combine(seed, ptr->requiredSubgroupSize);
231 				break;
232 			}
233 			case VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO:
234 			{
235 				VkPipelineTessellationDomainOriginStateCreateInfo* ptr = (VkPipelineTessellationDomainOriginStateCreateInfo *)pNext;
236 				hash_combine(seed, deUint32(ptr->domainOrigin));
237 				break;
238 			}
239 			case VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT:
240 			{
241 				VkPipelineVertexInputDivisorStateCreateInfoEXT* ptr = (VkPipelineVertexInputDivisorStateCreateInfoEXT *)pNext;
242 				if (ptr->pVertexBindingDivisors != DE_NULL)
243 					for (deUint32 i = 0; i < ptr->vertexBindingDivisorCount; ++i)
244 						hash_combine(seed, ptr->pVertexBindingDivisors[i].binding, ptr->pVertexBindingDivisors[i].divisor);
245 				break;
246 			}
247 			case VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO:
248 			{
249 				VkRenderPassInputAttachmentAspectCreateInfo* ptr = (VkRenderPassInputAttachmentAspectCreateInfo *)pNext;
250 				if (ptr->pAspectReferences != DE_NULL)
251 					for (deUint32 i = 0; i < ptr->aspectReferenceCount; ++i)
252 						hash_combine(seed, ptr->pAspectReferences[i].subpass, ptr->pAspectReferences[i].inputAttachmentIndex, ptr->pAspectReferences[i].aspectMask);
253 				break;
254 			}
255 			case VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO:
256 			{
257 				VkRenderPassMultiviewCreateInfo* ptr = (VkRenderPassMultiviewCreateInfo *)pNext;
258 				if (ptr->pViewMasks != DE_NULL)
259 					for (deUint32 i = 0; i < ptr->subpassCount; ++i)
260 						hash_combine(seed, ptr->pViewMasks[i]);
261 				if (ptr->pViewOffsets != DE_NULL)
262 					for (deUint32 i = 0; i < ptr->dependencyCount; ++i)
263 						hash_combine(seed, ptr->pViewOffsets[i]);
264 				if (ptr->pCorrelationMasks != DE_NULL)
265 					for (deUint32 i = 0; i < ptr->correlationMaskCount; ++i)
266 						hash_combine(seed, ptr->pCorrelationMasks[i]);
267 				break;
268 			}
269 			case VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT:
270 			{
271 				VkSamplerCustomBorderColorCreateInfoEXT* ptr = (VkSamplerCustomBorderColorCreateInfoEXT *)pNext;
272 				for (deUint32 i = 0; i < 4; ++i)
273 					hash_combine(seed, ptr->customBorderColor.uint32[i]);
274 				hash_combine(seed, deUint32(ptr->format));
275 				break;
276 			}
277 			case VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO:
278 			{
279 				VkSamplerReductionModeCreateInfo* ptr = (VkSamplerReductionModeCreateInfo *)pNext;
280 				hash_combine(seed, deUint32(ptr->reductionMode));
281 				break;
282 			}
283 			case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO:
284 			{
285 				VkSamplerYcbcrConversionInfo* ptr = (VkSamplerYcbcrConversionInfo *)pNext;
286 				{
287 					auto it = objectHashes.find(ptr->conversion.getInternal());
288 					if (it != end(objectHashes))
289 						hash_combine(seed, it->second);
290 				}
291 				break;
292 			}
293 			default:
294 				break;
295 		}
296 		hashPNextChain(seed, pBase->pNext, objectHashes);
297 	}
298 }
299 
graphicsPipelineHasDynamicState(const VkGraphicsPipelineCreateInfo & gpCI,VkDynamicState state)300 bool graphicsPipelineHasDynamicState(const VkGraphicsPipelineCreateInfo& gpCI, VkDynamicState state)
301 {
302 	if (gpCI.pDynamicState == DE_NULL)
303 		return false;
304 
305 	if (gpCI.pDynamicState->pDynamicStates == DE_NULL)
306 		return false;
307 
308 	for (deUint32 i = 0; i < gpCI.pDynamicState->dynamicStateCount; ++i)
309 		if (gpCI.pDynamicState->pDynamicStates[i] == state)
310 			return true;
311 
312 	return false;
313 }
314 
calculateGraphicsPipelineHash(const VkGraphicsPipelineCreateInfo & gpCI,const std::map<deUint64,std::size_t> & objectHashes)315 std::size_t calculateGraphicsPipelineHash (const VkGraphicsPipelineCreateInfo& gpCI, const std::map<deUint64, std::size_t>& objectHashes)
316 {
317 	std::size_t seed = 0;
318 
319 	hashPNextChain(seed, gpCI.pNext, objectHashes);
320 
321 	hash_combine(seed, gpCI.flags);
322 
323 	bool vertexInputStateRequired		= false;
324 	bool inputAssemblyStateRequired		= false;
325 	bool tessellationStateRequired		= false;
326 	bool viewportStateRequired			= false;
327 	bool viewportStateViewportsRequired	= false;
328 	bool viewportStateScissorsRequired	= false;
329 	bool multiSampleStateRequired		= false;
330 	bool depthStencilStateRequired		= false;
331 	bool colorBlendStateRequired		= false;
332 
333 	if (gpCI.pStages != DE_NULL)
334 	{
335 		for (deUint32 i = 0; i < gpCI.stageCount; ++i)
336 		{
337 			hashPNextChain(seed, gpCI.pStages[i].pNext, objectHashes);
338 
339 			hash_combine(seed, deUint32(gpCI.pStages[i].flags), deUint32(gpCI.pStages[i].stage));
340 			auto it = objectHashes.find(gpCI.pStages[i].module.getInternal());
341 			if (it != end(objectHashes))
342 				hash_combine(seed, it->second);
343 
344 			hash_combine(seed, std::string(gpCI.pStages[i].pName));
345 
346 			if (gpCI.pStages[i].pSpecializationInfo != DE_NULL)
347 			{
348 				if (gpCI.pStages[i].pSpecializationInfo->pMapEntries != DE_NULL)
349 				{
350 					for (deUint32 j = 0; j < gpCI.pStages[i].pSpecializationInfo->mapEntryCount; ++j)
351 						hash_combine(seed, gpCI.pStages[i].pSpecializationInfo->pMapEntries[j].constantID, gpCI.pStages[i].pSpecializationInfo->pMapEntries[j].offset, gpCI.pStages[i].pSpecializationInfo->pMapEntries[j].size);
352 
353 					hash_combine(seed, MemoryArea(gpCI.pStages[i].pSpecializationInfo->pData, gpCI.pStages[i].pSpecializationInfo->dataSize));
354 				}
355 			}
356 			if (gpCI.pStages[i].stage == VK_SHADER_STAGE_VERTEX_BIT)
357 			{
358 				vertexInputStateRequired	= true;
359 				inputAssemblyStateRequired	= true;
360 			}
361 			if (gpCI.pStages[i].stage == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
362 			{
363 				tessellationStateRequired	= true;
364 			}
365 		}
366 	}
367 	if (gpCI.pDynamicState != DE_NULL)
368 	{
369 		if (gpCI.pDynamicState->pDynamicStates != DE_NULL)
370 			for (deUint32 i = 0; i < gpCI.pDynamicState->dynamicStateCount; ++i)
371 			{
372 				if (gpCI.pDynamicState->pDynamicStates[i] == VK_DYNAMIC_STATE_VIEWPORT || gpCI.pDynamicState->pDynamicStates[i] == VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT)
373 				{
374 					viewportStateRequired			= true;
375 					viewportStateViewportsRequired	= true;
376 				}
377 				if (gpCI.pDynamicState->pDynamicStates[i] == VK_DYNAMIC_STATE_SCISSOR || gpCI.pDynamicState->pDynamicStates[i] == VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT)
378 				{
379 					viewportStateRequired			= true;
380 					viewportStateScissorsRequired	= true;
381 				}
382 				if (gpCI.pDynamicState->pDynamicStates[i] == VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT)
383 					viewportStateRequired = true;
384 			}
385 	}
386 	if (gpCI.pRasterizationState != DE_NULL)
387 	{
388 		if (gpCI.pRasterizationState->rasterizerDiscardEnable == VK_FALSE)
389 		{
390 			viewportStateRequired			= true;
391 			viewportStateViewportsRequired	= true;
392 			viewportStateScissorsRequired	= true;
393 			multiSampleStateRequired		= true;
394 			depthStencilStateRequired		= true;
395 			colorBlendStateRequired			= true;
396 		}
397 	}
398 
399 	if (vertexInputStateRequired && gpCI.pVertexInputState != DE_NULL)
400 	{
401 		hashPNextChain(seed, gpCI.pVertexInputState->pNext, objectHashes);
402 		hash_combine(seed, gpCI.pVertexInputState->flags);
403 		if (gpCI.pVertexInputState->pVertexBindingDescriptions != DE_NULL)
404 			for (deUint32 i = 0; i < gpCI.pVertexInputState->vertexBindingDescriptionCount; ++i)
405 				hash_combine(seed, gpCI.pVertexInputState->pVertexBindingDescriptions[i].binding, gpCI.pVertexInputState->pVertexBindingDescriptions[i].stride, deUint32(gpCI.pVertexInputState->pVertexBindingDescriptions[i].inputRate));
406 		if (gpCI.pVertexInputState->pVertexAttributeDescriptions != DE_NULL)
407 			for (deUint32 i = 0; i < gpCI.pVertexInputState->vertexAttributeDescriptionCount; ++i)
408 				hash_combine(seed, gpCI.pVertexInputState->pVertexAttributeDescriptions[i].location, gpCI.pVertexInputState->pVertexAttributeDescriptions[i].binding, deUint32(gpCI.pVertexInputState->pVertexAttributeDescriptions[i].format), gpCI.pVertexInputState->pVertexAttributeDescriptions[i].offset);
409 	}
410 
411 	if (inputAssemblyStateRequired && gpCI.pInputAssemblyState != DE_NULL)
412 	{
413 		hashPNextChain(seed, gpCI.pInputAssemblyState->pNext, objectHashes);
414 		hash_combine(seed, deUint32(gpCI.pInputAssemblyState->flags), deUint32(gpCI.pInputAssemblyState->topology), gpCI.pInputAssemblyState->primitiveRestartEnable);
415 	}
416 	if (tessellationStateRequired && gpCI.pTessellationState != DE_NULL)
417 	{
418 		hashPNextChain(seed, gpCI.pTessellationState->pNext, objectHashes);
419 		hash_combine(seed, gpCI.pTessellationState->flags, gpCI.pTessellationState->patchControlPoints);
420 	}
421 	if (viewportStateRequired && gpCI.pViewportState != DE_NULL)
422 	{
423 		hashPNextChain(seed, gpCI.pViewportState->pNext, objectHashes);
424 		hash_combine(seed, gpCI.pViewportState->flags);
425 
426 		if (viewportStateViewportsRequired && gpCI.pViewportState->pViewports != DE_NULL)
427 			for (deUint32 i = 0; i < gpCI.pViewportState->viewportCount; ++i)
428 				hash_combine(seed, gpCI.pViewportState->pViewports[i].x, gpCI.pViewportState->pViewports[i].y, gpCI.pViewportState->pViewports[i].width, gpCI.pViewportState->pViewports[i].height, gpCI.pViewportState->pViewports[i].minDepth, gpCI.pViewportState->pViewports[i].maxDepth);
429 
430 		if (viewportStateScissorsRequired && gpCI.pViewportState->pScissors != DE_NULL)
431 			for (deUint32 i = 0; i < gpCI.pViewportState->scissorCount; ++i)
432 				hash_combine(seed, gpCI.pViewportState->pScissors[i].offset.x, gpCI.pViewportState->pScissors[i].offset.y, gpCI.pViewportState->pScissors[i].extent.width, gpCI.pViewportState->pScissors[i].extent.height);
433 	}
434 	if (gpCI.pRasterizationState != DE_NULL)
435 	{
436 		hashPNextChain(seed, gpCI.pRasterizationState->pNext, objectHashes);
437 		hash_combine(seed, deUint32(gpCI.pRasterizationState->flags), gpCI.pRasterizationState->depthClampEnable, gpCI.pRasterizationState->rasterizerDiscardEnable, deUint32(gpCI.pRasterizationState->polygonMode), deUint32(gpCI.pRasterizationState->cullMode), deUint32(gpCI.pRasterizationState->frontFace), gpCI.pRasterizationState->depthBiasEnable, gpCI.pRasterizationState->depthBiasConstantFactor, gpCI.pRasterizationState->depthBiasClamp, gpCI.pRasterizationState->depthBiasSlopeFactor, gpCI.pRasterizationState->lineWidth);
438 	}
439 	if (multiSampleStateRequired && gpCI.pMultisampleState != DE_NULL)
440 	{
441 		hashPNextChain(seed, gpCI.pMultisampleState->pNext, objectHashes);
442 		hash_combine(seed, deUint32(gpCI.pMultisampleState->flags), deUint32(gpCI.pMultisampleState->rasterizationSamples), gpCI.pMultisampleState->sampleShadingEnable, gpCI.pMultisampleState->minSampleShading);
443 		if (gpCI.pMultisampleState->pSampleMask != DE_NULL)
444 			for (int i = 0; i < ((gpCI.pMultisampleState->rasterizationSamples + 31) / 32); i++)
445 				hash_combine(seed, gpCI.pMultisampleState->pSampleMask[i]);
446 		hash_combine(seed, gpCI.pMultisampleState->alphaToCoverageEnable, gpCI.pMultisampleState->alphaToOneEnable);
447 	}
448 	if (depthStencilStateRequired && gpCI.pDepthStencilState != DE_NULL)
449 	{
450 		hashPNextChain(seed, gpCI.pDepthStencilState->pNext, objectHashes);
451 		hash_combine(seed, deUint32(gpCI.pDepthStencilState->flags), gpCI.pDepthStencilState->depthTestEnable, gpCI.pDepthStencilState->depthWriteEnable, deUint32(gpCI.pDepthStencilState->depthCompareOp), gpCI.pDepthStencilState->depthBoundsTestEnable, gpCI.pDepthStencilState->stencilTestEnable);
452 		if (gpCI.pDepthStencilState->stencilTestEnable)
453 		{
454 			hash_combine(seed, deUint32(gpCI.pDepthStencilState->front.failOp), deUint32(gpCI.pDepthStencilState->front.passOp), deUint32(gpCI.pDepthStencilState->front.depthFailOp), deUint32(gpCI.pDepthStencilState->front.compareOp), gpCI.pDepthStencilState->front.compareMask, gpCI.pDepthStencilState->front.writeMask, gpCI.pDepthStencilState->front.reference);
455 			hash_combine(seed, deUint32(gpCI.pDepthStencilState->back.failOp), deUint32(gpCI.pDepthStencilState->back.passOp), deUint32(gpCI.pDepthStencilState->back.depthFailOp), deUint32(gpCI.pDepthStencilState->back.compareOp), gpCI.pDepthStencilState->back.compareMask, gpCI.pDepthStencilState->back.writeMask, gpCI.pDepthStencilState->back.reference);
456 		}
457 		hash_combine(seed, gpCI.pDepthStencilState->minDepthBounds, gpCI.pDepthStencilState->maxDepthBounds);
458 	}
459 	if (colorBlendStateRequired && gpCI.pColorBlendState != DE_NULL)
460 	{
461 		hashPNextChain(seed, gpCI.pColorBlendState->pNext, objectHashes);
462 		hash_combine(seed, deUint32(gpCI.pColorBlendState->flags), gpCI.pColorBlendState->logicOpEnable, deUint32(gpCI.pColorBlendState->logicOp));
463 
464 		bool hashBlendConstants = false;
465 		std::set<VkBlendFactor> constFactors = { VK_BLEND_FACTOR_CONSTANT_COLOR, VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR, VK_BLEND_FACTOR_CONSTANT_ALPHA, VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA };
466 		if (gpCI.pColorBlendState->pAttachments != DE_NULL)
467 		{
468 			for (deUint32 i = 0; i < gpCI.pColorBlendState->attachmentCount; ++i)
469 			{
470 				hash_combine
471 				(
472 					seed,
473 					gpCI.pColorBlendState->pAttachments[i].blendEnable, deUint32(gpCI.pColorBlendState->pAttachments[i].srcColorBlendFactor), deUint32(gpCI.pColorBlendState->pAttachments[i].dstColorBlendFactor), deUint32(gpCI.pColorBlendState->pAttachments[i].colorBlendOp),
474 					deUint32(gpCI.pColorBlendState->pAttachments[i].srcAlphaBlendFactor), deUint32(gpCI.pColorBlendState->pAttachments[i].dstAlphaBlendFactor), deUint32(gpCI.pColorBlendState->pAttachments[i].alphaBlendOp), deUint32(gpCI.pColorBlendState->pAttachments[i].colorWriteMask)
475 				);
476 				if (constFactors.find(gpCI.pColorBlendState->pAttachments[i].srcColorBlendFactor) != end(constFactors))	hashBlendConstants = true;
477 				if (constFactors.find(gpCI.pColorBlendState->pAttachments[i].dstColorBlendFactor) != end(constFactors))	hashBlendConstants = true;
478 				if (constFactors.find(gpCI.pColorBlendState->pAttachments[i].srcAlphaBlendFactor) != end(constFactors))	hashBlendConstants = true;
479 				if (constFactors.find(gpCI.pColorBlendState->pAttachments[i].dstAlphaBlendFactor) != end(constFactors))	hashBlendConstants = true;
480 			}
481 		}
482 		// omit blendConstants when VK_DYNAMIC_STATE_BLEND_CONSTANTS is present
483 		if (hashBlendConstants && !graphicsPipelineHasDynamicState(gpCI, VK_DYNAMIC_STATE_BLEND_CONSTANTS))
484 			for (deUint32 i = 0; i < 4; ++i)
485 				hash_combine(seed, gpCI.pColorBlendState->blendConstants[i]);
486 	}
487 	if (gpCI.pDynamicState != DE_NULL)
488 	{
489 		hashPNextChain(seed, gpCI.pDynamicState->pNext, objectHashes);
490 		hash_combine(seed, gpCI.pDynamicState->flags);
491 		if (gpCI.pDynamicState->pDynamicStates != DE_NULL)
492 			for (deUint32 i = 0; i < gpCI.pDynamicState->dynamicStateCount; ++i)
493 				hash_combine(seed, deUint32(gpCI.pDynamicState->pDynamicStates[i]));
494 	}
495 
496 	{
497 		auto it = objectHashes.find(gpCI.layout.getInternal());
498 		if (it != end(objectHashes))
499 			hash_combine(seed, it->second);
500 	}
501 
502 	{
503 		auto it = objectHashes.find(gpCI.renderPass.getInternal());
504 		if (it != end(objectHashes))
505 			hash_combine(seed, it->second);
506 	}
507 
508 	hash_combine(seed, gpCI.subpass);
509 
510 	{
511 		auto it = objectHashes.find(gpCI.basePipelineHandle.getInternal());
512 		if (it != end(objectHashes))
513 			hash_combine(seed, it->second);
514 	}
515 	hash_combine(seed, gpCI.basePipelineIndex);
516 
517 	return seed;
518 }
519 
calculateComputePipelineHash(const VkComputePipelineCreateInfo & cpCI,const std::map<deUint64,std::size_t> & objectHashes)520 std::size_t calculateComputePipelineHash (const VkComputePipelineCreateInfo& cpCI, const std::map<deUint64, std::size_t>& objectHashes)
521 {
522 	std::size_t seed = 0;
523 
524 	hashPNextChain(seed, cpCI.pNext, objectHashes);
525 
526 	hash_combine(seed, cpCI.flags);
527 
528 	{
529 		hash_combine(seed, deUint32(cpCI.stage.flags), deUint32(cpCI.stage.stage));
530 		auto it = objectHashes.find(cpCI.stage.module.getInternal());
531 		if (it != end(objectHashes))
532 			hash_combine(seed, it->second);
533 
534 		hash_combine(seed, std::string(cpCI.stage.pName));
535 
536 		if (cpCI.stage.pSpecializationInfo != DE_NULL)
537 		{
538 			if (cpCI.stage.pSpecializationInfo->pMapEntries != DE_NULL)
539 			{
540 				for (deUint32 j = 0; j < cpCI.stage.pSpecializationInfo->mapEntryCount; ++j)
541 					hash_combine(seed, cpCI.stage.pSpecializationInfo->pMapEntries[j].constantID, cpCI.stage.pSpecializationInfo->pMapEntries[j].offset, cpCI.stage.pSpecializationInfo->pMapEntries[j].size);
542 
543 				hash_combine(seed, MemoryArea(cpCI.stage.pSpecializationInfo->pData, cpCI.stage.pSpecializationInfo->dataSize));
544 			}
545 		}
546 	}
547 
548 	{
549 		auto it = objectHashes.find(cpCI.layout.getInternal());
550 		if (it != end(objectHashes))
551 			hash_combine(seed, it->second);
552 	}
553 
554 	{
555 		auto it = objectHashes.find(cpCI.basePipelineHandle.getInternal());
556 		if (it != end(objectHashes))
557 			hash_combine(seed, it->second);
558 	}
559 	hash_combine(seed, cpCI.basePipelineIndex);
560 
561 	return seed;
562 }
563 
calculateSamplerYcbcrConversionHash(const VkSamplerYcbcrConversionCreateInfo & scCI,const std::map<deUint64,std::size_t> & objectHashes)564 std::size_t calculateSamplerYcbcrConversionHash (const VkSamplerYcbcrConversionCreateInfo& scCI, const std::map<deUint64, std::size_t>& objectHashes)
565 {
566 	DE_UNREF(objectHashes);
567 	std::size_t seed = 0;
568 	hashPNextChain(seed, scCI.pNext, objectHashes);
569 	hash_combine(seed, deUint32(scCI.format), deUint32(scCI.ycbcrModel), deUint32(scCI.ycbcrRange), deUint32(scCI.components.r), deUint32(scCI.components.g), deUint32(scCI.components.b), deUint32(scCI.components.a), deUint32(scCI.xChromaOffset), deUint32(scCI.yChromaOffset), deUint32(scCI.chromaFilter), scCI.forceExplicitReconstruction);
570 	return seed;
571 }
572 
calculateSamplerHash(const VkSamplerCreateInfo & sCI,const std::map<deUint64,std::size_t> & objectHashes)573 std::size_t calculateSamplerHash (const VkSamplerCreateInfo& sCI, const std::map<deUint64, std::size_t>& objectHashes)
574 {
575 	std::size_t seed = 0;
576 	hashPNextChain(seed, sCI.pNext, objectHashes);
577 	hash_combine(seed, deUint32(sCI.flags), deUint32(sCI.magFilter), deUint32(sCI.minFilter), deUint32(sCI.mipmapMode), deUint32(sCI.addressModeU), deUint32(sCI.addressModeV), deUint32(sCI.addressModeW), sCI.mipLodBias, sCI.anisotropyEnable, sCI.maxAnisotropy, sCI.compareEnable, deUint32(sCI.compareOp), sCI.minLod, sCI.maxLod, deUint32(sCI.borderColor), sCI.unnormalizedCoordinates);
578 	return seed;
579 }
580 
calculateDescriptorSetLayoutHash(const VkDescriptorSetLayoutCreateInfo & sCI,const std::map<deUint64,std::size_t> & objectHashes)581 std::size_t calculateDescriptorSetLayoutHash (const VkDescriptorSetLayoutCreateInfo& sCI, const std::map<deUint64, std::size_t>& objectHashes)
582 {
583 	std::size_t seed = 0;
584 
585 	hashPNextChain(seed, sCI.pNext, objectHashes);
586 
587 	hash_combine(seed, deUint32(sCI.flags));
588 	if (sCI.pBindings != DE_NULL)
589 	{
590 		for (deUint32 i = 0; i < sCI.bindingCount; ++i)
591 		{
592 			hash_combine(seed, sCI.pBindings[i].binding, deUint32(sCI.pBindings[i].descriptorType), sCI.pBindings[i].descriptorCount, deUint32(sCI.pBindings[i].stageFlags));
593 			if (sCI.pBindings[i].pImmutableSamplers != DE_NULL)
594 			{
595 				for (deUint32 j = 0; j < sCI.pBindings[i].descriptorCount; ++j)
596 				{
597 					auto it = objectHashes.find(sCI.pBindings[i].pImmutableSamplers[j].getInternal());
598 					if (it != end(objectHashes))
599 						hash_combine(seed, it->second);
600 				}
601 			}
602 		}
603 	}
604 	return seed;
605 }
606 
calculatePipelineLayoutHash(const VkPipelineLayoutCreateInfo & pCI,const std::map<deUint64,std::size_t> & objectHashes)607 std::size_t calculatePipelineLayoutHash (const VkPipelineLayoutCreateInfo& pCI, const std::map<deUint64, std::size_t>& objectHashes)
608 {
609 	std::size_t seed = 0;
610 
611 	hashPNextChain(seed, pCI.pNext, objectHashes);
612 
613 	hash_combine(seed, deUint32(pCI.flags));
614 
615 	if (pCI.pSetLayouts != DE_NULL)
616 	{
617 		for (deUint32 i = 0; i < pCI.setLayoutCount; ++i)
618 		{
619 			auto it = objectHashes.find(pCI.pSetLayouts[i].getInternal());
620 			if (it != end(objectHashes))
621 				hash_combine(seed, it->second);
622 		}
623 	}
624 	if (pCI.pPushConstantRanges != DE_NULL)
625 	{
626 		for (deUint32 i = 0; i < pCI.pushConstantRangeCount; ++i)
627 		{
628 			hash_combine(seed, deUint32(pCI.pPushConstantRanges[i].stageFlags));
629 			hash_combine(seed, pCI.pPushConstantRanges[i].offset);
630 			hash_combine(seed, pCI.pPushConstantRanges[i].size);
631 		}
632 	}
633 
634 	return seed;
635 }
636 
calculateShaderModuleHash(const VkShaderModuleCreateInfo & sCI,const std::map<deUint64,std::size_t> & objectHashes)637 std::size_t calculateShaderModuleHash (const VkShaderModuleCreateInfo& sCI, const std::map<deUint64, std::size_t>& objectHashes)
638 {
639 	std::size_t seed = 0;
640 
641 	hashPNextChain(seed, sCI.pNext, objectHashes);
642 
643 	hash_combine(seed, deUint32(sCI.flags));
644 	hash_combine(seed, MemoryArea(sCI.pCode, sCI.codeSize));
645 
646 	return seed;
647 }
648 
649 
calculateRenderPassHash(const VkRenderPassCreateInfo & rCI,const std::map<deUint64,std::size_t> & objectHashes)650 std::size_t calculateRenderPassHash (const VkRenderPassCreateInfo& rCI, const std::map<deUint64, std::size_t>& objectHashes)
651 {
652 	std::size_t seed = 0;
653 
654 	hashPNextChain(seed, rCI.pNext, objectHashes);
655 
656 	hash_combine(seed, deUint32(rCI.flags));
657 
658 	if (rCI.pAttachments != DE_NULL)
659 		for (deUint32 i = 0; i < rCI.attachmentCount; ++i)
660 			hash_combine(seed, deUint32(rCI.pAttachments[i].flags), deUint32(rCI.pAttachments[i].format), deUint32(rCI.pAttachments[i].samples), deUint32(rCI.pAttachments[i].loadOp), deUint32(rCI.pAttachments[i].storeOp), deUint32(rCI.pAttachments[i].stencilLoadOp), deUint32(rCI.pAttachments[i].stencilStoreOp), deUint32(rCI.pAttachments[i].initialLayout), deUint32(rCI.pAttachments[i].finalLayout));
661 
662 	if (rCI.pSubpasses != DE_NULL)
663 	{
664 		for (deUint32 i = 0; i < rCI.subpassCount; ++i)
665 		{
666 			hash_combine(seed, deUint32(rCI.pSubpasses[i].flags), deUint32(rCI.pSubpasses[i].pipelineBindPoint));
667 			if (rCI.pSubpasses[i].pInputAttachments != DE_NULL)
668 				for (deUint32 j = 0; j < rCI.pSubpasses[i].inputAttachmentCount; ++j)
669 					hash_combine(seed, rCI.pSubpasses[i].pInputAttachments[j].attachment, deUint32(rCI.pSubpasses[i].pInputAttachments[j].layout));
670 			if (rCI.pSubpasses[i].pColorAttachments != DE_NULL)
671 				for (deUint32 j = 0; j < rCI.pSubpasses[i].colorAttachmentCount; ++j)
672 					hash_combine(seed, rCI.pSubpasses[i].pColorAttachments[j].attachment, deUint32(rCI.pSubpasses[i].pColorAttachments[j].layout));
673 			if (rCI.pSubpasses[i].pResolveAttachments != DE_NULL)
674 				for (deUint32 j = 0; j < rCI.pSubpasses[i].colorAttachmentCount; ++j)
675 					hash_combine(seed, rCI.pSubpasses[i].pResolveAttachments[j].attachment, deUint32(rCI.pSubpasses[i].pResolveAttachments[j].layout));
676 			if (rCI.pSubpasses[i].pDepthStencilAttachment != DE_NULL)
677 				hash_combine(seed, rCI.pSubpasses[i].pDepthStencilAttachment->attachment, deUint32(rCI.pSubpasses[i].pDepthStencilAttachment->layout));
678 			if (rCI.pSubpasses[i].pPreserveAttachments != DE_NULL)
679 				for (deUint32 j = 0; j < rCI.pSubpasses[i].preserveAttachmentCount; ++j)
680 					hash_combine(seed, rCI.pSubpasses[i].pPreserveAttachments[j]);
681 		}
682 	}
683 	if (rCI.pDependencies != DE_NULL)
684 		for (deUint32 i = 0; i < rCI.dependencyCount; ++i)
685 			hash_combine(seed, rCI.pDependencies[i].srcSubpass, rCI.pDependencies[i].dstSubpass, deUint32(rCI.pDependencies[i].srcStageMask), deUint32(rCI.pDependencies[i].dstStageMask), deUint64(rCI.pDependencies[i].srcAccessMask), deUint64(rCI.pDependencies[i].dstAccessMask), deUint32(rCI.pDependencies[i].dependencyFlags));
686 
687 	return seed;
688 }
689 
calculateRenderPass2Hash(const VkRenderPassCreateInfo2 & rCI,const std::map<deUint64,std::size_t> & objectHashes)690 std::size_t calculateRenderPass2Hash (const VkRenderPassCreateInfo2& rCI, const std::map<deUint64, std::size_t>& objectHashes)
691 {
692 	std::size_t seed = 0;
693 
694 	hashPNextChain(seed, rCI.pNext, objectHashes);
695 
696 	hash_combine(seed, rCI.flags);
697 
698 	if (rCI.pAttachments != DE_NULL)
699 		for (deUint32 i = 0; i < rCI.attachmentCount; ++i)
700 			hash_combine(seed, deUint32(rCI.pAttachments[i].flags), deUint32(rCI.pAttachments[i].format), deUint32(rCI.pAttachments[i].samples), deUint32(rCI.pAttachments[i].loadOp), deUint32(rCI.pAttachments[i].storeOp), deUint32(rCI.pAttachments[i].stencilLoadOp), deUint32(rCI.pAttachments[i].stencilStoreOp), deUint32(rCI.pAttachments[i].initialLayout), deUint32(rCI.pAttachments[i].finalLayout));
701 
702 	if (rCI.pSubpasses != DE_NULL)
703 	{
704 		for (deUint32 i = 0; i < rCI.subpassCount; ++i)
705 		{
706 			hash_combine(seed, deUint32(rCI.pSubpasses[i].flags), deUint32(rCI.pSubpasses[i].pipelineBindPoint));
707 			if (rCI.pSubpasses[i].pInputAttachments != DE_NULL)
708 				for (deUint32 j = 0; j < rCI.pSubpasses[i].inputAttachmentCount; ++j)
709 					hash_combine(seed, rCI.pSubpasses[i].pInputAttachments[j].attachment, deUint32(rCI.pSubpasses[i].pInputAttachments[j].layout));
710 			if (rCI.pSubpasses[i].pColorAttachments != DE_NULL)
711 				for (deUint32 j = 0; j < rCI.pSubpasses[i].colorAttachmentCount; ++j)
712 					hash_combine(seed, rCI.pSubpasses[i].pColorAttachments[j].attachment, deUint32(rCI.pSubpasses[i].pColorAttachments[j].layout));
713 			if (rCI.pSubpasses[i].pResolveAttachments != DE_NULL)
714 				for (deUint32 j = 0; j < rCI.pSubpasses[i].colorAttachmentCount; ++j)
715 					hash_combine(seed, rCI.pSubpasses[i].pResolveAttachments[j].attachment, deUint32(rCI.pSubpasses[i].pResolveAttachments[j].layout));
716 			if (rCI.pSubpasses[i].pDepthStencilAttachment != DE_NULL)
717 				hash_combine(seed, rCI.pSubpasses[i].pDepthStencilAttachment->attachment, deUint32(rCI.pSubpasses[i].pDepthStencilAttachment->layout));
718 			if (rCI.pSubpasses[i].pPreserveAttachments != DE_NULL)
719 				for (deUint32 j = 0; j < rCI.pSubpasses[i].preserveAttachmentCount; ++j)
720 					hash_combine(seed, rCI.pSubpasses[i].pPreserveAttachments[j]);
721 		}
722 	}
723 	if (rCI.pDependencies != DE_NULL)
724 		for (deUint32 i = 0; i < rCI.dependencyCount; ++i)
725 			hash_combine(seed, rCI.pDependencies[i].srcSubpass, rCI.pDependencies[i].dstSubpass, deUint32(rCI.pDependencies[i].srcStageMask), deUint32(rCI.pDependencies[i].dstStageMask), deUint64(rCI.pDependencies[i].srcAccessMask), deUint64(rCI.pDependencies[i].dstAccessMask), deUint32(rCI.pDependencies[i].dependencyFlags));
726 
727 	if (rCI.pCorrelatedViewMasks != DE_NULL)
728 		for (deUint32 i = 0; i < rCI.correlatedViewMaskCount; ++i)
729 			hash_combine(seed, rCI.pCorrelatedViewMasks[i]);
730 
731 	return seed;
732 }
733 
prepareSimpleGraphicsPipelineCI(VkPipelineVertexInputStateCreateInfo & vertexInputStateCreateInfo,std::vector<VkPipelineShaderStageCreateInfo> & shaderStageCreateInfos,VkPipelineInputAssemblyStateCreateInfo & inputAssemblyStateCreateInfo,VkPipelineViewportStateCreateInfo & viewPortStateCreateInfo,VkPipelineRasterizationStateCreateInfo & rasterizationStateCreateInfo,VkPipelineMultisampleStateCreateInfo & multisampleStateCreateInfo,VkPipelineColorBlendAttachmentState & colorBlendAttachmentState,VkPipelineColorBlendStateCreateInfo & colorBlendStateCreateInfo,VkPipelineDynamicStateCreateInfo & dynamicStateCreateInfo,std::vector<VkDynamicState> & dynamicStates,VkPipelineLayout pipelineLayout,VkRenderPass renderPass)734 VkGraphicsPipelineCreateInfo prepareSimpleGraphicsPipelineCI (VkPipelineVertexInputStateCreateInfo&			vertexInputStateCreateInfo,
735 															  std::vector<VkPipelineShaderStageCreateInfo>&	shaderStageCreateInfos,
736 															  VkPipelineInputAssemblyStateCreateInfo&		inputAssemblyStateCreateInfo,
737 															  VkPipelineViewportStateCreateInfo&			viewPortStateCreateInfo,
738 															  VkPipelineRasterizationStateCreateInfo&		rasterizationStateCreateInfo,
739 															  VkPipelineMultisampleStateCreateInfo&			multisampleStateCreateInfo,
740 															  VkPipelineColorBlendAttachmentState&			colorBlendAttachmentState,
741 															  VkPipelineColorBlendStateCreateInfo&			colorBlendStateCreateInfo,
742 															  VkPipelineDynamicStateCreateInfo&				dynamicStateCreateInfo,
743 															  std::vector<VkDynamicState>&					dynamicStates,
744 															  VkPipelineLayout								pipelineLayout,
745 															  VkRenderPass									renderPass)
746 {
747 	vertexInputStateCreateInfo =
748 	{
749 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,				// VkStructureType                             sType;
750 		DE_NULL,																// const void*                                 pNext;
751 		(VkPipelineVertexInputStateCreateFlags)0,								// VkPipelineVertexInputStateCreateFlags       flags;
752 		0u,																		// deUint32                                    vertexBindingDescriptionCount;
753 		DE_NULL,																// const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
754 		0u,																		// deUint32                                    vertexAttributeDescriptionCount;
755 		DE_NULL																	// const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
756 	};
757 
758 	inputAssemblyStateCreateInfo =
759 	{
760 		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,			// VkStructureType                            sType;
761 		DE_NULL,																// const void*                                pNext;
762 		(VkPipelineInputAssemblyStateCreateFlags)0,								// VkPipelineInputAssemblyStateCreateFlags    flags;
763 		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,									// VkPrimitiveTopology                        topology;
764 		VK_FALSE																// VkBool32                                   primitiveRestartEnable;
765 	};
766 
767 	viewPortStateCreateInfo =
768 	{
769 		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,					// VkStructureType                       sType;
770 		DE_NULL,																// const void*                           pNext;
771 		(VkPipelineViewportStateCreateFlags)0,									// VkPipelineViewportStateCreateFlags    flags;
772 		1,																		// deUint32                              viewportCount;
773 		DE_NULL,																// const VkViewport*                     pViewports;
774 		1,																		// deUint32                              scissorCount;
775 		DE_NULL																	// const VkRect2D*                       pScissors;
776 	};
777 
778 	rasterizationStateCreateInfo =
779 	{
780 		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,				// VkStructureType                            sType;
781 		DE_NULL,																// const void*                                pNext;
782 		(VkPipelineRasterizationStateCreateFlags)0,								// VkPipelineRasterizationStateCreateFlags    flags;
783 		VK_FALSE,																// VkBool32                                   depthClampEnable;
784 		VK_FALSE,																// VkBool32                                   rasterizerDiscardEnable;
785 		VK_POLYGON_MODE_FILL,													// VkPolygonMode                              polygonMode;
786 		VK_CULL_MODE_BACK_BIT,													// VkCullModeFlags                            cullMode;
787 		VK_FRONT_FACE_CLOCKWISE,												// VkFrontFace                                frontFace;
788 		VK_FALSE,																// VkBool32                                   depthBiasEnable;
789 		0.0f,																	// float                                      depthBiasConstantFactor;
790 		0.0f,																	// float                                      depthBiasClamp;
791 		0.0f,																	// float                                      depthBiasSlopeFactor;
792 		1.0f																	// float                                      lineWidth;
793 	};
794 
795 	multisampleStateCreateInfo =
796 	{
797 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,				// VkStructureType                          sType;
798 		DE_NULL,																// const void*                              pNext;
799 		(VkPipelineMultisampleStateCreateFlags)0,								// VkPipelineMultisampleStateCreateFlags    flags;
800 		VK_SAMPLE_COUNT_1_BIT,													// VkSampleCountFlagBits                    rasterizationSamples;
801 		VK_FALSE,																// VkBool32                                 sampleShadingEnable;
802 		0.0f,																	// float                                    minSampleShading;
803 		DE_NULL,																// const VkSampleMask*                      pSampleMask;
804 		VK_FALSE,																// VkBool32                                 alphaToCoverageEnable;
805 		VK_FALSE																// VkBool32                                 alphaToOneEnable;
806 	};
807 
808 	colorBlendAttachmentState =
809 	{
810 		VK_FALSE,																// VkBool32                 blendEnable;
811 		VK_BLEND_FACTOR_ZERO,													// VkBlendFactor            srcColorBlendFactor;
812 		VK_BLEND_FACTOR_ZERO,													// VkBlendFactor            dstColorBlendFactor;
813 		VK_BLEND_OP_ADD,														// VkBlendOp                colorBlendOp;
814 		VK_BLEND_FACTOR_ZERO,													// VkBlendFactor            srcAlphaBlendFactor;
815 		VK_BLEND_FACTOR_ZERO,													// VkBlendFactor            dstAlphaBlendFactor;
816 		VK_BLEND_OP_ADD,														// VkBlendOp                alphaBlendOp;
817 		(VkColorComponentFlags)0xFu												// VkColorComponentFlags    colorWriteMask;
818 	};
819 
820 	colorBlendStateCreateInfo =
821 	{
822 		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,				// VkStructureType                               sType;
823 		DE_NULL,																// const void*                                   pNext;
824 		(VkPipelineColorBlendStateCreateFlags)0,								// VkPipelineColorBlendStateCreateFlags          flags;
825 		DE_FALSE,																// VkBool32                                      logicOpEnable;
826 		VK_LOGIC_OP_CLEAR,														// VkLogicOp                                     logicOp;
827 		1,																		// deUint32                                      attachmentCount;
828 		&colorBlendAttachmentState,												// const VkPipelineColorBlendAttachmentState*    pAttachments;
829 		{ 1.0f, 1.0f, 1.0f, 1.0f }												// float                                         blendConstants[4];
830 	};
831 
832 	dynamicStateCreateInfo =
833 	{
834 		VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,					// VkStructureType                      sType;
835 		DE_NULL,																// const void*                          pNext;
836 		(VkPipelineDynamicStateCreateFlags)0u,									// VkPipelineDynamicStateCreateFlags    flags;
837 		deUint32(dynamicStates.size()),											// deUint32                             dynamicStateCount;
838 		dynamicStates.data()													// const VkDynamicState*                pDynamicStates;
839 	};
840 
841 	VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo =
842 	{
843 		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,						// VkStructureType                                  sType;
844 		DE_NULL,																// const void*                                      pNext;
845 		(VkPipelineCreateFlags)0,												// VkPipelineCreateFlags                            flags;
846 		deUint32(shaderStageCreateInfos.size()),								// deUint32                                         stageCount;
847 		shaderStageCreateInfos.data(),											// const VkPipelineShaderStageCreateInfo*           pStages;
848 		&vertexInputStateCreateInfo,											// const VkPipelineVertexInputStateCreateInfo*      pVertexInputState;
849 		&inputAssemblyStateCreateInfo,											// const VkPipelineInputAssemblyStateCreateInfo*    pInputAssemblyState;
850 		DE_NULL,																// const VkPipelineTessellationStateCreateInfo*     pTessellationState;
851 		&viewPortStateCreateInfo,												// const VkPipelineViewportStateCreateInfo*         pViewportState;
852 		&rasterizationStateCreateInfo,											// const VkPipelineRasterizationStateCreateInfo*    pRasterizationState;
853 		&multisampleStateCreateInfo,											// const VkPipelineMultisampleStateCreateInfo*      pMultisampleState;
854 		DE_NULL,																// const VkPipelineDepthStencilStateCreateInfo*     pDepthStencilState;
855 		&colorBlendStateCreateInfo,												// const VkPipelineColorBlendStateCreateInfo*       pColorBlendState;
856 		&dynamicStateCreateInfo,												// const VkPipelineDynamicStateCreateInfo*          pDynamicState;
857 		pipelineLayout,															// VkPipelineLayout                                 layout;
858 		renderPass,																// VkRenderPass                                     renderPass;
859 		0u,																		// deUint32                                         subpass;
860 		DE_NULL,																// VkPipeline                                       basePipelineHandle;
861 		0																		// int                                              basePipelineIndex;
862 	};
863 
864 	return graphicsPipelineCreateInfo;
865 }
866 
prepareSimpleComputePipelineCI(const VkPipelineShaderStageCreateInfo & shaderStageCreateInfo,VkPipelineLayout pipelineLayout)867 VkComputePipelineCreateInfo prepareSimpleComputePipelineCI (const VkPipelineShaderStageCreateInfo&	shaderStageCreateInfo,
868 															VkPipelineLayout						pipelineLayout)
869 {
870 	const VkComputePipelineCreateInfo				pipelineCreateInfo			=
871 	{
872 		VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,							// VkStructureType					sType
873 		DE_NULL,																// const void*						pNext
874 		0u,																		// VkPipelineCreateFlags			flags
875 		shaderStageCreateInfo,													// VkPipelineShaderStageCreateInfo	stage
876 		pipelineLayout,															// VkPipelineLayout					layout
877 		(vk::VkPipeline)0,														// VkPipeline						basePipelineHandle
878 		0u,																		// deInt32							basePipelineIndex
879 	};
880 	return pipelineCreateInfo;
881 }
882 
prepareSimpleRenderPassCI(VkFormat format,VkAttachmentDescription & attachmentDescription,VkAttachmentReference & attachmentReference,VkSubpassDescription & subpassDescription)883 VkRenderPassCreateInfo prepareSimpleRenderPassCI (VkFormat						format,
884 												  VkAttachmentDescription&		attachmentDescription,
885 												  VkAttachmentReference&		attachmentReference,
886 												  VkSubpassDescription&			subpassDescription)
887 {
888 	attachmentDescription =
889 	{
890 		(VkAttachmentDescriptionFlags)0u,										// VkAttachmentDescriptionFlags    flags;
891 		format,																	// VkFormat                        format;
892 		VK_SAMPLE_COUNT_1_BIT,													// VkSampleCountFlagBits           samples;
893 		VK_ATTACHMENT_LOAD_OP_CLEAR,											// VkAttachmentLoadOp              loadOp;
894 		VK_ATTACHMENT_STORE_OP_STORE,											// VkAttachmentStoreOp             storeOp;
895 		VK_ATTACHMENT_LOAD_OP_DONT_CARE,										// VkAttachmentLoadOp              stencilLoadOp;
896 		VK_ATTACHMENT_STORE_OP_DONT_CARE,										// VkAttachmentStoreOp             stencilStoreOp;
897 		VK_IMAGE_LAYOUT_UNDEFINED,												// VkImageLayout                   initialLayout;
898 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL								// VkImageLayout                   finalLayout;
899 	};
900 
901 	attachmentReference =
902 	{
903 		0u,		// deUint32			attachment;
904 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// VkImageLayout	layout;
905 	};
906 
907 	subpassDescription =
908 	{
909 		(VkSubpassDescriptionFlags)0u,											// VkSubpassDescriptionFlags       flags;
910 		VK_PIPELINE_BIND_POINT_GRAPHICS,										// VkPipelineBindPoint             pipelineBindPoint
911 		0u,																		// deUint32                        inputAttachmentCount
912 		DE_NULL,																// const VkAttachmentReference*    pInputAttachments
913 		1u,																		// deUint32                        colorAttachmentCount
914 		&attachmentReference,													// const VkAttachmentReference*    pColorAttachments
915 		DE_NULL,																// const VkAttachmentReference*    pResolveAttachments
916 		DE_NULL,																// const VkAttachmentReference*    pDepthStencilAttachment
917 		0u,																		// deUint32                        preserveAttachmentCount
918 		DE_NULL																	// const deUint32*                 pPreserveAttachments
919 	};
920 
921 	const VkRenderPassCreateInfo					renderPassCreateInfo		=
922 	{
923 		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,								// VkStructureType                   sType;
924 		DE_NULL,																// const void*                       pNext;
925 		(VkRenderPassCreateFlags)0u,											// VkRenderPassCreateFlags           flags;
926 		1u,																		// deUint32                          attachmentCount
927 		&attachmentDescription,													// const VkAttachmentDescription*    pAttachments
928 		1u,																		// deUint32                          subpassCount
929 		&subpassDescription,													// const VkSubpassDescription*       pSubpasses
930 		0u,																		// deUint32                          dependencyCount
931 		DE_NULL																	// const VkSubpassDependency*        pDependencies
932 	};
933 
934 	return renderPassCreateInfo;
935 }
936 
getRenderTargetFormat(const InstanceInterface & vk,const VkPhysicalDevice & device)937 VkFormat getRenderTargetFormat (const InstanceInterface& vk, const VkPhysicalDevice& device)
938 {
939 	const VkFormatFeatureFlags	featureFlags = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
940 	VkFormatProperties			formatProperties;
941 	vk.getPhysicalDeviceFormatProperties(device, VK_FORMAT_B8G8R8A8_UNORM, &formatProperties);
942 	if ((formatProperties.linearTilingFeatures & featureFlags) || (formatProperties.optimalTilingFeatures & featureFlags))
943 		return VK_FORMAT_B8G8R8A8_UNORM;
944 	vk.getPhysicalDeviceFormatProperties(device, VK_FORMAT_R8G8B8A8_UNORM, &formatProperties);
945 	if ((formatProperties.linearTilingFeatures & featureFlags) || formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)
946 		return VK_FORMAT_R8G8B8A8_UNORM;
947 	TCU_THROW(NotSupportedError, "Device does not support VK_FORMAT_B8G8R8A8_UNORM nor VK_FORMAT_R8G8B8A8_UNORM");
948 	return VK_FORMAT_UNDEFINED;
949 }
950 
951 } // vk
952 
953 #else
954 	DE_EMPTY_CPP_FILE
955 #endif // CTS_USES_VULKANSC
956