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