• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2021 The Khronos Group Inc.
6  * Copyright (c) 2023 LunarG, Inc.
7  * Copyright (c) 2023 Nintendo
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Wrapper that can construct monolithic pipeline or use
24           VK_EXT_graphics_pipeline_library for pipeline construction or use
25           VK_EXT_shader_object for shader objects.
26  *//*--------------------------------------------------------------------*/
27 
28 #include "vkRefUtil.hpp"
29 #include "vkQueryUtil.hpp"
30 #include "deSharedPtr.hpp"
31 #include "deSTLUtil.hpp"
32 #include "tcuVector.hpp"
33 #include "tcuVectorType.hpp"
34 #include "tcuMaybe.hpp"
35 #include "vkRefUtil.hpp"
36 #include "vkCmdUtil.hpp"
37 #include "vkObjUtil.hpp"
38 #include "vkTypeUtil.hpp"
39 #include "tcuTextureUtil.hpp"
40 #include "vkImageUtil.hpp"
41 #include "vkPipelineConstructionUtil.hpp"
42 #include "vkBarrierUtil.hpp"
43 
44 #include <memory>
45 #include <set>
46 #include <map>
47 
48 namespace vk
49 {
50 
51 namespace
52 {
53 
54 enum PipelineSetupState
55 {
56     PSS_NONE                      = 0x00000000,
57     PSS_VERTEX_INPUT_INTERFACE    = 0x00000001,
58     PSS_PRE_RASTERIZATION_SHADERS = 0x00000002,
59     PSS_FRAGMENT_SHADER           = 0x00000004,
60     PSS_FRAGMENT_OUTPUT_INTERFACE = 0x00000008,
61 };
62 
63 using TessellationDomainOriginStatePtr = std::unique_ptr<VkPipelineTessellationDomainOriginStateCreateInfo>;
64 
65 } // anonymous namespace
66 
67 static const VkVertexInputBindingDescription defaultVertexInputBindingDescription{
68     0u,                          // uint32_t                                        binding
69     sizeof(tcu::Vec4),           // uint32_t                                        stride
70     VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate                            inputRate
71 };
72 
73 static const VkVertexInputAttributeDescription defaultVertexInputAttributeDescription{
74     0u,                            // uint32_t                                        location
75     0u,                            // uint32_t                                        binding
76     VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat                                        format
77     0u                             // uint32_t                                        offset
78 };
79 
80 static const VkPipelineVertexInputStateCreateInfo defaultVertexInputState{
81     VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType                                sType
82     DE_NULL,                                                   // const void*                                    pNext
83     (VkPipelineVertexInputStateCreateFlags)0,                  // VkPipelineVertexInputStateCreateFlags        flags
84     1u, // uint32_t                                        vertexBindingDescriptionCount
85     &defaultVertexInputBindingDescription, // const VkVertexInputBindingDescription*        pVertexBindingDescriptions
86     1u, // uint32_t                                        vertexAttributeDescriptionCount
87     &defaultVertexInputAttributeDescription // const VkVertexInputAttributeDescription*        pVertexAttributeDescriptions
88 };
89 
90 static const VkStencilOpState defaultStencilOpState{
91     VK_STENCIL_OP_KEEP,  // VkStencilOp                                    failOp
92     VK_STENCIL_OP_KEEP,  // VkStencilOp                                    passOp
93     VK_STENCIL_OP_KEEP,  // VkStencilOp                                    depthFailOp
94     VK_COMPARE_OP_NEVER, // VkCompareOp                                    compareOp
95     0u,                  // uint32_t                                        compareMask
96     0u,                  // uint32_t                                        writeMask
97     0u                   // uint32_t                                        reference
98 };
99 
100 static const VkPipelineDepthStencilStateCreateInfo defaultDepthStencilState{
101     VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType                                sType
102     DE_NULL,                                                    // const void*                                    pNext
103     0u,                                                         // VkPipelineDepthStencilStateCreateFlags        flags
104     VK_FALSE,                    // VkBool32                                        depthTestEnable
105     VK_FALSE,                    // VkBool32                                        depthWriteEnable
106     VK_COMPARE_OP_LESS_OR_EQUAL, // VkCompareOp                                    depthCompareOp
107     VK_FALSE,                    // VkBool32                                        depthBoundsTestEnable
108     VK_FALSE,                    // VkBool32                                        stencilTestEnable
109     defaultStencilOpState,       // VkStencilOpState                                front
110     defaultStencilOpState,       // VkStencilOpState                                back
111     0.0f,                        // float                                        minDepthBounds
112     1.0f,                        // float                                        maxDepthBounds
113 };
114 
115 static const VkPipelineMultisampleStateCreateInfo defaultMultisampleState{
116     VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType                                sType
117     DE_NULL,                                                  // const void*                                    pNext
118     0u,                                                       // VkPipelineMultisampleStateCreateFlags        flags
119     VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits                        rasterizationSamples
120     VK_FALSE,              // VkBool32                                        sampleShadingEnable
121     1.0f,                  // float                                        minSampleShading
122     DE_NULL,               // const VkSampleMask*                            pSampleMask
123     VK_FALSE,              // VkBool32                                        alphaToCoverageEnable
124     VK_FALSE               // VkBool32                                        alphaToOneEnable
125 };
126 
127 static const VkPipelineColorBlendAttachmentState defaultColorBlendAttachmentState{
128     VK_FALSE,             // VkBool32                                        blendEnable
129     VK_BLEND_FACTOR_ZERO, // VkBlendFactor                                srcColorBlendFactor
130     VK_BLEND_FACTOR_ZERO, // VkBlendFactor                                dstColorBlendFactor
131     VK_BLEND_OP_ADD,      // VkBlendOp                                    colorBlendOp
132     VK_BLEND_FACTOR_ZERO, // VkBlendFactor                                srcAlphaBlendFactor
133     VK_BLEND_FACTOR_ZERO, // VkBlendFactor                                dstAlphaBlendFactor
134     VK_BLEND_OP_ADD,      // VkBlendOp                                    alphaBlendOp
135     0xf                   // VkColorComponentFlags                        colorWriteMask
136 };
137 
138 static const VkPipelineColorBlendStateCreateInfo defaultColorBlendState{
139     VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType                                sType
140     DE_NULL,                                                  // const void*                                    pNext
141     0u,                                                       // VkPipelineColorBlendStateCreateFlags            flags
142     VK_FALSE,                          // VkBool32                                        logicOpEnable
143     VK_LOGIC_OP_CLEAR,                 // VkLogicOp                                    logicOp
144     1u,                                // uint32_t                                        attachmentCount
145     &defaultColorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState*    pAttachments
146     {0.0f, 0.0f, 0.0f, 0.0f}           // float                                        blendConstants[4]
147 };
148 
149 namespace
150 {
151 #ifndef CTS_USES_VULKANSC
makeGraphicsPipelineLibraryCreateInfo(const VkGraphicsPipelineLibraryFlagsEXT flags)152 VkGraphicsPipelineLibraryCreateInfoEXT makeGraphicsPipelineLibraryCreateInfo(
153     const VkGraphicsPipelineLibraryFlagsEXT flags)
154 {
155     return {
156         VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT, // VkStructureType sType;
157         DE_NULL,                                                     // void* pNext;
158         flags,                                                       // VkGraphicsPipelineLibraryFlagsEXT flags;
159     };
160 }
161 #endif // CTS_USES_VULKANSC
162 
makeGraphicsPipeline(const DeviceInterface & vk,VkDevice device,VkPipelineCache pipelineCache,const VkGraphicsPipelineCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator=nullptr)163 Move<VkPipeline> makeGraphicsPipeline(const DeviceInterface &vk, VkDevice device, VkPipelineCache pipelineCache,
164                                       const VkGraphicsPipelineCreateInfo *pCreateInfo,
165                                       const VkAllocationCallbacks *pAllocator = nullptr)
166 {
167     VkPipeline object  = 0;
168     const auto retcode = vk.createGraphicsPipelines(device, pipelineCache, 1u, pCreateInfo, pAllocator, &object);
169 
170 #ifndef CTS_USES_VULKANSC
171     const bool allowCompileRequired =
172         ((pCreateInfo->flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT) != 0u);
173 
174     if (allowCompileRequired && retcode == VK_PIPELINE_COMPILE_REQUIRED)
175         throw PipelineCompileRequiredError("createGraphicsPipelines returned VK_PIPELINE_COMPILE_REQUIRED");
176 #endif // CTS_USES_VULKANSC
177 
178     VK_CHECK(retcode);
179     return Move<VkPipeline>(check<VkPipeline>(object), Deleter<VkPipeline>(vk, device, pAllocator));
180 }
181 
182 } // namespace
183 
isConstructionTypeLibrary(PipelineConstructionType pipelineConstructionType)184 bool isConstructionTypeLibrary(PipelineConstructionType pipelineConstructionType)
185 {
186     return pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_LINK_TIME_OPTIMIZED_LIBRARY ||
187            pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_FAST_LINKED_LIBRARY;
188 }
189 
isConstructionTypeShaderObject(PipelineConstructionType pipelineConstructionType)190 bool isConstructionTypeShaderObject(PipelineConstructionType pipelineConstructionType)
191 {
192     return pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_SHADER_OBJECT_UNLINKED_SPIRV ||
193            pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_SHADER_OBJECT_UNLINKED_BINARY ||
194            pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_SHADER_OBJECT_LINKED_SPIRV ||
195            pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_SHADER_OBJECT_LINKED_BINARY;
196 }
197 
checkPipelineConstructionRequirements(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,PipelineConstructionType pipelineConstructionType)198 void checkPipelineConstructionRequirements(const InstanceInterface &vki, VkPhysicalDevice physicalDevice,
199                                            PipelineConstructionType pipelineConstructionType)
200 {
201     if (pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
202         return;
203 
204     const auto &supportedExtensions = enumerateCachedDeviceExtensionProperties(vki, physicalDevice);
205 
206     if (isConstructionTypeShaderObject(pipelineConstructionType))
207     {
208         if (!isExtensionStructSupported(supportedExtensions, RequiredExtension("VK_EXT_shader_object")))
209             TCU_THROW(NotSupportedError, "VK_EXT_shader_object not supported");
210         return;
211     }
212 
213     if (!isExtensionStructSupported(supportedExtensions, RequiredExtension("VK_EXT_graphics_pipeline_library")))
214         TCU_THROW(NotSupportedError, "VK_EXT_graphics_pipeline_library not supported");
215 }
216 
translateCreateFlag(VkPipelineCreateFlags flagToTranslate)217 PipelineCreateFlags2 translateCreateFlag(VkPipelineCreateFlags flagToTranslate)
218 {
219     return (PipelineCreateFlags2)flagToTranslate;
220 }
221 
addToChain(void ** structThatStartsChain,void * structToAddAtTheEnd)222 void addToChain(void **structThatStartsChain, void *structToAddAtTheEnd)
223 {
224     DE_ASSERT(structThatStartsChain);
225 
226     if (structToAddAtTheEnd == DE_NULL)
227         return;
228 
229     // Cast to the base out structure which has a non-const pNext pointer.
230     auto *structToAddAtTheEndCasted = reinterpret_cast<VkBaseOutStructure *>(structToAddAtTheEnd);
231 
232     // make sure that pNext pointer of structure that is added to chain is empty;
233     // we are construting chains on our own and there are cases that use same
234     // structure for multiple instances of GraphicsPipelineWrapper
235     structToAddAtTheEndCasted->pNext = DE_NULL;
236 
237     uint32_t safetyCouter = 10u;
238     void **structInChain  = structThatStartsChain;
239 
240     do
241     {
242         // check if this is free spot
243         if (*structInChain == DE_NULL)
244         {
245             // attach new structure at the end
246             *structInChain = structToAddAtTheEndCasted;
247             return;
248         }
249 
250         // Cast to the base out structure which has a non-const pNext pointer.
251         auto *gpl = reinterpret_cast<VkBaseOutStructure *>(*structInChain);
252 
253         // move structure pointer one position down the pNext chain
254         structInChain = reinterpret_cast<void **>(&gpl->pNext);
255     } while (--safetyCouter);
256 
257     // probably safetyCouter is to small
258     DE_ASSERT(false);
259 }
260 
261 namespace
262 {
263 using PipelineShaderStageModuleIdPtr = std::unique_ptr<PipelineShaderStageModuleIdentifierCreateInfoWrapper>;
264 }
265 
PipelineLayoutWrapper(PipelineConstructionType pipelineConstructionType,const DeviceInterface & vk,VkDevice device,const std::vector<vk::Move<VkDescriptorSetLayout>> & descriptorSetLayout)266 PipelineLayoutWrapper::PipelineLayoutWrapper(PipelineConstructionType pipelineConstructionType,
267                                              const DeviceInterface &vk, VkDevice device,
268                                              const std::vector<vk::Move<VkDescriptorSetLayout>> &descriptorSetLayout)
269     : m_pipelineConstructionType(pipelineConstructionType)
270     , m_vk(&vk)
271     , m_device(device)
272     , m_flags((VkPipelineLayoutCreateFlags)0u)
273     , m_setLayoutCount((uint32_t)descriptorSetLayout.size())
274     , m_pushConstantRangeCount(0u)
275     , m_pushConstantRanges()
276 {
277 #ifndef CTS_USES_VULKANSC
278     if (isConstructionTypeShaderObject(pipelineConstructionType))
279         m_flags &= ~(VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT);
280 #endif
281 
282     m_setLayouts.resize(m_setLayoutCount);
283     for (uint32_t i = 0; i < m_setLayoutCount; ++i)
284         m_setLayouts[i] = *descriptorSetLayout[i];
285 
286     VkPipelineLayoutCreateInfo createInfo = vk::initVulkanStructure();
287     createInfo.flags                      = m_flags;
288     createInfo.setLayoutCount             = m_setLayoutCount;
289     createInfo.pSetLayouts                = de::dataOrNull(m_setLayouts);
290     createInfo.pushConstantRangeCount     = m_pushConstantRangeCount;
291     createInfo.pPushConstantRanges        = de::dataOrNull(m_pushConstantRanges);
292     m_pipelineLayout                      = createPipelineLayout(vk, device, &createInfo);
293 }
294 
PipelineLayoutWrapper(PipelineConstructionType pipelineConstructionType,const DeviceInterface & vk,VkDevice device,uint32_t setLayoutCount,const VkDescriptorSetLayout * descriptorSetLayout)295 PipelineLayoutWrapper::PipelineLayoutWrapper(PipelineConstructionType pipelineConstructionType,
296                                              const DeviceInterface &vk, VkDevice device, uint32_t setLayoutCount,
297                                              const VkDescriptorSetLayout *descriptorSetLayout)
298     : m_pipelineConstructionType(pipelineConstructionType)
299     , m_vk(&vk)
300     , m_device(device)
301     , m_flags((VkPipelineLayoutCreateFlags)0u)
302     , m_setLayoutCount(setLayoutCount)
303     , m_pushConstantRangeCount(0u)
304     , m_pushConstantRanges()
305 {
306 #ifndef CTS_USES_VULKANSC
307     if (isConstructionTypeShaderObject(pipelineConstructionType))
308         m_flags &= ~(VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT);
309 #endif
310 
311     m_setLayouts.resize(m_setLayoutCount);
312     for (uint32_t i = 0; i < m_setLayoutCount; ++i)
313         m_setLayouts[i] = descriptorSetLayout[i];
314 
315     VkPipelineLayoutCreateInfo createInfo = vk::initVulkanStructure();
316     createInfo.flags                      = m_flags;
317     createInfo.setLayoutCount             = m_setLayoutCount;
318     createInfo.pSetLayouts                = de::dataOrNull(m_setLayouts);
319     createInfo.pushConstantRangeCount     = m_pushConstantRangeCount;
320     createInfo.pPushConstantRanges        = de::dataOrNull(m_pushConstantRanges);
321     m_pipelineLayout                      = createPipelineLayout(vk, device, &createInfo);
322 }
323 
PipelineLayoutWrapper(PipelineConstructionType pipelineConstructionType,const DeviceInterface & vk,VkDevice device,const VkDescriptorSetLayout descriptorSetLayout,const VkPushConstantRange * pushConstantRange)324 PipelineLayoutWrapper::PipelineLayoutWrapper(PipelineConstructionType pipelineConstructionType,
325                                              const DeviceInterface &vk, VkDevice device,
326                                              const VkDescriptorSetLayout descriptorSetLayout,
327                                              const VkPushConstantRange *pushConstantRange)
328     : m_pipelineConstructionType(pipelineConstructionType)
329     , m_vk(&vk)
330     , m_device(device)
331     , m_flags((VkPipelineLayoutCreateFlags)0u)
332 {
333 #ifndef CTS_USES_VULKANSC
334     if (isConstructionTypeShaderObject(pipelineConstructionType))
335         m_flags &= ~(VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT);
336 #endif
337 
338     if (descriptorSetLayout == VK_NULL_HANDLE)
339     {
340         m_setLayoutCount = 0;
341     }
342     else
343     {
344         m_setLayoutCount = 1;
345         m_setLayouts.resize(1);
346         m_setLayouts[0] = descriptorSetLayout;
347     }
348     if (pushConstantRange == DE_NULL)
349     {
350         m_pushConstantRangeCount = 0;
351     }
352     else
353     {
354         m_pushConstantRangeCount = 1;
355         m_pushConstantRanges.resize(1);
356         m_pushConstantRanges[0] = *pushConstantRange;
357     }
358 
359     VkPipelineLayoutCreateInfo createInfo = vk::initVulkanStructure();
360     createInfo.flags                      = m_flags;
361     createInfo.setLayoutCount             = m_setLayoutCount;
362     createInfo.pSetLayouts                = de::dataOrNull(m_setLayouts);
363     createInfo.pushConstantRangeCount     = m_pushConstantRangeCount;
364     createInfo.pPushConstantRanges        = de::dataOrNull(m_pushConstantRanges);
365     m_pipelineLayout                      = createPipelineLayout(vk, device, &createInfo);
366 }
367 
PipelineLayoutWrapper(PipelineConstructionType pipelineConstructionType,const DeviceInterface & vk,VkDevice device,const VkPipelineLayoutCreateInfo * pCreateInfo,const VkAllocationCallbacks *)368 PipelineLayoutWrapper::PipelineLayoutWrapper(PipelineConstructionType pipelineConstructionType,
369                                              const DeviceInterface &vk, VkDevice device,
370                                              const VkPipelineLayoutCreateInfo *pCreateInfo,
371                                              const VkAllocationCallbacks *)
372     : m_pipelineConstructionType(pipelineConstructionType)
373     , m_vk(&vk)
374     , m_device(device)
375     , m_flags(pCreateInfo->flags)
376     , m_setLayoutCount(pCreateInfo->setLayoutCount)
377     , m_pushConstantRangeCount(pCreateInfo->pushConstantRangeCount)
378 {
379 #ifndef CTS_USES_VULKANSC
380     if (isConstructionTypeShaderObject(pipelineConstructionType))
381         m_flags &= ~(VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT);
382 #endif
383 
384     m_setLayouts.resize(pCreateInfo->setLayoutCount);
385     for (uint32_t i = 0; i < pCreateInfo->setLayoutCount; ++i)
386         m_setLayouts[i] = pCreateInfo->pSetLayouts[i];
387     m_pushConstantRanges.resize(pCreateInfo->pushConstantRangeCount);
388     for (uint32_t i = 0; i < pCreateInfo->pushConstantRangeCount; ++i)
389         m_pushConstantRanges[i] = pCreateInfo->pPushConstantRanges[i];
390 
391     VkPipelineLayoutCreateInfo createInfo = vk::initVulkanStructure();
392     createInfo.flags                      = m_flags;
393     createInfo.setLayoutCount             = m_setLayoutCount;
394     createInfo.pSetLayouts                = m_setLayouts.data();
395     createInfo.pushConstantRangeCount     = m_pushConstantRangeCount;
396     createInfo.pPushConstantRanges        = m_pushConstantRanges.data();
397     m_pipelineLayout                      = createPipelineLayout(vk, device, &createInfo);
398 }
399 
PipelineLayoutWrapper(PipelineConstructionType pipelineConstructionType,const DeviceInterface & vk,const VkDevice device,const uint32_t setLayoutCount,const VkDescriptorSetLayout * descriptorSetLayout,const uint32_t pushConstantRangeCount,const VkPushConstantRange * pPushConstantRanges,const VkPipelineLayoutCreateFlags flags)400 PipelineLayoutWrapper::PipelineLayoutWrapper(PipelineConstructionType pipelineConstructionType,
401                                              const DeviceInterface &vk, const VkDevice device,
402                                              const uint32_t setLayoutCount,
403                                              const VkDescriptorSetLayout *descriptorSetLayout,
404                                              const uint32_t pushConstantRangeCount,
405                                              const VkPushConstantRange *pPushConstantRanges,
406                                              const VkPipelineLayoutCreateFlags flags)
407     : m_pipelineConstructionType(pipelineConstructionType)
408     , m_vk(&vk)
409     , m_device(device)
410     , m_flags(flags)
411     , m_setLayoutCount(setLayoutCount)
412     , m_pushConstantRangeCount(pushConstantRangeCount)
413 {
414 #ifndef CTS_USES_VULKANSC
415     if (isConstructionTypeShaderObject(pipelineConstructionType))
416         m_flags &= ~(VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT);
417 #endif
418 
419     m_setLayouts.resize(m_setLayoutCount);
420     m_pushConstantRanges.resize(m_pushConstantRangeCount);
421     for (uint32_t i = 0; i < m_setLayoutCount; ++i)
422         m_setLayouts[i] = descriptorSetLayout[i];
423     for (uint32_t i = 0; i < m_pushConstantRangeCount; ++i)
424         m_pushConstantRanges[i] = pPushConstantRanges[i];
425 
426     VkPipelineLayoutCreateInfo createInfo = vk::initVulkanStructure();
427     createInfo.flags                      = m_flags;
428     createInfo.setLayoutCount             = m_setLayoutCount;
429     createInfo.pSetLayouts                = m_setLayouts.data();
430     createInfo.pushConstantRangeCount     = m_pushConstantRangeCount;
431     createInfo.pPushConstantRanges        = m_pushConstantRanges.data();
432     m_pipelineLayout                      = createPipelineLayout(vk, device, &createInfo);
433 }
434 
PipelineLayoutWrapper(PipelineLayoutWrapper && rhs)435 PipelineLayoutWrapper::PipelineLayoutWrapper(PipelineLayoutWrapper &&rhs) noexcept
436     : m_pipelineConstructionType(rhs.m_pipelineConstructionType)
437     , m_vk(rhs.m_vk)
438     , m_device(rhs.m_device)
439     , m_flags(rhs.m_flags)
440     , m_setLayoutCount(rhs.m_setLayoutCount)
441     , m_setLayouts(std::move(rhs.m_setLayouts))
442     , m_pushConstantRangeCount(rhs.m_pushConstantRangeCount)
443     , m_pushConstantRanges(std::move(rhs.m_pushConstantRanges))
444     , m_pipelineLayout(rhs.m_pipelineLayout)
445 {
446 }
447 
operator =(PipelineLayoutWrapper && rhs)448 PipelineLayoutWrapper &PipelineLayoutWrapper::operator=(PipelineLayoutWrapper &&rhs)
449 {
450     m_pipelineConstructionType = rhs.m_pipelineConstructionType;
451     m_vk                       = rhs.m_vk;
452     m_device                   = rhs.m_device;
453     m_flags                    = rhs.m_flags;
454     m_setLayoutCount           = rhs.m_setLayoutCount;
455     m_setLayouts               = std::move(rhs.m_setLayouts);
456     m_pushConstantRangeCount   = rhs.m_pushConstantRangeCount;
457     m_pushConstantRanges       = std::move(rhs.m_pushConstantRanges);
458     m_pipelineLayout           = rhs.m_pipelineLayout;
459 
460     return *this;
461 }
462 
bindDescriptorSets(VkCommandBuffer commandBuffer,VkPipelineBindPoint pipelineBindPoint,uint32_t firstSet,uint32_t descriptorSetCount,const VkDescriptorSet * pDescriptorSets,uint32_t dynamicOffsetCount,const uint32_t * pDynamicOffsets) const463 void PipelineLayoutWrapper::bindDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint,
464                                                uint32_t firstSet, uint32_t descriptorSetCount,
465                                                const VkDescriptorSet *pDescriptorSets, uint32_t dynamicOffsetCount,
466                                                const uint32_t *pDynamicOffsets) const
467 {
468     if (!isConstructionTypeShaderObject(m_pipelineConstructionType))
469     {
470         m_vk->cmdBindDescriptorSets(commandBuffer, pipelineBindPoint, *m_pipelineLayout, firstSet, descriptorSetCount,
471                                     pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
472     }
473     else
474     {
475         //m_vk->cmdBindDescriptorSets2EXT(commandBuffer, &m_setLayouts[firstSet], vk::VK_SHADER_STAGE_ALL_GRAPHICS, firstSet, descriptorSetCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
476         m_vk->cmdBindDescriptorSets(commandBuffer, pipelineBindPoint, *m_pipelineLayout, firstSet, descriptorSetCount,
477                                     pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
478     }
479 }
480 
481 #ifndef CTS_USES_VULKANSC
SubpassDependency(const VkSubpassDependency & dependency)482 RenderPassWrapper::SubpassDependency::SubpassDependency(const VkSubpassDependency &dependency)
483     : srcSubpass(dependency.srcSubpass)
484     , dstSubpass(dependency.dstSubpass)
485     , srcStageMask(dependency.srcStageMask)
486     , dstStageMask(dependency.dstStageMask)
487     , srcAccessMask(dependency.srcAccessMask)
488     , dstAccessMask(dependency.dstAccessMask)
489     , dependencyFlags(dependency.dependencyFlags)
490     , sync2(false)
491 {
492 }
493 
SubpassDependency(const VkSubpassDependency2 & dependency)494 RenderPassWrapper::SubpassDependency::SubpassDependency(const VkSubpassDependency2 &dependency)
495     : srcSubpass(dependency.srcSubpass)
496     , dstSubpass(dependency.dstSubpass)
497     , srcStageMask(0u)
498     , dstStageMask(0u)
499     , srcAccessMask(0u)
500     , dstAccessMask(0u)
501     , dependencyFlags(dependency.dependencyFlags)
502     , sync2(false)
503 {
504     DE_ASSERT(dependency.viewOffset == 0);
505     const auto memBarrier = findStructure<VkMemoryBarrier2>(dependency.pNext);
506     if (memBarrier)
507     {
508         srcStageMask  = memBarrier->srcStageMask;
509         dstStageMask  = memBarrier->dstStageMask;
510         srcAccessMask = memBarrier->srcAccessMask;
511         dstAccessMask = memBarrier->dstAccessMask;
512         sync2         = true;
513     }
514     else
515     {
516         srcStageMask  = dependency.srcStageMask;
517         dstStageMask  = dependency.dstStageMask;
518         srcAccessMask = dependency.srcAccessMask;
519         dstAccessMask = dependency.dstAccessMask;
520     }
521 }
522 #endif // CTS_USES_VULKANSC
523 
RenderPassWrapper(PipelineConstructionType pipelineConstructionType,const DeviceInterface & vk,VkDevice device,const VkRenderPassCreateInfo * pCreateInfo)524 RenderPassWrapper::RenderPassWrapper(PipelineConstructionType pipelineConstructionType, const DeviceInterface &vk,
525                                      VkDevice device, const VkRenderPassCreateInfo *pCreateInfo)
526     : m_isDynamicRendering(vk::isConstructionTypeShaderObject(pipelineConstructionType))
527 #ifndef CTS_USES_VULKANSC
528     , m_renderingInfo()
529     , m_secondaryCommandBuffers(false)
530 #endif
531 {
532     if (!m_isDynamicRendering)
533     {
534         m_renderPass = vk::createRenderPass(vk, device, pCreateInfo);
535     }
536     else
537     {
538 #ifndef CTS_USES_VULKANSC
539         const auto multiView = findStructure<VkRenderPassMultiviewCreateInfo>(pCreateInfo->pNext);
540         if (multiView)
541         {
542             for (uint32_t i = 0; i < multiView->subpassCount; ++i)
543                 m_viewMasks.push_back(multiView->pViewMasks[i]);
544         }
545 
546         m_attachments.resize(pCreateInfo->attachmentCount);
547         m_layouts.resize(pCreateInfo->attachmentCount);
548         for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
549         {
550             m_attachments[i]                = vk::initVulkanStructure();
551             m_attachments[i].flags          = pCreateInfo->pAttachments[i].flags;
552             m_attachments[i].format         = pCreateInfo->pAttachments[i].format;
553             m_attachments[i].samples        = pCreateInfo->pAttachments[i].samples;
554             m_attachments[i].loadOp         = pCreateInfo->pAttachments[i].loadOp;
555             m_attachments[i].storeOp        = pCreateInfo->pAttachments[i].storeOp;
556             m_attachments[i].stencilLoadOp  = pCreateInfo->pAttachments[i].stencilLoadOp;
557             m_attachments[i].stencilStoreOp = pCreateInfo->pAttachments[i].stencilStoreOp;
558             m_attachments[i].initialLayout  = pCreateInfo->pAttachments[i].initialLayout;
559             m_attachments[i].finalLayout    = pCreateInfo->pAttachments[i].finalLayout;
560             m_layouts[i]                    = pCreateInfo->pAttachments[i].initialLayout;
561         }
562 
563         m_subpasses.resize(pCreateInfo->subpassCount);
564         for (uint32_t s = 0; s < pCreateInfo->subpassCount; ++s)
565         {
566             // Input attachments are not supported with dynamic rendering
567             DE_ASSERT(pCreateInfo->pSubpasses[s].inputAttachmentCount == 0);
568             auto &subpass = m_subpasses[s];
569             subpass.m_colorAttachments.resize(pCreateInfo->pSubpasses[s].colorAttachmentCount);
570 
571             for (uint32_t i = 0; i < pCreateInfo->pSubpasses[s].colorAttachmentCount; ++i)
572             {
573                 uint32_t j = pCreateInfo->pSubpasses[s].pColorAttachments[i].attachment;
574                 if (j < pCreateInfo->attachmentCount)
575                 {
576                     subpass.m_colorAttachments[i].attachmentInfo = vk::initVulkanStructure();
577                     subpass.m_colorAttachments[i].index          = j;
578                     subpass.m_colorAttachments[i].format         = pCreateInfo->pAttachments[j].format;
579 
580                     subpass.m_colorAttachments[i].attachmentInfo.imageView = DE_NULL;
581                     subpass.m_colorAttachments[i].attachmentInfo.imageLayout =
582                         pCreateInfo->pSubpasses[s].pColorAttachments[i].layout;
583                     subpass.m_colorAttachments[i].attachmentInfo.resolveMode        = vk::VK_RESOLVE_MODE_NONE;
584                     subpass.m_colorAttachments[i].attachmentInfo.resolveImageView   = DE_NULL;
585                     subpass.m_colorAttachments[i].attachmentInfo.resolveImageLayout = vk::VK_IMAGE_LAYOUT_UNDEFINED;
586                     subpass.m_colorAttachments[i].attachmentInfo.loadOp     = pCreateInfo->pAttachments[j].loadOp;
587                     subpass.m_colorAttachments[i].attachmentInfo.storeOp    = pCreateInfo->pAttachments[j].storeOp;
588                     subpass.m_colorAttachments[i].attachmentInfo.clearValue = {};
589                 }
590                 else
591                 {
592                     subpass.m_colorAttachments[i].index = VK_ATTACHMENT_UNUSED;
593                 }
594             }
595 
596             if (pCreateInfo->pSubpasses[s].pDepthStencilAttachment != DE_NULL)
597             {
598                 uint32_t j = pCreateInfo->pSubpasses[s].pDepthStencilAttachment->attachment;
599                 if (j < pCreateInfo->attachmentCount)
600                 {
601                     subpass.m_depthStencilAttachment.attachmentInfo = vk::initVulkanStructure();
602                     subpass.m_depthStencilAttachment.index          = j;
603                     subpass.m_depthStencilAttachment.format         = pCreateInfo->pAttachments[j].format;
604 
605                     subpass.m_depthStencilAttachment.attachmentInfo.imageView = DE_NULL;
606                     subpass.m_depthStencilAttachment.attachmentInfo.imageLayout =
607                         pCreateInfo->pSubpasses[s].pDepthStencilAttachment->layout;
608                     subpass.m_depthStencilAttachment.attachmentInfo.resolveMode        = vk::VK_RESOLVE_MODE_NONE;
609                     subpass.m_depthStencilAttachment.attachmentInfo.resolveImageView   = DE_NULL;
610                     subpass.m_depthStencilAttachment.attachmentInfo.resolveImageLayout = vk::VK_IMAGE_LAYOUT_UNDEFINED;
611                     subpass.m_depthStencilAttachment.attachmentInfo.loadOp     = pCreateInfo->pAttachments[j].loadOp;
612                     subpass.m_depthStencilAttachment.attachmentInfo.storeOp    = pCreateInfo->pAttachments[j].storeOp;
613                     subpass.m_depthStencilAttachment.attachmentInfo.clearValue = {};
614                     subpass.m_depthStencilAttachment.stencilLoadOp  = pCreateInfo->pAttachments[j].stencilLoadOp;
615                     subpass.m_depthStencilAttachment.stencilStoreOp = pCreateInfo->pAttachments[j].stencilStoreOp;
616                 }
617                 else
618                 {
619                     subpass.m_depthStencilAttachment.index = VK_ATTACHMENT_UNUSED;
620                 }
621             }
622 
623             if (pCreateInfo->pSubpasses[s].pResolveAttachments != DE_NULL)
624             {
625                 subpass.m_resolveAttachments.resize(pCreateInfo->pSubpasses[s].colorAttachmentCount);
626                 for (uint32_t i = 0; i < pCreateInfo->pSubpasses[s].colorAttachmentCount; ++i)
627                 {
628                     uint32_t j = pCreateInfo->pSubpasses[s].pResolveAttachments[i].attachment;
629                     if (j < pCreateInfo->attachmentCount)
630                     {
631                         subpass.m_resolveAttachments[i].attachmentInfo = vk::initVulkanStructure();
632                         subpass.m_resolveAttachments[i].index          = j;
633                         subpass.m_resolveAttachments[i].format         = pCreateInfo->pAttachments[j].format;
634 
635                         subpass.m_resolveAttachments[i].attachmentInfo.imageView = DE_NULL;
636                         subpass.m_resolveAttachments[i].attachmentInfo.imageLayout =
637                             pCreateInfo->pSubpasses[s].pResolveAttachments[i].layout;
638                         subpass.m_resolveAttachments[i].attachmentInfo.resolveMode      = vk::VK_RESOLVE_MODE_NONE;
639                         subpass.m_resolveAttachments[i].attachmentInfo.resolveImageView = DE_NULL;
640                         subpass.m_resolveAttachments[i].attachmentInfo.resolveImageLayout =
641                             vk::VK_IMAGE_LAYOUT_UNDEFINED;
642                         subpass.m_resolveAttachments[i].attachmentInfo.loadOp  = pCreateInfo->pAttachments[j].loadOp;
643                         subpass.m_resolveAttachments[i].attachmentInfo.storeOp = pCreateInfo->pAttachments[j].storeOp;
644                         subpass.m_resolveAttachments[i].attachmentInfo.clearValue = {};
645                     }
646                     else
647                     {
648                         subpass.m_resolveAttachments[i].index = VK_ATTACHMENT_UNUSED;
649                     }
650                 }
651             }
652         }
653 
654         m_dependencies.reserve(pCreateInfo->dependencyCount);
655         for (uint32_t depIdx = 0u; depIdx < pCreateInfo->dependencyCount; ++depIdx)
656             m_dependencies.emplace_back(pCreateInfo->pDependencies[depIdx]);
657 #endif
658     }
659 }
660 
RenderPassWrapper(PipelineConstructionType pipelineConstructionType,const DeviceInterface & vk,VkDevice device,const VkRenderPassCreateInfo2 * pCreateInfo)661 RenderPassWrapper::RenderPassWrapper(PipelineConstructionType pipelineConstructionType, const DeviceInterface &vk,
662                                      VkDevice device, const VkRenderPassCreateInfo2 *pCreateInfo)
663     : RenderPassWrapper(vk, device, pCreateInfo, isConstructionTypeShaderObject(pipelineConstructionType))
664 {
665 }
666 
RenderPassWrapper(const DeviceInterface & vk,VkDevice device,const VkRenderPassCreateInfo2 * pCreateInfo,bool dynamicRendering)667 RenderPassWrapper::RenderPassWrapper(const DeviceInterface &vk, VkDevice device,
668                                      const VkRenderPassCreateInfo2 *pCreateInfo, bool dynamicRendering)
669     : m_isDynamicRendering(dynamicRendering)
670 #ifndef CTS_USES_VULKANSC
671     , m_renderingInfo()
672     , m_secondaryCommandBuffers(false)
673 #endif
674 {
675 
676     if (!m_isDynamicRendering)
677     {
678         m_renderPass = vk::createRenderPass2(vk, device, pCreateInfo);
679     }
680     else
681     {
682 #ifndef CTS_USES_VULKANSC
683         const auto multiView = findStructure<VkRenderPassMultiviewCreateInfo>(pCreateInfo->pNext);
684         if (multiView)
685         {
686             for (uint32_t i = 0; i < multiView->subpassCount; ++i)
687                 m_viewMasks.push_back(multiView->pViewMasks[i]);
688         }
689 
690         m_attachments.resize(pCreateInfo->attachmentCount);
691         m_layouts.resize(pCreateInfo->attachmentCount);
692         for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
693         {
694             m_attachments[i] = pCreateInfo->pAttachments[i];
695             m_layouts[i]     = pCreateInfo->pAttachments[i].initialLayout;
696         }
697 
698         m_subpasses.resize(pCreateInfo->subpassCount);
699         for (uint32_t s = 0; s < pCreateInfo->subpassCount; ++s)
700         {
701             // Input attachments are not supported with dynamic rendering
702             DE_ASSERT(pCreateInfo->pSubpasses[s].inputAttachmentCount == 0);
703             auto &subpass = m_subpasses[s];
704             subpass.m_colorAttachments.resize(pCreateInfo->pSubpasses[s].colorAttachmentCount);
705 
706             const auto msrtss =
707                 findStructure<VkMultisampledRenderToSingleSampledInfoEXT>(pCreateInfo->pSubpasses[s].pNext);
708             if (msrtss)
709                 subpass.m_msrtss = *msrtss;
710 
711             const auto dsr = findStructure<VkSubpassDescriptionDepthStencilResolve>(pCreateInfo->pSubpasses[s].pNext);
712             if (dsr)
713             {
714                 subpass.m_dsr = *dsr;
715                 if (dsr->pDepthStencilResolveAttachment)
716                 {
717                     subpass.m_depthStencilResolveAttachment      = *dsr->pDepthStencilResolveAttachment;
718                     subpass.m_dsr.pDepthStencilResolveAttachment = &subpass.m_depthStencilResolveAttachment;
719                 }
720             }
721 
722             for (uint32_t i = 0; i < pCreateInfo->pSubpasses[s].colorAttachmentCount; ++i)
723             {
724                 uint32_t j = pCreateInfo->pSubpasses[s].pColorAttachments[i].attachment;
725                 if (j < pCreateInfo->attachmentCount)
726                 {
727                     subpass.m_colorAttachments[i].attachmentInfo = vk::initVulkanStructure();
728                     subpass.m_colorAttachments[i].index          = j;
729                     subpass.m_colorAttachments[i].format         = pCreateInfo->pAttachments[j].format;
730 
731                     subpass.m_colorAttachments[i].attachmentInfo.imageView = DE_NULL;
732                     subpass.m_colorAttachments[i].attachmentInfo.imageLayout =
733                         pCreateInfo->pSubpasses[s].pColorAttachments[i].layout;
734                     subpass.m_colorAttachments[i].attachmentInfo.resolveMode        = vk::VK_RESOLVE_MODE_NONE;
735                     subpass.m_colorAttachments[i].attachmentInfo.resolveImageView   = DE_NULL;
736                     subpass.m_colorAttachments[i].attachmentInfo.resolveImageLayout = vk::VK_IMAGE_LAYOUT_UNDEFINED;
737                     subpass.m_colorAttachments[i].attachmentInfo.loadOp     = pCreateInfo->pAttachments[j].loadOp;
738                     subpass.m_colorAttachments[i].attachmentInfo.storeOp    = pCreateInfo->pAttachments[j].storeOp;
739                     subpass.m_colorAttachments[i].attachmentInfo.clearValue = {};
740                 }
741                 else
742                 {
743                     subpass.m_colorAttachments[i].index = VK_ATTACHMENT_UNUSED;
744                 }
745             }
746 
747             if (pCreateInfo->pSubpasses[s].pDepthStencilAttachment != DE_NULL)
748             {
749                 uint32_t j = pCreateInfo->pSubpasses[s].pDepthStencilAttachment->attachment;
750                 if (j < pCreateInfo->attachmentCount)
751                 {
752                     subpass.m_depthStencilAttachment.attachmentInfo = vk::initVulkanStructure();
753                     subpass.m_depthStencilAttachment.index          = j;
754                     subpass.m_depthStencilAttachment.format         = pCreateInfo->pAttachments[j].format;
755 
756                     subpass.m_depthStencilAttachment.attachmentInfo.imageView = DE_NULL;
757                     subpass.m_depthStencilAttachment.attachmentInfo.imageLayout =
758                         pCreateInfo->pSubpasses[s].pDepthStencilAttachment->layout;
759                     subpass.m_depthStencilAttachment.attachmentInfo.resolveMode        = vk::VK_RESOLVE_MODE_NONE;
760                     subpass.m_depthStencilAttachment.attachmentInfo.resolveImageView   = DE_NULL;
761                     subpass.m_depthStencilAttachment.attachmentInfo.resolveImageLayout = vk::VK_IMAGE_LAYOUT_UNDEFINED;
762                     subpass.m_depthStencilAttachment.attachmentInfo.loadOp     = pCreateInfo->pAttachments[j].loadOp;
763                     subpass.m_depthStencilAttachment.attachmentInfo.storeOp    = pCreateInfo->pAttachments[j].storeOp;
764                     subpass.m_depthStencilAttachment.attachmentInfo.clearValue = {};
765                     subpass.m_depthStencilAttachment.stencilLoadOp  = pCreateInfo->pAttachments[j].stencilLoadOp;
766                     subpass.m_depthStencilAttachment.stencilStoreOp = pCreateInfo->pAttachments[j].stencilStoreOp;
767                 }
768                 else
769                 {
770                     subpass.m_depthStencilAttachment.index = VK_ATTACHMENT_UNUSED;
771                 }
772             }
773 
774             if (pCreateInfo->pSubpasses[s].pResolveAttachments != DE_NULL)
775             {
776                 subpass.m_resolveAttachments.resize(pCreateInfo->pSubpasses[s].colorAttachmentCount);
777                 for (uint32_t i = 0; i < pCreateInfo->pSubpasses[s].colorAttachmentCount; ++i)
778                 {
779                     uint32_t j = pCreateInfo->pSubpasses[s].pResolveAttachments[i].attachment;
780                     if (j < pCreateInfo->attachmentCount)
781                     {
782                         subpass.m_resolveAttachments[i].attachmentInfo = vk::initVulkanStructure();
783                         subpass.m_resolveAttachments[i].index          = j;
784                         subpass.m_resolveAttachments[i].format         = pCreateInfo->pAttachments[j].format;
785 
786                         subpass.m_resolveAttachments[i].attachmentInfo.imageView = DE_NULL;
787                         subpass.m_resolveAttachments[i].attachmentInfo.imageLayout =
788                             pCreateInfo->pSubpasses[s].pResolveAttachments[i].layout;
789                         subpass.m_resolveAttachments[i].attachmentInfo.resolveMode      = vk::VK_RESOLVE_MODE_NONE;
790                         subpass.m_resolveAttachments[i].attachmentInfo.resolveImageView = DE_NULL;
791                         subpass.m_resolveAttachments[i].attachmentInfo.resolveImageLayout =
792                             vk::VK_IMAGE_LAYOUT_UNDEFINED;
793                         subpass.m_resolveAttachments[i].attachmentInfo.loadOp  = pCreateInfo->pAttachments[j].loadOp;
794                         subpass.m_resolveAttachments[i].attachmentInfo.storeOp = pCreateInfo->pAttachments[j].storeOp;
795                         subpass.m_resolveAttachments[i].attachmentInfo.clearValue = {};
796                     }
797                     else
798                     {
799                         subpass.m_resolveAttachments[i].index = VK_ATTACHMENT_UNUSED;
800                     }
801                 }
802             }
803         }
804 
805         m_dependencies.reserve(pCreateInfo->dependencyCount);
806         for (uint32_t depIdx = 0u; depIdx < pCreateInfo->dependencyCount; ++depIdx)
807             m_dependencies.emplace_back(pCreateInfo->pDependencies[depIdx]);
808 #endif
809     }
810 }
811 
RenderPassWrapper(PipelineConstructionType pipelineConstructionType,const DeviceInterface & vk,const VkDevice device,const VkFormat colorFormat,const VkFormat depthStencilFormat,const VkAttachmentLoadOp loadOperation,const VkImageLayout finalLayoutColor,const VkImageLayout finalLayoutDepthStencil,const VkImageLayout subpassLayoutColor,const VkImageLayout subpassLayoutDepthStencil,const VkAllocationCallbacks * const allocationCallbacks)812 RenderPassWrapper::RenderPassWrapper(PipelineConstructionType pipelineConstructionType, const DeviceInterface &vk,
813                                      const VkDevice device, const VkFormat colorFormat,
814                                      const VkFormat depthStencilFormat, const VkAttachmentLoadOp loadOperation,
815                                      const VkImageLayout finalLayoutColor, const VkImageLayout finalLayoutDepthStencil,
816                                      const VkImageLayout subpassLayoutColor,
817                                      const VkImageLayout subpassLayoutDepthStencil,
818                                      const VkAllocationCallbacks *const allocationCallbacks)
819     : m_isDynamicRendering(isConstructionTypeShaderObject(pipelineConstructionType))
820 #ifndef CTS_USES_VULKANSC
821     , m_renderingInfo()
822 #endif
823 {
824 
825     if (!m_isDynamicRendering)
826     {
827         m_renderPass = vk::makeRenderPass(vk, device, colorFormat, depthStencilFormat, loadOperation, finalLayoutColor,
828                                           finalLayoutDepthStencil, subpassLayoutColor, subpassLayoutDepthStencil,
829                                           allocationCallbacks);
830     }
831     else
832     {
833 #ifndef CTS_USES_VULKANSC
834         const bool hasColor                           = colorFormat != VK_FORMAT_UNDEFINED;
835         const bool hasDepthStencil                    = depthStencilFormat != VK_FORMAT_UNDEFINED;
836         const VkImageLayout initialLayoutColor        = loadOperation == VK_ATTACHMENT_LOAD_OP_LOAD ?
837                                                             VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL :
838                                                             VK_IMAGE_LAYOUT_UNDEFINED;
839         const VkImageLayout initialLayoutDepthStencil = loadOperation == VK_ATTACHMENT_LOAD_OP_LOAD ?
840                                                             VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL :
841                                                             VK_IMAGE_LAYOUT_UNDEFINED;
842 
843         m_subpasses.resize(1);
844         auto &subpass = m_subpasses[0];
845 
846         if (hasColor)
847         {
848             subpass.m_colorAttachments.resize(1);
849             subpass.m_colorAttachments[0].attachmentInfo = vk::initVulkanStructure();
850             subpass.m_colorAttachments[0].index          = 0u;
851             subpass.m_colorAttachments[0].format         = colorFormat;
852 
853             subpass.m_colorAttachments[0].attachmentInfo.imageView          = DE_NULL;
854             subpass.m_colorAttachments[0].attachmentInfo.imageLayout        = subpassLayoutColor;
855             subpass.m_colorAttachments[0].attachmentInfo.resolveMode        = vk::VK_RESOLVE_MODE_NONE;
856             subpass.m_colorAttachments[0].attachmentInfo.resolveImageView   = DE_NULL;
857             subpass.m_colorAttachments[0].attachmentInfo.resolveImageLayout = vk::VK_IMAGE_LAYOUT_UNDEFINED;
858             subpass.m_colorAttachments[0].attachmentInfo.loadOp             = loadOperation;
859             subpass.m_colorAttachments[0].attachmentInfo.storeOp            = VK_ATTACHMENT_STORE_OP_STORE;
860             subpass.m_colorAttachments[0].attachmentInfo.clearValue         = {};
861 
862             const VkAttachmentDescription2 colorAttachmentDescription = {
863                 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,
864                 DE_NULL,
865                 (VkAttachmentDescriptionFlags)0,  // VkAttachmentDescriptionFlags    flags
866                 colorFormat,                      // VkFormat                        format
867                 VK_SAMPLE_COUNT_1_BIT,            // VkSampleCountFlagBits           samples
868                 loadOperation,                    // VkAttachmentLoadOp              loadOp
869                 VK_ATTACHMENT_STORE_OP_STORE,     // VkAttachmentStoreOp             storeOp
870                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,  // VkAttachmentLoadOp              stencilLoadOp
871                 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp             stencilStoreOp
872                 initialLayoutColor,               // VkImageLayout                   initialLayout
873                 finalLayoutColor                  // VkImageLayout                   finalLayout
874             };
875             m_attachments.push_back(colorAttachmentDescription);
876             m_layouts.push_back(colorAttachmentDescription.initialLayout);
877         }
878         if (hasDepthStencil)
879         {
880             subpass.m_depthStencilAttachment.attachmentInfo = vk::initVulkanStructure();
881             subpass.m_depthStencilAttachment.index          = hasColor ? 1u : 0u;
882             subpass.m_depthStencilAttachment.format         = depthStencilFormat;
883 
884             subpass.m_depthStencilAttachment.attachmentInfo.imageView          = DE_NULL;
885             subpass.m_depthStencilAttachment.attachmentInfo.imageLayout        = subpassLayoutDepthStencil;
886             subpass.m_depthStencilAttachment.attachmentInfo.resolveMode        = vk::VK_RESOLVE_MODE_NONE;
887             subpass.m_depthStencilAttachment.attachmentInfo.resolveImageView   = DE_NULL;
888             subpass.m_depthStencilAttachment.attachmentInfo.resolveImageLayout = vk::VK_IMAGE_LAYOUT_UNDEFINED;
889             subpass.m_depthStencilAttachment.attachmentInfo.loadOp             = loadOperation;
890             subpass.m_depthStencilAttachment.attachmentInfo.storeOp            = VK_ATTACHMENT_STORE_OP_STORE;
891             subpass.m_depthStencilAttachment.attachmentInfo.clearValue         = {};
892             subpass.m_depthStencilAttachment.stencilLoadOp                     = loadOperation;
893             subpass.m_depthStencilAttachment.stencilStoreOp                    = VK_ATTACHMENT_STORE_OP_STORE;
894 
895             const VkAttachmentDescription2 depthStencilAttachmentDescription = {
896                 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,
897                 DE_NULL,
898                 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags    flags
899                 depthStencilFormat,              // VkFormat                        format
900                 VK_SAMPLE_COUNT_1_BIT,           // VkSampleCountFlagBits           samples
901                 loadOperation,                   // VkAttachmentLoadOp              loadOp
902                 VK_ATTACHMENT_STORE_OP_STORE,    // VkAttachmentStoreOp             storeOp
903                 loadOperation,                   // VkAttachmentLoadOp              stencilLoadOp
904                 VK_ATTACHMENT_STORE_OP_STORE,    // VkAttachmentStoreOp             stencilStoreOp
905                 initialLayoutDepthStencil,       // VkImageLayout                   initialLayout
906                 finalLayoutDepthStencil          // VkImageLayout                   finalLayout
907             };
908             m_attachments.push_back(depthStencilAttachmentDescription);
909             m_layouts.push_back(depthStencilAttachmentDescription.initialLayout);
910         }
911 #endif
912     }
913 }
914 
RenderPassWrapper(RenderPassWrapper && rhs)915 RenderPassWrapper::RenderPassWrapper(RenderPassWrapper &&rhs) noexcept
916     : m_isDynamicRendering(rhs.m_isDynamicRendering)
917     , m_renderPass(rhs.m_renderPass)
918     , m_framebuffer(rhs.m_framebuffer)
919 #ifndef CTS_USES_VULKANSC
920     , m_subpasses(std::move(rhs.m_subpasses))
921     , m_dependencies(std::move(rhs.m_dependencies))
922     , m_attachments(std::move(rhs.m_attachments))
923     , m_images(std::move(rhs.m_images))
924     , m_imageViews(std::move(rhs.m_imageViews))
925     , m_clearValues(std::move(rhs.m_clearValues))
926     , m_layouts(std::move(rhs.m_layouts))
927     , m_activeSubpass(rhs.m_activeSubpass)
928     , m_renderingInfo(rhs.m_renderingInfo)
929     , m_layers(rhs.m_layers)
930     , m_viewMasks(std::move(rhs.m_viewMasks))
931     , m_secondaryCommandBuffers(rhs.m_secondaryCommandBuffers)
932 #endif
933 {
934 }
935 
operator =(RenderPassWrapper && rhs)936 RenderPassWrapper &RenderPassWrapper::operator=(RenderPassWrapper &&rhs) noexcept
937 {
938     m_isDynamicRendering = rhs.m_isDynamicRendering;
939     m_renderPass         = rhs.m_renderPass;
940     m_framebuffer        = rhs.m_framebuffer;
941 #ifndef CTS_USES_VULKANSC
942     m_subpasses               = std::move(rhs.m_subpasses);
943     m_dependencies            = std::move(rhs.m_dependencies);
944     m_attachments             = std::move(rhs.m_attachments);
945     m_images                  = std::move(rhs.m_images);
946     m_imageViews              = std::move(rhs.m_imageViews);
947     m_clearValues             = std::move(rhs.m_clearValues);
948     m_layouts                 = std::move(rhs.m_layouts);
949     m_activeSubpass           = rhs.m_activeSubpass;
950     m_renderingInfo           = rhs.m_renderingInfo;
951     m_layers                  = rhs.m_layers;
952     m_viewMasks               = std::move(rhs.m_viewMasks);
953     m_secondaryCommandBuffers = rhs.m_secondaryCommandBuffers;
954 #endif
955     return *this;
956 }
957 
958 #ifndef CTS_USES_VULKANSC
959 
clearAttachments(const DeviceInterface & vk,const VkCommandBuffer commandBuffer) const960 void RenderPassWrapper::clearAttachments(const DeviceInterface &vk, const VkCommandBuffer commandBuffer) const
961 {
962     for (uint32_t i = 0; i < (uint32_t)m_attachments.size() && i < (uint32_t)m_clearValues.size(); ++i)
963     {
964         const auto tcuFormat  = vk::mapVkFormat(m_attachments[i].format);
965         bool hasDepthAspect   = tcu::hasDepthComponent(tcuFormat.order);
966         bool hasStencilAspect = tcu::hasStencilComponent(tcuFormat.order);
967 
968         if (m_attachments[i].loadOp != vk::VK_ATTACHMENT_LOAD_OP_CLEAR &&
969             !(hasStencilAspect && m_attachments[i].stencilLoadOp == vk::VK_ATTACHMENT_LOAD_OP_CLEAR))
970             continue;
971 
972         vk::VkRenderingInfo renderingInfo = vk::initVulkanStructure();
973         renderingInfo.renderArea          = m_renderingInfo.renderArea;
974         renderingInfo.layerCount          = m_renderingInfo.layerCount;
975 
976         vk::VkRenderingAttachmentInfo attachment = vk::initVulkanStructure();
977         attachment.imageView                     = m_imageViews[i];
978         attachment.imageLayout                   = m_layouts[i];
979         attachment.loadOp                        = vk::VK_ATTACHMENT_LOAD_OP_CLEAR;
980         attachment.storeOp                       = vk::VK_ATTACHMENT_STORE_OP_STORE;
981         attachment.clearValue                    = m_clearValues[i];
982 
983         if (hasDepthAspect || hasStencilAspect)
984         {
985             renderingInfo.pDepthAttachment   = hasDepthAspect ? &attachment : DE_NULL;
986             renderingInfo.pStencilAttachment = hasStencilAspect ? &attachment : DE_NULL;
987         }
988         else
989         {
990             renderingInfo.colorAttachmentCount = 1u;
991             renderingInfo.pColorAttachments    = &attachment;
992         }
993 
994         vk.cmdBeginRendering(commandBuffer, &renderingInfo);
995         vk.cmdEndRendering(commandBuffer);
996     }
997 }
998 
updateLayout(VkImage updatedImage,VkImageLayout newLayout) const999 void RenderPassWrapper::updateLayout(VkImage updatedImage, VkImageLayout newLayout) const
1000 {
1001     for (uint32_t i = 0; i < (uint32_t)m_images.size(); ++i)
1002         if (m_images[i] == updatedImage)
1003             m_layouts[i] = newLayout;
1004 }
1005 
1006 namespace
1007 {
1008 
recordImageBarrier(const DeviceInterface & vk,const VkCommandBuffer commandBuffer,const bool sync2,const VkPipelineStageFlags2 srcStageMask,const VkAccessFlags2 srcAccessMask,const VkPipelineStageFlags2 dstStageMask,const VkAccessFlags2 dstAccessMask,const VkImageLayout prevLayout,const VkImageLayout newLayout,const VkImage image,const VkImageSubresourceRange & subresourceRange)1009 void recordImageBarrier(const DeviceInterface &vk, const VkCommandBuffer commandBuffer, const bool sync2,
1010                         const VkPipelineStageFlags2 srcStageMask, const VkAccessFlags2 srcAccessMask,
1011                         const VkPipelineStageFlags2 dstStageMask, const VkAccessFlags2 dstAccessMask,
1012                         const VkImageLayout prevLayout, const VkImageLayout newLayout, const VkImage image,
1013                         const VkImageSubresourceRange &subresourceRange)
1014 {
1015     if (sync2)
1016     {
1017         const auto barrier = makeImageMemoryBarrier2(srcStageMask, srcAccessMask, dstStageMask, dstAccessMask,
1018                                                      prevLayout, newLayout, image, subresourceRange);
1019 
1020         const VkDependencyInfo depInfo = {
1021             VK_STRUCTURE_TYPE_DEPENDENCY_INFO, // VkStructureType sType;
1022             nullptr,                           // const void* pNext;
1023             0u,                                // VkDependencyFlags dependencyFlags;
1024             0u,                                // uint32_t memoryBarrierCount;
1025             nullptr,                           // const VkMemoryBarrier2* pMemoryBarriers;
1026             0u,                                // uint32_t bufferMemoryBarrierCount;
1027             nullptr,                           // const VkBufferMemoryBarrier2* pBufferMemoryBarriers;
1028             1u,                                // uint32_t imageMemoryBarrierCount;
1029             &barrier,                          // const VkImageMemoryBarrier2* pImageMemoryBarriers;
1030         };
1031 
1032         vk.cmdPipelineBarrier2(commandBuffer, &depInfo);
1033     }
1034     else
1035     {
1036         const auto barrier =
1037             makeImageMemoryBarrier(static_cast<VkAccessFlags>(srcAccessMask), static_cast<VkAccessFlags>(dstAccessMask),
1038                                    prevLayout, newLayout, image, subresourceRange);
1039 
1040         vk.cmdPipelineBarrier(commandBuffer, static_cast<VkPipelineStageFlags>(srcStageMask),
1041                               static_cast<VkPipelineStageFlags>(dstStageMask), 0u, 0u, nullptr, 0u, nullptr, 1u,
1042                               &barrier);
1043     }
1044 }
1045 
1046 } // anonymous namespace
1047 
transitionLayouts(const DeviceInterface & vk,const VkCommandBuffer commandBuffer,const Subpass & subpass,bool renderPassBegin) const1048 void RenderPassWrapper::transitionLayouts(const DeviceInterface &vk, const VkCommandBuffer commandBuffer,
1049                                           const Subpass &subpass, bool renderPassBegin) const
1050 {
1051     // Use the access and stage flags for dependencies on external subpasses in
1052     // the initial layout transitions for images.
1053     VkAccessFlags2 externalAccessFlags       = 0u;
1054     VkPipelineStageFlags2 externalStageFlags = 0u;
1055     bool sync2                               = false;
1056 
1057     if (renderPassBegin)
1058     {
1059         for (const auto &dep : m_dependencies)
1060         {
1061             if (dep.srcSubpass == VK_SUBPASS_EXTERNAL)
1062             {
1063                 externalAccessFlags |= dep.srcAccessMask;
1064                 externalStageFlags |= dep.srcStageMask;
1065             }
1066 
1067             if (dep.sync2)
1068                 sync2 = true;
1069         }
1070     }
1071 
1072     for (uint32_t i = 0; i < (uint32_t)m_attachments.size(); ++i)
1073     {
1074         // renderPassBegin is true when vkCmdBeginRenderPass should be called in a normal renderPass, and it is false when vkCmdNextSupass should be called
1075         // Every image is transioned from VK_IMAGE_LAYOUT_UNDEFINED to it's first used layout, so that all images can be cleared in the beginning
1076         if (renderPassBegin && m_layouts[i] != vk::VK_IMAGE_LAYOUT_UNDEFINED)
1077             continue;
1078 
1079         if (m_images[i] != VK_NULL_HANDLE)
1080         {
1081             for (uint32_t j = 0; j < (uint32_t)subpass.m_colorAttachments.size(); ++j)
1082             {
1083                 if (subpass.m_colorAttachments[j].index == i)
1084                 {
1085                     const auto subresourceRange = makeImageSubresourceRange(
1086                         vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, VK_REMAINING_MIP_LEVELS, 0u, VK_REMAINING_ARRAY_LAYERS);
1087 
1088                     const VkPipelineStageFlags2 srcStageMask =
1089                         (vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT | externalStageFlags);
1090                     const VkAccessFlags2 srcAccessMask       = externalAccessFlags;
1091                     const VkPipelineStageFlags2 dstStageMask = vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
1092                     const VkAccessFlags2 dstAccessMask       = vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
1093                     const VkImageLayout newLayout            = subpass.m_colorAttachments[j].attachmentInfo.imageLayout;
1094 
1095                     recordImageBarrier(vk, commandBuffer, sync2, srcStageMask, srcAccessMask, dstStageMask,
1096                                        dstAccessMask, m_layouts[i], newLayout, m_images[i], subresourceRange);
1097 
1098                     updateLayout(m_images[i], newLayout);
1099                 }
1100             }
1101             if (subpass.m_depthStencilAttachment.index == i)
1102             {
1103                 const auto tcuFormat        = vk::mapVkFormat(subpass.m_depthStencilAttachment.format);
1104                 const bool hasDepthAspect   = tcu::hasDepthComponent(tcuFormat.order);
1105                 const bool hasStencilAspect = tcu::hasStencilComponent(tcuFormat.order);
1106 
1107                 VkImageAspectFlags aspect = (VkImageAspectFlags)0u;
1108                 if (hasDepthAspect)
1109                     aspect |= vk::VK_IMAGE_ASPECT_DEPTH_BIT;
1110                 if (hasStencilAspect)
1111                     aspect |= vk::VK_IMAGE_ASPECT_STENCIL_BIT;
1112 
1113                 const auto subresourceRange =
1114                     makeImageSubresourceRange(aspect, 0u, VK_REMAINING_MIP_LEVELS, 0u, VK_REMAINING_ARRAY_LAYERS);
1115 
1116                 const VkPipelineStageFlags2 srcStageMask = (vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT | externalStageFlags);
1117                 const VkAccessFlags2 srcAccessMask       = externalAccessFlags;
1118                 const VkPipelineStageFlags2 dstStageMask =
1119                     (vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
1120                 const VkAccessFlags2 dstAccessMask = (vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
1121                                                       vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT);
1122                 const VkImageLayout newLayout      = subpass.m_depthStencilAttachment.attachmentInfo.imageLayout;
1123 
1124                 recordImageBarrier(vk, commandBuffer, sync2, srcStageMask, srcAccessMask, dstStageMask, dstAccessMask,
1125                                    m_layouts[i], newLayout, m_images[i], subresourceRange);
1126 
1127                 updateLayout(m_images[i], newLayout);
1128             }
1129             for (uint32_t j = 0; j < (uint32_t)subpass.m_resolveAttachments.size(); ++j)
1130             {
1131                 if (subpass.m_resolveAttachments[j].index == i)
1132                 {
1133                     const auto subresourceRange = makeImageSubresourceRange(
1134                         vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, VK_REMAINING_MIP_LEVELS, 0u, VK_REMAINING_ARRAY_LAYERS);
1135 
1136                     const VkPipelineStageFlags2 srcStageMask =
1137                         (vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT | externalStageFlags);
1138                     const VkAccessFlags2 srcAccessMask       = externalAccessFlags;
1139                     const VkPipelineStageFlags2 dstStageMask = vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
1140                     const VkAccessFlags2 dstAccessMask       = vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
1141                     const VkImageLayout newLayout = subpass.m_resolveAttachments[j].attachmentInfo.imageLayout;
1142 
1143                     recordImageBarrier(vk, commandBuffer, sync2, srcStageMask, srcAccessMask, dstStageMask,
1144                                        dstAccessMask, m_layouts[i], newLayout, m_images[i], subresourceRange);
1145 
1146                     updateLayout(m_images[i], newLayout);
1147                 }
1148             }
1149             if (subpass.m_dsr.sType == vk::VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE)
1150             {
1151                 if (subpass.m_dsr.pDepthStencilResolveAttachment &&
1152                     i == subpass.m_dsr.pDepthStencilResolveAttachment->attachment)
1153                 {
1154                     const auto tcuFormat        = vk::mapVkFormat(subpass.m_depthStencilAttachment.format);
1155                     const bool hasDepthAspect   = tcu::hasDepthComponent(tcuFormat.order);
1156                     const bool hasStencilAspect = tcu::hasStencilComponent(tcuFormat.order);
1157 
1158                     VkImageAspectFlags aspect = (VkImageAspectFlags)0u;
1159                     if (hasDepthAspect)
1160                         aspect |= vk::VK_IMAGE_ASPECT_DEPTH_BIT;
1161                     if (hasStencilAspect)
1162                         aspect |= vk::VK_IMAGE_ASPECT_STENCIL_BIT;
1163 
1164                     const auto subresourceRange =
1165                         makeImageSubresourceRange(aspect, 0u, VK_REMAINING_MIP_LEVELS, 0u, VK_REMAINING_ARRAY_LAYERS);
1166 
1167                     const VkPipelineStageFlags2 srcStageMask =
1168                         (vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT | externalStageFlags);
1169                     const VkAccessFlags2 srcAccessMask       = externalAccessFlags;
1170                     const VkPipelineStageFlags2 dstStageMask = (vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
1171                                                                 vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
1172                     const VkAccessFlags2 dstAccessMask       = vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
1173                                                          vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
1174                     const VkImageLayout newLayout = subpass.m_dsr.pDepthStencilResolveAttachment->layout;
1175 
1176                     recordImageBarrier(vk, commandBuffer, sync2, srcStageMask, srcAccessMask, dstStageMask,
1177                                        dstAccessMask, m_layouts[i], newLayout, m_images[i], subresourceRange);
1178 
1179                     updateLayout(m_images[i], newLayout);
1180                 }
1181             }
1182         }
1183     }
1184 }
1185 
insertDependencies(const DeviceInterface & vk,const VkCommandBuffer commandBuffer,uint32_t subpassIdx) const1186 void RenderPassWrapper::insertDependencies(const DeviceInterface &vk, const VkCommandBuffer commandBuffer,
1187                                            uint32_t subpassIdx) const
1188 {
1189     for (const auto &dep : m_dependencies)
1190     {
1191         // Subpass self-dependencies should be handled with manual barriers inside the render pass.
1192         if (dep.dstSubpass != subpassIdx || dep.srcSubpass == subpassIdx)
1193             continue;
1194 
1195         if (dep.sync2)
1196         {
1197             const VkMemoryBarrier2 barrier = {
1198                 VK_STRUCTURE_TYPE_MEMORY_BARRIER, // VkStructureType sType;
1199                 nullptr,                          // const void* pNext;
1200                 dep.srcStageMask,                 // VkPipelineStageFlags2 srcStageMask;
1201                 dep.srcAccessMask,                // VkAccessFlags2 srcAccessMask;
1202                 dep.dstStageMask,                 // VkPipelineStageFlags2 dstStageMask;
1203                 dep.dstAccessMask,                // VkAccessFlags2 dstAccessMask;
1204             };
1205             const VkDependencyInfo depInfo = {
1206                 VK_STRUCTURE_TYPE_DEPENDENCY_INFO, // VkStructureType sType;
1207                 nullptr,                           // const void* pNext;
1208                 dep.dependencyFlags,               // VkDependencyFlags dependencyFlags;
1209                 1u,                                // uint32_t memoryBarrierCount;
1210                 &barrier,                          // const VkMemoryBarrier2* pMemoryBarriers;
1211                 0u,                                // uint32_t bufferMemoryBarrierCount;
1212                 nullptr,                           // const VkBufferMemoryBarrier2* pBufferMemoryBarriers;
1213                 0u,                                // uint32_t imageMemoryBarrierCount;
1214                 nullptr,                           // const VkImageMemoryBarrier2* pImageMemoryBarriers;
1215             };
1216             vk.cmdPipelineBarrier2(commandBuffer, &depInfo);
1217         }
1218         else
1219         {
1220             const VkMemoryBarrier barrier = {
1221                 VK_STRUCTURE_TYPE_MEMORY_BARRIER,              // VkStructureType sType;
1222                 nullptr,                                       // const void* pNext;
1223                 static_cast<VkAccessFlags>(dep.srcAccessMask), // VkAccessFlags srcAccessMask;
1224                 static_cast<VkAccessFlags>(dep.dstAccessMask), // VkAccessFlags dstAccessMask;
1225             };
1226             vk.cmdPipelineBarrier(commandBuffer, static_cast<VkPipelineStageFlags>(dep.srcStageMask),
1227                                   static_cast<VkPipelineStageFlags>(dep.dstStageMask), dep.dependencyFlags, 1u,
1228                                   &barrier, 0u, nullptr, 0u, nullptr);
1229         }
1230     }
1231 }
1232 
fillInheritanceRenderingInfo(uint32_t subpassIndex,std::vector<vk::VkFormat> * colorFormats,vk::VkCommandBufferInheritanceRenderingInfo * inheritanceRenderingInfo) const1233 void RenderPassWrapper::fillInheritanceRenderingInfo(
1234     uint32_t subpassIndex, std::vector<vk::VkFormat> *colorFormats,
1235     vk::VkCommandBufferInheritanceRenderingInfo *inheritanceRenderingInfo) const
1236 {
1237     const auto &subpass = m_subpasses[subpassIndex];
1238     colorFormats->resize(subpass.m_colorAttachments.size());
1239     for (uint32_t i = 0; i < (uint32_t)subpass.m_colorAttachments.size(); ++i)
1240         (*colorFormats)[i] = subpass.m_colorAttachments[i].format;
1241 
1242     inheritanceRenderingInfo->colorAttachmentCount    = (uint32_t)subpass.m_colorAttachments.size();
1243     inheritanceRenderingInfo->pColorAttachmentFormats = colorFormats->data();
1244 
1245     if (subpass.m_depthStencilAttachment.format != vk::VK_FORMAT_UNDEFINED)
1246     {
1247         const auto tcuFormat = vk::mapVkFormat(subpass.m_depthStencilAttachment.format);
1248         if (tcu::hasDepthComponent(tcuFormat.order))
1249             inheritanceRenderingInfo->depthAttachmentFormat = subpass.m_depthStencilAttachment.format;
1250         if (tcu::hasStencilComponent(tcuFormat.order))
1251             inheritanceRenderingInfo->stencilAttachmentFormat = subpass.m_depthStencilAttachment.format;
1252     }
1253 
1254     if (subpassIndex < (uint32_t)m_viewMasks.size())
1255         inheritanceRenderingInfo->viewMask = m_viewMasks[subpassIndex];
1256 }
1257 
1258 #endif
1259 
begin(const DeviceInterface & vk,const VkCommandBuffer commandBuffer,const VkRect2D & renderArea,const uint32_t clearValueCount,const VkClearValue * clearValues,const VkSubpassContents contents,const void * pNext) const1260 void RenderPassWrapper::begin(const DeviceInterface &vk, const VkCommandBuffer commandBuffer,
1261                               const VkRect2D &renderArea, const uint32_t clearValueCount,
1262                               const VkClearValue *clearValues, const VkSubpassContents contents,
1263                               const void *pNext) const
1264 {
1265     if (!m_isDynamicRendering)
1266     {
1267         beginRenderPass(vk, commandBuffer, *m_renderPass, *m_framebuffer, renderArea, clearValueCount, clearValues,
1268                         contents, pNext);
1269     }
1270     else
1271     {
1272 #ifndef CTS_USES_VULKANSC
1273         m_activeSubpass = 0;
1274 
1275         m_clearValues.resize(clearValueCount);
1276         for (uint32_t i = 0; i < clearValueCount; ++i)
1277             m_clearValues[i] = clearValues[i];
1278 
1279         for (uint32_t i = 0; i < (uint32_t)m_subpasses.size(); ++i)
1280             transitionLayouts(vk, commandBuffer, m_subpasses[i], true);
1281 
1282         insertDependencies(vk, commandBuffer, 0u);
1283 
1284         m_secondaryCommandBuffers = contents == vk::VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS;
1285 
1286         m_renderingInfo            = vk::initVulkanStructure();
1287         m_renderingInfo.flags      = (vk::VkRenderingFlags)0u;
1288         m_renderingInfo.renderArea = renderArea;
1289         m_renderingInfo.layerCount = m_layers;
1290         m_renderingInfo.viewMask   = 0x0;
1291 
1292         clearAttachments(vk, commandBuffer);
1293 
1294         beginRendering(vk, commandBuffer);
1295 #endif
1296     }
1297 }
1298 
begin(const DeviceInterface & vk,const VkCommandBuffer commandBuffer,const VkRect2D & renderArea,const VkClearValue & clearValue,const VkSubpassContents contents) const1299 void RenderPassWrapper::begin(const DeviceInterface &vk, const VkCommandBuffer commandBuffer,
1300                               const VkRect2D &renderArea, const VkClearValue &clearValue,
1301                               const VkSubpassContents contents) const
1302 {
1303     begin(vk, commandBuffer, renderArea, 1u, &clearValue, contents);
1304 }
1305 
begin(const DeviceInterface & vk,const VkCommandBuffer commandBuffer,const VkRect2D & renderArea,const tcu::Vec4 & clearColor,const VkSubpassContents contents) const1306 void RenderPassWrapper::begin(const DeviceInterface &vk, const VkCommandBuffer commandBuffer,
1307                               const VkRect2D &renderArea, const tcu::Vec4 &clearColor,
1308                               const VkSubpassContents contents) const
1309 {
1310     const VkClearValue clearValue = makeClearValueColor(clearColor);
1311     begin(vk, commandBuffer, renderArea, clearValue, contents);
1312 }
1313 
begin(const DeviceInterface & vk,const VkCommandBuffer commandBuffer,const VkRect2D & renderArea,const tcu::Vec4 & clearColor,const float clearDepth,const uint32_t clearStencil,const VkSubpassContents contents) const1314 void RenderPassWrapper::begin(const DeviceInterface &vk, const VkCommandBuffer commandBuffer,
1315                               const VkRect2D &renderArea, const tcu::Vec4 &clearColor, const float clearDepth,
1316                               const uint32_t clearStencil, const VkSubpassContents contents) const
1317 {
1318     const VkClearValue clearValues[] = {
1319         makeClearValueColor(clearColor),                      // attachment 0
1320         makeClearValueDepthStencil(clearDepth, clearStencil), // attachment 1
1321     };
1322     begin(vk, commandBuffer, renderArea, 2, clearValues, contents);
1323 }
1324 
begin(const DeviceInterface & vk,const VkCommandBuffer commandBuffer,const VkRect2D & renderArea,const VkSubpassContents contents) const1325 void RenderPassWrapper::begin(const DeviceInterface &vk, const VkCommandBuffer commandBuffer,
1326                               const VkRect2D &renderArea, const VkSubpassContents contents) const
1327 {
1328     begin(vk, commandBuffer, renderArea, 0u, DE_NULL, contents);
1329 }
1330 
begin(const DeviceInterface & vk,const VkCommandBuffer commandBuffer,const VkRect2D & renderArea,const tcu::UVec4 & clearColor,const VkSubpassContents contents) const1331 void RenderPassWrapper::begin(const DeviceInterface &vk, const VkCommandBuffer commandBuffer,
1332                               const VkRect2D &renderArea, const tcu::UVec4 &clearColor,
1333                               const VkSubpassContents contents) const
1334 {
1335     const VkClearValue clearValue =
1336         makeClearValueColorU32(clearColor.x(), clearColor.y(), clearColor.z(), clearColor.w());
1337 
1338     begin(vk, commandBuffer, renderArea, clearValue, contents);
1339 }
1340 
end(const DeviceInterface & vk,const VkCommandBuffer commandBuffer) const1341 void RenderPassWrapper::end(const DeviceInterface &vk, const VkCommandBuffer commandBuffer) const
1342 {
1343     if (!m_isDynamicRendering)
1344     {
1345         vk.cmdEndRenderPass(commandBuffer);
1346     }
1347     else
1348     {
1349 #ifndef CTS_USES_VULKANSC
1350         vk.cmdEndRendering(commandBuffer);
1351 
1352         // Use dependencies for external subpasses to extract destination access
1353         // flags and pipeline stage flags for the final layout transition
1354         // barriers.
1355         VkAccessFlags2 externalAccessFlags       = 0u;
1356         VkPipelineStageFlags2 externalStageFlags = 0u;
1357         bool sync2                               = false;
1358 
1359         for (const auto &dep : m_dependencies)
1360         {
1361             if (dep.dstSubpass == VK_SUBPASS_EXTERNAL)
1362             {
1363                 externalAccessFlags |= dep.dstAccessMask;
1364                 externalStageFlags |= dep.dstStageMask;
1365             }
1366             if (dep.sync2)
1367                 sync2 = true;
1368         }
1369 
1370         for (uint32_t i = 0; i < (uint32_t)m_attachments.size(); ++i)
1371         {
1372             if (m_layouts[i] == m_attachments[i].finalLayout)
1373                 continue;
1374 
1375             const bool color = !vk::isDepthStencilFormat(m_attachments[i].format);
1376             VkImageAspectFlags aspect =
1377                 color ? (vk::VkImageAspectFlags)vk::VK_IMAGE_ASPECT_COLOR_BIT : (vk::VkImageAspectFlags)0u;
1378 
1379             if (!color)
1380             {
1381                 const bool hasDepthAspect   = tcu::hasDepthComponent(vk::mapVkFormat(m_attachments[i].format).order);
1382                 const bool hasStencilAspect = tcu::hasStencilComponent(vk::mapVkFormat(m_attachments[i].format).order);
1383 
1384                 if (hasDepthAspect)
1385                     aspect |= vk::VK_IMAGE_ASPECT_DEPTH_BIT;
1386                 if (hasStencilAspect)
1387                     aspect |= vk::VK_IMAGE_ASPECT_STENCIL_BIT;
1388             }
1389 
1390             const auto subresourceRange =
1391                 makeImageSubresourceRange(aspect, 0u, VK_REMAINING_MIP_LEVELS, 0u, VK_REMAINING_ARRAY_LAYERS);
1392 
1393             const VkPipelineStageFlags2 srcStageMask = (color ? vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT :
1394                                                                 vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
1395             const VkAccessFlags2 srcAccessMask =
1396                 (color ? vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT : vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT);
1397             const VkPipelineStageFlags2 dstStageMask = (vk::VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT | externalStageFlags);
1398             const VkAccessFlags2 dstAccessMask       = externalAccessFlags;
1399             const VkImageLayout newLayout            = m_attachments[i].finalLayout;
1400 
1401             recordImageBarrier(vk, commandBuffer, sync2, srcStageMask, srcAccessMask, dstStageMask, dstAccessMask,
1402                                m_layouts[i], newLayout, m_images[i], subresourceRange);
1403         }
1404 
1405         insertDependencies(vk, commandBuffer, VK_SUBPASS_EXTERNAL);
1406 #endif
1407     }
1408 }
1409 
beginRendering(const DeviceInterface & vk,const VkCommandBuffer commandBuffer) const1410 void RenderPassWrapper::beginRendering(const DeviceInterface &vk, const VkCommandBuffer commandBuffer) const
1411 {
1412     DE_UNREF(vk);
1413     DE_UNREF(commandBuffer);
1414 #ifndef CTS_USES_VULKANSC
1415     const auto &subpass = m_subpasses[m_activeSubpass];
1416     std::vector<vk::VkRenderingAttachmentInfo> colorAttachments;
1417     for (uint32_t i = 0; i < (uint32_t)subpass.m_colorAttachments.size(); ++i)
1418     {
1419         colorAttachments.emplace_back();
1420         auto &colorAttachment = colorAttachments.back();
1421         colorAttachment       = vk::initVulkanStructure();
1422         if (subpass.m_colorAttachments[i].index == VK_ATTACHMENT_UNUSED)
1423             continue;
1424         colorAttachment        = subpass.m_colorAttachments[i].attachmentInfo;
1425         colorAttachment.loadOp = vk::VK_ATTACHMENT_LOAD_OP_LOAD;
1426         if (!subpass.m_resolveAttachments.empty() && subpass.m_resolveAttachments[i].index != VK_ATTACHMENT_UNUSED)
1427         {
1428             if (isUintFormat(subpass.m_resolveAttachments[i].format) ||
1429                 isIntFormat(subpass.m_resolveAttachments[i].format))
1430                 colorAttachment.resolveMode = vk::VK_RESOLVE_MODE_SAMPLE_ZERO_BIT;
1431             else
1432                 colorAttachment.resolveMode = vk::VK_RESOLVE_MODE_AVERAGE_BIT;
1433             colorAttachment.resolveImageView   = subpass.m_resolveAttachments[i].attachmentInfo.imageView;
1434             colorAttachment.resolveImageLayout = subpass.m_resolveAttachments[i].attachmentInfo.imageLayout;
1435         }
1436     }
1437 
1438     m_renderingInfo.colorAttachmentCount = (uint32_t)colorAttachments.size();
1439     m_renderingInfo.pColorAttachments    = colorAttachments.data();
1440 
1441     subpass.m_depthStencilAttachment.attachmentInfo.loadOp = vk::VK_ATTACHMENT_LOAD_OP_LOAD;
1442     VkRenderingAttachmentInfo depthAttachment              = subpass.m_depthStencilAttachment.attachmentInfo;
1443     VkRenderingAttachmentInfo stencilAttachment            = subpass.m_depthStencilAttachment.attachmentInfo;
1444     stencilAttachment.storeOp                              = subpass.m_depthStencilAttachment.stencilStoreOp;
1445 
1446     if (depthAttachment.imageView != VK_NULL_HANDLE)
1447     {
1448         const auto tcuFormat               = vk::mapVkFormat(subpass.m_depthStencilAttachment.format);
1449         bool hasDepthAspect                = tcu::hasDepthComponent(tcuFormat.order);
1450         bool hasStencilAspect              = tcu::hasStencilComponent(tcuFormat.order);
1451         m_renderingInfo.pDepthAttachment   = hasDepthAspect ? &depthAttachment : DE_NULL;
1452         m_renderingInfo.pStencilAttachment = hasStencilAspect ? &stencilAttachment : DE_NULL;
1453     }
1454     else
1455     {
1456         m_renderingInfo.pDepthAttachment   = DE_NULL;
1457         m_renderingInfo.pStencilAttachment = DE_NULL;
1458     }
1459 
1460     if (m_activeSubpass < (uint32_t)m_viewMasks.size())
1461         m_renderingInfo.viewMask = m_viewMasks[m_activeSubpass];
1462 
1463     m_renderingInfo.pNext = DE_NULL;
1464     if (subpass.m_msrtss.sType == VK_STRUCTURE_TYPE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_INFO_EXT)
1465     {
1466         subpass.m_msrtss.pNext = DE_NULL;
1467         m_renderingInfo.pNext  = &subpass.m_msrtss;
1468     }
1469 
1470     if (subpass.m_dsr.sType == VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE)
1471     {
1472         depthAttachment.resolveMode   = subpass.m_dsr.depthResolveMode;
1473         stencilAttachment.resolveMode = subpass.m_dsr.stencilResolveMode;
1474         if (subpass.m_dsr.pDepthStencilResolveAttachment)
1475         {
1476             depthAttachment.resolveImageView   = m_imageViews[subpass.m_dsr.pDepthStencilResolveAttachment->attachment];
1477             depthAttachment.resolveImageLayout = subpass.m_dsr.pDepthStencilResolveAttachment->layout;
1478             stencilAttachment.resolveImageView = m_imageViews[subpass.m_dsr.pDepthStencilResolveAttachment->attachment];
1479             stencilAttachment.resolveImageLayout = subpass.m_dsr.pDepthStencilResolveAttachment->layout;
1480         }
1481     }
1482 
1483     m_renderingInfo.flags = (VkRenderingFlags)0u;
1484 
1485     if (m_secondaryCommandBuffers)
1486         m_renderingInfo.flags |= VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT;
1487 
1488     vk.cmdBeginRendering(commandBuffer, &m_renderingInfo);
1489 #endif
1490 }
1491 
nextSubpass(const DeviceInterface & vk,const VkCommandBuffer commandBuffer,const VkSubpassContents contents) const1492 void RenderPassWrapper::nextSubpass(const DeviceInterface &vk, const VkCommandBuffer commandBuffer,
1493                                     const VkSubpassContents contents) const
1494 {
1495     if (!m_isDynamicRendering)
1496     {
1497         vk.cmdNextSubpass(commandBuffer, contents);
1498     }
1499     else
1500     {
1501 #ifndef CTS_USES_VULKANSC
1502         vk.cmdEndRendering(commandBuffer);
1503         ++m_activeSubpass;
1504         DE_ASSERT(m_activeSubpass < (uint32_t)m_subpasses.size());
1505 
1506         const auto &subpass = m_subpasses[m_activeSubpass];
1507 
1508         transitionLayouts(vk, commandBuffer, subpass, false);
1509 
1510         insertDependencies(vk, commandBuffer, m_activeSubpass);
1511 
1512         beginRendering(vk, commandBuffer);
1513 #endif
1514     }
1515 }
1516 
createFramebuffer(const DeviceInterface & vk,const VkDevice device,const VkFramebufferCreateInfo * pCreateInfo,const std::vector<vk::VkImage> & images)1517 void RenderPassWrapper::createFramebuffer(const DeviceInterface &vk, const VkDevice device,
1518                                           const VkFramebufferCreateInfo *pCreateInfo,
1519                                           const std::vector<vk::VkImage> &images)
1520 {
1521     DE_UNREF(images);
1522     if (!m_isDynamicRendering)
1523     {
1524         m_framebuffer = vk::createFramebuffer(vk, device, pCreateInfo);
1525     }
1526     else
1527     {
1528 #ifndef CTS_USES_VULKANSC
1529         m_images = images;
1530         m_imageViews.resize(pCreateInfo->attachmentCount);
1531         for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
1532             m_imageViews[i] = pCreateInfo->pAttachments[i];
1533 
1534         for (auto &subpass : m_subpasses)
1535         {
1536             for (uint32_t i = 0; i < (uint32_t)subpass.m_colorAttachments.size(); ++i)
1537             {
1538                 if (subpass.m_colorAttachments[i].index != VK_ATTACHMENT_UNUSED)
1539                     subpass.m_colorAttachments[i].attachmentInfo.imageView =
1540                         pCreateInfo->pAttachments[subpass.m_colorAttachments[i].index];
1541             }
1542 
1543             if (subpass.m_depthStencilAttachment.attachmentInfo.imageLayout != VK_IMAGE_LAYOUT_UNDEFINED)
1544             {
1545                 if (subpass.m_depthStencilAttachment.index != VK_ATTACHMENT_UNUSED)
1546                     subpass.m_depthStencilAttachment.attachmentInfo.imageView =
1547                         pCreateInfo->pAttachments[subpass.m_depthStencilAttachment.index];
1548             }
1549 
1550             for (uint32_t i = 0; i < (uint32_t)subpass.m_resolveAttachments.size(); ++i)
1551             {
1552                 if (subpass.m_resolveAttachments[i].index != VK_ATTACHMENT_UNUSED)
1553                     subpass.m_resolveAttachments[i].attachmentInfo.imageView =
1554                         pCreateInfo->pAttachments[subpass.m_resolveAttachments[i].index];
1555             }
1556         }
1557         m_layers = pCreateInfo->layers;
1558 #endif
1559     }
1560 }
1561 
createFramebuffer(const DeviceInterface & vk,const VkDevice device,const VkFramebufferCreateInfo * pCreateInfo,vk::VkImage colorImage,vk::VkImage depthStencilImage)1562 void RenderPassWrapper::createFramebuffer(const DeviceInterface &vk, const VkDevice device,
1563                                           const VkFramebufferCreateInfo *pCreateInfo, vk::VkImage colorImage,
1564                                           vk::VkImage depthStencilImage)
1565 {
1566     DE_UNREF(colorImage);
1567     DE_UNREF(depthStencilImage);
1568     if (!m_isDynamicRendering)
1569     {
1570         m_framebuffer = vk::createFramebuffer(vk, device, pCreateInfo);
1571     }
1572     else
1573     {
1574 #ifndef CTS_USES_VULKANSC
1575         if (colorImage != VK_NULL_HANDLE)
1576         {
1577             m_images.push_back(colorImage);
1578             DE_ASSERT(pCreateInfo->attachmentCount > 0);
1579             m_imageViews.push_back(pCreateInfo->pAttachments[0]);
1580         }
1581         if (depthStencilImage != VK_NULL_HANDLE)
1582             m_images.push_back(depthStencilImage);
1583         for (auto &subpass : m_subpasses)
1584         {
1585             DE_ASSERT(subpass.m_colorAttachments.size() <= 1);
1586             if (pCreateInfo->pAttachments)
1587             {
1588                 if (!subpass.m_colorAttachments.empty() &&
1589                     subpass.m_colorAttachments[0].index < pCreateInfo->attachmentCount)
1590                     subpass.m_colorAttachments[0].attachmentInfo.imageView =
1591                         pCreateInfo->pAttachments[subpass.m_colorAttachments[0].index];
1592                 if (subpass.m_depthStencilAttachment.index < pCreateInfo->attachmentCount)
1593                     subpass.m_depthStencilAttachment.attachmentInfo.imageView =
1594                         pCreateInfo->pAttachments[subpass.m_depthStencilAttachment.index];
1595             }
1596         }
1597 #endif
1598     }
1599 }
1600 
createFramebuffer(const DeviceInterface & vk,const VkDevice device,const VkImage colorImage,const VkImageView colorAttachment,const uint32_t width,const uint32_t height,const uint32_t layers)1601 void RenderPassWrapper::createFramebuffer(const DeviceInterface &vk, const VkDevice device, const VkImage colorImage,
1602                                           const VkImageView colorAttachment, const uint32_t width,
1603                                           const uint32_t height, const uint32_t layers)
1604 {
1605     DE_UNREF(colorImage);
1606     if (!m_isDynamicRendering)
1607     {
1608         VkFramebufferCreateInfo createInfo = initVulkanStructure();
1609         createInfo.flags                   = (VkFramebufferCreateFlags)0u;
1610         createInfo.renderPass              = *m_renderPass;
1611         createInfo.attachmentCount         = (colorAttachment != VK_NULL_HANDLE) ? 1u : 0u;
1612         createInfo.pAttachments            = &colorAttachment;
1613         createInfo.width                   = width;
1614         createInfo.height                  = height;
1615         createInfo.layers                  = layers;
1616         m_framebuffer                      = vk::createFramebuffer(vk, device, &createInfo);
1617     }
1618     else
1619     {
1620 #ifndef CTS_USES_VULKANSC
1621         m_images.push_back(colorImage);
1622         m_imageViews.push_back(colorAttachment);
1623         if (colorImage != VK_NULL_HANDLE)
1624         {
1625             for (auto &subpass : m_subpasses)
1626             {
1627                 DE_ASSERT(subpass.m_colorAttachments.size() == 1);
1628                 subpass.m_colorAttachments[0].attachmentInfo.imageView = colorAttachment;
1629             }
1630         }
1631 #endif
1632     }
1633 }
1634 
createFramebuffer(const DeviceInterface & vk,const VkDevice device,const uint32_t attachmentCount,const VkImage * imagesArray,const VkImageView * attachmentsArray,const uint32_t width,const uint32_t height,const uint32_t layers)1635 void RenderPassWrapper::createFramebuffer(const DeviceInterface &vk, const VkDevice device,
1636                                           const uint32_t attachmentCount, const VkImage *imagesArray,
1637                                           const VkImageView *attachmentsArray, const uint32_t width,
1638                                           const uint32_t height, const uint32_t layers)
1639 {
1640     DE_UNREF(imagesArray);
1641     if (!m_isDynamicRendering)
1642     {
1643         VkFramebufferCreateInfo createInfo = initVulkanStructure();
1644         createInfo.flags                   = (VkFramebufferCreateFlags)0u;
1645         createInfo.renderPass              = *m_renderPass;
1646         createInfo.attachmentCount         = attachmentCount;
1647         createInfo.pAttachments            = attachmentsArray;
1648         createInfo.width                   = width;
1649         createInfo.height                  = height;
1650         createInfo.layers                  = layers;
1651         m_framebuffer                      = vk::createFramebuffer(vk, device, &createInfo);
1652     }
1653     else
1654     {
1655 #ifndef CTS_USES_VULKANSC
1656         for (uint32_t i = 0; i < attachmentCount; ++i)
1657         {
1658             m_images.push_back(imagesArray[i]);
1659             m_imageViews.push_back(attachmentsArray[i]);
1660         }
1661         for (auto &subpass : m_subpasses)
1662         {
1663             for (uint32_t i = 0; i < (uint32_t)subpass.m_colorAttachments.size(); ++i)
1664             {
1665                 if (subpass.m_colorAttachments[i].index != VK_ATTACHMENT_UNUSED)
1666                     subpass.m_colorAttachments[i].attachmentInfo.imageView =
1667                         attachmentsArray[subpass.m_colorAttachments[i].index];
1668             }
1669             if (subpass.m_depthStencilAttachment.attachmentInfo.imageLayout != VK_IMAGE_LAYOUT_UNDEFINED)
1670             {
1671                 if (subpass.m_depthStencilAttachment.index != VK_ATTACHMENT_UNUSED)
1672                     subpass.m_depthStencilAttachment.attachmentInfo.imageView =
1673                         attachmentsArray[subpass.m_depthStencilAttachment.index];
1674             }
1675             for (uint32_t i = 0; i < (uint32_t)subpass.m_resolveAttachments.size(); ++i)
1676             {
1677                 if (subpass.m_resolveAttachments[i].index != VK_ATTACHMENT_UNUSED)
1678                     subpass.m_resolveAttachments[i].attachmentInfo.imageView =
1679                         attachmentsArray[subpass.m_resolveAttachments[i].index];
1680             }
1681         }
1682 #endif
1683     }
1684 }
1685 
ShaderWrapper()1686 ShaderWrapper::ShaderWrapper()
1687     : m_vk(DE_NULL)
1688     , m_device(VK_NULL_HANDLE)
1689     , m_binary(DE_NULL)
1690     , m_moduleCreateFlags((VkShaderModuleCreateFlags)0u)
1691     , m_layout(DE_NULL)
1692     , m_specializationInfo(DE_NULL)
1693 #ifndef CTS_USES_VULKANSC
1694     , m_shaderCreateFlags((VkShaderCreateFlagsEXT)0u)
1695     , m_binaryDataSize(0u)
1696 #endif
1697 {
1698 }
1699 
ShaderWrapper(const DeviceInterface & vk,VkDevice device,const vk::ProgramBinary & binary,const vk::VkShaderModuleCreateFlags createFlags)1700 ShaderWrapper::ShaderWrapper(const DeviceInterface &vk, VkDevice device, const vk::ProgramBinary &binary,
1701                              const vk::VkShaderModuleCreateFlags createFlags)
1702     : m_vk(&vk)
1703     , m_device(device)
1704     , m_binary(&binary)
1705     , m_moduleCreateFlags(createFlags)
1706     , m_layout(DE_NULL)
1707     , m_specializationInfo(DE_NULL)
1708 #ifndef CTS_USES_VULKANSC
1709     , m_shaderCreateFlags((VkShaderCreateFlagsEXT)0u)
1710     , m_binaryDataSize(0u)
1711 #endif
1712 {
1713 }
1714 
ShaderWrapper(const ShaderWrapper & rhs)1715 ShaderWrapper::ShaderWrapper(const ShaderWrapper &rhs) noexcept
1716     : m_vk(rhs.m_vk)
1717     , m_device(rhs.m_device)
1718     , m_binary(rhs.m_binary)
1719     , m_moduleCreateFlags(rhs.m_moduleCreateFlags)
1720     , m_layout(rhs.m_layout)
1721     , m_specializationInfo(rhs.m_specializationInfo)
1722 #ifndef CTS_USES_VULKANSC
1723     , m_shaderCreateFlags(rhs.m_shaderCreateFlags)
1724     , m_binaryDataSize(rhs.m_binaryDataSize)
1725     , m_binaryData(rhs.m_binaryData)
1726 #endif
1727 {
1728 }
1729 
operator =(const ShaderWrapper & rhs)1730 ShaderWrapper &ShaderWrapper::operator=(const ShaderWrapper &rhs) noexcept
1731 {
1732     m_vk                 = rhs.m_vk;
1733     m_device             = rhs.m_device;
1734     m_binary             = rhs.m_binary;
1735     m_moduleCreateFlags  = rhs.m_moduleCreateFlags;
1736     m_layout             = rhs.m_layout;
1737     m_specializationInfo = rhs.m_specializationInfo;
1738 #ifndef CTS_USES_VULKANSC
1739     m_shaderCreateFlags = rhs.m_shaderCreateFlags;
1740     m_binaryDataSize    = rhs.m_binaryDataSize;
1741     m_binaryData        = rhs.m_binaryData;
1742 #endif
1743 
1744     return *this;
1745 }
1746 
getModule(void) const1747 vk::VkShaderModule ShaderWrapper::getModule(void) const
1748 {
1749     if (!m_module)
1750     {
1751         if (!m_vk)
1752             return DE_NULL;
1753         m_module = createShaderModule(*m_vk, m_device, *m_binary, m_moduleCreateFlags);
1754     }
1755     return *m_module;
1756 }
1757 
getCodeSize(void) const1758 size_t ShaderWrapper::getCodeSize(void) const
1759 {
1760     return m_binary->getSize();
1761 }
1762 
getBinary(void) const1763 void *ShaderWrapper::getBinary(void) const
1764 {
1765     return (void *)m_binary->getBinary();
1766 }
1767 
createModule(void)1768 void ShaderWrapper::createModule(void)
1769 {
1770     if (m_vk)
1771         m_module = createShaderModule(*m_vk, m_device, *m_binary, m_moduleCreateFlags);
1772 }
1773 
setLayoutAndSpecialization(const PipelineLayoutWrapper * layout,const VkSpecializationInfo * specializationInfo)1774 void ShaderWrapper::setLayoutAndSpecialization(const PipelineLayoutWrapper *layout,
1775                                                const VkSpecializationInfo *specializationInfo)
1776 {
1777     m_layout             = layout;
1778     m_specializationInfo = specializationInfo;
1779 }
1780 
1781 #ifndef CTS_USES_VULKANSC
getShaderBinary(void)1782 void ShaderWrapper::getShaderBinary(void)
1783 {
1784     m_vk->getShaderBinaryDataEXT(m_device, *m_shader, &m_binaryDataSize, DE_NULL);
1785     m_binaryData.resize(m_binaryDataSize);
1786     m_vk->getShaderBinaryDataEXT(m_device, *m_shader, &m_binaryDataSize, m_binaryData.data());
1787 }
1788 #endif
1789 
1790 // Structure storing *CreateInfo structures that do not need to exist in memory after pipeline was constructed.
1791 struct GraphicsPipelineWrapper::InternalData
1792 {
1793     const InstanceInterface &vki;
1794     const DeviceInterface &vk;
1795     VkPhysicalDevice physicalDevice;
1796     VkDevice device;
1797     const std::vector<std::string> &deviceExtensions;
1798     const PipelineConstructionType pipelineConstructionType;
1799     const VkPipelineCreateFlags pipelineFlags;
1800     PipelineCreateFlags2 pipelineFlags2;
1801 
1802     // attribute used for making sure pipeline is configured in correct order
1803     int setupState;
1804 
1805     std::vector<PipelineShaderStageModuleIdPtr> pipelineShaderIdentifiers;
1806     std::vector<VkPipelineShaderStageCreateInfo> pipelineShaderStages;
1807     VkPipelineInputAssemblyStateCreateInfo inputAssemblyState;
1808     VkPipelineRasterizationStateCreateInfo defaultRasterizationState;
1809     VkPipelineViewportStateCreateInfo viewportState;
1810     VkPipelineTessellationStateCreateInfo tessellationState;
1811     VkPipelineFragmentShadingRateStateCreateInfoKHR *pFragmentShadingRateState;
1812     PipelineRenderingCreateInfoWrapper pRenderingState;
1813     RenderingAttachmentLocationInfoWrapper pRenderingAttachmentLocation;
1814     RenderingInputAttachmentIndexInfoWrapper pRenderingInputAttachmentIndex;
1815     const VkPipelineDynamicStateCreateInfo *pDynamicState;
1816     PipelineRepresentativeFragmentTestCreateInfoWrapper pRepresentativeFragmentTestState;
1817     PipelineRobustnessCreateInfoWrapper pPipelineRobustnessState;
1818 
1819     TessellationDomainOriginStatePtr pTessellationDomainOrigin;
1820     bool useViewportState;
1821     bool useDefaultRasterizationState;
1822     bool useDefaultDepthStencilState;
1823     bool useDefaultColorBlendState;
1824     bool useDefaultMultisampleState;
1825     bool useDefaultVertexInputState;
1826     bool failOnCompileWhenLinking;
1827 
1828     bool explicitLinkPipelineLayoutSet;
1829     VkGraphicsPipelineCreateInfo monolithicPipelineCreateInfo;
1830 
1831     ShaderWrapper vertexShader;
1832     ShaderWrapper tessellationControlShader;
1833     ShaderWrapper tessellationEvaluationShader;
1834     ShaderWrapper geometryShader;
1835     ShaderWrapper fragmentShader;
1836 
1837     ShaderWrapper meshShader;
1838     ShaderWrapper taskShader;
1839 
1840     bool tessellationShaderFeature;
1841     bool geometryShaderFeature;
1842     bool taskShaderFeature;
1843     bool meshShaderFeature;
1844 
1845     // Store all dynamic state that are used with shader objects
1846     std::vector<vk::VkDynamicState> shaderObjectDynamicStates;
1847 
1848 #ifndef CTS_USES_VULKANSC
1849     // Store the state that a pipeline would be created with, but shader objects have to set dynamically
1850     struct PipelineCreateState
1851     {
1852         std::vector<VkViewport> viewports;
1853         std::vector<VkRect2D> scissors;
1854         float lineWidth = 1.0f;
1855         VkDepthBiasRepresentationEXT depthBiasRepresentation =
1856             vk::VK_DEPTH_BIAS_REPRESENTATION_LEAST_REPRESENTABLE_VALUE_FORMAT_EXT;
1857         VkBool32 depthBiasExact       = VK_FALSE;
1858         float depthBiasConstantFactor = 0.0f;
1859         float depthBiasClamp          = 0.0f;
1860         float depthBiasSlopeFactor    = 1.0f;
1861         float blendConstants[4]       = {0.0f, 0.0f, 0.0f, 0.0f};
1862         float minDepthBounds          = 0.0f;
1863         float maxDepthBounds          = 1.0f;
1864         VkStencilOpState stencilFront = {
1865             VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_NEVER, 0, 0, 0};
1866         VkStencilOpState stencilBack = {
1867             VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_NEVER, 0, 0, 0};
1868         VkCullModeFlags cullMode     = VK_CULL_MODE_NONE;
1869         bool depthTestEnable         = VK_FALSE;
1870         bool depthWriteEnable        = VK_FALSE;
1871         VkCompareOp depthCompareOp   = VK_COMPARE_OP_NEVER;
1872         bool depthBoundsTestEnable   = VK_FALSE;
1873         VkFrontFace frontFace        = VK_FRONT_FACE_COUNTER_CLOCKWISE;
1874         VkPrimitiveTopology topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
1875         bool stencilTestEnable       = VK_FALSE;
1876         std::vector<VkVertexInputAttributeDescription2EXT> attributes;
1877         std::vector<VkVertexInputBindingDescription2EXT> bindings;
1878         bool depthBiasEnable         = VK_FALSE;
1879         VkLogicOp logicOp            = VK_LOGIC_OP_CLEAR;
1880         uint32_t patchControlPoints  = 1;
1881         bool primitiveRestartEnable  = VK_FALSE;
1882         bool rasterizerDiscardEnable = VK_FALSE;
1883         bool alphaToCoverageEnable   = VK_FALSE;
1884         bool alphaToOneEnable        = VK_FALSE;
1885         std::vector<VkColorBlendAdvancedEXT> colorBlendAdvanced;
1886         std::vector<VkBool32> colorBlendEnables;
1887         std::vector<VkColorBlendEquationEXT> blendEquations;
1888         std::vector<VkColorComponentFlags> colorWriteMasks;
1889         VkConservativeRasterizationModeEXT conservativeRasterizationMode =
1890             VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT;
1891         VkCoverageModulationModeNV coverageModulationMode = VK_COVERAGE_MODULATION_MODE_NONE_NV;
1892         bool coverageModulationTableEnable                = VK_FALSE;
1893         std::vector<float> coverageModulationTable;
1894         VkCoverageReductionModeNV coverageReductionMode = VK_COVERAGE_REDUCTION_MODE_MERGE_NV;
1895         bool coverageToColorEnable                      = VK_FALSE;
1896         uint32_t coverageToColorLocation                = 0;
1897         bool depthClampEnable                           = VK_FALSE;
1898         bool depthClipEnable                            = VK_FALSE;
1899         bool negativeOneToOne                           = VK_FALSE;
1900         uint32_t colorWriteEnableAttachmentCount        = 0;
1901         std::vector<VkBool32> colorWriteEnables;
1902         float extraPrimitiveOverestimationSize            = 0.0f;
1903         VkLineRasterizationModeEXT lineRasterizationMode  = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT;
1904         bool stippledLineEnable                           = VK_FALSE;
1905         uint32_t lineStippleFactor                        = 1;
1906         uint16_t lineStipplePattern                       = 0x1;
1907         bool logicOpEnable                                = VK_FALSE;
1908         VkPolygonMode polygonMode                         = VK_POLYGON_MODE_FILL;
1909         VkProvokingVertexModeEXT provokingVertexMode      = VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT;
1910         VkSampleCountFlagBits rasterizationSamples        = VK_SAMPLE_COUNT_1_BIT;
1911         VkExtent2D fragmentShadingRateSize                = {1u, 1u};
1912         VkFragmentShadingRateCombinerOpKHR combinerOps[2] = {VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR,
1913                                                              VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR};
1914         uint32_t rasterizationStream                      = 0;
1915         bool representativeFragmentTestEnable             = VK_FALSE;
1916         bool sampleLocationsEnable                        = VK_FALSE;
1917         std::vector<VkSampleLocationEXT> pSampleLocations;
1918         VkSampleLocationsInfoEXT sampleLocationsInfo = vk::initVulkanStructure();
1919         std::vector<VkSampleMask> sampleMasks;
1920         bool shadingRateImageEnable             = VK_FALSE;
1921         VkTessellationDomainOrigin domainOrigin = VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT;
1922         std::vector<VkViewportSwizzleNV> viewportSwizzles;
1923         bool viewportWScalingEnable    = VK_FALSE;
1924         uint32_t viewportWScalingCount = 0;
1925         std::vector<VkViewportWScalingNV> viewportWScalings;
1926         VkCoarseSampleOrderTypeNV coarseSampleOrderType = VK_COARSE_SAMPLE_ORDER_TYPE_DEFAULT_NV;
1927         uint32_t coarseCustomSampleOrderCount           = 0;
1928         std::vector<std::vector<VkCoarseSampleLocationNV>> coarseSampleLocations;
1929         std::vector<VkCoarseSampleOrderCustomNV> coarseCustomSampleOrders;
1930         uint32_t shadingRatePaletteCount = 0;
1931         std::vector<std::vector<VkShadingRatePaletteEntryNV>> shadingRatePaletteEntries;
1932         std::vector<VkShadingRatePaletteNV> shadingRatePalettes;
1933         uint32_t exclusiveScissorCount = 0;
1934         std::vector<VkRect2D> exclussiveScissors;
1935         bool discardRectangleEnable = VK_FALSE;
1936         std::vector<VkRect2D> discardRectangles;
1937         VkDiscardRectangleModeEXT discardRectangleMode  = VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT;
1938         VkImageAspectFlags attachmentFeedbackLoopEnable = VK_IMAGE_ASPECT_NONE;
1939     } pipelineCreateState;
1940 #endif
1941 
1942     // initialize with most common values
InternalDatavk::GraphicsPipelineWrapper::InternalData1943     InternalData(const InstanceInterface& instanceInterface, const DeviceInterface& vkd, VkPhysicalDevice physDevice, VkDevice vkDevice, const std::vector<std::string>& deviceExts, const PipelineConstructionType constructionType, const VkPipelineCreateFlags pipelineCreateFlags)
1944         : vki                        (instanceInterface)
1945         , vk                        (vkd)
1946         , physicalDevice            (physDevice)
1947         , device                    (vkDevice)
1948         , deviceExtensions            (deviceExts)
1949         , pipelineConstructionType    (constructionType)
1950         , pipelineFlags                (pipelineCreateFlags)
1951         , pipelineFlags2            (0u)
1952         , setupState                (PSS_NONE)
1953         , inputAssemblyState
1954         {
1955             VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType                                sType
1956             DE_NULL, // const void*                                    pNext
1957             0u, // VkPipelineInputAssemblyStateCreateFlags        flags
1958             VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology                            topology
1959             VK_FALSE                                                        // VkBool32                                        primitiveRestartEnable
1960         }
1961         , defaultRasterizationState
1962         {
1963             VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType                                sType
1964             DE_NULL, // const void*                                    pNext
1965             0u, // VkPipelineRasterizationStateCreateFlags        flags
1966             VK_FALSE, // VkBool32                                        depthClampEnable
1967             VK_FALSE, // VkBool32                                        rasterizerDiscardEnable
1968             VK_POLYGON_MODE_FILL, // VkPolygonMode                                polygonMode
1969             VK_CULL_MODE_NONE, // VkCullModeFlags                                cullMode
1970             VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace                                    frontFace
1971             VK_FALSE, // VkBool32                                        depthBiasEnable
1972             0.0f, // float                                        depthBiasConstantFactor
1973             0.0f, // float                                        depthBiasClamp
1974             0.0f, // float                                        depthBiasSlopeFactor
1975             1.0f                                                            // float                                        lineWidth
1976         }
1977         , viewportState
1978         {
1979             VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType                                sType
1980             DE_NULL, // const void*                                    pNext
1981             (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags            flags
1982             1u, // uint32_t                                        viewportCount
1983             DE_NULL, // const VkViewport*                            pViewports
1984             1u, // uint32_t                                        scissorCount
1985             DE_NULL                                                            // const VkRect2D*                                pScissors
1986         }
1987         , tessellationState
1988         {
1989             VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType                                sType
1990             DE_NULL, // const void*                                    pNext
1991             0u, // VkPipelineTessellationStateCreateFlags        flags
1992             3u                                                                // uint32_t                                        patchControlPoints
1993         }
1994         , pFragmentShadingRateState        (nullptr)
1995         , pDynamicState                    (DE_NULL)
1996         , pRepresentativeFragmentTestState(nullptr)
1997         , pPipelineRobustnessState          (nullptr)
1998         , pTessellationDomainOrigin        ()
1999         , useViewportState                (true)
2000         , useDefaultRasterizationState    (false)
2001         , useDefaultDepthStencilState    (false)
2002         , useDefaultColorBlendState        (false)
2003         , useDefaultMultisampleState    (false)
2004         , useDefaultVertexInputState    (true)
2005         , failOnCompileWhenLinking        (false)
2006         , explicitLinkPipelineLayoutSet    (false)
2007         , tessellationShaderFeature        (false)
2008         , geometryShaderFeature            (false)
2009         , taskShaderFeature                (false)
2010         , meshShaderFeature                (false)
2011     {
2012         monolithicPipelineCreateInfo = initVulkanStructure();
2013     }
2014 
extensionEnabledvk::GraphicsPipelineWrapper::InternalData2015     bool extensionEnabled(const std::string &ext) const
2016     {
2017         return std::find(deviceExtensions.begin(), deviceExtensions.end(), ext) != deviceExtensions.end();
2018     }
2019 };
2020 
GraphicsPipelineWrapper(const InstanceInterface & vki,const DeviceInterface & vk,VkPhysicalDevice physicalDevice,VkDevice device,const std::vector<std::string> & deviceExtensions,const PipelineConstructionType pipelineConstructionType,const VkPipelineCreateFlags flags)2021 GraphicsPipelineWrapper::GraphicsPipelineWrapper(const InstanceInterface &vki, const DeviceInterface &vk,
2022                                                  VkPhysicalDevice physicalDevice, VkDevice device,
2023                                                  const std::vector<std::string> &deviceExtensions,
2024                                                  const PipelineConstructionType pipelineConstructionType,
2025                                                  const VkPipelineCreateFlags flags)
2026     : m_internalData(
2027           new InternalData(vki, vk, physicalDevice, device, deviceExtensions, pipelineConstructionType, flags))
2028 {
2029 }
2030 
GraphicsPipelineWrapper(GraphicsPipelineWrapper && pw)2031 GraphicsPipelineWrapper::GraphicsPipelineWrapper(GraphicsPipelineWrapper &&pw) noexcept
2032     : m_pipelineFinal(pw.m_pipelineFinal)
2033     , m_internalData(pw.m_internalData)
2034 {
2035     std::move(pw.m_pipelineParts, pw.m_pipelineParts + de::arrayLength(pw.m_pipelineParts), m_pipelineParts);
2036 }
2037 
setMonolithicPipelineLayout(const PipelineLayoutWrapper & layout)2038 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setMonolithicPipelineLayout(const PipelineLayoutWrapper &layout)
2039 {
2040     // make sure pipeline was not already built
2041     DE_ASSERT(m_pipelineFinal.get() == DE_NULL);
2042 
2043     m_internalData->monolithicPipelineCreateInfo.layout = *layout;
2044     m_internalData->explicitLinkPipelineLayoutSet       = true;
2045 
2046     return *this;
2047 }
2048 
setDynamicState(const VkPipelineDynamicStateCreateInfo * dynamicState)2049 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setDynamicState(const VkPipelineDynamicStateCreateInfo *dynamicState)
2050 {
2051     // make sure states are not yet setup - all pipeline states must know about dynamic state
2052     DE_ASSERT(m_internalData && m_internalData->setupState == PSS_NONE);
2053 
2054     m_internalData->pDynamicState                              = dynamicState;
2055     m_internalData->monolithicPipelineCreateInfo.pDynamicState = dynamicState;
2056 
2057     return *this;
2058 }
2059 
setRepresentativeFragmentTestState(PipelineRepresentativeFragmentTestCreateInfoWrapper representativeFragmentTestState)2060 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setRepresentativeFragmentTestState(
2061     PipelineRepresentativeFragmentTestCreateInfoWrapper representativeFragmentTestState)
2062 {
2063     // Representative fragment test state is needed by the fragment shader state.
2064     DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_FRAGMENT_SHADER));
2065 
2066     m_internalData->pRepresentativeFragmentTestState = representativeFragmentTestState;
2067     return *this;
2068 }
2069 
setPipelineCreateFlags2(PipelineCreateFlags2 pipelineFlags2)2070 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setPipelineCreateFlags2(PipelineCreateFlags2 pipelineFlags2)
2071 {
2072     // make sure states are not yet setup - all pipeline states must know about createFlags2
2073     DE_ASSERT(m_internalData && m_internalData->setupState == PSS_NONE);
2074 
2075     m_internalData->pipelineFlags2 = pipelineFlags2;
2076     return *this;
2077 }
2078 
setPipelineRobustnessState(PipelineRobustnessCreateInfoWrapper pipelineRobustnessState)2079 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setPipelineRobustnessState(
2080     PipelineRobustnessCreateInfoWrapper pipelineRobustnessState)
2081 {
2082     // pipeline robustness is needed by vertex input state, make sure vertex input state was not setup yet
2083     DE_ASSERT(m_internalData && (m_internalData->setupState == PSS_NONE));
2084 
2085     m_internalData->pPipelineRobustnessState = pipelineRobustnessState;
2086     return *this;
2087 }
2088 
getDynamicStates(const VkPipelineDynamicStateCreateInfo * dynamicStateInfo,uint32_t setupState)2089 std::vector<VkDynamicState> getDynamicStates(const VkPipelineDynamicStateCreateInfo *dynamicStateInfo,
2090                                              uint32_t setupState)
2091 {
2092     static const std::set<VkDynamicState> vertexInputStates{
2093         VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT,
2094         VK_DYNAMIC_STATE_VERTEX_INPUT_EXT,
2095         VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT,
2096         VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT,
2097     };
2098 
2099     static const std::set<VkDynamicState> preRastStates{
2100         VK_DYNAMIC_STATE_VIEWPORT,
2101         VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT,
2102         VK_DYNAMIC_STATE_SCISSOR,
2103         VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT,
2104         VK_DYNAMIC_STATE_LINE_WIDTH,
2105         VK_DYNAMIC_STATE_LINE_STIPPLE_EXT,
2106         VK_DYNAMIC_STATE_CULL_MODE_EXT,
2107         VK_DYNAMIC_STATE_FRONT_FACE_EXT,
2108         VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT,
2109         VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT,
2110         VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT,
2111         VK_DYNAMIC_STATE_DEPTH_BIAS,
2112         VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT,
2113         VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR,
2114 #ifndef CTS_USES_VULKANSC
2115         VK_DYNAMIC_STATE_TESSELLATION_DOMAIN_ORIGIN_EXT,
2116         VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT,
2117         VK_DYNAMIC_STATE_POLYGON_MODE_EXT,
2118         VK_DYNAMIC_STATE_RASTERIZATION_STREAM_EXT,
2119         VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT,
2120         VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT,
2121         VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT,
2122         VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT,
2123         VK_DYNAMIC_STATE_LINE_STIPPLE_EXT,
2124         VK_DYNAMIC_STATE_CONSERVATIVE_RASTERIZATION_MODE_EXT,
2125         VK_DYNAMIC_STATE_EXTRA_PRIMITIVE_OVERESTIMATION_SIZE_EXT,
2126         VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT,
2127         VK_DYNAMIC_STATE_VIEWPORT_SWIZZLE_NV,
2128         VK_DYNAMIC_STATE_SHADING_RATE_IMAGE_ENABLE_NV,
2129         VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_ENABLE_NV,
2130         VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV,
2131         VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV,
2132         VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV,
2133         VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV,
2134 #endif
2135     };
2136 
2137     static const std::set<VkDynamicState> fragShaderStates{
2138         VK_DYNAMIC_STATE_DEPTH_BOUNDS,
2139         VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT,
2140         VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT,
2141         VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT,
2142         VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT,
2143         VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
2144         VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
2145         VK_DYNAMIC_STATE_STENCIL_REFERENCE,
2146         VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT,
2147         VK_DYNAMIC_STATE_STENCIL_OP_EXT,
2148         VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR,
2149         // Needs MSAA info here as well as fragment output state
2150         VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT,
2151 #ifndef CTS_USES_VULKANSC
2152         VK_DYNAMIC_STATE_SAMPLE_MASK_EXT,
2153         VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT,
2154         VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT,
2155         VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_ENABLE_EXT,
2156         VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT,
2157         VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_ENABLE_NV,
2158         VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_LOCATION_NV,
2159         VK_DYNAMIC_STATE_COVERAGE_MODULATION_MODE_NV,
2160         VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_ENABLE_NV,
2161         VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_NV,
2162         VK_DYNAMIC_STATE_COVERAGE_REDUCTION_MODE_NV,
2163         VK_DYNAMIC_STATE_REPRESENTATIVE_FRAGMENT_TEST_ENABLE_NV,
2164 #endif
2165     };
2166 
2167     static const std::set<VkDynamicState> fragOutputStates{
2168         VK_DYNAMIC_STATE_LOGIC_OP_EXT,
2169         VK_DYNAMIC_STATE_BLEND_CONSTANTS,
2170         VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT,
2171         VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR,
2172         VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT,
2173 #ifndef CTS_USES_VULKANSC
2174         VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT,
2175         VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT,
2176         VK_DYNAMIC_STATE_COLOR_BLEND_ADVANCED_EXT,
2177         VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT,
2178         VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT,
2179         VK_DYNAMIC_STATE_SAMPLE_MASK_EXT,
2180         VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT,
2181         VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT,
2182         VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_ENABLE_EXT,
2183         VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT,
2184         VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_ENABLE_NV,
2185         VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_LOCATION_NV,
2186         VK_DYNAMIC_STATE_COVERAGE_MODULATION_MODE_NV,
2187         VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_ENABLE_NV,
2188         VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_NV,
2189         VK_DYNAMIC_STATE_COVERAGE_REDUCTION_MODE_NV,
2190         VK_DYNAMIC_STATE_REPRESENTATIVE_FRAGMENT_TEST_ENABLE_NV,
2191         VK_DYNAMIC_STATE_ATTACHMENT_FEEDBACK_LOOP_ENABLE_EXT,
2192 #endif
2193     };
2194 
2195     const std::set<VkDynamicState> dynamicStates(
2196         dynamicStateInfo->pDynamicStates, dynamicStateInfo->pDynamicStates + dynamicStateInfo->dynamicStateCount);
2197 
2198     // Verify all passed states are contained in at least one of the vectors above, so they won't get lost.
2199     for (const auto dynState : dynamicStates)
2200     {
2201         DE_UNREF(dynState); // For release builds.
2202         DE_ASSERT(de::contains(vertexInputStates.begin(), vertexInputStates.end(), dynState) ||
2203                   de::contains(preRastStates.begin(), preRastStates.end(), dynState) ||
2204                   de::contains(fragShaderStates.begin(), fragShaderStates.end(), dynState) ||
2205                   de::contains(fragOutputStates.begin(), fragOutputStates.end(), dynState));
2206     }
2207 
2208     std::set<VkDynamicState> intersectedStates;
2209 
2210     if (setupState & PSS_VERTEX_INPUT_INTERFACE)
2211         std::set_intersection(vertexInputStates.begin(), vertexInputStates.end(), dynamicStates.begin(),
2212                               dynamicStates.end(), std::inserter(intersectedStates, intersectedStates.end()));
2213 
2214     if (setupState & PSS_PRE_RASTERIZATION_SHADERS)
2215         std::set_intersection(preRastStates.begin(), preRastStates.end(), dynamicStates.begin(), dynamicStates.end(),
2216                               std::inserter(intersectedStates, intersectedStates.end()));
2217 
2218     if (setupState & PSS_FRAGMENT_SHADER)
2219         std::set_intersection(fragShaderStates.begin(), fragShaderStates.end(), dynamicStates.begin(),
2220                               dynamicStates.end(), std::inserter(intersectedStates, intersectedStates.end()));
2221 
2222     if (setupState & PSS_FRAGMENT_OUTPUT_INTERFACE)
2223         std::set_intersection(fragOutputStates.begin(), fragOutputStates.end(), dynamicStates.begin(),
2224                               dynamicStates.end(), std::inserter(intersectedStates, intersectedStates.end()));
2225 
2226     const std::vector<VkDynamicState> returnedStates(begin(intersectedStates), end(intersectedStates));
2227 
2228     return returnedStates;
2229 }
2230 
setDefaultTopology(const VkPrimitiveTopology topology)2231 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setDefaultTopology(const VkPrimitiveTopology topology)
2232 {
2233     // topology is needed by vertex input state, make sure vertex input state was not setup yet
2234     DE_ASSERT(m_internalData && (m_internalData->setupState == PSS_NONE));
2235 
2236     m_internalData->inputAssemblyState.topology = topology;
2237 
2238     return *this;
2239 }
2240 
setDefaultPatchControlPoints(const uint32_t patchControlPoints)2241 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setDefaultPatchControlPoints(const uint32_t patchControlPoints)
2242 {
2243     // patchControlPoints are needed by pre-rasterization shader state, make sure pre-rasterization state was not setup yet
2244     DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_PRE_RASTERIZATION_SHADERS));
2245 
2246     m_internalData->tessellationState.patchControlPoints = patchControlPoints;
2247 
2248     return *this;
2249 }
2250 
setDefaultTessellationDomainOrigin(const VkTessellationDomainOrigin domainOrigin,bool forceExtStruct)2251 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setDefaultTessellationDomainOrigin(
2252     const VkTessellationDomainOrigin domainOrigin, bool forceExtStruct)
2253 {
2254     // Tessellation domain origin is needed by pre-rasterization shader state, make sure pre-rasterization state was not setup yet
2255     DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_PRE_RASTERIZATION_SHADERS));
2256 
2257     // We need the extension structure when:
2258     // - We want to force it.
2259     // - The domain origin is not the default value.
2260     // - We have already hooked the extension structure.
2261     if (forceExtStruct || domainOrigin != VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT ||
2262         m_internalData->pTessellationDomainOrigin)
2263     {
2264         if (!m_internalData->pTessellationDomainOrigin)
2265         {
2266             m_internalData->pTessellationDomainOrigin.reset(
2267                 new VkPipelineTessellationDomainOriginStateCreateInfo(initVulkanStructure()));
2268             m_internalData->tessellationState.pNext = m_internalData->pTessellationDomainOrigin.get();
2269         }
2270         m_internalData->pTessellationDomainOrigin->domainOrigin = domainOrigin;
2271     }
2272 
2273     return *this;
2274 }
2275 
setDefaultRasterizerDiscardEnable(const bool rasterizerDiscardEnable)2276 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setDefaultRasterizerDiscardEnable(const bool rasterizerDiscardEnable)
2277 {
2278     // rasterizerDiscardEnable is used in pre-rasterization shader state, make sure pre-rasterization state was not setup yet
2279     DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_PRE_RASTERIZATION_SHADERS));
2280 
2281     m_internalData->defaultRasterizationState.rasterizerDiscardEnable = rasterizerDiscardEnable;
2282 
2283     return *this;
2284 }
2285 
setDefaultRasterizationState()2286 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setDefaultRasterizationState()
2287 {
2288     // RasterizationState is used in pre-rasterization shader state, make sure this state was not setup yet
2289     DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_PRE_RASTERIZATION_SHADERS));
2290 
2291     m_internalData->useDefaultRasterizationState = true;
2292 
2293     return *this;
2294 }
2295 
setDefaultDepthStencilState()2296 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setDefaultDepthStencilState()
2297 {
2298     // DepthStencilState is used in fragment shader state, make sure fragment shader state was not setup yet
2299     DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_FRAGMENT_SHADER));
2300 
2301     m_internalData->useDefaultDepthStencilState = true;
2302 
2303     return *this;
2304 }
2305 
setDefaultColorBlendState()2306 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setDefaultColorBlendState()
2307 {
2308     // ColorBlendState is used in fragment shader state, make sure fragment shader state was not setup yet
2309     DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_FRAGMENT_SHADER));
2310 
2311     m_internalData->useDefaultColorBlendState = true;
2312 
2313     return *this;
2314 }
2315 
setDefaultMultisampleState()2316 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setDefaultMultisampleState()
2317 {
2318     // MultisampleState is used in fragment shader state, make sure fragment shader state was not setup yet
2319     DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_FRAGMENT_SHADER));
2320 
2321     m_internalData->useDefaultMultisampleState = true;
2322 
2323     return *this;
2324 }
2325 
setDefaultVertexInputState(const bool useDefaultVertexInputState)2326 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setDefaultVertexInputState(const bool useDefaultVertexInputState)
2327 {
2328     // Make sure vertex input state was not setup yet.
2329     DE_ASSERT(m_internalData && (m_internalData->setupState == PSS_NONE));
2330 
2331     m_internalData->useDefaultVertexInputState = useDefaultVertexInputState;
2332 
2333     return *this;
2334 }
2335 
setDefaultViewportsCount(uint32_t viewportCount)2336 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setDefaultViewportsCount(uint32_t viewportCount)
2337 {
2338     // ViewportState is used in pre-rasterization shader state, make sure pre-rasterization state was not setup yet
2339     DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_PRE_RASTERIZATION_SHADERS));
2340 
2341     m_internalData->viewportState.viewportCount = viewportCount;
2342 
2343     return *this;
2344 }
2345 
setDefaultScissorsCount(uint32_t scissorCount)2346 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setDefaultScissorsCount(uint32_t scissorCount)
2347 {
2348     // ViewportState is used in pre-rasterization shader state, make sure pre-rasterization state was not setup yet
2349     DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_PRE_RASTERIZATION_SHADERS));
2350 
2351     m_internalData->viewportState.scissorCount = scissorCount;
2352 
2353     return *this;
2354 }
2355 
setViewportStatePnext(const void * pNext)2356 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setViewportStatePnext(const void *pNext)
2357 {
2358     // ViewportState is used in pre-rasterization shader state, make sure pre-rasterization state was not setup yet
2359     DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_PRE_RASTERIZATION_SHADERS));
2360 
2361     m_internalData->viewportState.pNext = pNext;
2362 
2363     return *this;
2364 }
2365 
2366 #ifndef CTS_USES_VULKANSC
setRenderingColorAttachmentsInfo(PipelineRenderingCreateInfoWrapper pipelineRenderingCreateInfo)2367 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setRenderingColorAttachmentsInfo(
2368     PipelineRenderingCreateInfoWrapper pipelineRenderingCreateInfo)
2369 {
2370     /* When both graphics pipeline library and dynamic rendering enabled, we just need only viewMask of VkPipelineRenderingCreateInfo
2371      * on non-fragment stages. But we need the rest info for setting up fragment output states.
2372      * This method provides a way to verify this condition.
2373      */
2374     if (!m_internalData->pRenderingState.ptr || !isConstructionTypeLibrary(m_internalData->pipelineConstructionType))
2375         return *this;
2376 
2377     DE_ASSERT(m_internalData && (m_internalData->setupState > PSS_VERTEX_INPUT_INTERFACE) &&
2378               (m_internalData->setupState < PSS_FRAGMENT_OUTPUT_INTERFACE) &&
2379               (m_internalData->pRenderingState.ptr->viewMask == pipelineRenderingCreateInfo.ptr->viewMask));
2380 
2381     m_internalData->pRenderingState.ptr = pipelineRenderingCreateInfo.ptr;
2382 
2383     return *this;
2384 }
2385 #endif
2386 
disableViewportState(const bool disable)2387 GraphicsPipelineWrapper &GraphicsPipelineWrapper::disableViewportState(const bool disable)
2388 {
2389     // ViewportState is used in pre-rasterization shader state, make sure pre-rasterization state was not setup yet
2390     DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_PRE_RASTERIZATION_SHADERS));
2391 
2392     m_internalData->useViewportState = !disable;
2393 
2394     return *this;
2395 }
2396 
setupVertexInputState(const VkPipelineVertexInputStateCreateInfo * vertexInputState,const VkPipelineInputAssemblyStateCreateInfo * inputAssemblyState,const VkPipelineCache partPipelineCache,PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback,const bool useNullPtrs)2397 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setupVertexInputState(
2398     const VkPipelineVertexInputStateCreateInfo *vertexInputState,
2399     const VkPipelineInputAssemblyStateCreateInfo *inputAssemblyState, const VkPipelineCache partPipelineCache,
2400     PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback, const bool useNullPtrs)
2401 {
2402     // make sure pipeline was not already build
2403     DE_ASSERT(m_pipelineFinal.get() == DE_NULL);
2404 
2405     // make sure states are set in order - no need to complicate logic to support out of order specification - this state needs to be set first
2406     DE_ASSERT(m_internalData && (m_internalData->setupState == PSS_NONE));
2407 
2408     // Unreference variables that are not used in Vulkan SC. No need to put this in ifdef.
2409     DE_UNREF(partPipelineCache);
2410     DE_UNREF(partCreationFeedback);
2411 
2412     m_internalData->setupState = PSS_VERTEX_INPUT_INTERFACE;
2413 
2414     const auto pVertexInputState =
2415         ((vertexInputState || useNullPtrs || !m_internalData->useDefaultVertexInputState) ? vertexInputState :
2416                                                                                             &defaultVertexInputState);
2417     const auto pInputAssemblyState =
2418         ((inputAssemblyState || useNullPtrs) ? inputAssemblyState : &m_internalData->inputAssemblyState);
2419 
2420     if (!isConstructionTypeLibrary(m_internalData->pipelineConstructionType))
2421     {
2422         m_internalData->monolithicPipelineCreateInfo.pVertexInputState   = pVertexInputState;
2423         m_internalData->monolithicPipelineCreateInfo.pInputAssemblyState = pInputAssemblyState;
2424     }
2425 
2426 #ifndef CTS_USES_VULKANSC
2427     // note we could just use else to if statement above but sinc
2428     // this section is cut out for Vulkan SC its cleaner with separate if
2429     if (isConstructionTypeLibrary(m_internalData->pipelineConstructionType))
2430     {
2431         auto libraryCreateInfo =
2432             makeGraphicsPipelineLibraryCreateInfo(VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT);
2433         void *firstStructInChain = reinterpret_cast<void *>(&libraryCreateInfo);
2434         addToChain(&firstStructInChain, partCreationFeedback.ptr);
2435         addToChain(&firstStructInChain, m_internalData->pPipelineRobustnessState.ptr);
2436 
2437         VkPipelineDynamicStateCreateInfo pickedDynamicStateInfo = initVulkanStructure();
2438         std::vector<VkDynamicState> states;
2439 
2440         if (m_internalData->pDynamicState)
2441         {
2442             states = getDynamicStates(m_internalData->pDynamicState, m_internalData->setupState);
2443 
2444             pickedDynamicStateInfo.pDynamicStates    = states.data();
2445             pickedDynamicStateInfo.dynamicStateCount = static_cast<uint32_t>(states.size());
2446         }
2447 
2448         VkGraphicsPipelineCreateInfo pipelinePartCreateInfo = initVulkanStructure();
2449         pipelinePartCreateInfo.pNext                        = firstStructInChain;
2450         pipelinePartCreateInfo.flags =
2451             (m_internalData->pipelineFlags | VK_PIPELINE_CREATE_LIBRARY_BIT_KHR) & ~VK_PIPELINE_CREATE_DERIVATIVE_BIT;
2452         pipelinePartCreateInfo.pVertexInputState   = pVertexInputState;
2453         pipelinePartCreateInfo.pInputAssemblyState = pInputAssemblyState;
2454         pipelinePartCreateInfo.pDynamicState       = &pickedDynamicStateInfo;
2455 
2456         if (m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_LINK_TIME_OPTIMIZED_LIBRARY)
2457             pipelinePartCreateInfo.flags |= VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
2458 
2459         VkPipelineCreateFlags2CreateInfoKHR pipelineFlags2CreateInfo = initVulkanStructure();
2460         if (m_internalData->pipelineFlags2)
2461         {
2462             pipelineFlags2CreateInfo.flags =
2463                 m_internalData->pipelineFlags2 | translateCreateFlag(pipelinePartCreateInfo.flags);
2464             addToChain(&firstStructInChain, &pipelineFlags2CreateInfo);
2465             pipelinePartCreateInfo.flags = 0u;
2466         }
2467 
2468         m_pipelineParts[0] = makeGraphicsPipeline(m_internalData->vk, m_internalData->device, partPipelineCache,
2469                                                   &pipelinePartCreateInfo);
2470     }
2471 #endif // CTS_USES_VULKANSC
2472 
2473     return *this;
2474 }
2475 
setupPreRasterizationShaderState(const std::vector<VkViewport> & viewports,const std::vector<VkRect2D> & scissors,const PipelineLayoutWrapper & layout,const VkRenderPass renderPass,const uint32_t subpass,const ShaderWrapper vertexShader,const VkPipelineRasterizationStateCreateInfo * rasterizationState,const ShaderWrapper tessellationControlShader,const ShaderWrapper tessellationEvalShader,const ShaderWrapper geometryShader,const VkSpecializationInfo * specializationInfo,VkPipelineFragmentShadingRateStateCreateInfoKHR * fragmentShadingRateState,PipelineRenderingCreateInfoWrapper rendering,const VkPipelineCache partPipelineCache,PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback)2476 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setupPreRasterizationShaderState(
2477     const std::vector<VkViewport> &viewports, const std::vector<VkRect2D> &scissors,
2478     const PipelineLayoutWrapper &layout, const VkRenderPass renderPass, const uint32_t subpass,
2479     const ShaderWrapper vertexShader, const VkPipelineRasterizationStateCreateInfo *rasterizationState,
2480     const ShaderWrapper tessellationControlShader, const ShaderWrapper tessellationEvalShader,
2481     const ShaderWrapper geometryShader, const VkSpecializationInfo *specializationInfo,
2482     VkPipelineFragmentShadingRateStateCreateInfoKHR *fragmentShadingRateState,
2483     PipelineRenderingCreateInfoWrapper rendering, const VkPipelineCache partPipelineCache,
2484     PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback)
2485 {
2486     return setupPreRasterizationShaderState2(
2487         viewports, scissors, layout, renderPass, subpass, vertexShader, rasterizationState, tessellationControlShader,
2488         tessellationEvalShader, geometryShader,
2489         // Reuse the same specialization info for all stages.
2490         specializationInfo, specializationInfo, specializationInfo, specializationInfo, fragmentShadingRateState,
2491         rendering, partPipelineCache, partCreationFeedback);
2492 }
2493 
setupPreRasterizationShaderState2(const std::vector<VkViewport> & viewports,const std::vector<VkRect2D> & scissors,const PipelineLayoutWrapper & layout,const VkRenderPass renderPass,const uint32_t subpass,const ShaderWrapper vertexShader,const VkPipelineRasterizationStateCreateInfo * rasterizationState,const ShaderWrapper tessellationControlShader,const ShaderWrapper tessellationEvalShader,const ShaderWrapper geometryShader,const VkSpecializationInfo * vertSpecializationInfo,const VkSpecializationInfo * tescSpecializationInfo,const VkSpecializationInfo * teseSpecializationInfo,const VkSpecializationInfo * geomSpecializationInfo,VkPipelineFragmentShadingRateStateCreateInfoKHR * fragmentShadingRateState,PipelineRenderingCreateInfoWrapper rendering,const VkPipelineCache partPipelineCache,PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback)2494 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setupPreRasterizationShaderState2(
2495     const std::vector<VkViewport> &viewports, const std::vector<VkRect2D> &scissors,
2496     const PipelineLayoutWrapper &layout, const VkRenderPass renderPass, const uint32_t subpass,
2497     const ShaderWrapper vertexShader, const VkPipelineRasterizationStateCreateInfo *rasterizationState,
2498     const ShaderWrapper tessellationControlShader, const ShaderWrapper tessellationEvalShader,
2499     const ShaderWrapper geometryShader, const VkSpecializationInfo *vertSpecializationInfo,
2500     const VkSpecializationInfo *tescSpecializationInfo, const VkSpecializationInfo *teseSpecializationInfo,
2501     const VkSpecializationInfo *geomSpecializationInfo,
2502     VkPipelineFragmentShadingRateStateCreateInfoKHR *fragmentShadingRateState,
2503     PipelineRenderingCreateInfoWrapper rendering, const VkPipelineCache partPipelineCache,
2504     PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback)
2505 {
2506     return setupPreRasterizationShaderState3(
2507         viewports, scissors, layout, renderPass, subpass, vertexShader,
2508         PipelineShaderStageModuleIdentifierCreateInfoWrapper(), rasterizationState, tessellationControlShader,
2509         PipelineShaderStageModuleIdentifierCreateInfoWrapper(), tessellationEvalShader,
2510         PipelineShaderStageModuleIdentifierCreateInfoWrapper(), geometryShader,
2511         PipelineShaderStageModuleIdentifierCreateInfoWrapper(), vertSpecializationInfo, tescSpecializationInfo,
2512         teseSpecializationInfo, geomSpecializationInfo, fragmentShadingRateState, rendering, partPipelineCache,
2513         partCreationFeedback);
2514 }
2515 
setupPreRasterizationShaderState3(const std::vector<VkViewport> & viewports,const std::vector<VkRect2D> & scissors,const PipelineLayoutWrapper & layout,const VkRenderPass renderPass,const uint32_t subpass,const ShaderWrapper vertexShader,PipelineShaderStageModuleIdentifierCreateInfoWrapper vertShaderModuleId,const VkPipelineRasterizationStateCreateInfo * rasterizationState,const ShaderWrapper tessellationControlShader,PipelineShaderStageModuleIdentifierCreateInfoWrapper tescShaderModuleId,const ShaderWrapper tessellationEvalShader,PipelineShaderStageModuleIdentifierCreateInfoWrapper teseShaderModuleId,const ShaderWrapper geometryShader,PipelineShaderStageModuleIdentifierCreateInfoWrapper geomShaderModuleId,const VkSpecializationInfo * vertSpecializationInfo,const VkSpecializationInfo * tescSpecializationInfo,const VkSpecializationInfo * teseSpecializationInfo,const VkSpecializationInfo * geomSpecializationInfo,VkPipelineFragmentShadingRateStateCreateInfoKHR * fragmentShadingRateState,PipelineRenderingCreateInfoWrapper rendering,const VkPipelineCache partPipelineCache,PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback)2516 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setupPreRasterizationShaderState3(
2517     const std::vector<VkViewport> &viewports, const std::vector<VkRect2D> &scissors,
2518     const PipelineLayoutWrapper &layout, const VkRenderPass renderPass, const uint32_t subpass,
2519     const ShaderWrapper vertexShader, PipelineShaderStageModuleIdentifierCreateInfoWrapper vertShaderModuleId,
2520     const VkPipelineRasterizationStateCreateInfo *rasterizationState, const ShaderWrapper tessellationControlShader,
2521     PipelineShaderStageModuleIdentifierCreateInfoWrapper tescShaderModuleId, const ShaderWrapper tessellationEvalShader,
2522     PipelineShaderStageModuleIdentifierCreateInfoWrapper teseShaderModuleId, const ShaderWrapper geometryShader,
2523     PipelineShaderStageModuleIdentifierCreateInfoWrapper geomShaderModuleId,
2524     const VkSpecializationInfo *vertSpecializationInfo, const VkSpecializationInfo *tescSpecializationInfo,
2525     const VkSpecializationInfo *teseSpecializationInfo, const VkSpecializationInfo *geomSpecializationInfo,
2526     VkPipelineFragmentShadingRateStateCreateInfoKHR *fragmentShadingRateState,
2527     PipelineRenderingCreateInfoWrapper rendering, const VkPipelineCache partPipelineCache,
2528     PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback)
2529 {
2530     // make sure pipeline was not already build
2531     DE_ASSERT(m_pipelineFinal.get() == DE_NULL);
2532 
2533     // make sure states are set in order - no need to complicate logic to support out of order specification - this state needs to be set second
2534     DE_ASSERT(m_internalData && (m_internalData->setupState == PSS_VERTEX_INPUT_INTERFACE));
2535 
2536     // Unreference variables that are not used in Vulkan SC. No need to put this in ifdef.
2537     DE_UNREF(partPipelineCache);
2538     DE_UNREF(partCreationFeedback);
2539     DE_UNREF(vertShaderModuleId);
2540     DE_UNREF(tescShaderModuleId);
2541     DE_UNREF(teseShaderModuleId);
2542     DE_UNREF(geomShaderModuleId);
2543 
2544     m_internalData->setupState |= PSS_PRE_RASTERIZATION_SHADERS;
2545     m_internalData->pFragmentShadingRateState = fragmentShadingRateState;
2546     m_internalData->pRenderingState.ptr       = rendering.ptr;
2547 
2548     const bool hasTesc = (tessellationControlShader.isSet() || tescShaderModuleId.ptr);
2549     const bool hasTese = (tessellationEvalShader.isSet() || teseShaderModuleId.ptr);
2550     const bool hasGeom = (geometryShader.isSet() || geomShaderModuleId.ptr);
2551 
2552     const auto pRasterizationState =
2553         rasterizationState ?
2554             rasterizationState :
2555             (m_internalData->useDefaultRasterizationState ? &m_internalData->defaultRasterizationState : DE_NULL);
2556     const bool forceNullTessState =
2557         (m_internalData->tessellationState.patchControlPoints == std::numeric_limits<uint32_t>::max());
2558     const auto pTessellationState =
2559         ((hasTesc || hasTese) && !forceNullTessState) ? &m_internalData->tessellationState : nullptr;
2560     const auto pViewportState = m_internalData->useViewportState ? &m_internalData->viewportState : DE_NULL;
2561 
2562     VkPipelineCreateFlags shaderModuleIdFlags = 0u;
2563 
2564     m_internalData->vertexShader = vertexShader;
2565     m_internalData->vertexShader.setLayoutAndSpecialization(&layout, vertSpecializationInfo);
2566     if (!isConstructionTypeShaderObject(m_internalData->pipelineConstructionType))
2567         m_internalData->vertexShader.createModule();
2568 
2569     // reserve space for all stages including fragment - this is needed when we create monolithic pipeline
2570     m_internalData->pipelineShaderStages = std::vector<VkPipelineShaderStageCreateInfo>(
2571         2u + hasTesc + hasTese + hasGeom,
2572         {
2573             VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType                        sType
2574             DE_NULL,                                             // const void*                            pNext
2575             0u,                                                  // VkPipelineShaderStageCreateFlags        flags
2576             VK_SHADER_STAGE_VERTEX_BIT,                          // VkShaderStageFlagBits                stage
2577             m_internalData->vertexShader.getModule(),            // VkShaderModule                        module
2578             "main",                                              // const char*                            pName
2579             vertSpecializationInfo // const VkSpecializationInfo*            pSpecializationInfo
2580         });
2581 
2582 #ifndef CTS_USES_VULKANSC
2583     if (vertShaderModuleId.ptr)
2584     {
2585         m_internalData->pipelineShaderIdentifiers.emplace_back(
2586             new PipelineShaderStageModuleIdentifierCreateInfoWrapper(vertShaderModuleId.ptr));
2587         m_internalData->pipelineShaderStages[0].pNext = m_internalData->pipelineShaderIdentifiers.back().get()->ptr;
2588 
2589         if (!vertexShader.isSet())
2590             shaderModuleIdFlags |= VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT;
2591     }
2592 #endif // CTS_USES_VULKANSC
2593 
2594     std::vector<VkPipelineShaderStageCreateInfo>::iterator currStage = m_internalData->pipelineShaderStages.begin() + 1;
2595 
2596     if (hasTesc)
2597     {
2598         m_internalData->tessellationControlShader = tessellationControlShader;
2599         m_internalData->tessellationControlShader.setLayoutAndSpecialization(&layout, tescSpecializationInfo);
2600         if (!isConstructionTypeShaderObject(m_internalData->pipelineConstructionType))
2601             m_internalData->tessellationControlShader.createModule();
2602 
2603         currStage->stage               = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
2604         currStage->module              = m_internalData->tessellationControlShader.getModule();
2605         currStage->pSpecializationInfo = tescSpecializationInfo;
2606 
2607 #ifndef CTS_USES_VULKANSC
2608         if (tescShaderModuleId.ptr)
2609         {
2610             m_internalData->pipelineShaderIdentifiers.emplace_back(
2611                 new PipelineShaderStageModuleIdentifierCreateInfoWrapper(tescShaderModuleId.ptr));
2612             currStage->pNext = m_internalData->pipelineShaderIdentifiers.back().get()->ptr;
2613 
2614             if (!tessellationControlShader.isSet())
2615                 shaderModuleIdFlags |= VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT;
2616         }
2617 #endif // CTS_USES_VULKANSC
2618 
2619         ++currStage;
2620     }
2621 
2622     if (hasTese)
2623     {
2624         m_internalData->tessellationEvaluationShader = tessellationEvalShader;
2625         m_internalData->tessellationEvaluationShader.setLayoutAndSpecialization(&layout, teseSpecializationInfo);
2626         if (!isConstructionTypeShaderObject(m_internalData->pipelineConstructionType))
2627             m_internalData->tessellationEvaluationShader.createModule();
2628 
2629         currStage->stage               = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
2630         currStage->module              = m_internalData->tessellationEvaluationShader.getModule();
2631         currStage->pSpecializationInfo = teseSpecializationInfo;
2632 
2633 #ifndef CTS_USES_VULKANSC
2634         if (teseShaderModuleId.ptr)
2635         {
2636             m_internalData->pipelineShaderIdentifiers.emplace_back(
2637                 new PipelineShaderStageModuleIdentifierCreateInfoWrapper(teseShaderModuleId.ptr));
2638             currStage->pNext = m_internalData->pipelineShaderIdentifiers.back().get()->ptr;
2639 
2640             if (!tessellationEvalShader.isSet())
2641                 shaderModuleIdFlags |= VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT;
2642         }
2643 #endif // CTS_USES_VULKANSC
2644 
2645         ++currStage;
2646     }
2647 
2648     if (hasGeom)
2649     {
2650         m_internalData->geometryShader = geometryShader;
2651         m_internalData->geometryShader.setLayoutAndSpecialization(&layout, geomSpecializationInfo);
2652         if (!isConstructionTypeShaderObject(m_internalData->pipelineConstructionType))
2653             m_internalData->geometryShader.createModule();
2654 
2655         currStage->stage               = VK_SHADER_STAGE_GEOMETRY_BIT;
2656         currStage->module              = m_internalData->geometryShader.getModule();
2657         currStage->pSpecializationInfo = geomSpecializationInfo;
2658 
2659 #ifndef CTS_USES_VULKANSC
2660         if (geomShaderModuleId.ptr)
2661         {
2662             m_internalData->pipelineShaderIdentifiers.emplace_back(
2663                 new PipelineShaderStageModuleIdentifierCreateInfoWrapper(geomShaderModuleId.ptr));
2664             currStage->pNext = m_internalData->pipelineShaderIdentifiers.back().get()->ptr;
2665 
2666             if (!geometryShader.isSet())
2667                 shaderModuleIdFlags |= VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT;
2668         }
2669 #endif // CTS_USES_VULKANSC
2670     }
2671 
2672     if (pViewportState)
2673     {
2674         if (!viewports.empty())
2675         {
2676             pViewportState->viewportCount = (uint32_t)viewports.size();
2677             pViewportState->pViewports    = &viewports[0];
2678         }
2679         if (!scissors.empty())
2680         {
2681             pViewportState->scissorCount = (uint32_t)scissors.size();
2682             pViewportState->pScissors    = &scissors[0];
2683         }
2684     }
2685 
2686     // if pipeline layout was not specified with setupMonolithicPipelineLayout
2687     // then use layout from setupPreRasterizationShaderState for link pipeline
2688     if (!m_internalData->explicitLinkPipelineLayoutSet)
2689         m_internalData->monolithicPipelineCreateInfo.layout = *layout;
2690 
2691     if (!isConstructionTypeLibrary(m_internalData->pipelineConstructionType))
2692     {
2693         m_internalData->monolithicPipelineCreateInfo.renderPass          = renderPass;
2694         m_internalData->monolithicPipelineCreateInfo.subpass             = subpass;
2695         m_internalData->monolithicPipelineCreateInfo.pRasterizationState = pRasterizationState;
2696         m_internalData->monolithicPipelineCreateInfo.pViewportState      = pViewportState;
2697         m_internalData->monolithicPipelineCreateInfo.stageCount          = 1u + hasTesc + hasTese + hasGeom;
2698         m_internalData->monolithicPipelineCreateInfo.pStages             = m_internalData->pipelineShaderStages.data();
2699         m_internalData->monolithicPipelineCreateInfo.pTessellationState  = pTessellationState;
2700         m_internalData->monolithicPipelineCreateInfo.flags |= shaderModuleIdFlags;
2701     }
2702 
2703 #ifndef CTS_USES_VULKANSC
2704     // note we could just use else to if statement above but sinc
2705     // this section is cut out for Vulkan SC its cleaner with separate if
2706     if (isConstructionTypeLibrary(m_internalData->pipelineConstructionType))
2707     {
2708         auto libraryCreateInfo =
2709             makeGraphicsPipelineLibraryCreateInfo(VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT);
2710         void *firstStructInChain = reinterpret_cast<void *>(&libraryCreateInfo);
2711         addToChain(&firstStructInChain, m_internalData->pFragmentShadingRateState);
2712         addToChain(&firstStructInChain, m_internalData->pRenderingState.ptr);
2713         addToChain(&firstStructInChain, partCreationFeedback.ptr);
2714         addToChain(&firstStructInChain, m_internalData->pPipelineRobustnessState.ptr);
2715 
2716         VkPipelineDynamicStateCreateInfo pickedDynamicStateInfo = initVulkanStructure();
2717         std::vector<VkDynamicState> states;
2718 
2719         if (m_internalData->pDynamicState)
2720         {
2721             states = getDynamicStates(m_internalData->pDynamicState, m_internalData->setupState);
2722 
2723             pickedDynamicStateInfo.pDynamicStates    = states.data();
2724             pickedDynamicStateInfo.dynamicStateCount = static_cast<uint32_t>(states.size());
2725         }
2726 
2727         VkGraphicsPipelineCreateInfo pipelinePartCreateInfo = initVulkanStructure();
2728         pipelinePartCreateInfo.pNext                        = firstStructInChain;
2729         pipelinePartCreateInfo.flags =
2730             (m_internalData->pipelineFlags | VK_PIPELINE_CREATE_LIBRARY_BIT_KHR | shaderModuleIdFlags) &
2731             ~VK_PIPELINE_CREATE_DERIVATIVE_BIT;
2732         pipelinePartCreateInfo.layout              = *layout;
2733         pipelinePartCreateInfo.renderPass          = renderPass;
2734         pipelinePartCreateInfo.subpass             = subpass;
2735         pipelinePartCreateInfo.pRasterizationState = pRasterizationState;
2736         pipelinePartCreateInfo.pViewportState      = pViewportState;
2737         pipelinePartCreateInfo.stageCount          = 1u + hasTesc + hasTese + hasGeom;
2738         pipelinePartCreateInfo.pStages             = m_internalData->pipelineShaderStages.data();
2739         pipelinePartCreateInfo.pTessellationState  = pTessellationState;
2740         pipelinePartCreateInfo.pDynamicState       = &pickedDynamicStateInfo;
2741 
2742         if (m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_LINK_TIME_OPTIMIZED_LIBRARY)
2743             pipelinePartCreateInfo.flags |= VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
2744 
2745         if ((shaderModuleIdFlags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT) != 0)
2746             m_internalData->failOnCompileWhenLinking = true;
2747 
2748         VkPipelineCreateFlags2CreateInfoKHR pipelineFlags2CreateInfo = initVulkanStructure();
2749         if (m_internalData->pipelineFlags2)
2750         {
2751             pipelineFlags2CreateInfo.flags =
2752                 m_internalData->pipelineFlags2 | translateCreateFlag(pipelinePartCreateInfo.flags);
2753             addToChain(&firstStructInChain, &pipelineFlags2CreateInfo);
2754             pipelinePartCreateInfo.flags = 0u;
2755         }
2756 
2757         m_pipelineParts[1] = makeGraphicsPipeline(m_internalData->vk, m_internalData->device, partPipelineCache,
2758                                                   &pipelinePartCreateInfo);
2759     }
2760 #endif // CTS_USES_VULKANSC
2761 
2762     return *this;
2763 }
2764 
2765 #ifndef CTS_USES_VULKANSC
setupPreRasterizationMeshShaderState(const std::vector<VkViewport> & viewports,const std::vector<VkRect2D> & scissors,const PipelineLayoutWrapper & layout,const VkRenderPass renderPass,const uint32_t subpass,const ShaderWrapper taskShader,const ShaderWrapper meshShader,const VkPipelineRasterizationStateCreateInfo * rasterizationState,const VkSpecializationInfo * taskSpecializationInfo,const VkSpecializationInfo * meshSpecializationInfo,VkPipelineFragmentShadingRateStateCreateInfoKHR * fragmentShadingRateState,PipelineRenderingCreateInfoWrapper rendering,const VkPipelineCache partPipelineCache,VkPipelineCreationFeedbackCreateInfoEXT * partCreationFeedback)2766 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setupPreRasterizationMeshShaderState(
2767     const std::vector<VkViewport> &viewports, const std::vector<VkRect2D> &scissors,
2768     const PipelineLayoutWrapper &layout, const VkRenderPass renderPass, const uint32_t subpass,
2769     const ShaderWrapper taskShader, const ShaderWrapper meshShader,
2770     const VkPipelineRasterizationStateCreateInfo *rasterizationState,
2771     const VkSpecializationInfo *taskSpecializationInfo, const VkSpecializationInfo *meshSpecializationInfo,
2772     VkPipelineFragmentShadingRateStateCreateInfoKHR *fragmentShadingRateState,
2773     PipelineRenderingCreateInfoWrapper rendering, const VkPipelineCache partPipelineCache,
2774     VkPipelineCreationFeedbackCreateInfoEXT *partCreationFeedback)
2775 {
2776     // Make sure pipeline was not already built.
2777     DE_ASSERT(m_pipelineFinal.get() == DE_NULL);
2778 
2779     // Make sure states are set in order - this state needs to be set first or second.
2780     DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_PRE_RASTERIZATION_SHADERS));
2781 
2782     // The vertex input interface is not needed for mesh shading pipelines, so we're going to mark it as ready here.
2783     m_internalData->setupState |= (PSS_VERTEX_INPUT_INTERFACE | PSS_PRE_RASTERIZATION_SHADERS);
2784     m_internalData->pFragmentShadingRateState = fragmentShadingRateState;
2785     m_internalData->pRenderingState           = rendering;
2786 
2787     const bool hasTask         = (taskShader.isSet());
2788     const auto taskShaderCount = static_cast<uint32_t>(hasTask);
2789     const auto pRasterizationState =
2790         rasterizationState ?
2791             rasterizationState :
2792             (m_internalData->useDefaultRasterizationState ? &m_internalData->defaultRasterizationState : nullptr);
2793     const auto pTessellationState = nullptr;
2794     const auto pViewportState     = m_internalData->useViewportState ? &m_internalData->viewportState : DE_NULL;
2795 
2796     // Reserve space for all stages including fragment. This is needed when we create monolithic pipeline.
2797     m_internalData->pipelineShaderStages = std::vector<VkPipelineShaderStageCreateInfo>(
2798         2u + taskShaderCount,
2799         {
2800             VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType                        sType
2801             nullptr,                                             // const void*                            pNext
2802             0u,                                                  // VkPipelineShaderStageCreateFlags        flags
2803             VK_SHADER_STAGE_VERTEX_BIT,                          // VkShaderStageFlagBits                stage
2804             DE_NULL,                                             // VkShaderModule                        module
2805             "main",                                              // const char*                            pName
2806             nullptr, // const VkSpecializationInfo*            pSpecializationInfo
2807         });
2808 
2809     // Mesh shader.
2810     auto currStage = m_internalData->pipelineShaderStages.begin();
2811     {
2812         m_internalData->meshShader = meshShader;
2813         m_internalData->meshShader.setLayoutAndSpecialization(&layout, meshSpecializationInfo);
2814         if (!isConstructionTypeShaderObject(m_internalData->pipelineConstructionType))
2815             m_internalData->meshShader.createModule();
2816 
2817         auto &stageInfo = *currStage;
2818 
2819         stageInfo.stage               = VK_SHADER_STAGE_MESH_BIT_EXT;
2820         stageInfo.module              = m_internalData->meshShader.getModule();
2821         stageInfo.pSpecializationInfo = meshSpecializationInfo;
2822 
2823         ++currStage;
2824     }
2825 
2826     if (hasTask)
2827     {
2828         m_internalData->taskShader = taskShader;
2829         m_internalData->taskShader.setLayoutAndSpecialization(&layout, taskSpecializationInfo);
2830         if (!isConstructionTypeShaderObject(m_internalData->pipelineConstructionType))
2831             m_internalData->taskShader.createModule();
2832 
2833         auto &stageInfo = *currStage;
2834 
2835         stageInfo.stage               = VK_SHADER_STAGE_TASK_BIT_EXT;
2836         stageInfo.module              = m_internalData->taskShader.getModule();
2837         stageInfo.pSpecializationInfo = taskSpecializationInfo;
2838 
2839         ++currStage;
2840     }
2841 
2842     if (pViewportState)
2843     {
2844         if (!viewports.empty())
2845         {
2846             pViewportState->viewportCount = (uint32_t)viewports.size();
2847             pViewportState->pViewports    = &viewports[0];
2848         }
2849         if (!scissors.empty())
2850         {
2851             pViewportState->scissorCount = (uint32_t)scissors.size();
2852             pViewportState->pScissors    = &scissors[0];
2853         }
2854     }
2855 
2856     // if pipeline layout was not specified with setupMonolithicPipelineLayout
2857     // then use layout from setupPreRasterizationMeshShaderState for link pipeline
2858     if (!m_internalData->explicitLinkPipelineLayoutSet)
2859         m_internalData->monolithicPipelineCreateInfo.layout = *layout;
2860 
2861     if (!isConstructionTypeLibrary(m_internalData->pipelineConstructionType))
2862     {
2863         m_internalData->monolithicPipelineCreateInfo.renderPass          = renderPass;
2864         m_internalData->monolithicPipelineCreateInfo.subpass             = subpass;
2865         m_internalData->monolithicPipelineCreateInfo.pRasterizationState = pRasterizationState;
2866         m_internalData->monolithicPipelineCreateInfo.pViewportState      = pViewportState;
2867         m_internalData->monolithicPipelineCreateInfo.stageCount          = 1u + taskShaderCount;
2868         m_internalData->monolithicPipelineCreateInfo.pStages             = m_internalData->pipelineShaderStages.data();
2869         m_internalData->monolithicPipelineCreateInfo.pTessellationState  = pTessellationState;
2870     }
2871     else
2872     {
2873         auto libraryCreateInfo =
2874             makeGraphicsPipelineLibraryCreateInfo(VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT);
2875         void *firstStructInChain = reinterpret_cast<void *>(&libraryCreateInfo);
2876         addToChain(&firstStructInChain, m_internalData->pFragmentShadingRateState);
2877         addToChain(&firstStructInChain, m_internalData->pRenderingState.ptr);
2878         addToChain(&firstStructInChain, partCreationFeedback);
2879         addToChain(&firstStructInChain, m_internalData->pPipelineRobustnessState.ptr);
2880 
2881         VkPipelineDynamicStateCreateInfo pickedDynamicStateInfo = initVulkanStructure();
2882         std::vector<VkDynamicState> states;
2883 
2884         if (m_internalData->pDynamicState)
2885         {
2886             states = getDynamicStates(m_internalData->pDynamicState, m_internalData->setupState);
2887 
2888             pickedDynamicStateInfo.pDynamicStates    = states.data();
2889             pickedDynamicStateInfo.dynamicStateCount = static_cast<uint32_t>(states.size());
2890         }
2891 
2892         VkGraphicsPipelineCreateInfo pipelinePartCreateInfo = initVulkanStructure();
2893         pipelinePartCreateInfo.pNext                        = firstStructInChain;
2894         pipelinePartCreateInfo.flags               = m_internalData->pipelineFlags | VK_PIPELINE_CREATE_LIBRARY_BIT_KHR;
2895         pipelinePartCreateInfo.layout              = *layout;
2896         pipelinePartCreateInfo.renderPass          = renderPass;
2897         pipelinePartCreateInfo.subpass             = subpass;
2898         pipelinePartCreateInfo.pRasterizationState = pRasterizationState;
2899         pipelinePartCreateInfo.pViewportState      = pViewportState;
2900         pipelinePartCreateInfo.stageCount          = 1u + taskShaderCount;
2901         pipelinePartCreateInfo.pStages             = m_internalData->pipelineShaderStages.data();
2902         pipelinePartCreateInfo.pTessellationState  = pTessellationState;
2903         pipelinePartCreateInfo.pDynamicState       = &pickedDynamicStateInfo;
2904 
2905         if (m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_LINK_TIME_OPTIMIZED_LIBRARY)
2906             pipelinePartCreateInfo.flags |= VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
2907 
2908         VkPipelineCreateFlags2CreateInfoKHR pipelineFlags2CreateInfo = initVulkanStructure();
2909         if (m_internalData->pipelineFlags2)
2910         {
2911             pipelineFlags2CreateInfo.flags =
2912                 m_internalData->pipelineFlags2 | translateCreateFlag(pipelinePartCreateInfo.flags);
2913             addToChain(&firstStructInChain, &pipelineFlags2CreateInfo);
2914             pipelinePartCreateInfo.flags = 0u;
2915         }
2916 
2917         m_pipelineParts[1] = createGraphicsPipeline(m_internalData->vk, m_internalData->device, partPipelineCache,
2918                                                     &pipelinePartCreateInfo);
2919     }
2920 
2921     return *this;
2922 }
2923 #endif // CTS_USES_VULKANSC
2924 
setupFragmentShaderState(const PipelineLayoutWrapper & layout,const VkRenderPass renderPass,const uint32_t subpass,const ShaderWrapper fragmentShader,const VkPipelineDepthStencilStateCreateInfo * depthStencilState,const VkPipelineMultisampleStateCreateInfo * multisampleState,const VkSpecializationInfo * specializationInfo,const VkPipelineCache partPipelineCache,PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback,RenderingInputAttachmentIndexInfoWrapper renderingInputAttachmentIndexInfo)2925 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setupFragmentShaderState(
2926     const PipelineLayoutWrapper &layout, const VkRenderPass renderPass, const uint32_t subpass,
2927     const ShaderWrapper fragmentShader, const VkPipelineDepthStencilStateCreateInfo *depthStencilState,
2928     const VkPipelineMultisampleStateCreateInfo *multisampleState, const VkSpecializationInfo *specializationInfo,
2929     const VkPipelineCache partPipelineCache, PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback,
2930     RenderingInputAttachmentIndexInfoWrapper renderingInputAttachmentIndexInfo)
2931 {
2932     return setupFragmentShaderState2(layout, renderPass, subpass, fragmentShader,
2933                                      PipelineShaderStageModuleIdentifierCreateInfoWrapper(), depthStencilState,
2934                                      multisampleState, specializationInfo, partPipelineCache, partCreationFeedback,
2935                                      renderingInputAttachmentIndexInfo);
2936 }
2937 
setupFragmentShaderState2(const PipelineLayoutWrapper & layout,const VkRenderPass renderPass,const uint32_t subpass,const ShaderWrapper fragmentShader,PipelineShaderStageModuleIdentifierCreateInfoWrapper fragmentShaderModuleId,const VkPipelineDepthStencilStateCreateInfo * depthStencilState,const VkPipelineMultisampleStateCreateInfo * multisampleState,const VkSpecializationInfo * specializationInfo,const VkPipelineCache partPipelineCache,PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback,RenderingInputAttachmentIndexInfoWrapper renderingInputAttachmentIndexInfo)2938 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setupFragmentShaderState2(
2939     const PipelineLayoutWrapper &layout, const VkRenderPass renderPass, const uint32_t subpass,
2940     const ShaderWrapper fragmentShader, PipelineShaderStageModuleIdentifierCreateInfoWrapper fragmentShaderModuleId,
2941     const VkPipelineDepthStencilStateCreateInfo *depthStencilState,
2942     const VkPipelineMultisampleStateCreateInfo *multisampleState, const VkSpecializationInfo *specializationInfo,
2943     const VkPipelineCache partPipelineCache, PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback,
2944     RenderingInputAttachmentIndexInfoWrapper renderingInputAttachmentIndexInfo)
2945 {
2946     // make sure pipeline was not already build
2947     DE_ASSERT(m_pipelineFinal.get() == DE_NULL);
2948 
2949     // make sure states are set in order - no need to complicate logic to support out of order specification - this state needs to be set third
2950     DE_ASSERT(m_internalData &&
2951               (m_internalData->setupState == (PSS_VERTEX_INPUT_INTERFACE | PSS_PRE_RASTERIZATION_SHADERS)));
2952 
2953     // Unreference variables that are not used in Vulkan SC. No need to put this in ifdef.
2954     DE_UNREF(layout);
2955     DE_UNREF(renderPass);
2956     DE_UNREF(subpass);
2957     DE_UNREF(partPipelineCache);
2958     DE_UNREF(partCreationFeedback);
2959     DE_UNREF(fragmentShaderModuleId);
2960 
2961     m_internalData->setupState |= PSS_FRAGMENT_SHADER;
2962     m_internalData->pRenderingInputAttachmentIndex.ptr = renderingInputAttachmentIndexInfo.ptr;
2963 
2964     const auto pDepthStencilState =
2965         depthStencilState ? depthStencilState :
2966                             (m_internalData->useDefaultDepthStencilState ? &defaultDepthStencilState : DE_NULL);
2967     const auto pMultisampleState =
2968         multisampleState ? multisampleState :
2969                            (m_internalData->useDefaultMultisampleState ? &defaultMultisampleState : DE_NULL);
2970     const bool hasFrag = (fragmentShader.isSet() || fragmentShaderModuleId.ptr);
2971 
2972     VkPipelineCreateFlags shaderModuleIdFlags = 0u;
2973 
2974     uint32_t stageIndex = 1;
2975     if (hasFrag)
2976     {
2977         // find free space for fragment shader
2978         for (; stageIndex < 5; ++stageIndex)
2979         {
2980             if (m_internalData->pipelineShaderStages[stageIndex].stage == VK_SHADER_STAGE_VERTEX_BIT)
2981             {
2982                 m_internalData->fragmentShader = fragmentShader;
2983                 m_internalData->fragmentShader.setLayoutAndSpecialization(&layout, specializationInfo);
2984                 if (!isConstructionTypeShaderObject(m_internalData->pipelineConstructionType))
2985                     m_internalData->fragmentShader.createModule();
2986 
2987                 m_internalData->pipelineShaderStages[stageIndex].stage  = VK_SHADER_STAGE_FRAGMENT_BIT;
2988                 m_internalData->pipelineShaderStages[stageIndex].module = m_internalData->fragmentShader.getModule();
2989                 m_internalData->pipelineShaderStages[stageIndex].pSpecializationInfo = specializationInfo;
2990 #ifndef CTS_USES_VULKANSC
2991                 if (fragmentShaderModuleId.ptr)
2992                 {
2993                     m_internalData->pipelineShaderIdentifiers.emplace_back(
2994                         new PipelineShaderStageModuleIdentifierCreateInfoWrapper(fragmentShaderModuleId.ptr));
2995                     m_internalData->pipelineShaderStages[stageIndex].pNext =
2996                         m_internalData->pipelineShaderIdentifiers.back().get()->ptr;
2997 
2998                     if (!fragmentShader.isSet())
2999                         shaderModuleIdFlags |= VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT;
3000                 }
3001 #endif // CTS_USES_VULKANSC
3002                 break;
3003             }
3004         }
3005     }
3006 
3007     if (!isConstructionTypeLibrary(m_internalData->pipelineConstructionType))
3008     {
3009         m_internalData->monolithicPipelineCreateInfo.pDepthStencilState = pDepthStencilState;
3010         m_internalData->monolithicPipelineCreateInfo.pMultisampleState  = pMultisampleState;
3011         m_internalData->monolithicPipelineCreateInfo.stageCount += (hasFrag ? 1u : 0u);
3012         m_internalData->monolithicPipelineCreateInfo.flags |= shaderModuleIdFlags;
3013     }
3014 
3015 #ifndef CTS_USES_VULKANSC
3016     // note we could just use else to if statement above but sinc
3017     // this section is cut out for Vulkan SC its cleaner with separate if
3018     if (isConstructionTypeLibrary(m_internalData->pipelineConstructionType))
3019     {
3020         auto libraryCreateInfo =
3021             makeGraphicsPipelineLibraryCreateInfo(VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT);
3022         void *firstStructInChain = reinterpret_cast<void *>(&libraryCreateInfo);
3023         addToChain(&firstStructInChain, m_internalData->pFragmentShadingRateState);
3024         addToChain(&firstStructInChain, m_internalData->pRenderingState.ptr);
3025         addToChain(&firstStructInChain, m_internalData->pRenderingInputAttachmentIndex.ptr);
3026         addToChain(&firstStructInChain, partCreationFeedback.ptr);
3027         addToChain(&firstStructInChain, m_internalData->pRepresentativeFragmentTestState.ptr);
3028         addToChain(&firstStructInChain, m_internalData->pPipelineRobustnessState.ptr);
3029 
3030         VkPipelineDynamicStateCreateInfo pickedDynamicStateInfo = initVulkanStructure();
3031         std::vector<VkDynamicState> states;
3032 
3033         if (m_internalData->pDynamicState)
3034         {
3035             states = getDynamicStates(m_internalData->pDynamicState, m_internalData->setupState);
3036 
3037             pickedDynamicStateInfo.pDynamicStates    = states.data();
3038             pickedDynamicStateInfo.dynamicStateCount = static_cast<uint32_t>(states.size());
3039         }
3040 
3041         VkGraphicsPipelineCreateInfo pipelinePartCreateInfo = initVulkanStructure();
3042         pipelinePartCreateInfo.pNext                        = firstStructInChain;
3043         pipelinePartCreateInfo.flags =
3044             (m_internalData->pipelineFlags | VK_PIPELINE_CREATE_LIBRARY_BIT_KHR | shaderModuleIdFlags) &
3045             ~VK_PIPELINE_CREATE_DERIVATIVE_BIT;
3046         pipelinePartCreateInfo.layout             = *layout;
3047         pipelinePartCreateInfo.renderPass         = renderPass;
3048         pipelinePartCreateInfo.subpass            = subpass;
3049         pipelinePartCreateInfo.pDepthStencilState = pDepthStencilState;
3050         pipelinePartCreateInfo.pMultisampleState  = pMultisampleState;
3051         pipelinePartCreateInfo.stageCount         = hasFrag;
3052         pipelinePartCreateInfo.pStages       = hasFrag ? &m_internalData->pipelineShaderStages[stageIndex] : DE_NULL;
3053         pipelinePartCreateInfo.pDynamicState = &pickedDynamicStateInfo;
3054 
3055         if (m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_LINK_TIME_OPTIMIZED_LIBRARY)
3056             pipelinePartCreateInfo.flags |= VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
3057 
3058         if ((shaderModuleIdFlags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT) != 0)
3059             m_internalData->failOnCompileWhenLinking = true;
3060 
3061         VkPipelineCreateFlags2CreateInfoKHR pipelineFlags2CreateInfo = initVulkanStructure();
3062         if (m_internalData->pipelineFlags2)
3063         {
3064             pipelineFlags2CreateInfo.flags =
3065                 m_internalData->pipelineFlags2 | translateCreateFlag(pipelinePartCreateInfo.flags);
3066             addToChain(&firstStructInChain, &pipelineFlags2CreateInfo);
3067             pipelinePartCreateInfo.flags = 0u;
3068         }
3069 
3070         m_pipelineParts[2] = makeGraphicsPipeline(m_internalData->vk, m_internalData->device, partPipelineCache,
3071                                                   &pipelinePartCreateInfo);
3072     }
3073 #endif // CTS_USES_VULKANSC
3074 
3075     return *this;
3076 }
3077 
setupFragmentOutputState(const VkRenderPass renderPass,const uint32_t subpass,const VkPipelineColorBlendStateCreateInfo * colorBlendState,const VkPipelineMultisampleStateCreateInfo * multisampleState,const VkPipelineCache partPipelineCache,PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback,RenderingAttachmentLocationInfoWrapper renderingAttachmentLocationInfo)3078 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setupFragmentOutputState(
3079     const VkRenderPass renderPass, const uint32_t subpass, const VkPipelineColorBlendStateCreateInfo *colorBlendState,
3080     const VkPipelineMultisampleStateCreateInfo *multisampleState, const VkPipelineCache partPipelineCache,
3081     PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback,
3082     RenderingAttachmentLocationInfoWrapper renderingAttachmentLocationInfo)
3083 {
3084     // make sure pipeline was not already build
3085     DE_ASSERT(m_pipelineFinal.get() == DE_NULL);
3086 
3087     // make sure states are set in order - no need to complicate logic to support out of order specification - this state needs to be set last
3088     DE_ASSERT(m_internalData && (m_internalData->setupState ==
3089                                  (PSS_VERTEX_INPUT_INTERFACE | PSS_PRE_RASTERIZATION_SHADERS | PSS_FRAGMENT_SHADER)));
3090     m_internalData->setupState |= PSS_FRAGMENT_OUTPUT_INTERFACE;
3091     m_internalData->pRenderingAttachmentLocation.ptr = renderingAttachmentLocationInfo.ptr;
3092 
3093     // Unreference variables that are not used in Vulkan SC. No need to put this in ifdef.
3094     DE_UNREF(renderPass);
3095     DE_UNREF(subpass);
3096     DE_UNREF(partPipelineCache);
3097     DE_UNREF(partCreationFeedback);
3098 
3099     void *firstStructInChain = DE_NULL;
3100     addToChain(&firstStructInChain, m_internalData->pFragmentShadingRateState);
3101 
3102 #ifndef CTS_USES_VULKANSC
3103     addToChain(&firstStructInChain, m_internalData->pRenderingState.ptr);
3104 #endif // CTS_USES_VULKANSC
3105 
3106     const auto pColorBlendState = colorBlendState ?
3107                                       colorBlendState :
3108                                       (m_internalData->useDefaultColorBlendState ? &defaultColorBlendState : DE_NULL);
3109     const auto pMultisampleState =
3110         multisampleState ? multisampleState :
3111                            (m_internalData->useDefaultMultisampleState ? &defaultMultisampleState : DE_NULL);
3112 
3113     if (!isConstructionTypeLibrary(m_internalData->pipelineConstructionType))
3114     {
3115         m_internalData->monolithicPipelineCreateInfo.pNext = firstStructInChain;
3116         m_internalData->monolithicPipelineCreateInfo.flags |= m_internalData->pipelineFlags;
3117         m_internalData->monolithicPipelineCreateInfo.pColorBlendState  = pColorBlendState;
3118         m_internalData->monolithicPipelineCreateInfo.pMultisampleState = pMultisampleState;
3119     }
3120 
3121 #ifndef CTS_USES_VULKANSC
3122     // note we could just use else to if statement above but sinc
3123     // this section is cut out for Vulkan SC its cleaner with separate if
3124     if (isConstructionTypeLibrary(m_internalData->pipelineConstructionType))
3125     {
3126         auto libraryCreateInfo =
3127             makeGraphicsPipelineLibraryCreateInfo(VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT);
3128         addToChain(&firstStructInChain, &libraryCreateInfo);
3129         addToChain(&firstStructInChain, partCreationFeedback.ptr);
3130         addToChain(&firstStructInChain, m_internalData->pRenderingAttachmentLocation.ptr);
3131         addToChain(&firstStructInChain, m_internalData->pPipelineRobustnessState.ptr);
3132 
3133         VkPipelineDynamicStateCreateInfo pickedDynamicStateInfo = initVulkanStructure();
3134         std::vector<VkDynamicState> states;
3135 
3136         if (m_internalData->pDynamicState)
3137         {
3138             states = getDynamicStates(m_internalData->pDynamicState, m_internalData->setupState);
3139 
3140             pickedDynamicStateInfo.pDynamicStates    = states.data();
3141             pickedDynamicStateInfo.dynamicStateCount = static_cast<uint32_t>(states.size());
3142         }
3143 
3144         VkGraphicsPipelineCreateInfo pipelinePartCreateInfo = initVulkanStructure();
3145         pipelinePartCreateInfo.pNext                        = firstStructInChain;
3146         pipelinePartCreateInfo.flags =
3147             (m_internalData->pipelineFlags | VK_PIPELINE_CREATE_LIBRARY_BIT_KHR) & ~VK_PIPELINE_CREATE_DERIVATIVE_BIT;
3148         pipelinePartCreateInfo.renderPass        = renderPass;
3149         pipelinePartCreateInfo.subpass           = subpass;
3150         pipelinePartCreateInfo.pColorBlendState  = pColorBlendState;
3151         pipelinePartCreateInfo.pMultisampleState = pMultisampleState;
3152         pipelinePartCreateInfo.pDynamicState     = &pickedDynamicStateInfo;
3153 
3154         if (m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_LINK_TIME_OPTIMIZED_LIBRARY)
3155             pipelinePartCreateInfo.flags |= VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
3156 
3157         VkPipelineCreateFlags2CreateInfoKHR pipelineFlags2CreateInfo = initVulkanStructure();
3158         if (m_internalData->pipelineFlags2)
3159         {
3160             pipelineFlags2CreateInfo.flags =
3161                 m_internalData->pipelineFlags2 | translateCreateFlag(pipelinePartCreateInfo.flags);
3162             addToChain(&firstStructInChain, &pipelineFlags2CreateInfo);
3163             pipelinePartCreateInfo.flags = 0u;
3164         }
3165 
3166         m_pipelineParts[3] = makeGraphicsPipeline(m_internalData->vk, m_internalData->device, partPipelineCache,
3167                                                   &pipelinePartCreateInfo);
3168     }
3169 #endif // CTS_USES_VULKANSC
3170 
3171     return *this;
3172 }
3173 
3174 #ifndef CTS_USES_VULKANSC
getNextStages(vk::VkShaderStageFlagBits shaderStage,bool tessellationShaders,bool geometryShaders,bool link)3175 vk::VkShaderStageFlags GraphicsPipelineWrapper::getNextStages(vk::VkShaderStageFlagBits shaderStage,
3176                                                               bool tessellationShaders, bool geometryShaders, bool link)
3177 {
3178     if (link)
3179     {
3180         if (shaderStage == vk::VK_SHADER_STAGE_VERTEX_BIT)
3181         {
3182             if (m_internalData->tessellationControlShader.isSet())
3183                 return vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
3184             if (m_internalData->geometryShader.isSet())
3185                 return vk::VK_SHADER_STAGE_GEOMETRY_BIT;
3186             if (m_internalData->fragmentShader.isSet())
3187                 return vk::VK_SHADER_STAGE_FRAGMENT_BIT;
3188         }
3189         if (shaderStage == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
3190             return vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
3191         if (shaderStage == vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
3192         {
3193             if (m_internalData->geometryShader.isSet())
3194                 return vk::VK_SHADER_STAGE_GEOMETRY_BIT;
3195             if (m_internalData->fragmentShader.isSet())
3196                 return vk::VK_SHADER_STAGE_FRAGMENT_BIT;
3197         }
3198         if (shaderStage == vk::VK_SHADER_STAGE_GEOMETRY_BIT)
3199         {
3200             if (m_internalData->fragmentShader.isSet())
3201                 return vk::VK_SHADER_STAGE_FRAGMENT_BIT;
3202         }
3203         if (shaderStage == vk::VK_SHADER_STAGE_TASK_BIT_EXT)
3204         {
3205             if (m_internalData->meshShader.isSet())
3206                 return vk::VK_SHADER_STAGE_MESH_BIT_EXT;
3207             if (m_internalData->fragmentShader.isSet())
3208                 return vk::VK_SHADER_STAGE_FRAGMENT_BIT;
3209         }
3210         if (shaderStage == vk::VK_SHADER_STAGE_MESH_BIT_EXT)
3211         {
3212             if (m_internalData->fragmentShader.isSet())
3213                 return vk::VK_SHADER_STAGE_FRAGMENT_BIT;
3214         }
3215     }
3216     else
3217     {
3218         if (shaderStage == vk::VK_SHADER_STAGE_VERTEX_BIT)
3219         {
3220             VkShaderStageFlags flags = vk::VK_SHADER_STAGE_FRAGMENT_BIT;
3221             if (tessellationShaders)
3222                 flags |= vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
3223             if (geometryShaders)
3224                 flags |= vk::VK_SHADER_STAGE_GEOMETRY_BIT;
3225             return flags;
3226         }
3227         else if (shaderStage == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
3228         {
3229             return vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
3230         }
3231         else if (shaderStage == vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
3232         {
3233             VkShaderStageFlags flags = vk::VK_SHADER_STAGE_FRAGMENT_BIT;
3234             if (geometryShaders)
3235                 flags |= vk::VK_SHADER_STAGE_GEOMETRY_BIT;
3236             return flags;
3237         }
3238         else if (shaderStage == vk::VK_SHADER_STAGE_GEOMETRY_BIT)
3239         {
3240             return vk::VK_SHADER_STAGE_FRAGMENT_BIT;
3241         }
3242         else if (shaderStage == vk::VK_SHADER_STAGE_TASK_BIT_EXT)
3243         {
3244             return vk::VK_SHADER_STAGE_MESH_BIT_EXT;
3245         }
3246         else if (shaderStage == vk::VK_SHADER_STAGE_MESH_BIT_EXT)
3247         {
3248             return vk::VK_SHADER_STAGE_FRAGMENT_BIT;
3249         }
3250     }
3251     return 0;
3252 }
3253 
makeShaderCreateInfo(VkShaderStageFlagBits stage,ShaderWrapper & shader,bool link,bool binary,ShaderWrapper & other)3254 vk::VkShaderCreateInfoEXT GraphicsPipelineWrapper::makeShaderCreateInfo(VkShaderStageFlagBits stage,
3255                                                                         ShaderWrapper &shader, bool link, bool binary,
3256                                                                         ShaderWrapper &other)
3257 {
3258     if (binary)
3259         shader.getShaderBinary();
3260 
3261     vk::VkShaderCreateInfoEXT shaderCreateInfo = vk::initVulkanStructure();
3262     shaderCreateInfo.flags =
3263         link ? (vk::VkShaderCreateFlagsEXT)vk::VK_SHADER_CREATE_LINK_STAGE_BIT_EXT : (vk::VkShaderCreateFlagsEXT)0u;
3264     shaderCreateInfo.stage = stage;
3265     shaderCreateInfo.nextStage =
3266         getNextStages(stage, m_internalData->tessellationShaderFeature, m_internalData->geometryShaderFeature, link);
3267     if (binary)
3268     {
3269         shaderCreateInfo.codeType = vk::VK_SHADER_CODE_TYPE_BINARY_EXT;
3270         shaderCreateInfo.codeSize = shader.getShaderBinaryDataSize();
3271         shaderCreateInfo.pCode    = shader.getShaderBinaryData();
3272     }
3273     else
3274     {
3275         shaderCreateInfo.codeType = vk::VK_SHADER_CODE_TYPE_SPIRV_EXT;
3276         shaderCreateInfo.codeSize = shader.getCodeSize();
3277         shaderCreateInfo.pCode    = shader.getBinary();
3278     }
3279     shaderCreateInfo.pName = "main";
3280     if (shader.getPipelineLayout() != DE_NULL)
3281     {
3282         shaderCreateInfo.setLayoutCount         = shader.getPipelineLayout()->getSetLayoutCount();
3283         shaderCreateInfo.pSetLayouts            = shader.getPipelineLayout()->getSetLayouts();
3284         shaderCreateInfo.pushConstantRangeCount = shader.getPipelineLayout()->getPushConstantRangeCount();
3285         shaderCreateInfo.pPushConstantRanges    = shader.getPipelineLayout()->getPushConstantRanges();
3286     }
3287     // Pipeline layouts and push constant ranges must match between shaders that are used together
3288     if (other.isSet() && shaderCreateInfo.setLayoutCount == 0)
3289     {
3290         shaderCreateInfo.setLayoutCount = other.getPipelineLayout()->getSetLayoutCount();
3291         shaderCreateInfo.pSetLayouts    = other.getPipelineLayout()->getSetLayouts();
3292     }
3293     if (other.isSet() && shaderCreateInfo.pushConstantRangeCount == 0)
3294     {
3295         shaderCreateInfo.pushConstantRangeCount = other.getPipelineLayout()->getPushConstantRangeCount();
3296         shaderCreateInfo.pPushConstantRanges    = other.getPipelineLayout()->getPushConstantRanges();
3297     }
3298     shaderCreateInfo.pSpecializationInfo = shader.getSpecializationInfo();
3299     return shaderCreateInfo;
3300 }
3301 
createShaders(bool linked,bool binary)3302 void GraphicsPipelineWrapper::createShaders(bool linked, bool binary)
3303 {
3304     std::vector<vk::VkShaderCreateInfoEXT> createInfos;
3305     if (m_internalData->vertexShader.isSet())
3306         createInfos.push_back(makeShaderCreateInfo(vk::VK_SHADER_STAGE_VERTEX_BIT, m_internalData->vertexShader, linked,
3307                                                    binary, m_internalData->fragmentShader));
3308     if (m_internalData->tessellationControlShader.isSet())
3309         createInfos.push_back(makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
3310                                                    m_internalData->tessellationControlShader, linked, binary,
3311                                                    m_internalData->fragmentShader));
3312     if (m_internalData->tessellationEvaluationShader.isSet())
3313         createInfos.push_back(makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
3314                                                    m_internalData->tessellationEvaluationShader, linked, binary,
3315                                                    m_internalData->fragmentShader));
3316     if (m_internalData->geometryShader.isSet())
3317         createInfos.push_back(makeShaderCreateInfo(vk::VK_SHADER_STAGE_GEOMETRY_BIT, m_internalData->geometryShader,
3318                                                    linked, binary, m_internalData->fragmentShader));
3319     if (m_internalData->fragmentShader.isSet())
3320         createInfos.push_back(makeShaderCreateInfo(vk::VK_SHADER_STAGE_FRAGMENT_BIT, m_internalData->fragmentShader,
3321                                                    linked, binary, m_internalData->vertexShader));
3322     if (m_internalData->taskShader.isSet())
3323         createInfos.push_back(makeShaderCreateInfo(vk::VK_SHADER_STAGE_TASK_BIT_EXT, m_internalData->taskShader, linked,
3324                                                    binary, m_internalData->fragmentShader));
3325     if (m_internalData->meshShader.isSet())
3326     {
3327         createInfos.push_back(makeShaderCreateInfo(vk::VK_SHADER_STAGE_MESH_BIT_EXT, m_internalData->meshShader, linked,
3328                                                    binary, m_internalData->fragmentShader));
3329         if (!m_internalData->taskShader.isSet())
3330             createInfos.back().flags |= vk::VK_SHADER_CREATE_NO_TASK_SHADER_BIT_EXT;
3331     }
3332 
3333     std::vector<VkShaderEXT> shaders(createInfos.size());
3334     m_internalData->vk.createShadersEXT(m_internalData->device, (uint32_t)createInfos.size(), createInfos.data(),
3335                                         DE_NULL, shaders.data());
3336     uint32_t shaderIndex = 0;
3337     if (m_internalData->vertexShader.isSet())
3338         m_internalData->vertexShader.setShader(
3339             Move<VkShaderEXT>(check<VkShaderEXT>(shaders[shaderIndex++]),
3340                               Deleter<VkShaderEXT>(m_internalData->vk, m_internalData->device, DE_NULL)));
3341     if (m_internalData->tessellationControlShader.isSet())
3342         m_internalData->tessellationControlShader.setShader(
3343             Move<VkShaderEXT>(check<VkShaderEXT>(shaders[shaderIndex++]),
3344                               Deleter<VkShaderEXT>(m_internalData->vk, m_internalData->device, DE_NULL)));
3345     if (m_internalData->tessellationEvaluationShader.isSet())
3346         m_internalData->tessellationEvaluationShader.setShader(
3347             Move<VkShaderEXT>(check<VkShaderEXT>(shaders[shaderIndex++]),
3348                               Deleter<VkShaderEXT>(m_internalData->vk, m_internalData->device, DE_NULL)));
3349     if (m_internalData->geometryShader.isSet())
3350         m_internalData->geometryShader.setShader(
3351             Move<VkShaderEXT>(check<VkShaderEXT>(shaders[shaderIndex++]),
3352                               Deleter<VkShaderEXT>(m_internalData->vk, m_internalData->device, DE_NULL)));
3353     if (m_internalData->fragmentShader.isSet())
3354         m_internalData->fragmentShader.setShader(
3355             Move<VkShaderEXT>(check<VkShaderEXT>(shaders[shaderIndex++]),
3356                               Deleter<VkShaderEXT>(m_internalData->vk, m_internalData->device, DE_NULL)));
3357     if (m_internalData->taskShader.isSet())
3358         m_internalData->taskShader.setShader(
3359             Move<VkShaderEXT>(check<VkShaderEXT>(shaders[shaderIndex++]),
3360                               Deleter<VkShaderEXT>(m_internalData->vk, m_internalData->device, DE_NULL)));
3361     if (m_internalData->meshShader.isSet())
3362         m_internalData->meshShader.setShader(
3363             Move<VkShaderEXT>(check<VkShaderEXT>(shaders[shaderIndex++]),
3364                               Deleter<VkShaderEXT>(m_internalData->vk, m_internalData->device, DE_NULL)));
3365 }
3366 #endif
3367 
buildPipeline(const VkPipelineCache pipelineCache,const VkPipeline basePipelineHandle,const int32_t basePipelineIndex,PipelineCreationFeedbackCreateInfoWrapper creationFeedback)3368 void GraphicsPipelineWrapper::buildPipeline(const VkPipelineCache pipelineCache, const VkPipeline basePipelineHandle,
3369                                             const int32_t basePipelineIndex,
3370                                             PipelineCreationFeedbackCreateInfoWrapper creationFeedback)
3371 {
3372     // make sure we are not trying to build pipeline second time
3373     DE_ASSERT(m_pipelineFinal.get() == DE_NULL);
3374 
3375     // make sure all states were set
3376     DE_ASSERT(m_internalData &&
3377               (m_internalData->setupState == (PSS_VERTEX_INPUT_INTERFACE | PSS_PRE_RASTERIZATION_SHADERS |
3378                                               PSS_FRAGMENT_SHADER | PSS_FRAGMENT_OUTPUT_INTERFACE)));
3379 
3380     // Unreference variables that are not used in Vulkan SC. No need to put this in ifdef.
3381     DE_UNREF(creationFeedback);
3382 
3383     VkGraphicsPipelineCreateInfo *pointerToCreateInfo = &m_internalData->monolithicPipelineCreateInfo;
3384 
3385     if (isConstructionTypeShaderObject(m_internalData->pipelineConstructionType))
3386     {
3387 #ifndef CTS_USES_VULKANSC
3388         // Dynamic states that don't require additional extensions
3389         std::vector<vk::VkDynamicState> dynamicStates = {
3390             vk::VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT,
3391             vk::VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT,
3392             vk::VK_DYNAMIC_STATE_LINE_WIDTH,
3393             vk::VK_DYNAMIC_STATE_DEPTH_BIAS,
3394             vk::VK_DYNAMIC_STATE_BLEND_CONSTANTS,
3395             vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS,
3396             vk::VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
3397             vk::VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
3398             vk::VK_DYNAMIC_STATE_STENCIL_REFERENCE,
3399             vk::VK_DYNAMIC_STATE_CULL_MODE_EXT,
3400             vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT,
3401             vk::VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT,
3402             vk::VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT,
3403             vk::VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT,
3404             vk::VK_DYNAMIC_STATE_FRONT_FACE_EXT,
3405             vk::VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT,
3406             vk::VK_DYNAMIC_STATE_STENCIL_OP_EXT,
3407             vk::VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT,
3408             vk::VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT,
3409             vk::VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT,
3410             vk::VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT,
3411             vk::VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT,
3412             vk::VK_DYNAMIC_STATE_LOGIC_OP_EXT,
3413             vk::VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT,
3414             vk::VK_DYNAMIC_STATE_TESSELLATION_DOMAIN_ORIGIN_EXT,
3415             vk::VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT,
3416             vk::VK_DYNAMIC_STATE_POLYGON_MODE_EXT,
3417             vk::VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT,
3418             vk::VK_DYNAMIC_STATE_SAMPLE_MASK_EXT,
3419             vk::VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT,
3420             vk::VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT,
3421             vk::VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT,
3422             vk::VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT,
3423             vk::VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT,
3424             vk::VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT,
3425             vk::VK_DYNAMIC_STATE_VERTEX_INPUT_EXT,
3426         };
3427 
3428         vk::VkPhysicalDeviceMeshShaderFeaturesEXT meshShaderFeatures = initVulkanStructure();
3429         vk::VkPhysicalDeviceFeatures2 features                       = initVulkanStructure(&meshShaderFeatures);
3430         m_internalData->vki.getPhysicalDeviceFeatures2(m_internalData->physicalDevice, &features);
3431 
3432         m_internalData->tessellationShaderFeature = features.features.tessellationShader;
3433         m_internalData->geometryShaderFeature     = features.features.geometryShader;
3434         m_internalData->taskShaderFeature         = meshShaderFeatures.taskShader;
3435         m_internalData->meshShaderFeature         = meshShaderFeatures.meshShader;
3436 
3437         DE_ASSERT(m_internalData->extensionEnabled("VK_EXT_shader_object"));
3438 
3439         // Add dynamic states that are required for each enabled extension
3440         if (m_internalData->extensionEnabled("VK_EXT_transform_feedback"))
3441             dynamicStates.push_back(vk::VK_DYNAMIC_STATE_RASTERIZATION_STREAM_EXT);
3442         if (m_internalData->extensionEnabled("VK_EXT_blend_operation_advanced"))
3443             dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_BLEND_ADVANCED_EXT);
3444         if (m_internalData->extensionEnabled("VK_EXT_conservative_rasterization"))
3445             dynamicStates.push_back(vk::VK_DYNAMIC_STATE_CONSERVATIVE_RASTERIZATION_MODE_EXT);
3446         if (m_internalData->extensionEnabled("VK_NV_framebuffer_mixed_samples"))
3447             dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_MODULATION_MODE_NV);
3448         if (m_internalData->extensionEnabled("VK_NV_framebuffer_mixed_samples"))
3449             dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_ENABLE_NV);
3450         if (m_internalData->extensionEnabled("VK_NV_framebuffer_mixed_samples"))
3451             dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_NV);
3452         if (m_internalData->extensionEnabled("VK_NV_coverage_reduction_mode"))
3453             dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_REDUCTION_MODE_NV);
3454         if (m_internalData->extensionEnabled("VK_NV_fragment_coverage_to_color"))
3455             dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_ENABLE_NV);
3456         if (m_internalData->extensionEnabled("VK_NV_fragment_coverage_to_color"))
3457             dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_LOCATION_NV);
3458         if (m_internalData->extensionEnabled("VK_EXT_depth_clip_enable"))
3459             dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT);
3460         if (m_internalData->extensionEnabled("VK_EXT_depth_clip_control"))
3461             dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT);
3462         if (m_internalData->extensionEnabled("VK_EXT_color_write_enable"))
3463             dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT);
3464         if (m_internalData->extensionEnabled("VK_EXT_conservative_rasterization"))
3465             dynamicStates.push_back(vk::VK_DYNAMIC_STATE_EXTRA_PRIMITIVE_OVERESTIMATION_SIZE_EXT);
3466         if (m_internalData->extensionEnabled("VK_KHR_line_rasterization") ||
3467             m_internalData->extensionEnabled("VK_EXT_line_rasterization"))
3468             dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT);
3469         if (m_internalData->extensionEnabled("VK_KHR_line_rasterization") ||
3470             m_internalData->extensionEnabled("VK_EXT_line_rasterization"))
3471             dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT);
3472         if (m_internalData->extensionEnabled("VK_KHR_line_rasterization") ||
3473             m_internalData->extensionEnabled("VK_EXT_line_rasterization"))
3474             dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LINE_STIPPLE_KHR);
3475         if (m_internalData->extensionEnabled("VK_EXT_provoking_vertex"))
3476             dynamicStates.push_back(vk::VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT);
3477         if (m_internalData->extensionEnabled("VK_KHR_fragment_shading_rate"))
3478             dynamicStates.push_back(vk::VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR);
3479         if (m_internalData->extensionEnabled("VK_NV_representative_fragment_test"))
3480             dynamicStates.push_back(vk::VK_DYNAMIC_STATE_REPRESENTATIVE_FRAGMENT_TEST_ENABLE_NV);
3481         if (m_internalData->extensionEnabled("VK_EXT_sample_locations"))
3482             dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_ENABLE_EXT);
3483         if (m_internalData->extensionEnabled("VK_EXT_sample_locations"))
3484             dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT);
3485         // Not working with VK_KHR_fragment_shading_rate
3486         /*if (m_internalData->extensionEnabled("VK_NV_shading_rate_image"))
3487             dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SHADING_RATE_IMAGE_ENABLE_NV);
3488         if (m_internalData->extensionEnabled("VK_NV_shading_rate_image"))
3489             dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV);
3490         if (m_internalData->extensionEnabled("VK_NV_shading_rate_image"))
3491             dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV);*/
3492         if (m_internalData->extensionEnabled("VK_NV_viewport_swizzle"))
3493             dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_SWIZZLE_NV);
3494         if (m_internalData->extensionEnabled("VK_NV_clip_space_w_scaling"))
3495             dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_ENABLE_NV);
3496         if (m_internalData->extensionEnabled("VK_NV_clip_space_w_scaling"))
3497             dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV);
3498         if (m_internalData->extensionEnabled("VK_NV_scissor_exclusive"))
3499             dynamicStates.push_back(vk::VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_ENABLE_NV);
3500         if (m_internalData->extensionEnabled("VK_NV_scissor_exclusive"))
3501             dynamicStates.push_back(vk::VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV);
3502         if (m_internalData->extensionEnabled("VK_EXT_discard_rectangles"))
3503             dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_ENABLE_EXT);
3504         if (m_internalData->extensionEnabled("VK_EXT_discard_rectangles"))
3505             dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT);
3506         if (m_internalData->extensionEnabled("VK_EXT_discard_rectangles"))
3507             dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_MODE_EXT);
3508         if (m_internalData->extensionEnabled("VK_EXT_attachment_feedback_loop_dynamic_state"))
3509             dynamicStates.push_back(vk::VK_DYNAMIC_STATE_ATTACHMENT_FEEDBACK_LOOP_ENABLE_EXT);
3510 
3511         // Remove dynamic states that were already set as dynamic for the pipeline
3512         // These dynamic state will already be set in the tests
3513         bool depthClampEnableDynamic = false;
3514         if (pointerToCreateInfo->pDynamicState)
3515         {
3516             for (uint32_t i = 0; i < pointerToCreateInfo->pDynamicState->dynamicStateCount; ++i)
3517             {
3518                 if (pointerToCreateInfo->pDynamicState->pDynamicStates[i] == vk::VK_DYNAMIC_STATE_VIEWPORT)
3519                     dynamicStates.erase(std::remove(dynamicStates.begin(), dynamicStates.end(),
3520                                                     vk::VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT),
3521                                         dynamicStates.end());
3522                 else if (pointerToCreateInfo->pDynamicState->pDynamicStates[i] == vk::VK_DYNAMIC_STATE_SCISSOR)
3523                     dynamicStates.erase(std::remove(dynamicStates.begin(), dynamicStates.end(),
3524                                                     vk::VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT),
3525                                         dynamicStates.end());
3526                 else if (pointerToCreateInfo->pDynamicState->pDynamicStates[i] ==
3527                          vk::VK_DYNAMIC_STATE_COLOR_BLEND_ADVANCED_EXT)
3528                 {
3529                     dynamicStates.erase(std::remove(dynamicStates.begin(), dynamicStates.end(),
3530                                                     vk::VK_DYNAMIC_STATE_COLOR_BLEND_ADVANCED_EXT),
3531                                         dynamicStates.end());
3532                     dynamicStates.erase(std::remove(dynamicStates.begin(), dynamicStates.end(),
3533                                                     vk::VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT),
3534                                         dynamicStates.end());
3535                 }
3536                 else if (pointerToCreateInfo->pDynamicState->pDynamicStates[i] == vk::VK_DYNAMIC_STATE_VERTEX_INPUT_EXT)
3537                 {
3538                     dynamicStates.erase(
3539                         std::remove(dynamicStates.begin(), dynamicStates.end(), vk::VK_DYNAMIC_STATE_VERTEX_INPUT_EXT),
3540                         dynamicStates.end());
3541                     dynamicStates.erase(std::remove(dynamicStates.begin(), dynamicStates.end(),
3542                                                     vk::VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT),
3543                                         dynamicStates.end());
3544                 }
3545                 else
3546                     dynamicStates.erase(std::remove(dynamicStates.begin(), dynamicStates.end(),
3547                                                     pointerToCreateInfo->pDynamicState->pDynamicStates[i]),
3548                                         dynamicStates.end());
3549 
3550                 if (pointerToCreateInfo->pDynamicState->pDynamicStates[i] ==
3551                     vk::VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT)
3552                     depthClampEnableDynamic = true;
3553             }
3554         }
3555 
3556         m_internalData->shaderObjectDynamicStates = dynamicStates;
3557 
3558         // Save state needed for setting shader object dynamic state
3559         auto state = &m_internalData->pipelineCreateState;
3560         if (pointerToCreateInfo->pViewportState)
3561         {
3562             if (pointerToCreateInfo->pViewportState->pViewports)
3563             {
3564                 state->viewports.resize(pointerToCreateInfo->pViewportState->viewportCount);
3565                 for (uint32_t i = 0; i < pointerToCreateInfo->pViewportState->viewportCount; ++i)
3566                     state->viewports[i] = pointerToCreateInfo->pViewportState->pViewports[i];
3567             }
3568 
3569             if (pointerToCreateInfo->pViewportState->pScissors)
3570             {
3571                 state->scissors.resize(pointerToCreateInfo->pViewportState->scissorCount);
3572                 for (uint32_t i = 0; i < pointerToCreateInfo->pViewportState->scissorCount; ++i)
3573                     state->scissors[i] = pointerToCreateInfo->pViewportState->pScissors[i];
3574             }
3575 
3576             const auto depthClipControl = findStructure<VkPipelineViewportDepthClipControlCreateInfoEXT>(
3577                 pointerToCreateInfo->pViewportState->pNext);
3578             if (depthClipControl)
3579                 state->negativeOneToOne = depthClipControl->negativeOneToOne;
3580             const auto viewportShadingRate = findStructure<VkPipelineViewportShadingRateImageStateCreateInfoNV>(
3581                 pointerToCreateInfo->pViewportState->pNext);
3582             if (viewportShadingRate)
3583             {
3584                 state->shadingRateImageEnable  = viewportShadingRate->shadingRateImageEnable;
3585                 state->shadingRatePaletteCount = viewportShadingRate->viewportCount;
3586                 state->shadingRatePalettes.resize(viewportShadingRate->viewportCount);
3587                 state->shadingRatePaletteEntries.resize(viewportShadingRate->viewportCount);
3588                 for (uint32_t i = 0; i < viewportShadingRate->viewportCount; ++i)
3589                 {
3590                     state->shadingRatePalettes[i] = viewportShadingRate->pShadingRatePalettes[i];
3591                     state->shadingRatePaletteEntries[i].resize(
3592                         viewportShadingRate->pShadingRatePalettes[i].shadingRatePaletteEntryCount);
3593                     for (uint32_t j = 0; j < viewportShadingRate->pShadingRatePalettes[i].shadingRatePaletteEntryCount;
3594                          ++j)
3595                         state->shadingRatePaletteEntries[i][j] =
3596                             viewportShadingRate->pShadingRatePalettes[i].pShadingRatePaletteEntries[j];
3597                     state->shadingRatePalettes[i].pShadingRatePaletteEntries =
3598                         state->shadingRatePaletteEntries[i].data();
3599                 }
3600             }
3601             const auto viewportSwizzle =
3602                 findStructure<VkPipelineViewportSwizzleStateCreateInfoNV>(pointerToCreateInfo->pViewportState->pNext);
3603             if (viewportSwizzle)
3604             {
3605                 state->viewportSwizzles.resize(viewportSwizzle->viewportCount);
3606                 for (uint32_t i = 0; i < viewportSwizzle->viewportCount; ++i)
3607                     state->viewportSwizzles[i] = viewportSwizzle->pViewportSwizzles[i];
3608             }
3609             const auto viewportWScaling =
3610                 findStructure<VkPipelineViewportWScalingStateCreateInfoNV>(pointerToCreateInfo->pViewportState->pNext);
3611             if (viewportWScaling)
3612             {
3613                 state->viewportWScalingEnable = viewportWScaling->viewportWScalingEnable;
3614                 state->viewportWScalingCount  = viewportWScaling->viewportCount;
3615                 state->viewportWScalings.resize(viewportWScaling->viewportCount);
3616                 for (uint32_t i = 0; i < viewportWScaling->viewportCount; ++i)
3617                     state->viewportWScalings[i] = viewportWScaling->pViewportWScalings[i];
3618             }
3619             const auto coarseSampleOrder = findStructure<VkPipelineViewportCoarseSampleOrderStateCreateInfoNV>(
3620                 pointerToCreateInfo->pViewportState->pNext);
3621             if (coarseSampleOrder)
3622             {
3623                 state->coarseSampleOrderType        = coarseSampleOrder->sampleOrderType;
3624                 state->coarseCustomSampleOrderCount = coarseSampleOrder->customSampleOrderCount;
3625                 state->coarseCustomSampleOrders.resize(coarseSampleOrder->customSampleOrderCount);
3626                 state->coarseSampleLocations.resize(coarseSampleOrder->customSampleOrderCount);
3627                 for (uint32_t i = 0; i < coarseSampleOrder->customSampleOrderCount; ++i)
3628                 {
3629                     state->coarseCustomSampleOrders[i] = coarseSampleOrder->pCustomSampleOrders[i];
3630                     state->coarseSampleLocations[i].resize(coarseSampleOrder->pCustomSampleOrders[i].sampleCount);
3631                     for (uint32_t j = 0; j < coarseSampleOrder->pCustomSampleOrders[i].sampleCount; ++j)
3632                         state->coarseSampleLocations[i][j] =
3633                             coarseSampleOrder->pCustomSampleOrders[i].pSampleLocations[j];
3634                     state->coarseCustomSampleOrders[i].pSampleLocations = state->coarseSampleLocations[i].data();
3635                 }
3636             }
3637         }
3638 
3639         if (pointerToCreateInfo->pRasterizationState)
3640         {
3641             state->lineWidth               = pointerToCreateInfo->pRasterizationState->lineWidth;
3642             state->depthBiasConstantFactor = pointerToCreateInfo->pRasterizationState->depthBiasConstantFactor;
3643             state->depthBiasClamp          = pointerToCreateInfo->pRasterizationState->depthBiasClamp;
3644             state->depthBiasSlopeFactor    = pointerToCreateInfo->pRasterizationState->depthBiasSlopeFactor;
3645             state->cullMode                = pointerToCreateInfo->pRasterizationState->cullMode;
3646             state->frontFace               = pointerToCreateInfo->pRasterizationState->frontFace;
3647             state->depthBiasEnable         = pointerToCreateInfo->pRasterizationState->depthBiasEnable;
3648             state->rasterizerDiscardEnable = pointerToCreateInfo->pRasterizationState->rasterizerDiscardEnable;
3649             const auto conservative        = findStructure<VkPipelineRasterizationConservativeStateCreateInfoEXT>(
3650                 pointerToCreateInfo->pRasterizationState->pNext);
3651             if (conservative)
3652             {
3653                 state->conservativeRasterizationMode    = conservative->conservativeRasterizationMode;
3654                 state->extraPrimitiveOverestimationSize = conservative->extraPrimitiveOverestimationSize;
3655             }
3656             state->depthClampEnable = pointerToCreateInfo->pRasterizationState->depthClampEnable;
3657             const auto depthClip    = findStructure<VkPipelineRasterizationDepthClipStateCreateInfoEXT>(
3658                 pointerToCreateInfo->pRasterizationState->pNext);
3659             if (depthClip)
3660                 state->depthClipEnable = depthClip->depthClipEnable;
3661             else
3662                 state->depthClipEnable =
3663                     !pointerToCreateInfo->pRasterizationState->depthClampEnable && !depthClampEnableDynamic;
3664 
3665             const auto rasterizationLine = findStructure<VkPipelineRasterizationLineStateCreateInfoEXT>(
3666                 pointerToCreateInfo->pRasterizationState->pNext);
3667             if (rasterizationLine)
3668             {
3669                 state->lineRasterizationMode = rasterizationLine->lineRasterizationMode;
3670                 state->stippledLineEnable    = rasterizationLine->stippledLineEnable;
3671                 state->lineStippleFactor     = rasterizationLine->lineStippleFactor;
3672                 state->lineStipplePattern    = rasterizationLine->lineStipplePattern;
3673             }
3674             const auto rasterizationStream = findStructure<VkPipelineRasterizationStateStreamCreateInfoEXT>(
3675                 pointerToCreateInfo->pRasterizationState->pNext);
3676             if (rasterizationStream)
3677                 state->rasterizationStream = rasterizationStream->rasterizationStream;
3678             state->polygonMode         = pointerToCreateInfo->pRasterizationState->polygonMode;
3679             const auto provokingVertex = findStructure<VkPipelineRasterizationProvokingVertexStateCreateInfoEXT>(
3680                 pointerToCreateInfo->pRasterizationState->pNext);
3681             if (provokingVertex)
3682                 state->provokingVertexMode = provokingVertex->provokingVertexMode;
3683             const auto depthBiasRepresentationInfo =
3684                 findStructure<VkDepthBiasRepresentationInfoEXT>(pointerToCreateInfo->pRasterizationState->pNext);
3685             if (depthBiasRepresentationInfo)
3686             {
3687                 state->depthBiasRepresentation = depthBiasRepresentationInfo->depthBiasRepresentation;
3688                 state->depthBiasExact          = depthBiasRepresentationInfo->depthBiasExact;
3689             }
3690         }
3691         if (pointerToCreateInfo->pColorBlendState)
3692         {
3693             memcpy(&state->blendConstants, pointerToCreateInfo->pColorBlendState->blendConstants, sizeof(float) * 4);
3694             state->logicOp                = pointerToCreateInfo->pColorBlendState->logicOp;
3695             const auto blendAdvancedState = findStructure<VkPipelineColorBlendAdvancedStateCreateInfoEXT>(
3696                 pointerToCreateInfo->pColorBlendState->pNext);
3697             if (blendAdvancedState)
3698             {
3699                 state->colorBlendAdvanced.resize(pointerToCreateInfo->pColorBlendState->attachmentCount);
3700                 for (uint32_t i = 0; i < pointerToCreateInfo->pColorBlendState->attachmentCount; ++i)
3701                 {
3702                     if (pointerToCreateInfo->pColorBlendState->pAttachments)
3703                         state->colorBlendAdvanced[i].advancedBlendOp =
3704                             pointerToCreateInfo->pColorBlendState->pAttachments[i].colorBlendOp;
3705                     state->colorBlendAdvanced[i].srcPremultiplied = blendAdvancedState->srcPremultiplied;
3706                     state->colorBlendAdvanced[i].dstPremultiplied = blendAdvancedState->dstPremultiplied;
3707                     state->colorBlendAdvanced[i].blendOverlap     = blendAdvancedState->blendOverlap;
3708                     state->colorBlendAdvanced[i].clampResults     = VK_FALSE;
3709                 }
3710             }
3711             state->colorBlendEnables.resize(pointerToCreateInfo->pColorBlendState->attachmentCount);
3712             state->blendEquations.resize(pointerToCreateInfo->pColorBlendState->attachmentCount);
3713             state->colorWriteMasks.resize(pointerToCreateInfo->pColorBlendState->attachmentCount);
3714             for (uint32_t i = 0; i < (uint32_t)pointerToCreateInfo->pColorBlendState->attachmentCount; ++i)
3715             {
3716                 if (pointerToCreateInfo->pColorBlendState->pAttachments)
3717                 {
3718                     state->colorBlendEnables[i] = pointerToCreateInfo->pColorBlendState->pAttachments[i].blendEnable;
3719                     state->blendEquations[i].srcColorBlendFactor =
3720                         pointerToCreateInfo->pColorBlendState->pAttachments[i].srcColorBlendFactor;
3721                     state->blendEquations[i].dstColorBlendFactor =
3722                         pointerToCreateInfo->pColorBlendState->pAttachments[i].dstColorBlendFactor;
3723                     state->blendEquations[i].colorBlendOp =
3724                         pointerToCreateInfo->pColorBlendState->pAttachments[i].colorBlendOp;
3725                     state->blendEquations[i].srcAlphaBlendFactor =
3726                         pointerToCreateInfo->pColorBlendState->pAttachments[i].srcAlphaBlendFactor;
3727                     state->blendEquations[i].dstAlphaBlendFactor =
3728                         pointerToCreateInfo->pColorBlendState->pAttachments[i].dstAlphaBlendFactor;
3729                     state->blendEquations[i].alphaBlendOp =
3730                         pointerToCreateInfo->pColorBlendState->pAttachments[i].alphaBlendOp;
3731                     state->colorWriteMasks[i] = pointerToCreateInfo->pColorBlendState->pAttachments[i].colorWriteMask;
3732                 }
3733 
3734                 // colorBlendOp and alphaBlendOp must not be advanced blend operations and they will be set with colorBlendAdvanced
3735                 if (blendAdvancedState)
3736                 {
3737                     state->blendEquations[i].colorBlendOp = vk::VK_BLEND_OP_ADD;
3738                     state->blendEquations[i].alphaBlendOp = vk::VK_BLEND_OP_ADD;
3739                 }
3740             }
3741             state->logicOpEnable = pointerToCreateInfo->pColorBlendState->logicOpEnable;
3742             const auto colorWrite =
3743                 findStructure<VkPipelineColorWriteCreateInfoEXT>(pointerToCreateInfo->pColorBlendState->pNext);
3744             if (colorWrite)
3745             {
3746                 state->colorWriteEnableAttachmentCount = colorWrite->attachmentCount;
3747                 state->colorWriteEnables.resize(colorWrite->attachmentCount);
3748                 for (uint32_t i = 0; i < colorWrite->attachmentCount; ++i)
3749                     state->colorWriteEnables[i] = colorWrite->pColorWriteEnables[i];
3750             }
3751         }
3752         if (pointerToCreateInfo->pDepthStencilState)
3753         {
3754             state->minDepthBounds        = pointerToCreateInfo->pDepthStencilState->minDepthBounds;
3755             state->maxDepthBounds        = pointerToCreateInfo->pDepthStencilState->maxDepthBounds;
3756             state->stencilFront          = pointerToCreateInfo->pDepthStencilState->front;
3757             state->stencilBack           = pointerToCreateInfo->pDepthStencilState->back;
3758             state->depthBoundsTestEnable = pointerToCreateInfo->pDepthStencilState->depthBoundsTestEnable;
3759             state->depthCompareOp        = pointerToCreateInfo->pDepthStencilState->depthCompareOp;
3760             state->depthTestEnable       = pointerToCreateInfo->pDepthStencilState->depthTestEnable;
3761             state->depthWriteEnable      = pointerToCreateInfo->pDepthStencilState->depthWriteEnable;
3762             state->stencilTestEnable     = pointerToCreateInfo->pDepthStencilState->stencilTestEnable;
3763         }
3764         if (pointerToCreateInfo->pInputAssemblyState)
3765         {
3766             state->topology               = pointerToCreateInfo->pInputAssemblyState->topology;
3767             state->primitiveRestartEnable = pointerToCreateInfo->pInputAssemblyState->primitiveRestartEnable;
3768         }
3769         if (pointerToCreateInfo->pVertexInputState)
3770         {
3771             state->attributes.resize(pointerToCreateInfo->pVertexInputState->vertexAttributeDescriptionCount);
3772             state->bindings.resize(pointerToCreateInfo->pVertexInputState->vertexBindingDescriptionCount);
3773             for (uint32_t i = 0; i < pointerToCreateInfo->pVertexInputState->vertexAttributeDescriptionCount; ++i)
3774             {
3775                 state->attributes[i] = initVulkanStructure();
3776                 state->attributes[i].location =
3777                     pointerToCreateInfo->pVertexInputState->pVertexAttributeDescriptions[i].location;
3778                 state->attributes[i].binding =
3779                     pointerToCreateInfo->pVertexInputState->pVertexAttributeDescriptions[i].binding;
3780                 state->attributes[i].format =
3781                     pointerToCreateInfo->pVertexInputState->pVertexAttributeDescriptions[i].format;
3782                 state->attributes[i].offset =
3783                     pointerToCreateInfo->pVertexInputState->pVertexAttributeDescriptions[i].offset;
3784             }
3785 
3786             const auto divisorInfo = findStructure<VkPipelineVertexInputDivisorStateCreateInfoEXT>(
3787                 pointerToCreateInfo->pVertexInputState->pNext);
3788 
3789             for (uint32_t i = 0; i < pointerToCreateInfo->pVertexInputState->vertexBindingDescriptionCount; ++i)
3790             {
3791                 state->bindings[i] = initVulkanStructure();
3792                 state->bindings[i].binding =
3793                     pointerToCreateInfo->pVertexInputState->pVertexBindingDescriptions[i].binding;
3794                 state->bindings[i].stride =
3795                     pointerToCreateInfo->pVertexInputState->pVertexBindingDescriptions[i].stride;
3796                 state->bindings[i].inputRate =
3797                     pointerToCreateInfo->pVertexInputState->pVertexBindingDescriptions[i].inputRate;
3798                 state->bindings[i].divisor = 1;
3799                 if (divisorInfo)
3800                 {
3801                     for (uint32_t j = 0; j < divisorInfo->vertexBindingDivisorCount; ++j)
3802                     {
3803                         if (state->bindings[i].binding == divisorInfo->pVertexBindingDivisors[j].binding)
3804                         {
3805                             state->bindings[i].divisor = divisorInfo->pVertexBindingDivisors[i].divisor;
3806                         }
3807                     }
3808                 }
3809             }
3810         }
3811         if (pointerToCreateInfo->pTessellationState)
3812         {
3813             state->patchControlPoints           = pointerToCreateInfo->pTessellationState->patchControlPoints;
3814             const auto tessellationDomainOrigin = findStructure<VkPipelineTessellationDomainOriginStateCreateInfo>(
3815                 pointerToCreateInfo->pTessellationState->pNext);
3816             if (tessellationDomainOrigin)
3817                 state->domainOrigin = tessellationDomainOrigin->domainOrigin;
3818         }
3819         if (pointerToCreateInfo->pMultisampleState)
3820         {
3821             state->alphaToCoverageEnable  = pointerToCreateInfo->pMultisampleState->alphaToCoverageEnable;
3822             state->alphaToOneEnable       = pointerToCreateInfo->pMultisampleState->alphaToOneEnable;
3823             const auto coverageModulation = findStructure<VkPipelineCoverageModulationStateCreateInfoNV>(
3824                 pointerToCreateInfo->pMultisampleState->pNext);
3825             if (coverageModulation)
3826             {
3827                 state->coverageModulationMode        = coverageModulation->coverageModulationMode;
3828                 state->coverageModulationTableEnable = coverageModulation->coverageModulationTableEnable;
3829                 state->coverageModulationTable.resize(coverageModulation->coverageModulationTableCount);
3830                 for (uint32_t i = 0; i < (uint32_t)coverageModulation->coverageModulationTableCount; ++i)
3831                     state->coverageModulationTable[i] = coverageModulation->pCoverageModulationTable[i];
3832             }
3833             const auto coverageReduction = findStructure<VkPipelineCoverageReductionStateCreateInfoNV>(
3834                 pointerToCreateInfo->pMultisampleState->pNext);
3835             if (coverageReduction)
3836                 state->coverageReductionMode = coverageReduction->coverageReductionMode;
3837             const auto coverageToColor = findStructure<VkPipelineCoverageToColorStateCreateInfoNV>(
3838                 pointerToCreateInfo->pMultisampleState->pNext);
3839             if (coverageToColor)
3840             {
3841                 state->coverageToColorEnable   = coverageToColor->coverageToColorEnable;
3842                 state->coverageToColorLocation = coverageToColor->coverageToColorLocation;
3843             }
3844             state->rasterizationSamples = pointerToCreateInfo->pMultisampleState->rasterizationSamples;
3845             const auto sampleLocations  = findStructure<VkPipelineSampleLocationsStateCreateInfoEXT>(
3846                 pointerToCreateInfo->pMultisampleState->pNext);
3847             if (sampleLocations)
3848             {
3849                 state->sampleLocationsEnable = sampleLocations->sampleLocationsEnable;
3850                 state->sampleLocationsInfo   = sampleLocations->sampleLocationsInfo;
3851                 state->pSampleLocations.resize(sampleLocations->sampleLocationsInfo.sampleLocationsCount);
3852                 for (uint32_t i = 0; i < sampleLocations->sampleLocationsInfo.sampleLocationsCount; ++i)
3853                     state->pSampleLocations[i] = sampleLocations->sampleLocationsInfo.pSampleLocations[i];
3854                 state->sampleLocationsInfo.pSampleLocations = state->pSampleLocations.data();
3855             }
3856             state->rasterizationSamples = pointerToCreateInfo->pMultisampleState->rasterizationSamples;
3857             uint32_t count =
3858                 (pointerToCreateInfo->pMultisampleState->rasterizationSamples > vk::VK_SAMPLE_COUNT_32_BIT) ? 2 : 1;
3859             state->sampleMasks.resize(count, 0);
3860             for (uint32_t i = 0; i < count; ++i)
3861                 if (pointerToCreateInfo->pMultisampleState->pSampleMask)
3862                     state->sampleMasks[i] = pointerToCreateInfo->pMultisampleState->pSampleMask[i];
3863                 else
3864                     state->sampleMasks[i] =
3865                         0xFF; // If pSampleMask is NULL, it is treated as if the mask has all bits set to 1
3866         }
3867         const auto representativeFragment =
3868             findStructure<VkPipelineRepresentativeFragmentTestStateCreateInfoNV>(pointerToCreateInfo->pNext);
3869         if (representativeFragment)
3870         {
3871             state->representativeFragmentTestEnable = representativeFragment->representativeFragmentTestEnable;
3872         }
3873         const auto fragmentShadingRate =
3874             findStructure<VkPipelineFragmentShadingRateStateCreateInfoKHR>(pointerToCreateInfo->pNext);
3875         if (fragmentShadingRate)
3876         {
3877             state->fragmentShadingRateSize = fragmentShadingRate->fragmentSize;
3878             state->combinerOps[0]          = fragmentShadingRate->combinerOps[0];
3879             state->combinerOps[1]          = fragmentShadingRate->combinerOps[1];
3880         }
3881         const auto exclusiveScissor =
3882             findStructure<VkPipelineViewportExclusiveScissorStateCreateInfoNV>(pointerToCreateInfo->pNext);
3883         if (exclusiveScissor)
3884         {
3885             state->exclusiveScissorCount = exclusiveScissor->exclusiveScissorCount;
3886             state->exclussiveScissors.resize(exclusiveScissor->exclusiveScissorCount);
3887             for (uint32_t i = 0; i < exclusiveScissor->exclusiveScissorCount; ++i)
3888                 state->exclussiveScissors[i] = exclusiveScissor->pExclusiveScissors[i];
3889         }
3890         const auto discardRectangle =
3891             findStructure<VkPipelineDiscardRectangleStateCreateInfoEXT>(pointerToCreateInfo->pNext);
3892         if (discardRectangle)
3893         {
3894             state->discardRectangleEnable = discardRectangle->discardRectangleCount > 0;
3895             state->discardRectangles.resize(discardRectangle->discardRectangleCount);
3896             for (uint32_t i = 0; i < discardRectangle->discardRectangleCount; ++i)
3897                 state->discardRectangles[i] = discardRectangle->pDiscardRectangles[i];
3898             state->discardRectangleMode = discardRectangle->discardRectangleMode;
3899         }
3900         if (pointerToCreateInfo->flags & VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT)
3901             state->attachmentFeedbackLoopEnable |= VK_IMAGE_ASPECT_COLOR_BIT;
3902         if (pointerToCreateInfo->flags & VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT)
3903             state->attachmentFeedbackLoopEnable |= VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
3904 
3905         bool linked =
3906             m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_SHADER_OBJECT_LINKED_SPIRV ||
3907             m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_SHADER_OBJECT_LINKED_BINARY;
3908         bool binary =
3909             m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_SHADER_OBJECT_UNLINKED_BINARY ||
3910             m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_SHADER_OBJECT_LINKED_BINARY;
3911         createShaders(linked, false);
3912         if (binary)
3913         {
3914             createShaders(linked, true);
3915         }
3916 #endif
3917     }
3918     else
3919     {
3920 #ifndef CTS_USES_VULKANSC
3921         VkGraphicsPipelineCreateInfo linkedCreateInfo = initVulkanStructure();
3922         std::vector<VkPipeline> rawPipelines;
3923         VkPipelineLibraryCreateInfoKHR linkingInfo{
3924             VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR, // VkStructureType sType;
3925             creationFeedback.ptr,                               // const void* pNext;
3926             0u,                                                 // uint32_t libraryCount;
3927             nullptr,                                            // const VkPipeline* pLibraries;
3928         };
3929 
3930         if (isConstructionTypeLibrary(m_internalData->pipelineConstructionType))
3931         {
3932             for (const auto &pipelinePtr : m_pipelineParts)
3933             {
3934                 const auto &pipeline = pipelinePtr.get();
3935                 if (pipeline != DE_NULL)
3936                     rawPipelines.push_back(pipeline);
3937             }
3938 
3939             linkingInfo.libraryCount = static_cast<uint32_t>(rawPipelines.size());
3940             linkingInfo.pLibraries   = de::dataOrNull(rawPipelines);
3941 
3942             // If a test hits the following assert, it's likely missing a call
3943             // to the setMonolithicPipelineLayout() method. Related VUs:
3944             //   * VUID-VkGraphicsPipelineCreateInfo-flags-06642
3945             //   * VUID-VkGraphicsPipelineCreateInfo-None-07826
3946             //   * VUID-VkGraphicsPipelineCreateInfo-layout-07827
3947             //   * VUID-VkGraphicsPipelineCreateInfo-flags-06729
3948             //   * VUID-VkGraphicsPipelineCreateInfo-flags-06730
3949             DE_ASSERT(m_internalData->monolithicPipelineCreateInfo.layout != VK_NULL_HANDLE);
3950             linkedCreateInfo.layout = m_internalData->monolithicPipelineCreateInfo.layout;
3951             linkedCreateInfo.flags  = m_internalData->pipelineFlags;
3952             linkedCreateInfo.pNext  = &linkingInfo;
3953 
3954             pointerToCreateInfo = &linkedCreateInfo;
3955 
3956             if (m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_LINK_TIME_OPTIMIZED_LIBRARY)
3957                 linkedCreateInfo.flags |= VK_PIPELINE_CREATE_LINK_TIME_OPTIMIZATION_BIT_EXT;
3958 
3959             if (m_internalData->failOnCompileWhenLinking)
3960                 linkedCreateInfo.flags |= VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT;
3961         }
3962         else
3963         {
3964             // note: there might be other structures in the chain already
3965             void *firstStructInChain = static_cast<void *>(pointerToCreateInfo);
3966             addToChain(&firstStructInChain, creationFeedback.ptr);
3967             addToChain(&firstStructInChain, m_internalData->pRepresentativeFragmentTestState.ptr);
3968             addToChain(&firstStructInChain, m_internalData->pRenderingInputAttachmentIndex.ptr);
3969             addToChain(&firstStructInChain, m_internalData->pRenderingAttachmentLocation.ptr);
3970             addToChain(&firstStructInChain, m_internalData->pPipelineRobustnessState.ptr);
3971         }
3972 
3973         VkPipelineCreateFlags2CreateInfoKHR pipelineFlags2CreateInfo = initVulkanStructure();
3974         if (m_internalData->pipelineFlags2)
3975         {
3976             void *firstStructInChain = static_cast<void *>(pointerToCreateInfo);
3977             pipelineFlags2CreateInfo.flags =
3978                 m_internalData->pipelineFlags2 | translateCreateFlag(pointerToCreateInfo->flags);
3979             addToChain(&firstStructInChain, &pipelineFlags2CreateInfo);
3980             pointerToCreateInfo->flags = 0u;
3981         }
3982 #endif // CTS_USES_VULKANSC
3983 
3984         pointerToCreateInfo->basePipelineHandle = basePipelineHandle;
3985         pointerToCreateInfo->basePipelineIndex  = basePipelineIndex;
3986 
3987         m_pipelineFinal =
3988             makeGraphicsPipeline(m_internalData->vk, m_internalData->device, pipelineCache, pointerToCreateInfo);
3989     }
3990 }
3991 
isShaderObjectDynamic(vk::VkDynamicState dynamicState) const3992 bool GraphicsPipelineWrapper::isShaderObjectDynamic(vk::VkDynamicState dynamicState) const
3993 {
3994     return std::find(m_internalData->shaderObjectDynamicStates.begin(), m_internalData->shaderObjectDynamicStates.end(),
3995                      dynamicState) != m_internalData->shaderObjectDynamicStates.end();
3996 }
3997 
setShaderObjectDynamicStates(vk::VkCommandBuffer cmdBuffer) const3998 void GraphicsPipelineWrapper::setShaderObjectDynamicStates(vk::VkCommandBuffer cmdBuffer) const
3999 {
4000     DE_UNREF(cmdBuffer);
4001 #ifndef CTS_USES_VULKANSC
4002     const auto &vk   = m_internalData->vk;
4003     const auto state = &m_internalData->pipelineCreateState;
4004 
4005     // Some dynamic state only need to be set when these conditions are met
4006     const bool meshOrTask        = m_internalData->meshShader.isSet() || m_internalData->taskShader.isSet();
4007     const bool tese              = m_internalData->tessellationEvaluationShader.isSet();
4008     const bool topologyPatchList = !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY) ||
4009                                    state->topology == VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
4010     const bool rasterizerDiscardDisabled =
4011         !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE) || !state->rasterizerDiscardEnable;
4012     const bool polygonModeLine =
4013         !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_POLYGON_MODE_EXT) || state->polygonMode == vk::VK_POLYGON_MODE_LINE;
4014     const bool topologyLine = !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY) ||
4015                               state->topology == vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST ||
4016                               state->topology == vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY ||
4017                               state->topology == vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP ||
4018                               state->topology == vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY;
4019     const bool depthTestEnabled =
4020         !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE) || state->depthTestEnable;
4021     const bool depthBoundsTestEnabled =
4022         !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE) || state->depthBoundsTestEnable;
4023     const bool depthBiasEnabled =
4024         !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE) || state->depthBiasEnable;
4025     const bool stencilTestEnabled =
4026         !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE) || state->stencilTestEnable;
4027     const bool logicOpEnabled =
4028         !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT) || state->logicOpEnable;
4029     const bool discardRectangle =
4030         !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_ENABLE_EXT) || state->discardRectangleEnable;
4031     const bool sampleLocationsEnabled =
4032         !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_ENABLE_EXT) || state->sampleLocationsEnable;
4033     const bool stippledLineEnabled =
4034         !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT) || state->stippledLineEnable;
4035     bool blendFactorConstant = !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT);
4036     for (const auto &blend : state->blendEquations)
4037     {
4038         if (blend.srcColorBlendFactor == vk::VK_BLEND_FACTOR_CONSTANT_COLOR ||
4039             blend.srcColorBlendFactor == vk::VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR ||
4040             blend.srcColorBlendFactor == vk::VK_BLEND_FACTOR_CONSTANT_ALPHA ||
4041             blend.srcColorBlendFactor == vk::VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA ||
4042             blend.dstColorBlendFactor == vk::VK_BLEND_FACTOR_CONSTANT_COLOR ||
4043             blend.dstColorBlendFactor == vk::VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR ||
4044             blend.dstColorBlendFactor == vk::VK_BLEND_FACTOR_CONSTANT_ALPHA ||
4045             blend.dstColorBlendFactor == vk::VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA ||
4046             blend.srcAlphaBlendFactor == vk::VK_BLEND_FACTOR_CONSTANT_COLOR ||
4047             blend.srcAlphaBlendFactor == vk::VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR ||
4048             blend.srcAlphaBlendFactor == vk::VK_BLEND_FACTOR_CONSTANT_ALPHA ||
4049             blend.srcAlphaBlendFactor == vk::VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA ||
4050             blend.dstAlphaBlendFactor == vk::VK_BLEND_FACTOR_CONSTANT_COLOR ||
4051             blend.dstAlphaBlendFactor == vk::VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR ||
4052             blend.dstAlphaBlendFactor == vk::VK_BLEND_FACTOR_CONSTANT_ALPHA ||
4053             blend.dstAlphaBlendFactor == vk::VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA)
4054 
4055             blendFactorConstant = true;
4056     }
4057 
4058     for (const auto dynamicState : m_internalData->shaderObjectDynamicStates)
4059     {
4060         switch (dynamicState)
4061         {
4062         case vk::VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT:
4063             if (!state->viewports.empty())
4064                 vk.cmdSetViewportWithCount(cmdBuffer, (uint32_t)state->viewports.size(), state->viewports.data());
4065             break;
4066         case vk::VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT:
4067             if (!state->scissors.empty())
4068                 vk.cmdSetScissorWithCount(cmdBuffer, (uint32_t)state->scissors.size(), state->scissors.data());
4069             break;
4070         case vk::VK_DYNAMIC_STATE_LINE_WIDTH:
4071             if (polygonModeLine || topologyLine)
4072                 vk.cmdSetLineWidth(cmdBuffer, state->lineWidth);
4073             break;
4074         case vk::VK_DYNAMIC_STATE_DEPTH_BIAS:
4075             if (rasterizerDiscardDisabled && depthBiasEnabled)
4076             {
4077                 if (m_internalData->extensionEnabled("VK_EXT_depth_bias_control"))
4078                 {
4079                     VkDepthBiasRepresentationInfoEXT depthBiasRepresentationInfo = vk::initVulkanStructure();
4080                     depthBiasRepresentationInfo.depthBiasRepresentation          = state->depthBiasRepresentation;
4081                     depthBiasRepresentationInfo.depthBiasExact                   = state->depthBiasExact;
4082 
4083                     vk::VkDepthBiasInfoEXT depthBiasInfo  = vk::initVulkanStructure(&depthBiasRepresentationInfo);
4084                     depthBiasInfo.depthBiasConstantFactor = state->depthBiasConstantFactor;
4085                     depthBiasInfo.depthBiasClamp          = state->depthBiasClamp;
4086                     depthBiasInfo.depthBiasSlopeFactor    = state->depthBiasSlopeFactor;
4087                     vk.cmdSetDepthBias2EXT(cmdBuffer, &depthBiasInfo);
4088                 }
4089                 else
4090                 {
4091                     vk.cmdSetDepthBias(cmdBuffer, state->depthBiasConstantFactor, state->depthBiasClamp,
4092                                        state->depthBiasSlopeFactor);
4093                 }
4094             }
4095             break;
4096         case vk::VK_DYNAMIC_STATE_BLEND_CONSTANTS:
4097             if (rasterizerDiscardDisabled && blendFactorConstant)
4098                 vk.cmdSetBlendConstants(cmdBuffer, state->blendConstants);
4099             break;
4100         case vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS:
4101             if (rasterizerDiscardDisabled && depthBoundsTestEnabled)
4102                 vk.cmdSetDepthBounds(cmdBuffer, state->minDepthBounds, state->maxDepthBounds);
4103             break;
4104         case vk::VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK:
4105         {
4106             vk.cmdSetStencilCompareMask(cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, state->stencilFront.compareMask);
4107             vk.cmdSetStencilCompareMask(cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, state->stencilBack.compareMask);
4108         }
4109         break;
4110         case vk::VK_DYNAMIC_STATE_STENCIL_WRITE_MASK:
4111         {
4112             vk.cmdSetStencilWriteMask(cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, state->stencilFront.writeMask);
4113             vk.cmdSetStencilWriteMask(cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, state->stencilBack.writeMask);
4114         }
4115         break;
4116         case vk::VK_DYNAMIC_STATE_STENCIL_REFERENCE:
4117         {
4118             vk.cmdSetStencilReference(cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, state->stencilFront.reference);
4119             vk.cmdSetStencilReference(cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, state->stencilBack.reference);
4120         }
4121         break;
4122         case vk::VK_DYNAMIC_STATE_CULL_MODE_EXT:
4123             vk.cmdSetCullMode(cmdBuffer, state->cullMode);
4124             break;
4125         case vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT:
4126             if (rasterizerDiscardDisabled)
4127                 vk.cmdSetDepthBoundsTestEnable(cmdBuffer, state->depthBoundsTestEnable);
4128             break;
4129         case vk::VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT:
4130             if (rasterizerDiscardDisabled && depthTestEnabled)
4131                 vk.cmdSetDepthCompareOp(cmdBuffer, state->depthCompareOp);
4132             break;
4133         case vk::VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT:
4134             if (rasterizerDiscardDisabled)
4135                 vk.cmdSetDepthTestEnable(cmdBuffer, state->depthTestEnable);
4136             break;
4137         case vk::VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT:
4138             if (rasterizerDiscardDisabled)
4139                 vk.cmdSetDepthWriteEnable(cmdBuffer, state->depthWriteEnable);
4140             break;
4141         case vk::VK_DYNAMIC_STATE_FRONT_FACE_EXT:
4142             vk.cmdSetFrontFace(cmdBuffer, state->frontFace);
4143             break;
4144         case vk::VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT:
4145             if (!meshOrTask)
4146                 vk.cmdSetPrimitiveTopology(cmdBuffer, state->topology);
4147             break;
4148         case vk::VK_DYNAMIC_STATE_STENCIL_OP_EXT:
4149             if (rasterizerDiscardDisabled && stencilTestEnabled)
4150             {
4151                 vk.cmdSetStencilOp(cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, state->stencilFront.failOp,
4152                                    state->stencilFront.passOp, state->stencilFront.depthFailOp,
4153                                    state->stencilFront.compareOp);
4154                 vk.cmdSetStencilOp(cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, state->stencilBack.failOp,
4155                                    state->stencilBack.passOp, state->stencilBack.depthFailOp,
4156                                    state->stencilBack.compareOp);
4157             }
4158             break;
4159         case vk::VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT:
4160             if (rasterizerDiscardDisabled)
4161                 vk.cmdSetStencilTestEnable(cmdBuffer, state->stencilTestEnable);
4162             break;
4163         case vk::VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT:
4164             if (!meshOrTask)
4165                 vk.cmdSetVertexInputEXT(cmdBuffer, (uint32_t)state->bindings.size(), state->bindings.data(),
4166                                         (uint32_t)state->attributes.size(), state->attributes.data());
4167             break;
4168         case vk::VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT:
4169             if (rasterizerDiscardDisabled)
4170                 vk.cmdSetDepthBiasEnable(cmdBuffer, state->depthBiasEnable);
4171             break;
4172         case vk::VK_DYNAMIC_STATE_LOGIC_OP_EXT:
4173             if (rasterizerDiscardDisabled && logicOpEnabled)
4174                 vk.cmdSetLogicOpEXT(cmdBuffer, state->logicOp);
4175             break;
4176         case vk::VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT:
4177             if (topologyPatchList && !meshOrTask && tese)
4178                 vk.cmdSetPatchControlPointsEXT(cmdBuffer, state->patchControlPoints);
4179             break;
4180         case vk::VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT:
4181             if (!meshOrTask)
4182                 vk.cmdSetPrimitiveRestartEnable(cmdBuffer, state->primitiveRestartEnable);
4183             break;
4184         case vk::VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT:
4185             vk.cmdSetRasterizerDiscardEnable(cmdBuffer, state->rasterizerDiscardEnable);
4186             break;
4187         case vk::VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT:
4188             vk.cmdSetAlphaToCoverageEnableEXT(cmdBuffer, state->alphaToCoverageEnable);
4189             break;
4190         case vk::VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT:
4191             vk.cmdSetAlphaToOneEnableEXT(cmdBuffer, state->alphaToOneEnable);
4192             break;
4193         case vk::VK_DYNAMIC_STATE_COLOR_BLEND_ADVANCED_EXT:
4194             if (!state->colorBlendAdvanced.empty())
4195             {
4196                 for (uint32_t i = 0; i < (uint32_t)state->colorBlendAdvanced.size(); ++i)
4197                     if (!isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT) ||
4198                         state->colorBlendEnables[i])
4199                         vk.cmdSetColorBlendAdvancedEXT(cmdBuffer, i, 1, &state->colorBlendAdvanced[i]);
4200             }
4201             break;
4202         case vk::VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT:
4203             if (rasterizerDiscardDisabled)
4204             {
4205                 if (!state->colorBlendEnables.empty())
4206                 {
4207                     vk.cmdSetColorBlendEnableEXT(cmdBuffer, 0, (uint32_t)state->colorBlendEnables.size(),
4208                                                  state->colorBlendEnables.data());
4209                 }
4210                 else
4211                 {
4212                     VkBool32 disable = VK_FALSE;
4213                     vk.cmdSetColorBlendEnableEXT(cmdBuffer, 0, 1u, &disable);
4214                 }
4215             }
4216             break;
4217         case vk::VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT:
4218             if (rasterizerDiscardDisabled)
4219             {
4220                 if (!state->blendEquations.empty())
4221                 {
4222                     vk.cmdSetColorBlendEquationEXT(cmdBuffer, 0, (uint32_t)state->blendEquations.size(),
4223                                                    state->blendEquations.data());
4224                 }
4225                 else
4226                 {
4227                     vk::VkColorBlendEquationEXT blendEquation = {
4228                         VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcColorBlendFactor;
4229                         VK_BLEND_FACTOR_DST_ALPHA, // VkBlendFactor dstColorBlendFactor;
4230                         VK_BLEND_OP_ADD,           // VkBlendOp colorBlendOp;
4231                         VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcAlphaBlendFactor;
4232                         VK_BLEND_FACTOR_DST_ALPHA, // VkBlendFactor dstAlphaBlendFactor;
4233                         VK_BLEND_OP_ADD,           // VkBlendOp alphaBlendOp;
4234                     };
4235                     vk.cmdSetColorBlendEquationEXT(cmdBuffer, 0, 1u, &blendEquation);
4236                 }
4237             }
4238             break;
4239         case vk::VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT:
4240             if (rasterizerDiscardDisabled)
4241             {
4242                 if (!state->colorWriteMasks.empty())
4243                 {
4244                     vk.cmdSetColorWriteMaskEXT(cmdBuffer, 0, (uint32_t)state->colorWriteMasks.size(),
4245                                                state->colorWriteMasks.data());
4246                 }
4247                 else
4248                 {
4249                     VkColorComponentFlags colorWriteMask = 0u;
4250                     vk.cmdSetColorWriteMaskEXT(cmdBuffer, 0, 1u, &colorWriteMask);
4251                 }
4252             }
4253             break;
4254         case vk::VK_DYNAMIC_STATE_CONSERVATIVE_RASTERIZATION_MODE_EXT:
4255             vk.cmdSetConservativeRasterizationModeEXT(cmdBuffer, state->conservativeRasterizationMode);
4256             break;
4257         case vk::VK_DYNAMIC_STATE_COVERAGE_MODULATION_MODE_NV:
4258             vk.cmdSetCoverageModulationModeNV(cmdBuffer, state->coverageModulationMode);
4259             break;
4260         case vk::VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_ENABLE_NV:
4261             vk.cmdSetCoverageModulationTableEnableNV(cmdBuffer, state->coverageModulationTableEnable);
4262             break;
4263         case vk::VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_NV:
4264             if (!state->coverageModulationTable.empty())
4265                 vk.cmdSetCoverageModulationTableNV(cmdBuffer, (uint32_t)state->coverageModulationTable.size(),
4266                                                    state->coverageModulationTable.data());
4267             break;
4268         case vk::VK_DYNAMIC_STATE_COVERAGE_REDUCTION_MODE_NV:
4269             vk.cmdSetCoverageReductionModeNV(cmdBuffer, state->coverageReductionMode);
4270             break;
4271         case vk::VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_ENABLE_NV:
4272             vk.cmdSetCoverageToColorEnableNV(cmdBuffer, state->coverageToColorEnable);
4273             break;
4274         case vk::VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_LOCATION_NV:
4275             vk.cmdSetCoverageToColorLocationNV(cmdBuffer, state->coverageToColorLocation);
4276             break;
4277         case vk::VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT:
4278             if (rasterizerDiscardDisabled)
4279                 vk.cmdSetDepthClampEnableEXT(cmdBuffer, state->depthClampEnable);
4280             break;
4281         case vk::VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT:
4282             vk.cmdSetDepthClipEnableEXT(cmdBuffer, state->depthClipEnable);
4283             break;
4284         case vk::VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT:
4285             vk.cmdSetDepthClipNegativeOneToOneEXT(cmdBuffer, state->negativeOneToOne);
4286             break;
4287         case vk::VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT:
4288             if (state->colorWriteEnableAttachmentCount > 0)
4289                 vk.cmdSetColorWriteEnableEXT(cmdBuffer, state->colorWriteEnableAttachmentCount,
4290                                              state->colorWriteEnables.data());
4291             else
4292             {
4293                 std::vector<VkBool32> enable(state->colorBlendEnables.empty() ? 1u : state->colorBlendEnables.size(),
4294                                              VK_TRUE);
4295                 vk.cmdSetColorWriteEnableEXT(cmdBuffer, (uint32_t)enable.size(), enable.data());
4296             }
4297             break;
4298         case vk::VK_DYNAMIC_STATE_EXTRA_PRIMITIVE_OVERESTIMATION_SIZE_EXT:
4299             vk.cmdSetExtraPrimitiveOverestimationSizeEXT(cmdBuffer, state->extraPrimitiveOverestimationSize);
4300             break;
4301         case vk::VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT:
4302             vk.cmdSetLineRasterizationModeEXT(cmdBuffer, state->lineRasterizationMode);
4303             break;
4304         case vk::VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT:
4305             vk.cmdSetLineStippleEnableEXT(cmdBuffer, state->stippledLineEnable);
4306             break;
4307         case vk::VK_DYNAMIC_STATE_LINE_STIPPLE_EXT:
4308             if (stippledLineEnabled)
4309                 vk.cmdSetLineStippleKHR(cmdBuffer, state->lineStippleFactor, state->lineStipplePattern);
4310             break;
4311         case vk::VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT:
4312             if (rasterizerDiscardDisabled)
4313                 vk.cmdSetLogicOpEnableEXT(cmdBuffer, state->logicOpEnable);
4314             break;
4315         case vk::VK_DYNAMIC_STATE_POLYGON_MODE_EXT:
4316             vk.cmdSetPolygonModeEXT(cmdBuffer, state->polygonMode);
4317             break;
4318         case vk::VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT:
4319             vk.cmdSetProvokingVertexModeEXT(cmdBuffer, state->provokingVertexMode);
4320             break;
4321         case vk::VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT:
4322             vk.cmdSetRasterizationSamplesEXT(cmdBuffer, state->rasterizationSamples);
4323             break;
4324         case vk::VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR:
4325             vk.cmdSetFragmentShadingRateKHR(cmdBuffer, &state->fragmentShadingRateSize, state->combinerOps);
4326             break;
4327         case vk::VK_DYNAMIC_STATE_RASTERIZATION_STREAM_EXT:
4328             vk.cmdSetRasterizationStreamEXT(cmdBuffer, state->rasterizationStream);
4329             break;
4330         case vk::VK_DYNAMIC_STATE_REPRESENTATIVE_FRAGMENT_TEST_ENABLE_NV:
4331             vk.cmdSetRepresentativeFragmentTestEnableNV(cmdBuffer, state->representativeFragmentTestEnable);
4332             break;
4333         case vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_ENABLE_EXT:
4334             vk.cmdSetSampleLocationsEnableEXT(cmdBuffer, state->sampleLocationsEnable);
4335             break;
4336         case vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT:
4337             if (sampleLocationsEnabled)
4338                 vk.cmdSetSampleLocationsEXT(cmdBuffer, &state->sampleLocationsInfo);
4339             break;
4340         case vk::VK_DYNAMIC_STATE_SAMPLE_MASK_EXT:
4341             if (!state->sampleMasks.empty())
4342                 vk.cmdSetSampleMaskEXT(cmdBuffer, state->rasterizationSamples, state->sampleMasks.data());
4343             break;
4344         case vk::VK_DYNAMIC_STATE_SHADING_RATE_IMAGE_ENABLE_NV:
4345             vk.cmdSetShadingRateImageEnableNV(cmdBuffer, state->shadingRateImageEnable);
4346             break;
4347         case vk::VK_DYNAMIC_STATE_TESSELLATION_DOMAIN_ORIGIN_EXT:
4348             if (tese)
4349                 vk.cmdSetTessellationDomainOriginEXT(cmdBuffer, state->domainOrigin);
4350             break;
4351         case vk::VK_DYNAMIC_STATE_VIEWPORT_SWIZZLE_NV:
4352             if (!state->viewportSwizzles.empty())
4353             {
4354                 vk.cmdSetViewportSwizzleNV(cmdBuffer, 0, (uint32_t)state->viewportSwizzles.size(),
4355                                            state->viewportSwizzles.data());
4356             }
4357             else
4358             {
4359                 std::vector<vk::VkViewportSwizzleNV> idSwizzles(4u);
4360                 for (auto &swizzle : idSwizzles)
4361                 {
4362                     swizzle = {
4363                         vk::VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NV,
4364                         vk::VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Y_NV,
4365                         vk::VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Z_NV,
4366                         vk::VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_W_NV,
4367                     };
4368                 }
4369                 vk.cmdSetViewportSwizzleNV(cmdBuffer, 0u, (uint32_t)idSwizzles.size(), idSwizzles.data());
4370             }
4371             break;
4372         case vk::VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_ENABLE_NV:
4373             vk.cmdSetViewportWScalingEnableNV(cmdBuffer, state->viewportWScalingEnable);
4374             break;
4375         case vk::VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV:
4376             if (state->viewportWScalingCount > 0)
4377                 vk.cmdSetViewportWScalingNV(cmdBuffer, 0, state->viewportWScalingCount,
4378                                             state->viewportWScalings.data());
4379             break;
4380         case vk::VK_DYNAMIC_STATE_VERTEX_INPUT_EXT:
4381             if (!meshOrTask)
4382                 vk.cmdSetVertexInputEXT(cmdBuffer, (uint32_t)state->bindings.size(), state->bindings.data(),
4383                                         (uint32_t)state->attributes.size(), state->attributes.data());
4384             break;
4385         case vk::VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV:
4386             vk.cmdSetCoarseSampleOrderNV(cmdBuffer, state->coarseSampleOrderType, state->coarseCustomSampleOrderCount,
4387                                          state->coarseCustomSampleOrders.data());
4388             break;
4389         case vk::VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV:
4390             if (state->shadingRatePaletteCount > 0)
4391                 vk.cmdSetViewportShadingRatePaletteNV(cmdBuffer, 0, state->shadingRatePaletteCount,
4392                                                       state->shadingRatePalettes.data());
4393             break;
4394         case vk::VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_ENABLE_NV:
4395         {
4396             if (state->exclusiveScissorCount > 0)
4397             {
4398                 std::vector<VkBool32> exclusiveScissorEnable(state->exclusiveScissorCount, VK_TRUE);
4399                 vk.cmdSetExclusiveScissorEnableNV(cmdBuffer, 0u, state->exclusiveScissorCount,
4400                                                   exclusiveScissorEnable.data());
4401             }
4402             else
4403             {
4404                 VkBool32 enable = VK_FALSE;
4405                 vk.cmdSetExclusiveScissorEnableNV(cmdBuffer, 0u, 1u, &enable);
4406             }
4407             break;
4408         }
4409         case vk::VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV:
4410             if (state->exclusiveScissorCount > 0)
4411                 vk.cmdSetExclusiveScissorNV(cmdBuffer, 0u, state->exclusiveScissorCount,
4412                                             state->exclussiveScissors.data());
4413             break;
4414         case vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_ENABLE_EXT:
4415             vk.cmdSetDiscardRectangleEnableEXT(cmdBuffer, state->discardRectangleEnable);
4416             break;
4417         case vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT:
4418             if (discardRectangle)
4419                 vk.cmdSetDiscardRectangleEXT(cmdBuffer, 0, (uint32_t)state->discardRectangles.size(),
4420                                              state->discardRectangles.data());
4421             break;
4422         case vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_MODE_EXT:
4423             if (discardRectangle)
4424                 vk.cmdSetDiscardRectangleModeEXT(cmdBuffer, state->discardRectangleMode);
4425             break;
4426         case vk::VK_DYNAMIC_STATE_ATTACHMENT_FEEDBACK_LOOP_ENABLE_EXT:
4427             vk.cmdSetAttachmentFeedbackLoopEnableEXT(cmdBuffer, state->attachmentFeedbackLoopEnable);
4428             break;
4429         default:
4430             break;
4431         }
4432     }
4433 #endif // CTS_USES_VULKANSC
4434 }
4435 
bind(vk::VkCommandBuffer cmdBuffer) const4436 void GraphicsPipelineWrapper::bind(vk::VkCommandBuffer cmdBuffer) const
4437 {
4438     const auto &vk = m_internalData->vk;
4439     if (!isConstructionTypeShaderObject(m_internalData->pipelineConstructionType))
4440     {
4441         vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, getPipeline());
4442     }
4443     else
4444     {
4445 #ifndef CTS_USES_VULKANSC
4446         const VkShaderStageFlagBits vertStage = vk::VK_SHADER_STAGE_VERTEX_BIT;
4447         VkShaderEXT vertShader                = m_internalData->vertexShader.getShader();
4448         vk.cmdBindShadersEXT(cmdBuffer, 1, &vertStage, &vertShader);
4449         const VkShaderStageFlagBits tescStage = vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
4450         VkShaderEXT tescShader                = m_internalData->tessellationControlShader.getShader();
4451         vk.cmdBindShadersEXT(cmdBuffer, 1, &tescStage, &tescShader);
4452         const VkShaderStageFlagBits teseStage = vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
4453         VkShaderEXT teseShader                = m_internalData->tessellationEvaluationShader.getShader();
4454         vk.cmdBindShadersEXT(cmdBuffer, 1, &teseStage, &teseShader);
4455         const VkShaderStageFlagBits geomStage = vk::VK_SHADER_STAGE_GEOMETRY_BIT;
4456         VkShaderEXT geomShader                = m_internalData->geometryShader.getShader();
4457         vk.cmdBindShadersEXT(cmdBuffer, 1, &geomStage, &geomShader);
4458         const VkShaderStageFlagBits fragStage = vk::VK_SHADER_STAGE_FRAGMENT_BIT;
4459         VkShaderEXT fragShader                = m_internalData->fragmentShader.getShader();
4460         vk.cmdBindShadersEXT(cmdBuffer, 1, &fragStage, &fragShader);
4461         if (m_internalData->meshShaderFeature)
4462         {
4463             const VkShaderStageFlagBits meshStage = vk::VK_SHADER_STAGE_MESH_BIT_EXT;
4464             VkShaderEXT meshShader                = m_internalData->meshShader.getShader();
4465             vk.cmdBindShadersEXT(cmdBuffer, 1, &meshStage, &meshShader);
4466         }
4467         if (m_internalData->taskShaderFeature)
4468         {
4469             const VkShaderStageFlagBits taskStage = vk::VK_SHADER_STAGE_TASK_BIT_EXT;
4470             VkShaderEXT taskShader                = m_internalData->taskShader.getShader();
4471             vk.cmdBindShadersEXT(cmdBuffer, 1, &taskStage, &taskShader);
4472         }
4473         // Set all dynamic state that would otherwise have been set with the pipeline
4474         setShaderObjectDynamicStates(cmdBuffer);
4475 #endif
4476     }
4477 }
4478 
wasBuild() const4479 bool GraphicsPipelineWrapper::wasBuild() const
4480 {
4481     return !!m_pipelineFinal.get();
4482 }
4483 
wasPipelineOrShaderObjectBuild(void) const4484 bool GraphicsPipelineWrapper::wasPipelineOrShaderObjectBuild(void) const
4485 {
4486     if (!!m_pipelineFinal.get())
4487         return true;
4488 
4489 #ifndef CTS_USES_VULKANSC
4490     if (!!m_internalData->vertexShader.getShader() || !!m_internalData->tessellationControlShader.getShader() ||
4491         !!m_internalData->tessellationEvaluationShader.getShader() || !!m_internalData->geometryShader.getShader() ||
4492         !!m_internalData->fragmentShader.getShader() || !!m_internalData->taskShader.getShader() ||
4493         !!m_internalData->meshShader.getShader())
4494         return true;
4495 #endif
4496 
4497     return false;
4498 }
4499 
getPipeline(void) const4500 VkPipeline GraphicsPipelineWrapper::getPipeline(void) const
4501 {
4502     DE_ASSERT(m_pipelineFinal.get() != DE_NULL);
4503     return m_pipelineFinal.get();
4504 }
4505 
destroyPipeline(void)4506 void GraphicsPipelineWrapper::destroyPipeline(void)
4507 {
4508     DE_ASSERT(m_pipelineFinal.get() != DE_NULL);
4509 
4510     m_pipelineFinal = Move<VkPipeline>();
4511 }
4512 
4513 } // namespace vk
4514