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