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