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