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
1260 // If a render pass is reused, image layouts have to be reset so that when vkCmdBeginRenderPass is called image layouts are transitioned correctly
resetLayouts(void)1261 void RenderPassWrapper::resetLayouts(void)
1262 {
1263 #ifndef CTS_USES_VULKANSC
1264 for (auto &layout : m_layouts)
1265 layout = vk::VK_IMAGE_LAYOUT_UNDEFINED;
1266 #endif
1267 }
1268
begin(const DeviceInterface & vk,const VkCommandBuffer commandBuffer,const VkRect2D & renderArea,const uint32_t clearValueCount,const VkClearValue * clearValues,const VkSubpassContents contents,const void * pNext) const1269 void RenderPassWrapper::begin(const DeviceInterface &vk, const VkCommandBuffer commandBuffer,
1270 const VkRect2D &renderArea, const uint32_t clearValueCount,
1271 const VkClearValue *clearValues, const VkSubpassContents contents,
1272 const void *pNext) const
1273 {
1274 if (!m_isDynamicRendering)
1275 {
1276 beginRenderPass(vk, commandBuffer, *m_renderPass, *m_framebuffer, renderArea, clearValueCount, clearValues,
1277 contents, pNext);
1278 }
1279 else
1280 {
1281 #ifndef CTS_USES_VULKANSC
1282 m_activeSubpass = 0;
1283
1284 m_clearValues.resize(clearValueCount);
1285 for (uint32_t i = 0; i < clearValueCount; ++i)
1286 m_clearValues[i] = clearValues[i];
1287
1288 for (uint32_t i = 0; i < (uint32_t)m_subpasses.size(); ++i)
1289 transitionLayouts(vk, commandBuffer, m_subpasses[i], true);
1290
1291 insertDependencies(vk, commandBuffer, 0u);
1292
1293 m_secondaryCommandBuffers = contents == vk::VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS;
1294
1295 m_renderingInfo = vk::initVulkanStructure();
1296 m_renderingInfo.flags = (vk::VkRenderingFlags)0u;
1297 m_renderingInfo.renderArea = renderArea;
1298 m_renderingInfo.layerCount = m_layers;
1299 m_renderingInfo.viewMask = 0x0;
1300
1301 clearAttachments(vk, commandBuffer);
1302
1303 beginRendering(vk, commandBuffer);
1304 #endif
1305 }
1306 }
1307
begin(const DeviceInterface & vk,const VkCommandBuffer commandBuffer,const VkRect2D & renderArea,const VkClearValue & clearValue,const VkSubpassContents contents) const1308 void RenderPassWrapper::begin(const DeviceInterface &vk, const VkCommandBuffer commandBuffer,
1309 const VkRect2D &renderArea, const VkClearValue &clearValue,
1310 const VkSubpassContents contents) const
1311 {
1312 begin(vk, commandBuffer, renderArea, 1u, &clearValue, contents);
1313 }
1314
begin(const DeviceInterface & vk,const VkCommandBuffer commandBuffer,const VkRect2D & renderArea,const tcu::Vec4 & clearColor,const VkSubpassContents contents) const1315 void RenderPassWrapper::begin(const DeviceInterface &vk, const VkCommandBuffer commandBuffer,
1316 const VkRect2D &renderArea, const tcu::Vec4 &clearColor,
1317 const VkSubpassContents contents) const
1318 {
1319 const VkClearValue clearValue = makeClearValueColor(clearColor);
1320 begin(vk, commandBuffer, renderArea, clearValue, contents);
1321 }
1322
begin(const DeviceInterface & vk,const VkCommandBuffer commandBuffer,const VkRect2D & renderArea,const tcu::Vec4 & clearColor,const float clearDepth,const uint32_t clearStencil,const VkSubpassContents contents) const1323 void RenderPassWrapper::begin(const DeviceInterface &vk, const VkCommandBuffer commandBuffer,
1324 const VkRect2D &renderArea, const tcu::Vec4 &clearColor, const float clearDepth,
1325 const uint32_t clearStencil, const VkSubpassContents contents) const
1326 {
1327 const VkClearValue clearValues[] = {
1328 makeClearValueColor(clearColor), // attachment 0
1329 makeClearValueDepthStencil(clearDepth, clearStencil), // attachment 1
1330 };
1331 begin(vk, commandBuffer, renderArea, 2, clearValues, contents);
1332 }
1333
begin(const DeviceInterface & vk,const VkCommandBuffer commandBuffer,const VkRect2D & renderArea,const VkSubpassContents contents) const1334 void RenderPassWrapper::begin(const DeviceInterface &vk, const VkCommandBuffer commandBuffer,
1335 const VkRect2D &renderArea, const VkSubpassContents contents) const
1336 {
1337 begin(vk, commandBuffer, renderArea, 0u, DE_NULL, contents);
1338 }
1339
begin(const DeviceInterface & vk,const VkCommandBuffer commandBuffer,const VkRect2D & renderArea,const tcu::UVec4 & clearColor,const VkSubpassContents contents) const1340 void RenderPassWrapper::begin(const DeviceInterface &vk, const VkCommandBuffer commandBuffer,
1341 const VkRect2D &renderArea, const tcu::UVec4 &clearColor,
1342 const VkSubpassContents contents) const
1343 {
1344 const VkClearValue clearValue =
1345 makeClearValueColorU32(clearColor.x(), clearColor.y(), clearColor.z(), clearColor.w());
1346
1347 begin(vk, commandBuffer, renderArea, clearValue, contents);
1348 }
1349
end(const DeviceInterface & vk,const VkCommandBuffer commandBuffer) const1350 void RenderPassWrapper::end(const DeviceInterface &vk, const VkCommandBuffer commandBuffer) const
1351 {
1352 if (!m_isDynamicRendering)
1353 {
1354 vk.cmdEndRenderPass(commandBuffer);
1355 }
1356 else
1357 {
1358 #ifndef CTS_USES_VULKANSC
1359 vk.cmdEndRendering(commandBuffer);
1360
1361 // Use dependencies for external subpasses to extract destination access
1362 // flags and pipeline stage flags for the final layout transition
1363 // barriers.
1364 VkAccessFlags2 externalAccessFlags = 0u;
1365 VkPipelineStageFlags2 externalStageFlags = 0u;
1366 bool sync2 = false;
1367
1368 for (const auto &dep : m_dependencies)
1369 {
1370 if (dep.dstSubpass == VK_SUBPASS_EXTERNAL)
1371 {
1372 externalAccessFlags |= dep.dstAccessMask;
1373 externalStageFlags |= dep.dstStageMask;
1374 }
1375 if (dep.sync2)
1376 sync2 = true;
1377 }
1378
1379 for (uint32_t i = 0; i < (uint32_t)m_attachments.size(); ++i)
1380 {
1381 if (m_layouts[i] == m_attachments[i].finalLayout)
1382 continue;
1383
1384 const bool color = !vk::isDepthStencilFormat(m_attachments[i].format);
1385 VkImageAspectFlags aspect =
1386 color ? (vk::VkImageAspectFlags)vk::VK_IMAGE_ASPECT_COLOR_BIT : (vk::VkImageAspectFlags)0u;
1387
1388 if (!color)
1389 {
1390 const bool hasDepthAspect = tcu::hasDepthComponent(vk::mapVkFormat(m_attachments[i].format).order);
1391 const bool hasStencilAspect = tcu::hasStencilComponent(vk::mapVkFormat(m_attachments[i].format).order);
1392
1393 if (hasDepthAspect)
1394 aspect |= vk::VK_IMAGE_ASPECT_DEPTH_BIT;
1395 if (hasStencilAspect)
1396 aspect |= vk::VK_IMAGE_ASPECT_STENCIL_BIT;
1397 }
1398
1399 const auto subresourceRange =
1400 makeImageSubresourceRange(aspect, 0u, VK_REMAINING_MIP_LEVELS, 0u, VK_REMAINING_ARRAY_LAYERS);
1401
1402 const VkPipelineStageFlags2 srcStageMask = (color ? vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT :
1403 vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
1404 const VkAccessFlags2 srcAccessMask =
1405 (color ? vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT : vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT);
1406 const VkPipelineStageFlags2 dstStageMask = (vk::VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT | externalStageFlags);
1407 const VkAccessFlags2 dstAccessMask = externalAccessFlags;
1408 const VkImageLayout newLayout = m_attachments[i].finalLayout;
1409
1410 recordImageBarrier(vk, commandBuffer, sync2, srcStageMask, srcAccessMask, dstStageMask, dstAccessMask,
1411 m_layouts[i], newLayout, m_images[i], subresourceRange);
1412 }
1413
1414 insertDependencies(vk, commandBuffer, VK_SUBPASS_EXTERNAL);
1415 #endif
1416 }
1417 }
1418
beginRendering(const DeviceInterface & vk,const VkCommandBuffer commandBuffer) const1419 void RenderPassWrapper::beginRendering(const DeviceInterface &vk, const VkCommandBuffer commandBuffer) const
1420 {
1421 DE_UNREF(vk);
1422 DE_UNREF(commandBuffer);
1423 #ifndef CTS_USES_VULKANSC
1424 const auto &subpass = m_subpasses[m_activeSubpass];
1425 std::vector<vk::VkRenderingAttachmentInfo> colorAttachments;
1426 for (uint32_t i = 0; i < (uint32_t)subpass.m_colorAttachments.size(); ++i)
1427 {
1428 colorAttachments.emplace_back();
1429 auto &colorAttachment = colorAttachments.back();
1430 colorAttachment = vk::initVulkanStructure();
1431 if (subpass.m_colorAttachments[i].index == VK_ATTACHMENT_UNUSED)
1432 continue;
1433 colorAttachment = subpass.m_colorAttachments[i].attachmentInfo;
1434 colorAttachment.loadOp = vk::VK_ATTACHMENT_LOAD_OP_LOAD;
1435 if (!subpass.m_resolveAttachments.empty() && subpass.m_resolveAttachments[i].index != VK_ATTACHMENT_UNUSED)
1436 {
1437 if (isUintFormat(subpass.m_resolveAttachments[i].format) ||
1438 isIntFormat(subpass.m_resolveAttachments[i].format))
1439 colorAttachment.resolveMode = vk::VK_RESOLVE_MODE_SAMPLE_ZERO_BIT;
1440 else
1441 colorAttachment.resolveMode = vk::VK_RESOLVE_MODE_AVERAGE_BIT;
1442 colorAttachment.resolveImageView = subpass.m_resolveAttachments[i].attachmentInfo.imageView;
1443 colorAttachment.resolveImageLayout = subpass.m_resolveAttachments[i].attachmentInfo.imageLayout;
1444 }
1445 }
1446
1447 m_renderingInfo.colorAttachmentCount = (uint32_t)colorAttachments.size();
1448 m_renderingInfo.pColorAttachments = colorAttachments.data();
1449
1450 subpass.m_depthStencilAttachment.attachmentInfo.loadOp = vk::VK_ATTACHMENT_LOAD_OP_LOAD;
1451 VkRenderingAttachmentInfo depthAttachment = subpass.m_depthStencilAttachment.attachmentInfo;
1452 VkRenderingAttachmentInfo stencilAttachment = subpass.m_depthStencilAttachment.attachmentInfo;
1453 stencilAttachment.storeOp = subpass.m_depthStencilAttachment.stencilStoreOp;
1454
1455 if (depthAttachment.imageView != VK_NULL_HANDLE)
1456 {
1457 const auto tcuFormat = vk::mapVkFormat(subpass.m_depthStencilAttachment.format);
1458 bool hasDepthAspect = tcu::hasDepthComponent(tcuFormat.order);
1459 bool hasStencilAspect = tcu::hasStencilComponent(tcuFormat.order);
1460 m_renderingInfo.pDepthAttachment = hasDepthAspect ? &depthAttachment : DE_NULL;
1461 m_renderingInfo.pStencilAttachment = hasStencilAspect ? &stencilAttachment : DE_NULL;
1462 }
1463 else
1464 {
1465 m_renderingInfo.pDepthAttachment = DE_NULL;
1466 m_renderingInfo.pStencilAttachment = DE_NULL;
1467 }
1468
1469 if (m_activeSubpass < (uint32_t)m_viewMasks.size())
1470 m_renderingInfo.viewMask = m_viewMasks[m_activeSubpass];
1471
1472 m_renderingInfo.pNext = DE_NULL;
1473 if (subpass.m_msrtss.sType == VK_STRUCTURE_TYPE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_INFO_EXT)
1474 {
1475 subpass.m_msrtss.pNext = DE_NULL;
1476 m_renderingInfo.pNext = &subpass.m_msrtss;
1477 }
1478
1479 if (subpass.m_dsr.sType == VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE)
1480 {
1481 depthAttachment.resolveMode = subpass.m_dsr.depthResolveMode;
1482 stencilAttachment.resolveMode = subpass.m_dsr.stencilResolveMode;
1483 if (subpass.m_dsr.pDepthStencilResolveAttachment)
1484 {
1485 depthAttachment.resolveImageView = m_imageViews[subpass.m_dsr.pDepthStencilResolveAttachment->attachment];
1486 depthAttachment.resolveImageLayout = subpass.m_dsr.pDepthStencilResolveAttachment->layout;
1487 stencilAttachment.resolveImageView = m_imageViews[subpass.m_dsr.pDepthStencilResolveAttachment->attachment];
1488 stencilAttachment.resolveImageLayout = subpass.m_dsr.pDepthStencilResolveAttachment->layout;
1489 }
1490 }
1491
1492 m_renderingInfo.flags = (VkRenderingFlags)0u;
1493
1494 if (m_secondaryCommandBuffers)
1495 m_renderingInfo.flags |= VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT;
1496
1497 vk.cmdBeginRendering(commandBuffer, &m_renderingInfo);
1498 #endif
1499 }
1500
nextSubpass(const DeviceInterface & vk,const VkCommandBuffer commandBuffer,const VkSubpassContents contents) const1501 void RenderPassWrapper::nextSubpass(const DeviceInterface &vk, const VkCommandBuffer commandBuffer,
1502 const VkSubpassContents contents) const
1503 {
1504 if (!m_isDynamicRendering)
1505 {
1506 vk.cmdNextSubpass(commandBuffer, contents);
1507 }
1508 else
1509 {
1510 #ifndef CTS_USES_VULKANSC
1511 vk.cmdEndRendering(commandBuffer);
1512 ++m_activeSubpass;
1513 DE_ASSERT(m_activeSubpass < (uint32_t)m_subpasses.size());
1514
1515 const auto &subpass = m_subpasses[m_activeSubpass];
1516
1517 transitionLayouts(vk, commandBuffer, subpass, false);
1518
1519 insertDependencies(vk, commandBuffer, m_activeSubpass);
1520
1521 beginRendering(vk, commandBuffer);
1522 #endif
1523 }
1524 }
1525
createFramebuffer(const DeviceInterface & vk,const VkDevice device,const VkFramebufferCreateInfo * pCreateInfo,const std::vector<vk::VkImage> & images)1526 void RenderPassWrapper::createFramebuffer(const DeviceInterface &vk, const VkDevice device,
1527 const VkFramebufferCreateInfo *pCreateInfo,
1528 const std::vector<vk::VkImage> &images)
1529 {
1530 DE_UNREF(images);
1531 if (!m_isDynamicRendering)
1532 {
1533 m_framebuffer = vk::createFramebuffer(vk, device, pCreateInfo);
1534 }
1535 else
1536 {
1537 #ifndef CTS_USES_VULKANSC
1538 m_images = images;
1539 m_imageViews.resize(pCreateInfo->attachmentCount);
1540 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i)
1541 m_imageViews[i] = pCreateInfo->pAttachments[i];
1542
1543 for (auto &subpass : m_subpasses)
1544 {
1545 for (uint32_t i = 0; i < (uint32_t)subpass.m_colorAttachments.size(); ++i)
1546 {
1547 if (subpass.m_colorAttachments[i].index != VK_ATTACHMENT_UNUSED)
1548 subpass.m_colorAttachments[i].attachmentInfo.imageView =
1549 pCreateInfo->pAttachments[subpass.m_colorAttachments[i].index];
1550 }
1551
1552 if (subpass.m_depthStencilAttachment.attachmentInfo.imageLayout != VK_IMAGE_LAYOUT_UNDEFINED)
1553 {
1554 if (subpass.m_depthStencilAttachment.index != VK_ATTACHMENT_UNUSED)
1555 subpass.m_depthStencilAttachment.attachmentInfo.imageView =
1556 pCreateInfo->pAttachments[subpass.m_depthStencilAttachment.index];
1557 }
1558
1559 for (uint32_t i = 0; i < (uint32_t)subpass.m_resolveAttachments.size(); ++i)
1560 {
1561 if (subpass.m_resolveAttachments[i].index != VK_ATTACHMENT_UNUSED)
1562 subpass.m_resolveAttachments[i].attachmentInfo.imageView =
1563 pCreateInfo->pAttachments[subpass.m_resolveAttachments[i].index];
1564 }
1565 }
1566 m_layers = pCreateInfo->layers;
1567 #endif
1568 }
1569 }
1570
createFramebuffer(const DeviceInterface & vk,const VkDevice device,const VkFramebufferCreateInfo * pCreateInfo,vk::VkImage colorImage,vk::VkImage depthStencilImage)1571 void RenderPassWrapper::createFramebuffer(const DeviceInterface &vk, const VkDevice device,
1572 const VkFramebufferCreateInfo *pCreateInfo, vk::VkImage colorImage,
1573 vk::VkImage depthStencilImage)
1574 {
1575 DE_UNREF(colorImage);
1576 DE_UNREF(depthStencilImage);
1577 if (!m_isDynamicRendering)
1578 {
1579 m_framebuffer = vk::createFramebuffer(vk, device, pCreateInfo);
1580 }
1581 else
1582 {
1583 #ifndef CTS_USES_VULKANSC
1584 if (colorImage != VK_NULL_HANDLE)
1585 {
1586 m_images.push_back(colorImage);
1587 DE_ASSERT(pCreateInfo->attachmentCount > 0);
1588 m_imageViews.push_back(pCreateInfo->pAttachments[0]);
1589 }
1590 if (depthStencilImage != VK_NULL_HANDLE)
1591 m_images.push_back(depthStencilImage);
1592 for (auto &subpass : m_subpasses)
1593 {
1594 DE_ASSERT(subpass.m_colorAttachments.size() <= 1);
1595 if (pCreateInfo->pAttachments)
1596 {
1597 if (!subpass.m_colorAttachments.empty() &&
1598 subpass.m_colorAttachments[0].index < pCreateInfo->attachmentCount)
1599 subpass.m_colorAttachments[0].attachmentInfo.imageView =
1600 pCreateInfo->pAttachments[subpass.m_colorAttachments[0].index];
1601 if (subpass.m_depthStencilAttachment.index < pCreateInfo->attachmentCount)
1602 subpass.m_depthStencilAttachment.attachmentInfo.imageView =
1603 pCreateInfo->pAttachments[subpass.m_depthStencilAttachment.index];
1604 }
1605 }
1606 #endif
1607 }
1608 }
1609
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)1610 void RenderPassWrapper::createFramebuffer(const DeviceInterface &vk, const VkDevice device, const VkImage colorImage,
1611 const VkImageView colorAttachment, const uint32_t width,
1612 const uint32_t height, const uint32_t layers)
1613 {
1614 DE_UNREF(colorImage);
1615 if (!m_isDynamicRendering)
1616 {
1617 VkFramebufferCreateInfo createInfo = initVulkanStructure();
1618 createInfo.flags = (VkFramebufferCreateFlags)0u;
1619 createInfo.renderPass = *m_renderPass;
1620 createInfo.attachmentCount = (colorAttachment != VK_NULL_HANDLE) ? 1u : 0u;
1621 createInfo.pAttachments = &colorAttachment;
1622 createInfo.width = width;
1623 createInfo.height = height;
1624 createInfo.layers = layers;
1625 m_framebuffer = vk::createFramebuffer(vk, device, &createInfo);
1626 }
1627 else
1628 {
1629 #ifndef CTS_USES_VULKANSC
1630 m_images.push_back(colorImage);
1631 m_imageViews.push_back(colorAttachment);
1632 if (colorImage != VK_NULL_HANDLE)
1633 {
1634 for (auto &subpass : m_subpasses)
1635 {
1636 DE_ASSERT(subpass.m_colorAttachments.size() == 1);
1637 subpass.m_colorAttachments[0].attachmentInfo.imageView = colorAttachment;
1638 }
1639 }
1640 #endif
1641 }
1642 }
1643
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)1644 void RenderPassWrapper::createFramebuffer(const DeviceInterface &vk, const VkDevice device,
1645 const uint32_t attachmentCount, const VkImage *imagesArray,
1646 const VkImageView *attachmentsArray, const uint32_t width,
1647 const uint32_t height, const uint32_t layers)
1648 {
1649 DE_UNREF(imagesArray);
1650 if (!m_isDynamicRendering)
1651 {
1652 VkFramebufferCreateInfo createInfo = initVulkanStructure();
1653 createInfo.flags = (VkFramebufferCreateFlags)0u;
1654 createInfo.renderPass = *m_renderPass;
1655 createInfo.attachmentCount = attachmentCount;
1656 createInfo.pAttachments = attachmentsArray;
1657 createInfo.width = width;
1658 createInfo.height = height;
1659 createInfo.layers = layers;
1660 m_framebuffer = vk::createFramebuffer(vk, device, &createInfo);
1661 }
1662 else
1663 {
1664 #ifndef CTS_USES_VULKANSC
1665 for (uint32_t i = 0; i < attachmentCount; ++i)
1666 {
1667 m_images.push_back(imagesArray[i]);
1668 m_imageViews.push_back(attachmentsArray[i]);
1669 }
1670 for (auto &subpass : m_subpasses)
1671 {
1672 for (uint32_t i = 0; i < (uint32_t)subpass.m_colorAttachments.size(); ++i)
1673 {
1674 if (subpass.m_colorAttachments[i].index != VK_ATTACHMENT_UNUSED)
1675 subpass.m_colorAttachments[i].attachmentInfo.imageView =
1676 attachmentsArray[subpass.m_colorAttachments[i].index];
1677 }
1678 if (subpass.m_depthStencilAttachment.attachmentInfo.imageLayout != VK_IMAGE_LAYOUT_UNDEFINED)
1679 {
1680 if (subpass.m_depthStencilAttachment.index != VK_ATTACHMENT_UNUSED)
1681 subpass.m_depthStencilAttachment.attachmentInfo.imageView =
1682 attachmentsArray[subpass.m_depthStencilAttachment.index];
1683 }
1684 for (uint32_t i = 0; i < (uint32_t)subpass.m_resolveAttachments.size(); ++i)
1685 {
1686 if (subpass.m_resolveAttachments[i].index != VK_ATTACHMENT_UNUSED)
1687 subpass.m_resolveAttachments[i].attachmentInfo.imageView =
1688 attachmentsArray[subpass.m_resolveAttachments[i].index];
1689 }
1690 }
1691 #endif
1692 }
1693 }
1694
ShaderWrapper()1695 ShaderWrapper::ShaderWrapper()
1696 : m_vk(DE_NULL)
1697 , m_device(VK_NULL_HANDLE)
1698 , m_binary(DE_NULL)
1699 , m_moduleCreateFlags((VkShaderModuleCreateFlags)0u)
1700 , m_layout(DE_NULL)
1701 , m_specializationInfo(DE_NULL)
1702 #ifndef CTS_USES_VULKANSC
1703 , m_shaderCreateFlags((VkShaderCreateFlagsEXT)0u)
1704 , m_binaryDataSize(0u)
1705 #endif
1706 {
1707 }
1708
ShaderWrapper(const DeviceInterface & vk,VkDevice device,const vk::ProgramBinary & binary,const vk::VkShaderModuleCreateFlags createFlags)1709 ShaderWrapper::ShaderWrapper(const DeviceInterface &vk, VkDevice device, const vk::ProgramBinary &binary,
1710 const vk::VkShaderModuleCreateFlags createFlags)
1711 : m_vk(&vk)
1712 , m_device(device)
1713 , m_binary(&binary)
1714 , m_moduleCreateFlags(createFlags)
1715 , m_layout(DE_NULL)
1716 , m_specializationInfo(DE_NULL)
1717 #ifndef CTS_USES_VULKANSC
1718 , m_shaderCreateFlags((VkShaderCreateFlagsEXT)0u)
1719 , m_binaryDataSize(0u)
1720 #endif
1721 {
1722 }
1723
ShaderWrapper(const ShaderWrapper & rhs)1724 ShaderWrapper::ShaderWrapper(const ShaderWrapper &rhs) noexcept
1725 : m_vk(rhs.m_vk)
1726 , m_device(rhs.m_device)
1727 , m_binary(rhs.m_binary)
1728 , m_moduleCreateFlags(rhs.m_moduleCreateFlags)
1729 , m_layout(rhs.m_layout)
1730 , m_specializationInfo(rhs.m_specializationInfo)
1731 #ifndef CTS_USES_VULKANSC
1732 , m_shaderCreateFlags(rhs.m_shaderCreateFlags)
1733 , m_binaryDataSize(rhs.m_binaryDataSize)
1734 , m_binaryData(rhs.m_binaryData)
1735 #endif
1736 {
1737 }
1738
operator =(const ShaderWrapper & rhs)1739 ShaderWrapper &ShaderWrapper::operator=(const ShaderWrapper &rhs) noexcept
1740 {
1741 m_vk = rhs.m_vk;
1742 m_device = rhs.m_device;
1743 m_binary = rhs.m_binary;
1744 m_moduleCreateFlags = rhs.m_moduleCreateFlags;
1745 m_layout = rhs.m_layout;
1746 m_specializationInfo = rhs.m_specializationInfo;
1747 #ifndef CTS_USES_VULKANSC
1748 m_shaderCreateFlags = rhs.m_shaderCreateFlags;
1749 m_binaryDataSize = rhs.m_binaryDataSize;
1750 m_binaryData = rhs.m_binaryData;
1751 #endif
1752
1753 return *this;
1754 }
1755
getModule(void) const1756 vk::VkShaderModule ShaderWrapper::getModule(void) const
1757 {
1758 if (!m_module)
1759 {
1760 if (!m_vk)
1761 return DE_NULL;
1762 m_module = createShaderModule(*m_vk, m_device, *m_binary, m_moduleCreateFlags);
1763 }
1764 return *m_module;
1765 }
1766
getCodeSize(void) const1767 size_t ShaderWrapper::getCodeSize(void) const
1768 {
1769 return m_binary->getSize();
1770 }
1771
getBinary(void) const1772 void *ShaderWrapper::getBinary(void) const
1773 {
1774 return (void *)m_binary->getBinary();
1775 }
1776
createModule(void)1777 void ShaderWrapper::createModule(void)
1778 {
1779 if (m_vk)
1780 m_module = createShaderModule(*m_vk, m_device, *m_binary, m_moduleCreateFlags);
1781 }
1782
setLayoutAndSpecialization(const PipelineLayoutWrapper * layout,const VkSpecializationInfo * specializationInfo)1783 void ShaderWrapper::setLayoutAndSpecialization(const PipelineLayoutWrapper *layout,
1784 const VkSpecializationInfo *specializationInfo)
1785 {
1786 m_layout = layout;
1787 m_specializationInfo = specializationInfo;
1788 }
1789
1790 #ifndef CTS_USES_VULKANSC
getShaderBinary(void)1791 void ShaderWrapper::getShaderBinary(void)
1792 {
1793 m_vk->getShaderBinaryDataEXT(m_device, *m_shader, &m_binaryDataSize, DE_NULL);
1794 m_binaryData.resize(m_binaryDataSize);
1795 m_vk->getShaderBinaryDataEXT(m_device, *m_shader, &m_binaryDataSize, m_binaryData.data());
1796 }
1797 #endif
1798
1799 // Structure storing *CreateInfo structures that do not need to exist in memory after pipeline was constructed.
1800 struct GraphicsPipelineWrapper::InternalData
1801 {
1802 const InstanceInterface &vki;
1803 const DeviceInterface &vk;
1804 VkPhysicalDevice physicalDevice;
1805 VkDevice device;
1806 const std::vector<std::string> &deviceExtensions;
1807 const PipelineConstructionType pipelineConstructionType;
1808 const VkPipelineCreateFlags pipelineFlags;
1809 PipelineCreateFlags2 pipelineFlags2;
1810
1811 // attribute used for making sure pipeline is configured in correct order
1812 int setupState;
1813
1814 std::vector<PipelineShaderStageModuleIdPtr> pipelineShaderIdentifiers;
1815 std::vector<VkPipelineShaderStageCreateInfo> pipelineShaderStages;
1816 VkPipelineInputAssemblyStateCreateInfo inputAssemblyState;
1817 VkPipelineRasterizationStateCreateInfo defaultRasterizationState;
1818 VkPipelineViewportStateCreateInfo viewportState;
1819 VkPipelineTessellationStateCreateInfo tessellationState;
1820 VkPipelineFragmentShadingRateStateCreateInfoKHR *pFragmentShadingRateState;
1821 PipelineRenderingCreateInfoWrapper pRenderingState;
1822 RenderingAttachmentLocationInfoWrapper pRenderingAttachmentLocation;
1823 RenderingInputAttachmentIndexInfoWrapper pRenderingInputAttachmentIndex;
1824 const VkPipelineDynamicStateCreateInfo *pDynamicState;
1825 PipelineRepresentativeFragmentTestCreateInfoWrapper pRepresentativeFragmentTestState;
1826 PipelineRobustnessCreateInfoWrapper pPipelineRobustnessState;
1827
1828 TessellationDomainOriginStatePtr pTessellationDomainOrigin;
1829 bool useViewportState;
1830 bool useDefaultRasterizationState;
1831 bool useDefaultDepthStencilState;
1832 bool useDefaultColorBlendState;
1833 bool useDefaultMultisampleState;
1834 bool useDefaultVertexInputState;
1835 bool failOnCompileWhenLinking;
1836
1837 bool explicitLinkPipelineLayoutSet;
1838 VkGraphicsPipelineCreateInfo monolithicPipelineCreateInfo;
1839
1840 ShaderWrapper vertexShader;
1841 ShaderWrapper tessellationControlShader;
1842 ShaderWrapper tessellationEvaluationShader;
1843 ShaderWrapper geometryShader;
1844 ShaderWrapper fragmentShader;
1845
1846 ShaderWrapper meshShader;
1847 ShaderWrapper taskShader;
1848
1849 bool tessellationShaderFeature;
1850 bool geometryShaderFeature;
1851 bool taskShaderFeature;
1852 bool meshShaderFeature;
1853
1854 // Store all dynamic state that are used with shader objects
1855 std::vector<vk::VkDynamicState> shaderObjectDynamicStates;
1856
1857 #ifndef CTS_USES_VULKANSC
1858 // Store the state that a pipeline would be created with, but shader objects have to set dynamically
1859 struct PipelineCreateState
1860 {
1861 std::vector<VkViewport> viewports;
1862 std::vector<VkRect2D> scissors;
1863 float lineWidth = 1.0f;
1864 VkDepthBiasRepresentationEXT depthBiasRepresentation =
1865 vk::VK_DEPTH_BIAS_REPRESENTATION_LEAST_REPRESENTABLE_VALUE_FORMAT_EXT;
1866 VkBool32 depthBiasExact = VK_FALSE;
1867 float depthBiasConstantFactor = 0.0f;
1868 float depthBiasClamp = 0.0f;
1869 float depthBiasSlopeFactor = 1.0f;
1870 float blendConstants[4] = {0.0f, 0.0f, 0.0f, 0.0f};
1871 float minDepthBounds = 0.0f;
1872 float maxDepthBounds = 1.0f;
1873 VkStencilOpState stencilFront = {
1874 VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_NEVER, 0, 0, 0};
1875 VkStencilOpState stencilBack = {
1876 VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_NEVER, 0, 0, 0};
1877 VkCullModeFlags cullMode = VK_CULL_MODE_NONE;
1878 bool depthTestEnable = VK_FALSE;
1879 bool depthWriteEnable = VK_FALSE;
1880 VkCompareOp depthCompareOp = VK_COMPARE_OP_NEVER;
1881 bool depthBoundsTestEnable = VK_FALSE;
1882 VkFrontFace frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
1883 VkPrimitiveTopology topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
1884 bool stencilTestEnable = VK_FALSE;
1885 std::vector<VkVertexInputAttributeDescription2EXT> attributes;
1886 std::vector<VkVertexInputBindingDescription2EXT> bindings;
1887 bool depthBiasEnable = VK_FALSE;
1888 VkLogicOp logicOp = VK_LOGIC_OP_CLEAR;
1889 uint32_t patchControlPoints = 1;
1890 bool primitiveRestartEnable = VK_FALSE;
1891 bool rasterizerDiscardEnable = VK_FALSE;
1892 bool alphaToCoverageEnable = VK_FALSE;
1893 bool alphaToOneEnable = VK_FALSE;
1894 std::vector<VkColorBlendAdvancedEXT> colorBlendAdvanced;
1895 std::vector<VkBool32> colorBlendEnables;
1896 std::vector<VkColorBlendEquationEXT> blendEquations;
1897 std::vector<VkColorComponentFlags> colorWriteMasks;
1898 VkConservativeRasterizationModeEXT conservativeRasterizationMode =
1899 VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT;
1900 VkCoverageModulationModeNV coverageModulationMode = VK_COVERAGE_MODULATION_MODE_NONE_NV;
1901 bool coverageModulationTableEnable = VK_FALSE;
1902 std::vector<float> coverageModulationTable;
1903 VkCoverageReductionModeNV coverageReductionMode = VK_COVERAGE_REDUCTION_MODE_MERGE_NV;
1904 bool coverageToColorEnable = VK_FALSE;
1905 uint32_t coverageToColorLocation = 0;
1906 bool depthClampEnable = VK_FALSE;
1907 bool depthClipEnable = VK_FALSE;
1908 bool negativeOneToOne = VK_FALSE;
1909 uint32_t colorWriteEnableAttachmentCount = 0;
1910 std::vector<VkBool32> colorWriteEnables;
1911 float extraPrimitiveOverestimationSize = 0.0f;
1912 VkLineRasterizationModeEXT lineRasterizationMode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT;
1913 bool stippledLineEnable = VK_FALSE;
1914 uint32_t lineStippleFactor = 1;
1915 uint16_t lineStipplePattern = 0x1;
1916 bool logicOpEnable = VK_FALSE;
1917 VkPolygonMode polygonMode = VK_POLYGON_MODE_FILL;
1918 VkProvokingVertexModeEXT provokingVertexMode = VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT;
1919 VkSampleCountFlagBits rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
1920 VkExtent2D fragmentShadingRateSize = {1u, 1u};
1921 VkFragmentShadingRateCombinerOpKHR combinerOps[2] = {VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR,
1922 VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR};
1923 uint32_t rasterizationStream = 0;
1924 bool representativeFragmentTestEnable = VK_FALSE;
1925 bool sampleLocationsEnable = VK_FALSE;
1926 std::vector<VkSampleLocationEXT> pSampleLocations;
1927 VkSampleLocationsInfoEXT sampleLocationsInfo = vk::initVulkanStructure();
1928 std::vector<VkSampleMask> sampleMasks;
1929 bool shadingRateImageEnable = VK_FALSE;
1930 VkTessellationDomainOrigin domainOrigin = VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT;
1931 std::vector<VkViewportSwizzleNV> viewportSwizzles;
1932 bool viewportWScalingEnable = VK_FALSE;
1933 uint32_t viewportWScalingCount = 0;
1934 std::vector<VkViewportWScalingNV> viewportWScalings;
1935 VkCoarseSampleOrderTypeNV coarseSampleOrderType = VK_COARSE_SAMPLE_ORDER_TYPE_DEFAULT_NV;
1936 uint32_t coarseCustomSampleOrderCount = 0;
1937 std::vector<std::vector<VkCoarseSampleLocationNV>> coarseSampleLocations;
1938 std::vector<VkCoarseSampleOrderCustomNV> coarseCustomSampleOrders;
1939 uint32_t shadingRatePaletteCount = 0;
1940 std::vector<std::vector<VkShadingRatePaletteEntryNV>> shadingRatePaletteEntries;
1941 std::vector<VkShadingRatePaletteNV> shadingRatePalettes;
1942 uint32_t exclusiveScissorCount = 0;
1943 std::vector<VkRect2D> exclussiveScissors;
1944 bool discardRectangleEnable = VK_FALSE;
1945 std::vector<VkRect2D> discardRectangles;
1946 VkDiscardRectangleModeEXT discardRectangleMode = VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT;
1947 VkImageAspectFlags attachmentFeedbackLoopEnable = VK_IMAGE_ASPECT_NONE;
1948 } pipelineCreateState;
1949 #endif
1950
1951 // initialize with most common values
InternalDatavk::GraphicsPipelineWrapper::InternalData1952 InternalData(const InstanceInterface& instanceInterface, const DeviceInterface& vkd, VkPhysicalDevice physDevice, VkDevice vkDevice, const std::vector<std::string>& deviceExts, const PipelineConstructionType constructionType, const VkPipelineCreateFlags pipelineCreateFlags)
1953 : vki (instanceInterface)
1954 , vk (vkd)
1955 , physicalDevice (physDevice)
1956 , device (vkDevice)
1957 , deviceExtensions (deviceExts)
1958 , pipelineConstructionType (constructionType)
1959 , pipelineFlags (pipelineCreateFlags)
1960 , pipelineFlags2 (0u)
1961 , setupState (PSS_NONE)
1962 , inputAssemblyState
1963 {
1964 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType
1965 DE_NULL, // const void* pNext
1966 0u, // VkPipelineInputAssemblyStateCreateFlags flags
1967 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology topology
1968 VK_FALSE // VkBool32 primitiveRestartEnable
1969 }
1970 , defaultRasterizationState
1971 {
1972 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType
1973 DE_NULL, // const void* pNext
1974 0u, // VkPipelineRasterizationStateCreateFlags flags
1975 VK_FALSE, // VkBool32 depthClampEnable
1976 VK_FALSE, // VkBool32 rasterizerDiscardEnable
1977 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode
1978 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode
1979 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace
1980 VK_FALSE, // VkBool32 depthBiasEnable
1981 0.0f, // float depthBiasConstantFactor
1982 0.0f, // float depthBiasClamp
1983 0.0f, // float depthBiasSlopeFactor
1984 1.0f // float lineWidth
1985 }
1986 , viewportState
1987 {
1988 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType
1989 DE_NULL, // const void* pNext
1990 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags
1991 1u, // uint32_t viewportCount
1992 DE_NULL, // const VkViewport* pViewports
1993 1u, // uint32_t scissorCount
1994 DE_NULL // const VkRect2D* pScissors
1995 }
1996 , tessellationState
1997 {
1998 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType
1999 DE_NULL, // const void* pNext
2000 0u, // VkPipelineTessellationStateCreateFlags flags
2001 3u // uint32_t patchControlPoints
2002 }
2003 , pFragmentShadingRateState (nullptr)
2004 , pDynamicState (DE_NULL)
2005 , pRepresentativeFragmentTestState(nullptr)
2006 , pPipelineRobustnessState (nullptr)
2007 , pTessellationDomainOrigin ()
2008 , useViewportState (true)
2009 , useDefaultRasterizationState (false)
2010 , useDefaultDepthStencilState (false)
2011 , useDefaultColorBlendState (false)
2012 , useDefaultMultisampleState (false)
2013 , useDefaultVertexInputState (true)
2014 , failOnCompileWhenLinking (false)
2015 , explicitLinkPipelineLayoutSet (false)
2016 , tessellationShaderFeature (false)
2017 , geometryShaderFeature (false)
2018 , taskShaderFeature (false)
2019 , meshShaderFeature (false)
2020 {
2021 monolithicPipelineCreateInfo = initVulkanStructure();
2022 }
2023
extensionEnabledvk::GraphicsPipelineWrapper::InternalData2024 bool extensionEnabled(const std::string &ext) const
2025 {
2026 return std::find(deviceExtensions.begin(), deviceExtensions.end(), ext) != deviceExtensions.end();
2027 }
2028 };
2029
GraphicsPipelineWrapper(const InstanceInterface & vki,const DeviceInterface & vk,VkPhysicalDevice physicalDevice,VkDevice device,const std::vector<std::string> & deviceExtensions,const PipelineConstructionType pipelineConstructionType,const VkPipelineCreateFlags flags)2030 GraphicsPipelineWrapper::GraphicsPipelineWrapper(const InstanceInterface &vki, const DeviceInterface &vk,
2031 VkPhysicalDevice physicalDevice, VkDevice device,
2032 const std::vector<std::string> &deviceExtensions,
2033 const PipelineConstructionType pipelineConstructionType,
2034 const VkPipelineCreateFlags flags)
2035 : m_internalData(
2036 new InternalData(vki, vk, physicalDevice, device, deviceExtensions, pipelineConstructionType, flags))
2037 {
2038 }
2039
GraphicsPipelineWrapper(GraphicsPipelineWrapper && pw)2040 GraphicsPipelineWrapper::GraphicsPipelineWrapper(GraphicsPipelineWrapper &&pw) noexcept
2041 : m_pipelineFinal(pw.m_pipelineFinal)
2042 , m_internalData(pw.m_internalData)
2043 {
2044 std::move(pw.m_pipelineParts, pw.m_pipelineParts + de::arrayLength(pw.m_pipelineParts), m_pipelineParts);
2045 }
2046
setMonolithicPipelineLayout(const PipelineLayoutWrapper & layout)2047 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setMonolithicPipelineLayout(const PipelineLayoutWrapper &layout)
2048 {
2049 // make sure pipeline was not already built
2050 DE_ASSERT(m_pipelineFinal.get() == DE_NULL);
2051
2052 m_internalData->monolithicPipelineCreateInfo.layout = *layout;
2053 m_internalData->explicitLinkPipelineLayoutSet = true;
2054
2055 return *this;
2056 }
2057
setDynamicState(const VkPipelineDynamicStateCreateInfo * dynamicState)2058 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setDynamicState(const VkPipelineDynamicStateCreateInfo *dynamicState)
2059 {
2060 // make sure states are not yet setup - all pipeline states must know about dynamic state
2061 DE_ASSERT(m_internalData && m_internalData->setupState == PSS_NONE);
2062
2063 m_internalData->pDynamicState = dynamicState;
2064 m_internalData->monolithicPipelineCreateInfo.pDynamicState = dynamicState;
2065
2066 return *this;
2067 }
2068
setRepresentativeFragmentTestState(PipelineRepresentativeFragmentTestCreateInfoWrapper representativeFragmentTestState)2069 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setRepresentativeFragmentTestState(
2070 PipelineRepresentativeFragmentTestCreateInfoWrapper representativeFragmentTestState)
2071 {
2072 // Representative fragment test state is needed by the fragment shader state.
2073 DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_FRAGMENT_SHADER));
2074
2075 m_internalData->pRepresentativeFragmentTestState = representativeFragmentTestState;
2076 return *this;
2077 }
2078
setPipelineCreateFlags2(PipelineCreateFlags2 pipelineFlags2)2079 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setPipelineCreateFlags2(PipelineCreateFlags2 pipelineFlags2)
2080 {
2081 // make sure states are not yet setup - all pipeline states must know about createFlags2
2082 DE_ASSERT(m_internalData && m_internalData->setupState == PSS_NONE);
2083
2084 m_internalData->pipelineFlags2 = pipelineFlags2;
2085 return *this;
2086 }
2087
setPipelineRobustnessState(PipelineRobustnessCreateInfoWrapper pipelineRobustnessState)2088 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setPipelineRobustnessState(
2089 PipelineRobustnessCreateInfoWrapper pipelineRobustnessState)
2090 {
2091 // pipeline robustness is needed by vertex input state, make sure vertex input state was not setup yet
2092 DE_ASSERT(m_internalData && (m_internalData->setupState == PSS_NONE));
2093
2094 m_internalData->pPipelineRobustnessState = pipelineRobustnessState;
2095 return *this;
2096 }
2097
getDynamicStates(const VkPipelineDynamicStateCreateInfo * dynamicStateInfo,uint32_t setupState)2098 std::vector<VkDynamicState> getDynamicStates(const VkPipelineDynamicStateCreateInfo *dynamicStateInfo,
2099 uint32_t setupState)
2100 {
2101 static const std::set<VkDynamicState> vertexInputStates{
2102 VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT,
2103 VK_DYNAMIC_STATE_VERTEX_INPUT_EXT,
2104 VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT,
2105 VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT,
2106 };
2107
2108 static const std::set<VkDynamicState> preRastStates{
2109 VK_DYNAMIC_STATE_VIEWPORT,
2110 VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT,
2111 VK_DYNAMIC_STATE_SCISSOR,
2112 VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT,
2113 VK_DYNAMIC_STATE_LINE_WIDTH,
2114 VK_DYNAMIC_STATE_LINE_STIPPLE_EXT,
2115 VK_DYNAMIC_STATE_CULL_MODE_EXT,
2116 VK_DYNAMIC_STATE_FRONT_FACE_EXT,
2117 VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT,
2118 VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT,
2119 VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT,
2120 VK_DYNAMIC_STATE_DEPTH_BIAS,
2121 VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT,
2122 VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR,
2123 #ifndef CTS_USES_VULKANSC
2124 VK_DYNAMIC_STATE_TESSELLATION_DOMAIN_ORIGIN_EXT,
2125 VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT,
2126 VK_DYNAMIC_STATE_POLYGON_MODE_EXT,
2127 VK_DYNAMIC_STATE_RASTERIZATION_STREAM_EXT,
2128 VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT,
2129 VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT,
2130 VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT,
2131 VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT,
2132 VK_DYNAMIC_STATE_LINE_STIPPLE_EXT,
2133 VK_DYNAMIC_STATE_CONSERVATIVE_RASTERIZATION_MODE_EXT,
2134 VK_DYNAMIC_STATE_EXTRA_PRIMITIVE_OVERESTIMATION_SIZE_EXT,
2135 VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT,
2136 VK_DYNAMIC_STATE_VIEWPORT_SWIZZLE_NV,
2137 VK_DYNAMIC_STATE_SHADING_RATE_IMAGE_ENABLE_NV,
2138 VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_ENABLE_NV,
2139 VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV,
2140 VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV,
2141 VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV,
2142 VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV,
2143 #endif
2144 };
2145
2146 static const std::set<VkDynamicState> fragShaderStates{
2147 VK_DYNAMIC_STATE_DEPTH_BOUNDS,
2148 VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT,
2149 VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT,
2150 VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT,
2151 VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT,
2152 VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
2153 VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
2154 VK_DYNAMIC_STATE_STENCIL_REFERENCE,
2155 VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT,
2156 VK_DYNAMIC_STATE_STENCIL_OP_EXT,
2157 VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR,
2158 // Needs MSAA info here as well as fragment output state
2159 VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT,
2160 #ifndef CTS_USES_VULKANSC
2161 VK_DYNAMIC_STATE_SAMPLE_MASK_EXT,
2162 VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT,
2163 VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT,
2164 VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_ENABLE_EXT,
2165 VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT,
2166 VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_ENABLE_NV,
2167 VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_LOCATION_NV,
2168 VK_DYNAMIC_STATE_COVERAGE_MODULATION_MODE_NV,
2169 VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_ENABLE_NV,
2170 VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_NV,
2171 VK_DYNAMIC_STATE_COVERAGE_REDUCTION_MODE_NV,
2172 VK_DYNAMIC_STATE_REPRESENTATIVE_FRAGMENT_TEST_ENABLE_NV,
2173 #endif
2174 };
2175
2176 static const std::set<VkDynamicState> fragOutputStates{
2177 VK_DYNAMIC_STATE_LOGIC_OP_EXT,
2178 VK_DYNAMIC_STATE_BLEND_CONSTANTS,
2179 VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT,
2180 VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR,
2181 VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT,
2182 #ifndef CTS_USES_VULKANSC
2183 VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT,
2184 VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT,
2185 VK_DYNAMIC_STATE_COLOR_BLEND_ADVANCED_EXT,
2186 VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT,
2187 VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT,
2188 VK_DYNAMIC_STATE_SAMPLE_MASK_EXT,
2189 VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT,
2190 VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT,
2191 VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_ENABLE_EXT,
2192 VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT,
2193 VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_ENABLE_NV,
2194 VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_LOCATION_NV,
2195 VK_DYNAMIC_STATE_COVERAGE_MODULATION_MODE_NV,
2196 VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_ENABLE_NV,
2197 VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_NV,
2198 VK_DYNAMIC_STATE_COVERAGE_REDUCTION_MODE_NV,
2199 VK_DYNAMIC_STATE_REPRESENTATIVE_FRAGMENT_TEST_ENABLE_NV,
2200 VK_DYNAMIC_STATE_ATTACHMENT_FEEDBACK_LOOP_ENABLE_EXT,
2201 #endif
2202 };
2203
2204 const std::set<VkDynamicState> dynamicStates(
2205 dynamicStateInfo->pDynamicStates, dynamicStateInfo->pDynamicStates + dynamicStateInfo->dynamicStateCount);
2206
2207 // Verify all passed states are contained in at least one of the vectors above, so they won't get lost.
2208 for (const auto dynState : dynamicStates)
2209 {
2210 DE_UNREF(dynState); // For release builds.
2211 DE_ASSERT(de::contains(vertexInputStates.begin(), vertexInputStates.end(), dynState) ||
2212 de::contains(preRastStates.begin(), preRastStates.end(), dynState) ||
2213 de::contains(fragShaderStates.begin(), fragShaderStates.end(), dynState) ||
2214 de::contains(fragOutputStates.begin(), fragOutputStates.end(), dynState));
2215 }
2216
2217 std::set<VkDynamicState> intersectedStates;
2218
2219 if (setupState & PSS_VERTEX_INPUT_INTERFACE)
2220 std::set_intersection(vertexInputStates.begin(), vertexInputStates.end(), dynamicStates.begin(),
2221 dynamicStates.end(), std::inserter(intersectedStates, intersectedStates.end()));
2222
2223 if (setupState & PSS_PRE_RASTERIZATION_SHADERS)
2224 std::set_intersection(preRastStates.begin(), preRastStates.end(), dynamicStates.begin(), dynamicStates.end(),
2225 std::inserter(intersectedStates, intersectedStates.end()));
2226
2227 if (setupState & PSS_FRAGMENT_SHADER)
2228 std::set_intersection(fragShaderStates.begin(), fragShaderStates.end(), dynamicStates.begin(),
2229 dynamicStates.end(), std::inserter(intersectedStates, intersectedStates.end()));
2230
2231 if (setupState & PSS_FRAGMENT_OUTPUT_INTERFACE)
2232 std::set_intersection(fragOutputStates.begin(), fragOutputStates.end(), dynamicStates.begin(),
2233 dynamicStates.end(), std::inserter(intersectedStates, intersectedStates.end()));
2234
2235 const std::vector<VkDynamicState> returnedStates(begin(intersectedStates), end(intersectedStates));
2236
2237 return returnedStates;
2238 }
2239
setDefaultTopology(const VkPrimitiveTopology topology)2240 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setDefaultTopology(const VkPrimitiveTopology topology)
2241 {
2242 // topology is needed by vertex input state, make sure vertex input state was not setup yet
2243 DE_ASSERT(m_internalData && (m_internalData->setupState == PSS_NONE));
2244
2245 m_internalData->inputAssemblyState.topology = topology;
2246
2247 return *this;
2248 }
2249
setDefaultPatchControlPoints(const uint32_t patchControlPoints)2250 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setDefaultPatchControlPoints(const uint32_t patchControlPoints)
2251 {
2252 // patchControlPoints are needed by pre-rasterization shader state, make sure pre-rasterization state was not setup yet
2253 DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_PRE_RASTERIZATION_SHADERS));
2254
2255 m_internalData->tessellationState.patchControlPoints = patchControlPoints;
2256
2257 return *this;
2258 }
2259
setDefaultTessellationDomainOrigin(const VkTessellationDomainOrigin domainOrigin,bool forceExtStruct)2260 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setDefaultTessellationDomainOrigin(
2261 const VkTessellationDomainOrigin domainOrigin, bool forceExtStruct)
2262 {
2263 // Tessellation domain origin is needed by pre-rasterization shader state, make sure pre-rasterization state was not setup yet
2264 DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_PRE_RASTERIZATION_SHADERS));
2265
2266 // We need the extension structure when:
2267 // - We want to force it.
2268 // - The domain origin is not the default value.
2269 // - We have already hooked the extension structure.
2270 if (forceExtStruct || domainOrigin != VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT ||
2271 m_internalData->pTessellationDomainOrigin)
2272 {
2273 if (!m_internalData->pTessellationDomainOrigin)
2274 {
2275 m_internalData->pTessellationDomainOrigin.reset(
2276 new VkPipelineTessellationDomainOriginStateCreateInfo(initVulkanStructure()));
2277 m_internalData->tessellationState.pNext = m_internalData->pTessellationDomainOrigin.get();
2278 }
2279 m_internalData->pTessellationDomainOrigin->domainOrigin = domainOrigin;
2280 }
2281
2282 return *this;
2283 }
2284
setDefaultRasterizerDiscardEnable(const bool rasterizerDiscardEnable)2285 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setDefaultRasterizerDiscardEnable(const bool rasterizerDiscardEnable)
2286 {
2287 // rasterizerDiscardEnable is used in pre-rasterization shader state, make sure pre-rasterization state was not setup yet
2288 DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_PRE_RASTERIZATION_SHADERS));
2289
2290 m_internalData->defaultRasterizationState.rasterizerDiscardEnable = rasterizerDiscardEnable;
2291
2292 return *this;
2293 }
2294
setDefaultRasterizationState()2295 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setDefaultRasterizationState()
2296 {
2297 // RasterizationState is used in pre-rasterization shader state, make sure this state was not setup yet
2298 DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_PRE_RASTERIZATION_SHADERS));
2299
2300 m_internalData->useDefaultRasterizationState = true;
2301
2302 return *this;
2303 }
2304
setDefaultDepthStencilState()2305 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setDefaultDepthStencilState()
2306 {
2307 // DepthStencilState is used in fragment shader state, make sure fragment shader state was not setup yet
2308 DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_FRAGMENT_SHADER));
2309
2310 m_internalData->useDefaultDepthStencilState = true;
2311
2312 return *this;
2313 }
2314
setDefaultColorBlendState()2315 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setDefaultColorBlendState()
2316 {
2317 // ColorBlendState is used in fragment shader state, make sure fragment shader state was not setup yet
2318 DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_FRAGMENT_SHADER));
2319
2320 m_internalData->useDefaultColorBlendState = true;
2321
2322 return *this;
2323 }
2324
setDefaultMultisampleState()2325 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setDefaultMultisampleState()
2326 {
2327 // MultisampleState is used in fragment shader state, make sure fragment shader state was not setup yet
2328 DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_FRAGMENT_SHADER));
2329
2330 m_internalData->useDefaultMultisampleState = true;
2331
2332 return *this;
2333 }
2334
setDefaultVertexInputState(const bool useDefaultVertexInputState)2335 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setDefaultVertexInputState(const bool useDefaultVertexInputState)
2336 {
2337 // Make sure vertex input state was not setup yet.
2338 DE_ASSERT(m_internalData && (m_internalData->setupState == PSS_NONE));
2339
2340 m_internalData->useDefaultVertexInputState = useDefaultVertexInputState;
2341
2342 return *this;
2343 }
2344
setDefaultViewportsCount(uint32_t viewportCount)2345 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setDefaultViewportsCount(uint32_t viewportCount)
2346 {
2347 // ViewportState is used in pre-rasterization shader state, make sure pre-rasterization state was not setup yet
2348 DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_PRE_RASTERIZATION_SHADERS));
2349
2350 m_internalData->viewportState.viewportCount = viewportCount;
2351
2352 return *this;
2353 }
2354
setDefaultScissorsCount(uint32_t scissorCount)2355 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setDefaultScissorsCount(uint32_t scissorCount)
2356 {
2357 // ViewportState is used in pre-rasterization shader state, make sure pre-rasterization state was not setup yet
2358 DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_PRE_RASTERIZATION_SHADERS));
2359
2360 m_internalData->viewportState.scissorCount = scissorCount;
2361
2362 return *this;
2363 }
2364
setViewportStatePnext(const void * pNext)2365 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setViewportStatePnext(const void *pNext)
2366 {
2367 // ViewportState is used in pre-rasterization shader state, make sure pre-rasterization state was not setup yet
2368 DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_PRE_RASTERIZATION_SHADERS));
2369
2370 m_internalData->viewportState.pNext = pNext;
2371
2372 return *this;
2373 }
2374
2375 #ifndef CTS_USES_VULKANSC
setRenderingColorAttachmentsInfo(PipelineRenderingCreateInfoWrapper pipelineRenderingCreateInfo)2376 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setRenderingColorAttachmentsInfo(
2377 PipelineRenderingCreateInfoWrapper pipelineRenderingCreateInfo)
2378 {
2379 /* When both graphics pipeline library and dynamic rendering enabled, we just need only viewMask of VkPipelineRenderingCreateInfo
2380 * on non-fragment stages. But we need the rest info for setting up fragment output states.
2381 * This method provides a way to verify this condition.
2382 */
2383 if (!m_internalData->pRenderingState.ptr || !isConstructionTypeLibrary(m_internalData->pipelineConstructionType))
2384 return *this;
2385
2386 DE_ASSERT(m_internalData && (m_internalData->setupState > PSS_VERTEX_INPUT_INTERFACE) &&
2387 (m_internalData->setupState < PSS_FRAGMENT_OUTPUT_INTERFACE) &&
2388 (m_internalData->pRenderingState.ptr->viewMask == pipelineRenderingCreateInfo.ptr->viewMask));
2389
2390 m_internalData->pRenderingState.ptr = pipelineRenderingCreateInfo.ptr;
2391
2392 return *this;
2393 }
2394 #endif
2395
disableViewportState(const bool disable)2396 GraphicsPipelineWrapper &GraphicsPipelineWrapper::disableViewportState(const bool disable)
2397 {
2398 // ViewportState is used in pre-rasterization shader state, make sure pre-rasterization state was not setup yet
2399 DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_PRE_RASTERIZATION_SHADERS));
2400
2401 m_internalData->useViewportState = !disable;
2402
2403 return *this;
2404 }
2405
setupVertexInputState(const VkPipelineVertexInputStateCreateInfo * vertexInputState,const VkPipelineInputAssemblyStateCreateInfo * inputAssemblyState,const VkPipelineCache partPipelineCache,PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback,const bool useNullPtrs)2406 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setupVertexInputState(
2407 const VkPipelineVertexInputStateCreateInfo *vertexInputState,
2408 const VkPipelineInputAssemblyStateCreateInfo *inputAssemblyState, const VkPipelineCache partPipelineCache,
2409 PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback, const bool useNullPtrs)
2410 {
2411 // make sure pipeline was not already build
2412 DE_ASSERT(m_pipelineFinal.get() == DE_NULL);
2413
2414 // 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
2415 DE_ASSERT(m_internalData && (m_internalData->setupState == PSS_NONE));
2416
2417 // Unreference variables that are not used in Vulkan SC. No need to put this in ifdef.
2418 DE_UNREF(partPipelineCache);
2419 DE_UNREF(partCreationFeedback);
2420
2421 m_internalData->setupState = PSS_VERTEX_INPUT_INTERFACE;
2422
2423 const auto pVertexInputState =
2424 ((vertexInputState || useNullPtrs || !m_internalData->useDefaultVertexInputState) ? vertexInputState :
2425 &defaultVertexInputState);
2426 const auto pInputAssemblyState =
2427 ((inputAssemblyState || useNullPtrs) ? inputAssemblyState : &m_internalData->inputAssemblyState);
2428
2429 if (!isConstructionTypeLibrary(m_internalData->pipelineConstructionType))
2430 {
2431 m_internalData->monolithicPipelineCreateInfo.pVertexInputState = pVertexInputState;
2432 m_internalData->monolithicPipelineCreateInfo.pInputAssemblyState = pInputAssemblyState;
2433 }
2434
2435 #ifndef CTS_USES_VULKANSC
2436 // note we could just use else to if statement above but sinc
2437 // this section is cut out for Vulkan SC its cleaner with separate if
2438 if (isConstructionTypeLibrary(m_internalData->pipelineConstructionType))
2439 {
2440 auto libraryCreateInfo =
2441 makeGraphicsPipelineLibraryCreateInfo(VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT);
2442 void *firstStructInChain = reinterpret_cast<void *>(&libraryCreateInfo);
2443 addToChain(&firstStructInChain, partCreationFeedback.ptr);
2444 addToChain(&firstStructInChain, m_internalData->pPipelineRobustnessState.ptr);
2445
2446 VkPipelineDynamicStateCreateInfo pickedDynamicStateInfo = initVulkanStructure();
2447 std::vector<VkDynamicState> states;
2448
2449 if (m_internalData->pDynamicState)
2450 {
2451 states = getDynamicStates(m_internalData->pDynamicState, m_internalData->setupState);
2452
2453 pickedDynamicStateInfo.pDynamicStates = states.data();
2454 pickedDynamicStateInfo.dynamicStateCount = static_cast<uint32_t>(states.size());
2455 }
2456
2457 VkGraphicsPipelineCreateInfo pipelinePartCreateInfo = initVulkanStructure();
2458 pipelinePartCreateInfo.pNext = firstStructInChain;
2459 pipelinePartCreateInfo.flags =
2460 (m_internalData->pipelineFlags | VK_PIPELINE_CREATE_LIBRARY_BIT_KHR) & ~VK_PIPELINE_CREATE_DERIVATIVE_BIT;
2461 pipelinePartCreateInfo.pVertexInputState = pVertexInputState;
2462 pipelinePartCreateInfo.pInputAssemblyState = pInputAssemblyState;
2463 pipelinePartCreateInfo.pDynamicState = &pickedDynamicStateInfo;
2464
2465 if (m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_LINK_TIME_OPTIMIZED_LIBRARY)
2466 pipelinePartCreateInfo.flags |= VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
2467
2468 VkPipelineCreateFlags2CreateInfoKHR pipelineFlags2CreateInfo = initVulkanStructure();
2469 if (m_internalData->pipelineFlags2)
2470 {
2471 pipelineFlags2CreateInfo.flags =
2472 m_internalData->pipelineFlags2 | translateCreateFlag(pipelinePartCreateInfo.flags);
2473 addToChain(&firstStructInChain, &pipelineFlags2CreateInfo);
2474 pipelinePartCreateInfo.flags = 0u;
2475 }
2476
2477 m_pipelineParts[0] = makeGraphicsPipeline(m_internalData->vk, m_internalData->device, partPipelineCache,
2478 &pipelinePartCreateInfo);
2479 }
2480 #endif // CTS_USES_VULKANSC
2481
2482 return *this;
2483 }
2484
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)2485 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setupPreRasterizationShaderState(
2486 const std::vector<VkViewport> &viewports, const std::vector<VkRect2D> &scissors,
2487 const PipelineLayoutWrapper &layout, const VkRenderPass renderPass, const uint32_t subpass,
2488 const ShaderWrapper vertexShader, const VkPipelineRasterizationStateCreateInfo *rasterizationState,
2489 const ShaderWrapper tessellationControlShader, const ShaderWrapper tessellationEvalShader,
2490 const ShaderWrapper geometryShader, const VkSpecializationInfo *specializationInfo,
2491 VkPipelineFragmentShadingRateStateCreateInfoKHR *fragmentShadingRateState,
2492 PipelineRenderingCreateInfoWrapper rendering, const VkPipelineCache partPipelineCache,
2493 PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback)
2494 {
2495 return setupPreRasterizationShaderState2(
2496 viewports, scissors, layout, renderPass, subpass, vertexShader, rasterizationState, tessellationControlShader,
2497 tessellationEvalShader, geometryShader,
2498 // Reuse the same specialization info for all stages.
2499 specializationInfo, specializationInfo, specializationInfo, specializationInfo, fragmentShadingRateState,
2500 rendering, partPipelineCache, partCreationFeedback);
2501 }
2502
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)2503 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setupPreRasterizationShaderState2(
2504 const std::vector<VkViewport> &viewports, const std::vector<VkRect2D> &scissors,
2505 const PipelineLayoutWrapper &layout, const VkRenderPass renderPass, const uint32_t subpass,
2506 const ShaderWrapper vertexShader, const VkPipelineRasterizationStateCreateInfo *rasterizationState,
2507 const ShaderWrapper tessellationControlShader, const ShaderWrapper tessellationEvalShader,
2508 const ShaderWrapper geometryShader, const VkSpecializationInfo *vertSpecializationInfo,
2509 const VkSpecializationInfo *tescSpecializationInfo, const VkSpecializationInfo *teseSpecializationInfo,
2510 const VkSpecializationInfo *geomSpecializationInfo,
2511 VkPipelineFragmentShadingRateStateCreateInfoKHR *fragmentShadingRateState,
2512 PipelineRenderingCreateInfoWrapper rendering, const VkPipelineCache partPipelineCache,
2513 PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback)
2514 {
2515 return setupPreRasterizationShaderState3(
2516 viewports, scissors, layout, renderPass, subpass, vertexShader,
2517 PipelineShaderStageModuleIdentifierCreateInfoWrapper(), rasterizationState, tessellationControlShader,
2518 PipelineShaderStageModuleIdentifierCreateInfoWrapper(), tessellationEvalShader,
2519 PipelineShaderStageModuleIdentifierCreateInfoWrapper(), geometryShader,
2520 PipelineShaderStageModuleIdentifierCreateInfoWrapper(), vertSpecializationInfo, tescSpecializationInfo,
2521 teseSpecializationInfo, geomSpecializationInfo, fragmentShadingRateState, rendering, partPipelineCache,
2522 partCreationFeedback);
2523 }
2524
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)2525 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setupPreRasterizationShaderState3(
2526 const std::vector<VkViewport> &viewports, const std::vector<VkRect2D> &scissors,
2527 const PipelineLayoutWrapper &layout, const VkRenderPass renderPass, const uint32_t subpass,
2528 const ShaderWrapper vertexShader, PipelineShaderStageModuleIdentifierCreateInfoWrapper vertShaderModuleId,
2529 const VkPipelineRasterizationStateCreateInfo *rasterizationState, const ShaderWrapper tessellationControlShader,
2530 PipelineShaderStageModuleIdentifierCreateInfoWrapper tescShaderModuleId, const ShaderWrapper tessellationEvalShader,
2531 PipelineShaderStageModuleIdentifierCreateInfoWrapper teseShaderModuleId, const ShaderWrapper geometryShader,
2532 PipelineShaderStageModuleIdentifierCreateInfoWrapper geomShaderModuleId,
2533 const VkSpecializationInfo *vertSpecializationInfo, const VkSpecializationInfo *tescSpecializationInfo,
2534 const VkSpecializationInfo *teseSpecializationInfo, const VkSpecializationInfo *geomSpecializationInfo,
2535 VkPipelineFragmentShadingRateStateCreateInfoKHR *fragmentShadingRateState,
2536 PipelineRenderingCreateInfoWrapper rendering, const VkPipelineCache partPipelineCache,
2537 PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback)
2538 {
2539 // make sure pipeline was not already build
2540 DE_ASSERT(m_pipelineFinal.get() == DE_NULL);
2541
2542 // 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
2543 DE_ASSERT(m_internalData && (m_internalData->setupState == PSS_VERTEX_INPUT_INTERFACE));
2544
2545 // Unreference variables that are not used in Vulkan SC. No need to put this in ifdef.
2546 DE_UNREF(partPipelineCache);
2547 DE_UNREF(partCreationFeedback);
2548 DE_UNREF(vertShaderModuleId);
2549 DE_UNREF(tescShaderModuleId);
2550 DE_UNREF(teseShaderModuleId);
2551 DE_UNREF(geomShaderModuleId);
2552
2553 m_internalData->setupState |= PSS_PRE_RASTERIZATION_SHADERS;
2554 m_internalData->pFragmentShadingRateState = fragmentShadingRateState;
2555 m_internalData->pRenderingState.ptr = rendering.ptr;
2556
2557 const bool hasTesc = (tessellationControlShader.isSet() || tescShaderModuleId.ptr);
2558 const bool hasTese = (tessellationEvalShader.isSet() || teseShaderModuleId.ptr);
2559 const bool hasGeom = (geometryShader.isSet() || geomShaderModuleId.ptr);
2560
2561 const auto pRasterizationState =
2562 rasterizationState ?
2563 rasterizationState :
2564 (m_internalData->useDefaultRasterizationState ? &m_internalData->defaultRasterizationState : DE_NULL);
2565 const bool forceNullTessState =
2566 (m_internalData->tessellationState.patchControlPoints == std::numeric_limits<uint32_t>::max());
2567 const auto pTessellationState =
2568 ((hasTesc || hasTese) && !forceNullTessState) ? &m_internalData->tessellationState : nullptr;
2569 const auto pViewportState = m_internalData->useViewportState ? &m_internalData->viewportState : DE_NULL;
2570
2571 VkPipelineCreateFlags shaderModuleIdFlags = 0u;
2572
2573 m_internalData->vertexShader = vertexShader;
2574 m_internalData->vertexShader.setLayoutAndSpecialization(&layout, vertSpecializationInfo);
2575 if (!isConstructionTypeShaderObject(m_internalData->pipelineConstructionType))
2576 m_internalData->vertexShader.createModule();
2577
2578 // reserve space for all stages including fragment - this is needed when we create monolithic pipeline
2579 m_internalData->pipelineShaderStages = std::vector<VkPipelineShaderStageCreateInfo>(
2580 2u + hasTesc + hasTese + hasGeom,
2581 {
2582 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType
2583 DE_NULL, // const void* pNext
2584 0u, // VkPipelineShaderStageCreateFlags flags
2585 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage
2586 m_internalData->vertexShader.getModule(), // VkShaderModule module
2587 "main", // const char* pName
2588 vertSpecializationInfo // const VkSpecializationInfo* pSpecializationInfo
2589 });
2590
2591 #ifndef CTS_USES_VULKANSC
2592 if (vertShaderModuleId.ptr)
2593 {
2594 m_internalData->pipelineShaderIdentifiers.emplace_back(
2595 new PipelineShaderStageModuleIdentifierCreateInfoWrapper(vertShaderModuleId.ptr));
2596 m_internalData->pipelineShaderStages[0].pNext = m_internalData->pipelineShaderIdentifiers.back().get()->ptr;
2597
2598 if (!vertexShader.isSet())
2599 shaderModuleIdFlags |= VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT;
2600 }
2601 #endif // CTS_USES_VULKANSC
2602
2603 std::vector<VkPipelineShaderStageCreateInfo>::iterator currStage = m_internalData->pipelineShaderStages.begin() + 1;
2604
2605 if (hasTesc)
2606 {
2607 m_internalData->tessellationControlShader = tessellationControlShader;
2608 m_internalData->tessellationControlShader.setLayoutAndSpecialization(&layout, tescSpecializationInfo);
2609 if (!isConstructionTypeShaderObject(m_internalData->pipelineConstructionType))
2610 m_internalData->tessellationControlShader.createModule();
2611
2612 currStage->stage = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
2613 currStage->module = m_internalData->tessellationControlShader.getModule();
2614 currStage->pSpecializationInfo = tescSpecializationInfo;
2615
2616 #ifndef CTS_USES_VULKANSC
2617 if (tescShaderModuleId.ptr)
2618 {
2619 m_internalData->pipelineShaderIdentifiers.emplace_back(
2620 new PipelineShaderStageModuleIdentifierCreateInfoWrapper(tescShaderModuleId.ptr));
2621 currStage->pNext = m_internalData->pipelineShaderIdentifiers.back().get()->ptr;
2622
2623 if (!tessellationControlShader.isSet())
2624 shaderModuleIdFlags |= VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT;
2625 }
2626 #endif // CTS_USES_VULKANSC
2627
2628 ++currStage;
2629 }
2630
2631 if (hasTese)
2632 {
2633 m_internalData->tessellationEvaluationShader = tessellationEvalShader;
2634 m_internalData->tessellationEvaluationShader.setLayoutAndSpecialization(&layout, teseSpecializationInfo);
2635 if (!isConstructionTypeShaderObject(m_internalData->pipelineConstructionType))
2636 m_internalData->tessellationEvaluationShader.createModule();
2637
2638 currStage->stage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
2639 currStage->module = m_internalData->tessellationEvaluationShader.getModule();
2640 currStage->pSpecializationInfo = teseSpecializationInfo;
2641
2642 #ifndef CTS_USES_VULKANSC
2643 if (teseShaderModuleId.ptr)
2644 {
2645 m_internalData->pipelineShaderIdentifiers.emplace_back(
2646 new PipelineShaderStageModuleIdentifierCreateInfoWrapper(teseShaderModuleId.ptr));
2647 currStage->pNext = m_internalData->pipelineShaderIdentifiers.back().get()->ptr;
2648
2649 if (!tessellationEvalShader.isSet())
2650 shaderModuleIdFlags |= VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT;
2651 }
2652 #endif // CTS_USES_VULKANSC
2653
2654 ++currStage;
2655 }
2656
2657 if (hasGeom)
2658 {
2659 m_internalData->geometryShader = geometryShader;
2660 m_internalData->geometryShader.setLayoutAndSpecialization(&layout, geomSpecializationInfo);
2661 if (!isConstructionTypeShaderObject(m_internalData->pipelineConstructionType))
2662 m_internalData->geometryShader.createModule();
2663
2664 currStage->stage = VK_SHADER_STAGE_GEOMETRY_BIT;
2665 currStage->module = m_internalData->geometryShader.getModule();
2666 currStage->pSpecializationInfo = geomSpecializationInfo;
2667
2668 #ifndef CTS_USES_VULKANSC
2669 if (geomShaderModuleId.ptr)
2670 {
2671 m_internalData->pipelineShaderIdentifiers.emplace_back(
2672 new PipelineShaderStageModuleIdentifierCreateInfoWrapper(geomShaderModuleId.ptr));
2673 currStage->pNext = m_internalData->pipelineShaderIdentifiers.back().get()->ptr;
2674
2675 if (!geometryShader.isSet())
2676 shaderModuleIdFlags |= VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT;
2677 }
2678 #endif // CTS_USES_VULKANSC
2679 }
2680
2681 if (pViewportState)
2682 {
2683 if (!viewports.empty())
2684 {
2685 pViewportState->viewportCount = (uint32_t)viewports.size();
2686 pViewportState->pViewports = &viewports[0];
2687 }
2688 if (!scissors.empty())
2689 {
2690 pViewportState->scissorCount = (uint32_t)scissors.size();
2691 pViewportState->pScissors = &scissors[0];
2692 }
2693 }
2694
2695 // if pipeline layout was not specified with setupMonolithicPipelineLayout
2696 // then use layout from setupPreRasterizationShaderState for link pipeline
2697 if (!m_internalData->explicitLinkPipelineLayoutSet)
2698 m_internalData->monolithicPipelineCreateInfo.layout = *layout;
2699
2700 if (!isConstructionTypeLibrary(m_internalData->pipelineConstructionType))
2701 {
2702 m_internalData->monolithicPipelineCreateInfo.renderPass = renderPass;
2703 m_internalData->monolithicPipelineCreateInfo.subpass = subpass;
2704 m_internalData->monolithicPipelineCreateInfo.pRasterizationState = pRasterizationState;
2705 m_internalData->monolithicPipelineCreateInfo.pViewportState = pViewportState;
2706 m_internalData->monolithicPipelineCreateInfo.stageCount = 1u + hasTesc + hasTese + hasGeom;
2707 m_internalData->monolithicPipelineCreateInfo.pStages = m_internalData->pipelineShaderStages.data();
2708 m_internalData->monolithicPipelineCreateInfo.pTessellationState = pTessellationState;
2709 m_internalData->monolithicPipelineCreateInfo.flags |= shaderModuleIdFlags;
2710 }
2711
2712 #ifndef CTS_USES_VULKANSC
2713 // note we could just use else to if statement above but sinc
2714 // this section is cut out for Vulkan SC its cleaner with separate if
2715 if (isConstructionTypeLibrary(m_internalData->pipelineConstructionType))
2716 {
2717 auto libraryCreateInfo =
2718 makeGraphicsPipelineLibraryCreateInfo(VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT);
2719 void *firstStructInChain = reinterpret_cast<void *>(&libraryCreateInfo);
2720 addToChain(&firstStructInChain, m_internalData->pFragmentShadingRateState);
2721 addToChain(&firstStructInChain, m_internalData->pRenderingState.ptr);
2722 addToChain(&firstStructInChain, partCreationFeedback.ptr);
2723 addToChain(&firstStructInChain, m_internalData->pPipelineRobustnessState.ptr);
2724
2725 VkPipelineDynamicStateCreateInfo pickedDynamicStateInfo = initVulkanStructure();
2726 std::vector<VkDynamicState> states;
2727
2728 if (m_internalData->pDynamicState)
2729 {
2730 states = getDynamicStates(m_internalData->pDynamicState, m_internalData->setupState);
2731
2732 pickedDynamicStateInfo.pDynamicStates = states.data();
2733 pickedDynamicStateInfo.dynamicStateCount = static_cast<uint32_t>(states.size());
2734 }
2735
2736 VkGraphicsPipelineCreateInfo pipelinePartCreateInfo = initVulkanStructure();
2737 pipelinePartCreateInfo.pNext = firstStructInChain;
2738 pipelinePartCreateInfo.flags =
2739 (m_internalData->pipelineFlags | VK_PIPELINE_CREATE_LIBRARY_BIT_KHR | shaderModuleIdFlags) &
2740 ~VK_PIPELINE_CREATE_DERIVATIVE_BIT;
2741 pipelinePartCreateInfo.layout = *layout;
2742 pipelinePartCreateInfo.renderPass = renderPass;
2743 pipelinePartCreateInfo.subpass = subpass;
2744 pipelinePartCreateInfo.pRasterizationState = pRasterizationState;
2745 pipelinePartCreateInfo.pViewportState = pViewportState;
2746 pipelinePartCreateInfo.stageCount = 1u + hasTesc + hasTese + hasGeom;
2747 pipelinePartCreateInfo.pStages = m_internalData->pipelineShaderStages.data();
2748 pipelinePartCreateInfo.pTessellationState = pTessellationState;
2749 pipelinePartCreateInfo.pDynamicState = &pickedDynamicStateInfo;
2750
2751 if (m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_LINK_TIME_OPTIMIZED_LIBRARY)
2752 pipelinePartCreateInfo.flags |= VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
2753
2754 if ((shaderModuleIdFlags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT) != 0)
2755 m_internalData->failOnCompileWhenLinking = true;
2756
2757 VkPipelineCreateFlags2CreateInfoKHR pipelineFlags2CreateInfo = initVulkanStructure();
2758 if (m_internalData->pipelineFlags2)
2759 {
2760 pipelineFlags2CreateInfo.flags =
2761 m_internalData->pipelineFlags2 | translateCreateFlag(pipelinePartCreateInfo.flags);
2762 addToChain(&firstStructInChain, &pipelineFlags2CreateInfo);
2763 pipelinePartCreateInfo.flags = 0u;
2764 }
2765
2766 m_pipelineParts[1] = makeGraphicsPipeline(m_internalData->vk, m_internalData->device, partPipelineCache,
2767 &pipelinePartCreateInfo);
2768 }
2769 #endif // CTS_USES_VULKANSC
2770
2771 return *this;
2772 }
2773
2774 #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)2775 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setupPreRasterizationMeshShaderState(
2776 const std::vector<VkViewport> &viewports, const std::vector<VkRect2D> &scissors,
2777 const PipelineLayoutWrapper &layout, const VkRenderPass renderPass, const uint32_t subpass,
2778 const ShaderWrapper taskShader, const ShaderWrapper meshShader,
2779 const VkPipelineRasterizationStateCreateInfo *rasterizationState,
2780 const VkSpecializationInfo *taskSpecializationInfo, const VkSpecializationInfo *meshSpecializationInfo,
2781 VkPipelineFragmentShadingRateStateCreateInfoKHR *fragmentShadingRateState,
2782 PipelineRenderingCreateInfoWrapper rendering, const VkPipelineCache partPipelineCache,
2783 VkPipelineCreationFeedbackCreateInfoEXT *partCreationFeedback)
2784 {
2785 // Make sure pipeline was not already built.
2786 DE_ASSERT(m_pipelineFinal.get() == DE_NULL);
2787
2788 // Make sure states are set in order - this state needs to be set first or second.
2789 DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_PRE_RASTERIZATION_SHADERS));
2790
2791 // The vertex input interface is not needed for mesh shading pipelines, so we're going to mark it as ready here.
2792 m_internalData->setupState |= (PSS_VERTEX_INPUT_INTERFACE | PSS_PRE_RASTERIZATION_SHADERS);
2793 m_internalData->pFragmentShadingRateState = fragmentShadingRateState;
2794 m_internalData->pRenderingState = rendering;
2795
2796 const bool hasTask = (taskShader.isSet());
2797 const auto taskShaderCount = static_cast<uint32_t>(hasTask);
2798 const auto pRasterizationState =
2799 rasterizationState ?
2800 rasterizationState :
2801 (m_internalData->useDefaultRasterizationState ? &m_internalData->defaultRasterizationState : nullptr);
2802 const auto pTessellationState = nullptr;
2803 const auto pViewportState = m_internalData->useViewportState ? &m_internalData->viewportState : DE_NULL;
2804
2805 // Reserve space for all stages including fragment. This is needed when we create monolithic pipeline.
2806 m_internalData->pipelineShaderStages = std::vector<VkPipelineShaderStageCreateInfo>(
2807 2u + taskShaderCount,
2808 {
2809 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType
2810 nullptr, // const void* pNext
2811 0u, // VkPipelineShaderStageCreateFlags flags
2812 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage
2813 DE_NULL, // VkShaderModule module
2814 "main", // const char* pName
2815 nullptr, // const VkSpecializationInfo* pSpecializationInfo
2816 });
2817
2818 // Mesh shader.
2819 auto currStage = m_internalData->pipelineShaderStages.begin();
2820 {
2821 m_internalData->meshShader = meshShader;
2822 m_internalData->meshShader.setLayoutAndSpecialization(&layout, meshSpecializationInfo);
2823 if (!isConstructionTypeShaderObject(m_internalData->pipelineConstructionType))
2824 m_internalData->meshShader.createModule();
2825
2826 auto &stageInfo = *currStage;
2827
2828 stageInfo.stage = VK_SHADER_STAGE_MESH_BIT_EXT;
2829 stageInfo.module = m_internalData->meshShader.getModule();
2830 stageInfo.pSpecializationInfo = meshSpecializationInfo;
2831
2832 ++currStage;
2833 }
2834
2835 if (hasTask)
2836 {
2837 m_internalData->taskShader = taskShader;
2838 m_internalData->taskShader.setLayoutAndSpecialization(&layout, taskSpecializationInfo);
2839 if (!isConstructionTypeShaderObject(m_internalData->pipelineConstructionType))
2840 m_internalData->taskShader.createModule();
2841
2842 auto &stageInfo = *currStage;
2843
2844 stageInfo.stage = VK_SHADER_STAGE_TASK_BIT_EXT;
2845 stageInfo.module = m_internalData->taskShader.getModule();
2846 stageInfo.pSpecializationInfo = taskSpecializationInfo;
2847
2848 ++currStage;
2849 }
2850
2851 if (pViewportState)
2852 {
2853 if (!viewports.empty())
2854 {
2855 pViewportState->viewportCount = (uint32_t)viewports.size();
2856 pViewportState->pViewports = &viewports[0];
2857 }
2858 if (!scissors.empty())
2859 {
2860 pViewportState->scissorCount = (uint32_t)scissors.size();
2861 pViewportState->pScissors = &scissors[0];
2862 }
2863 }
2864
2865 // if pipeline layout was not specified with setupMonolithicPipelineLayout
2866 // then use layout from setupPreRasterizationMeshShaderState for link pipeline
2867 if (!m_internalData->explicitLinkPipelineLayoutSet)
2868 m_internalData->monolithicPipelineCreateInfo.layout = *layout;
2869
2870 if (!isConstructionTypeLibrary(m_internalData->pipelineConstructionType))
2871 {
2872 m_internalData->monolithicPipelineCreateInfo.renderPass = renderPass;
2873 m_internalData->monolithicPipelineCreateInfo.subpass = subpass;
2874 m_internalData->monolithicPipelineCreateInfo.pRasterizationState = pRasterizationState;
2875 m_internalData->monolithicPipelineCreateInfo.pViewportState = pViewportState;
2876 m_internalData->monolithicPipelineCreateInfo.stageCount = 1u + taskShaderCount;
2877 m_internalData->monolithicPipelineCreateInfo.pStages = m_internalData->pipelineShaderStages.data();
2878 m_internalData->monolithicPipelineCreateInfo.pTessellationState = pTessellationState;
2879 }
2880 else
2881 {
2882 auto libraryCreateInfo =
2883 makeGraphicsPipelineLibraryCreateInfo(VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT);
2884 void *firstStructInChain = reinterpret_cast<void *>(&libraryCreateInfo);
2885 addToChain(&firstStructInChain, m_internalData->pFragmentShadingRateState);
2886 addToChain(&firstStructInChain, m_internalData->pRenderingState.ptr);
2887 addToChain(&firstStructInChain, partCreationFeedback);
2888 addToChain(&firstStructInChain, m_internalData->pPipelineRobustnessState.ptr);
2889
2890 VkPipelineDynamicStateCreateInfo pickedDynamicStateInfo = initVulkanStructure();
2891 std::vector<VkDynamicState> states;
2892
2893 if (m_internalData->pDynamicState)
2894 {
2895 states = getDynamicStates(m_internalData->pDynamicState, m_internalData->setupState);
2896
2897 pickedDynamicStateInfo.pDynamicStates = states.data();
2898 pickedDynamicStateInfo.dynamicStateCount = static_cast<uint32_t>(states.size());
2899 }
2900
2901 VkGraphicsPipelineCreateInfo pipelinePartCreateInfo = initVulkanStructure();
2902 pipelinePartCreateInfo.pNext = firstStructInChain;
2903 pipelinePartCreateInfo.flags = m_internalData->pipelineFlags | VK_PIPELINE_CREATE_LIBRARY_BIT_KHR;
2904 pipelinePartCreateInfo.layout = *layout;
2905 pipelinePartCreateInfo.renderPass = renderPass;
2906 pipelinePartCreateInfo.subpass = subpass;
2907 pipelinePartCreateInfo.pRasterizationState = pRasterizationState;
2908 pipelinePartCreateInfo.pViewportState = pViewportState;
2909 pipelinePartCreateInfo.stageCount = 1u + taskShaderCount;
2910 pipelinePartCreateInfo.pStages = m_internalData->pipelineShaderStages.data();
2911 pipelinePartCreateInfo.pTessellationState = pTessellationState;
2912 pipelinePartCreateInfo.pDynamicState = &pickedDynamicStateInfo;
2913
2914 if (m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_LINK_TIME_OPTIMIZED_LIBRARY)
2915 pipelinePartCreateInfo.flags |= VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
2916
2917 VkPipelineCreateFlags2CreateInfoKHR pipelineFlags2CreateInfo = initVulkanStructure();
2918 if (m_internalData->pipelineFlags2)
2919 {
2920 pipelineFlags2CreateInfo.flags =
2921 m_internalData->pipelineFlags2 | translateCreateFlag(pipelinePartCreateInfo.flags);
2922 addToChain(&firstStructInChain, &pipelineFlags2CreateInfo);
2923 pipelinePartCreateInfo.flags = 0u;
2924 }
2925
2926 m_pipelineParts[1] = createGraphicsPipeline(m_internalData->vk, m_internalData->device, partPipelineCache,
2927 &pipelinePartCreateInfo);
2928 }
2929
2930 return *this;
2931 }
2932 #endif // CTS_USES_VULKANSC
2933
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)2934 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setupFragmentShaderState(
2935 const PipelineLayoutWrapper &layout, const VkRenderPass renderPass, const uint32_t subpass,
2936 const ShaderWrapper fragmentShader, const VkPipelineDepthStencilStateCreateInfo *depthStencilState,
2937 const VkPipelineMultisampleStateCreateInfo *multisampleState, const VkSpecializationInfo *specializationInfo,
2938 const VkPipelineCache partPipelineCache, PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback,
2939 RenderingInputAttachmentIndexInfoWrapper renderingInputAttachmentIndexInfo)
2940 {
2941 return setupFragmentShaderState2(layout, renderPass, subpass, fragmentShader,
2942 PipelineShaderStageModuleIdentifierCreateInfoWrapper(), depthStencilState,
2943 multisampleState, specializationInfo, partPipelineCache, partCreationFeedback,
2944 renderingInputAttachmentIndexInfo);
2945 }
2946
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)2947 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setupFragmentShaderState2(
2948 const PipelineLayoutWrapper &layout, const VkRenderPass renderPass, const uint32_t subpass,
2949 const ShaderWrapper fragmentShader, PipelineShaderStageModuleIdentifierCreateInfoWrapper fragmentShaderModuleId,
2950 const VkPipelineDepthStencilStateCreateInfo *depthStencilState,
2951 const VkPipelineMultisampleStateCreateInfo *multisampleState, const VkSpecializationInfo *specializationInfo,
2952 const VkPipelineCache partPipelineCache, PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback,
2953 RenderingInputAttachmentIndexInfoWrapper renderingInputAttachmentIndexInfo)
2954 {
2955 // make sure pipeline was not already build
2956 DE_ASSERT(m_pipelineFinal.get() == DE_NULL);
2957
2958 // 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
2959 DE_ASSERT(m_internalData &&
2960 (m_internalData->setupState == (PSS_VERTEX_INPUT_INTERFACE | PSS_PRE_RASTERIZATION_SHADERS)));
2961
2962 // Unreference variables that are not used in Vulkan SC. No need to put this in ifdef.
2963 DE_UNREF(layout);
2964 DE_UNREF(renderPass);
2965 DE_UNREF(subpass);
2966 DE_UNREF(partPipelineCache);
2967 DE_UNREF(partCreationFeedback);
2968 DE_UNREF(fragmentShaderModuleId);
2969
2970 m_internalData->setupState |= PSS_FRAGMENT_SHADER;
2971 m_internalData->pRenderingInputAttachmentIndex.ptr = renderingInputAttachmentIndexInfo.ptr;
2972
2973 const auto pDepthStencilState =
2974 depthStencilState ? depthStencilState :
2975 (m_internalData->useDefaultDepthStencilState ? &defaultDepthStencilState : DE_NULL);
2976 const auto pMultisampleState =
2977 multisampleState ? multisampleState :
2978 (m_internalData->useDefaultMultisampleState ? &defaultMultisampleState : DE_NULL);
2979 const bool hasFrag = (fragmentShader.isSet() || fragmentShaderModuleId.ptr);
2980
2981 VkPipelineCreateFlags shaderModuleIdFlags = 0u;
2982
2983 uint32_t stageIndex = 1;
2984 if (hasFrag)
2985 {
2986 // find free space for fragment shader
2987 for (; stageIndex < 5; ++stageIndex)
2988 {
2989 if (m_internalData->pipelineShaderStages[stageIndex].stage == VK_SHADER_STAGE_VERTEX_BIT)
2990 {
2991 m_internalData->fragmentShader = fragmentShader;
2992 m_internalData->fragmentShader.setLayoutAndSpecialization(&layout, specializationInfo);
2993 if (!isConstructionTypeShaderObject(m_internalData->pipelineConstructionType))
2994 m_internalData->fragmentShader.createModule();
2995
2996 m_internalData->pipelineShaderStages[stageIndex].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
2997 m_internalData->pipelineShaderStages[stageIndex].module = m_internalData->fragmentShader.getModule();
2998 m_internalData->pipelineShaderStages[stageIndex].pSpecializationInfo = specializationInfo;
2999 #ifndef CTS_USES_VULKANSC
3000 if (fragmentShaderModuleId.ptr)
3001 {
3002 m_internalData->pipelineShaderIdentifiers.emplace_back(
3003 new PipelineShaderStageModuleIdentifierCreateInfoWrapper(fragmentShaderModuleId.ptr));
3004 m_internalData->pipelineShaderStages[stageIndex].pNext =
3005 m_internalData->pipelineShaderIdentifiers.back().get()->ptr;
3006
3007 if (!fragmentShader.isSet())
3008 shaderModuleIdFlags |= VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT;
3009 }
3010 #endif // CTS_USES_VULKANSC
3011 break;
3012 }
3013 }
3014 }
3015
3016 if (!isConstructionTypeLibrary(m_internalData->pipelineConstructionType))
3017 {
3018 m_internalData->monolithicPipelineCreateInfo.pDepthStencilState = pDepthStencilState;
3019 m_internalData->monolithicPipelineCreateInfo.pMultisampleState = pMultisampleState;
3020 m_internalData->monolithicPipelineCreateInfo.stageCount += (hasFrag ? 1u : 0u);
3021 m_internalData->monolithicPipelineCreateInfo.flags |= shaderModuleIdFlags;
3022 }
3023
3024 #ifndef CTS_USES_VULKANSC
3025 // note we could just use else to if statement above but sinc
3026 // this section is cut out for Vulkan SC its cleaner with separate if
3027 if (isConstructionTypeLibrary(m_internalData->pipelineConstructionType))
3028 {
3029 auto libraryCreateInfo =
3030 makeGraphicsPipelineLibraryCreateInfo(VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT);
3031 void *firstStructInChain = reinterpret_cast<void *>(&libraryCreateInfo);
3032 addToChain(&firstStructInChain, m_internalData->pFragmentShadingRateState);
3033 addToChain(&firstStructInChain, m_internalData->pRenderingState.ptr);
3034 addToChain(&firstStructInChain, m_internalData->pRenderingInputAttachmentIndex.ptr);
3035 addToChain(&firstStructInChain, partCreationFeedback.ptr);
3036 addToChain(&firstStructInChain, m_internalData->pRepresentativeFragmentTestState.ptr);
3037 addToChain(&firstStructInChain, m_internalData->pPipelineRobustnessState.ptr);
3038
3039 VkPipelineDynamicStateCreateInfo pickedDynamicStateInfo = initVulkanStructure();
3040 std::vector<VkDynamicState> states;
3041
3042 if (m_internalData->pDynamicState)
3043 {
3044 states = getDynamicStates(m_internalData->pDynamicState, m_internalData->setupState);
3045
3046 pickedDynamicStateInfo.pDynamicStates = states.data();
3047 pickedDynamicStateInfo.dynamicStateCount = static_cast<uint32_t>(states.size());
3048 }
3049
3050 VkGraphicsPipelineCreateInfo pipelinePartCreateInfo = initVulkanStructure();
3051 pipelinePartCreateInfo.pNext = firstStructInChain;
3052 pipelinePartCreateInfo.flags =
3053 (m_internalData->pipelineFlags | VK_PIPELINE_CREATE_LIBRARY_BIT_KHR | shaderModuleIdFlags) &
3054 ~VK_PIPELINE_CREATE_DERIVATIVE_BIT;
3055 pipelinePartCreateInfo.layout = *layout;
3056 pipelinePartCreateInfo.renderPass = renderPass;
3057 pipelinePartCreateInfo.subpass = subpass;
3058 pipelinePartCreateInfo.pDepthStencilState = pDepthStencilState;
3059 pipelinePartCreateInfo.pMultisampleState = pMultisampleState;
3060 pipelinePartCreateInfo.stageCount = hasFrag;
3061 pipelinePartCreateInfo.pStages = hasFrag ? &m_internalData->pipelineShaderStages[stageIndex] : DE_NULL;
3062 pipelinePartCreateInfo.pDynamicState = &pickedDynamicStateInfo;
3063
3064 if (m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_LINK_TIME_OPTIMIZED_LIBRARY)
3065 pipelinePartCreateInfo.flags |= VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
3066
3067 if ((shaderModuleIdFlags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT) != 0)
3068 m_internalData->failOnCompileWhenLinking = true;
3069
3070 VkPipelineCreateFlags2CreateInfoKHR pipelineFlags2CreateInfo = initVulkanStructure();
3071 if (m_internalData->pipelineFlags2)
3072 {
3073 pipelineFlags2CreateInfo.flags =
3074 m_internalData->pipelineFlags2 | translateCreateFlag(pipelinePartCreateInfo.flags);
3075 addToChain(&firstStructInChain, &pipelineFlags2CreateInfo);
3076 pipelinePartCreateInfo.flags = 0u;
3077 }
3078
3079 m_pipelineParts[2] = makeGraphicsPipeline(m_internalData->vk, m_internalData->device, partPipelineCache,
3080 &pipelinePartCreateInfo);
3081 }
3082 #endif // CTS_USES_VULKANSC
3083
3084 return *this;
3085 }
3086
setupFragmentOutputState(const VkRenderPass renderPass,const uint32_t subpass,const VkPipelineColorBlendStateCreateInfo * colorBlendState,const VkPipelineMultisampleStateCreateInfo * multisampleState,const VkPipelineCache partPipelineCache,PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback,RenderingAttachmentLocationInfoWrapper renderingAttachmentLocationInfo)3087 GraphicsPipelineWrapper &GraphicsPipelineWrapper::setupFragmentOutputState(
3088 const VkRenderPass renderPass, const uint32_t subpass, const VkPipelineColorBlendStateCreateInfo *colorBlendState,
3089 const VkPipelineMultisampleStateCreateInfo *multisampleState, const VkPipelineCache partPipelineCache,
3090 PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback,
3091 RenderingAttachmentLocationInfoWrapper renderingAttachmentLocationInfo)
3092 {
3093 // make sure pipeline was not already build
3094 DE_ASSERT(m_pipelineFinal.get() == DE_NULL);
3095
3096 // 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
3097 DE_ASSERT(m_internalData && (m_internalData->setupState ==
3098 (PSS_VERTEX_INPUT_INTERFACE | PSS_PRE_RASTERIZATION_SHADERS | PSS_FRAGMENT_SHADER)));
3099 m_internalData->setupState |= PSS_FRAGMENT_OUTPUT_INTERFACE;
3100 m_internalData->pRenderingAttachmentLocation.ptr = renderingAttachmentLocationInfo.ptr;
3101
3102 // Unreference variables that are not used in Vulkan SC. No need to put this in ifdef.
3103 DE_UNREF(renderPass);
3104 DE_UNREF(subpass);
3105 DE_UNREF(partPipelineCache);
3106 DE_UNREF(partCreationFeedback);
3107
3108 void *firstStructInChain = DE_NULL;
3109 addToChain(&firstStructInChain, m_internalData->pFragmentShadingRateState);
3110
3111 #ifndef CTS_USES_VULKANSC
3112 addToChain(&firstStructInChain, m_internalData->pRenderingState.ptr);
3113 #endif // CTS_USES_VULKANSC
3114
3115 const auto pColorBlendState = colorBlendState ?
3116 colorBlendState :
3117 (m_internalData->useDefaultColorBlendState ? &defaultColorBlendState : DE_NULL);
3118 const auto pMultisampleState =
3119 multisampleState ? multisampleState :
3120 (m_internalData->useDefaultMultisampleState ? &defaultMultisampleState : DE_NULL);
3121
3122 if (!isConstructionTypeLibrary(m_internalData->pipelineConstructionType))
3123 {
3124 m_internalData->monolithicPipelineCreateInfo.pNext = firstStructInChain;
3125 m_internalData->monolithicPipelineCreateInfo.flags |= m_internalData->pipelineFlags;
3126 m_internalData->monolithicPipelineCreateInfo.pColorBlendState = pColorBlendState;
3127 m_internalData->monolithicPipelineCreateInfo.pMultisampleState = pMultisampleState;
3128 }
3129
3130 #ifndef CTS_USES_VULKANSC
3131 // note we could just use else to if statement above but sinc
3132 // this section is cut out for Vulkan SC its cleaner with separate if
3133 if (isConstructionTypeLibrary(m_internalData->pipelineConstructionType))
3134 {
3135 auto libraryCreateInfo =
3136 makeGraphicsPipelineLibraryCreateInfo(VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT);
3137 addToChain(&firstStructInChain, &libraryCreateInfo);
3138 addToChain(&firstStructInChain, partCreationFeedback.ptr);
3139 addToChain(&firstStructInChain, m_internalData->pRenderingAttachmentLocation.ptr);
3140 addToChain(&firstStructInChain, m_internalData->pPipelineRobustnessState.ptr);
3141
3142 VkPipelineDynamicStateCreateInfo pickedDynamicStateInfo = initVulkanStructure();
3143 std::vector<VkDynamicState> states;
3144
3145 if (m_internalData->pDynamicState)
3146 {
3147 states = getDynamicStates(m_internalData->pDynamicState, m_internalData->setupState);
3148
3149 pickedDynamicStateInfo.pDynamicStates = states.data();
3150 pickedDynamicStateInfo.dynamicStateCount = static_cast<uint32_t>(states.size());
3151 }
3152
3153 VkGraphicsPipelineCreateInfo pipelinePartCreateInfo = initVulkanStructure();
3154 pipelinePartCreateInfo.pNext = firstStructInChain;
3155 pipelinePartCreateInfo.flags =
3156 (m_internalData->pipelineFlags | VK_PIPELINE_CREATE_LIBRARY_BIT_KHR) & ~VK_PIPELINE_CREATE_DERIVATIVE_BIT;
3157 pipelinePartCreateInfo.renderPass = renderPass;
3158 pipelinePartCreateInfo.subpass = subpass;
3159 pipelinePartCreateInfo.pColorBlendState = pColorBlendState;
3160 pipelinePartCreateInfo.pMultisampleState = pMultisampleState;
3161 pipelinePartCreateInfo.pDynamicState = &pickedDynamicStateInfo;
3162
3163 if (m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_LINK_TIME_OPTIMIZED_LIBRARY)
3164 pipelinePartCreateInfo.flags |= VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
3165
3166 VkPipelineCreateFlags2CreateInfoKHR pipelineFlags2CreateInfo = initVulkanStructure();
3167 if (m_internalData->pipelineFlags2)
3168 {
3169 pipelineFlags2CreateInfo.flags =
3170 m_internalData->pipelineFlags2 | translateCreateFlag(pipelinePartCreateInfo.flags);
3171 addToChain(&firstStructInChain, &pipelineFlags2CreateInfo);
3172 pipelinePartCreateInfo.flags = 0u;
3173 }
3174
3175 m_pipelineParts[3] = makeGraphicsPipeline(m_internalData->vk, m_internalData->device, partPipelineCache,
3176 &pipelinePartCreateInfo);
3177 }
3178 #endif // CTS_USES_VULKANSC
3179
3180 return *this;
3181 }
3182
3183 #ifndef CTS_USES_VULKANSC
getNextStages(vk::VkShaderStageFlagBits shaderStage,bool tessellationShaders,bool geometryShaders,bool link)3184 vk::VkShaderStageFlags GraphicsPipelineWrapper::getNextStages(vk::VkShaderStageFlagBits shaderStage,
3185 bool tessellationShaders, bool geometryShaders, bool link)
3186 {
3187 if (link)
3188 {
3189 if (shaderStage == vk::VK_SHADER_STAGE_VERTEX_BIT)
3190 {
3191 if (m_internalData->tessellationControlShader.isSet())
3192 return vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
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_TESSELLATION_CONTROL_BIT)
3199 return vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
3200 if (shaderStage == vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
3201 {
3202 if (m_internalData->geometryShader.isSet())
3203 return vk::VK_SHADER_STAGE_GEOMETRY_BIT;
3204 if (m_internalData->fragmentShader.isSet())
3205 return vk::VK_SHADER_STAGE_FRAGMENT_BIT;
3206 }
3207 if (shaderStage == vk::VK_SHADER_STAGE_GEOMETRY_BIT)
3208 {
3209 if (m_internalData->fragmentShader.isSet())
3210 return vk::VK_SHADER_STAGE_FRAGMENT_BIT;
3211 }
3212 if (shaderStage == vk::VK_SHADER_STAGE_TASK_BIT_EXT)
3213 {
3214 if (m_internalData->meshShader.isSet())
3215 return vk::VK_SHADER_STAGE_MESH_BIT_EXT;
3216 if (m_internalData->fragmentShader.isSet())
3217 return vk::VK_SHADER_STAGE_FRAGMENT_BIT;
3218 }
3219 if (shaderStage == vk::VK_SHADER_STAGE_MESH_BIT_EXT)
3220 {
3221 if (m_internalData->fragmentShader.isSet())
3222 return vk::VK_SHADER_STAGE_FRAGMENT_BIT;
3223 }
3224 }
3225 else
3226 {
3227 if (shaderStage == vk::VK_SHADER_STAGE_VERTEX_BIT)
3228 {
3229 VkShaderStageFlags flags = vk::VK_SHADER_STAGE_FRAGMENT_BIT;
3230 if (tessellationShaders)
3231 flags |= vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
3232 if (geometryShaders)
3233 flags |= vk::VK_SHADER_STAGE_GEOMETRY_BIT;
3234 return flags;
3235 }
3236 else if (shaderStage == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
3237 {
3238 return vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
3239 }
3240 else if (shaderStage == vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
3241 {
3242 VkShaderStageFlags flags = vk::VK_SHADER_STAGE_FRAGMENT_BIT;
3243 if (geometryShaders)
3244 flags |= vk::VK_SHADER_STAGE_GEOMETRY_BIT;
3245 return flags;
3246 }
3247 else if (shaderStage == vk::VK_SHADER_STAGE_GEOMETRY_BIT)
3248 {
3249 return vk::VK_SHADER_STAGE_FRAGMENT_BIT;
3250 }
3251 else if (shaderStage == vk::VK_SHADER_STAGE_TASK_BIT_EXT)
3252 {
3253 return vk::VK_SHADER_STAGE_MESH_BIT_EXT;
3254 }
3255 else if (shaderStage == vk::VK_SHADER_STAGE_MESH_BIT_EXT)
3256 {
3257 return vk::VK_SHADER_STAGE_FRAGMENT_BIT;
3258 }
3259 }
3260 return 0;
3261 }
3262
makeShaderCreateInfo(VkShaderStageFlagBits stage,ShaderWrapper & shader,bool link,bool binary,ShaderWrapper & other)3263 vk::VkShaderCreateInfoEXT GraphicsPipelineWrapper::makeShaderCreateInfo(VkShaderStageFlagBits stage,
3264 ShaderWrapper &shader, bool link, bool binary,
3265 ShaderWrapper &other)
3266 {
3267 if (binary)
3268 shader.getShaderBinary();
3269
3270 vk::VkShaderCreateInfoEXT shaderCreateInfo = vk::initVulkanStructure();
3271 shaderCreateInfo.flags =
3272 link ? (vk::VkShaderCreateFlagsEXT)vk::VK_SHADER_CREATE_LINK_STAGE_BIT_EXT : (vk::VkShaderCreateFlagsEXT)0u;
3273 shaderCreateInfo.stage = stage;
3274 shaderCreateInfo.nextStage =
3275 getNextStages(stage, m_internalData->tessellationShaderFeature, m_internalData->geometryShaderFeature, link);
3276 if (binary)
3277 {
3278 shaderCreateInfo.codeType = vk::VK_SHADER_CODE_TYPE_BINARY_EXT;
3279 shaderCreateInfo.codeSize = shader.getShaderBinaryDataSize();
3280 shaderCreateInfo.pCode = shader.getShaderBinaryData();
3281 }
3282 else
3283 {
3284 shaderCreateInfo.codeType = vk::VK_SHADER_CODE_TYPE_SPIRV_EXT;
3285 shaderCreateInfo.codeSize = shader.getCodeSize();
3286 shaderCreateInfo.pCode = shader.getBinary();
3287 }
3288 shaderCreateInfo.pName = "main";
3289 if (shader.getPipelineLayout() != DE_NULL)
3290 {
3291 shaderCreateInfo.setLayoutCount = shader.getPipelineLayout()->getSetLayoutCount();
3292 shaderCreateInfo.pSetLayouts = shader.getPipelineLayout()->getSetLayouts();
3293 shaderCreateInfo.pushConstantRangeCount = shader.getPipelineLayout()->getPushConstantRangeCount();
3294 shaderCreateInfo.pPushConstantRanges = shader.getPipelineLayout()->getPushConstantRanges();
3295 }
3296 // Pipeline layouts and push constant ranges must match between shaders that are used together
3297 if (other.isSet() && shaderCreateInfo.setLayoutCount == 0)
3298 {
3299 shaderCreateInfo.setLayoutCount = other.getPipelineLayout()->getSetLayoutCount();
3300 shaderCreateInfo.pSetLayouts = other.getPipelineLayout()->getSetLayouts();
3301 }
3302 if (other.isSet() && shaderCreateInfo.pushConstantRangeCount == 0)
3303 {
3304 shaderCreateInfo.pushConstantRangeCount = other.getPipelineLayout()->getPushConstantRangeCount();
3305 shaderCreateInfo.pPushConstantRanges = other.getPipelineLayout()->getPushConstantRanges();
3306 }
3307 shaderCreateInfo.pSpecializationInfo = shader.getSpecializationInfo();
3308 return shaderCreateInfo;
3309 }
3310
createShaders(bool linked,bool binary)3311 void GraphicsPipelineWrapper::createShaders(bool linked, bool binary)
3312 {
3313 std::vector<vk::VkShaderCreateInfoEXT> createInfos;
3314 if (m_internalData->vertexShader.isSet())
3315 createInfos.push_back(makeShaderCreateInfo(vk::VK_SHADER_STAGE_VERTEX_BIT, m_internalData->vertexShader, linked,
3316 binary, m_internalData->fragmentShader));
3317 if (m_internalData->tessellationControlShader.isSet())
3318 createInfos.push_back(makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
3319 m_internalData->tessellationControlShader, linked, binary,
3320 m_internalData->fragmentShader));
3321 if (m_internalData->tessellationEvaluationShader.isSet())
3322 createInfos.push_back(makeShaderCreateInfo(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
3323 m_internalData->tessellationEvaluationShader, linked, binary,
3324 m_internalData->fragmentShader));
3325 if (m_internalData->geometryShader.isSet())
3326 createInfos.push_back(makeShaderCreateInfo(vk::VK_SHADER_STAGE_GEOMETRY_BIT, m_internalData->geometryShader,
3327 linked, binary, m_internalData->fragmentShader));
3328 if (m_internalData->fragmentShader.isSet())
3329 createInfos.push_back(makeShaderCreateInfo(vk::VK_SHADER_STAGE_FRAGMENT_BIT, m_internalData->fragmentShader,
3330 linked, binary, m_internalData->vertexShader));
3331 if (m_internalData->taskShader.isSet())
3332 createInfos.push_back(makeShaderCreateInfo(vk::VK_SHADER_STAGE_TASK_BIT_EXT, m_internalData->taskShader, linked,
3333 binary, m_internalData->fragmentShader));
3334 if (m_internalData->meshShader.isSet())
3335 {
3336 createInfos.push_back(makeShaderCreateInfo(vk::VK_SHADER_STAGE_MESH_BIT_EXT, m_internalData->meshShader, linked,
3337 binary, m_internalData->fragmentShader));
3338 if (!m_internalData->taskShader.isSet())
3339 createInfos.back().flags |= vk::VK_SHADER_CREATE_NO_TASK_SHADER_BIT_EXT;
3340 }
3341
3342 std::vector<VkShaderEXT> shaders(createInfos.size());
3343 m_internalData->vk.createShadersEXT(m_internalData->device, (uint32_t)createInfos.size(), createInfos.data(),
3344 DE_NULL, shaders.data());
3345 uint32_t shaderIndex = 0;
3346 if (m_internalData->vertexShader.isSet())
3347 m_internalData->vertexShader.setShader(
3348 Move<VkShaderEXT>(check<VkShaderEXT>(shaders[shaderIndex++]),
3349 Deleter<VkShaderEXT>(m_internalData->vk, m_internalData->device, DE_NULL)));
3350 if (m_internalData->tessellationControlShader.isSet())
3351 m_internalData->tessellationControlShader.setShader(
3352 Move<VkShaderEXT>(check<VkShaderEXT>(shaders[shaderIndex++]),
3353 Deleter<VkShaderEXT>(m_internalData->vk, m_internalData->device, DE_NULL)));
3354 if (m_internalData->tessellationEvaluationShader.isSet())
3355 m_internalData->tessellationEvaluationShader.setShader(
3356 Move<VkShaderEXT>(check<VkShaderEXT>(shaders[shaderIndex++]),
3357 Deleter<VkShaderEXT>(m_internalData->vk, m_internalData->device, DE_NULL)));
3358 if (m_internalData->geometryShader.isSet())
3359 m_internalData->geometryShader.setShader(
3360 Move<VkShaderEXT>(check<VkShaderEXT>(shaders[shaderIndex++]),
3361 Deleter<VkShaderEXT>(m_internalData->vk, m_internalData->device, DE_NULL)));
3362 if (m_internalData->fragmentShader.isSet())
3363 m_internalData->fragmentShader.setShader(
3364 Move<VkShaderEXT>(check<VkShaderEXT>(shaders[shaderIndex++]),
3365 Deleter<VkShaderEXT>(m_internalData->vk, m_internalData->device, DE_NULL)));
3366 if (m_internalData->taskShader.isSet())
3367 m_internalData->taskShader.setShader(
3368 Move<VkShaderEXT>(check<VkShaderEXT>(shaders[shaderIndex++]),
3369 Deleter<VkShaderEXT>(m_internalData->vk, m_internalData->device, DE_NULL)));
3370 if (m_internalData->meshShader.isSet())
3371 m_internalData->meshShader.setShader(
3372 Move<VkShaderEXT>(check<VkShaderEXT>(shaders[shaderIndex++]),
3373 Deleter<VkShaderEXT>(m_internalData->vk, m_internalData->device, DE_NULL)));
3374 }
3375 #endif
3376
buildPipeline(const VkPipelineCache pipelineCache,const VkPipeline basePipelineHandle,const int32_t basePipelineIndex,PipelineCreationFeedbackCreateInfoWrapper creationFeedback)3377 void GraphicsPipelineWrapper::buildPipeline(const VkPipelineCache pipelineCache, const VkPipeline basePipelineHandle,
3378 const int32_t basePipelineIndex,
3379 PipelineCreationFeedbackCreateInfoWrapper creationFeedback)
3380 {
3381 // make sure we are not trying to build pipeline second time
3382 DE_ASSERT(m_pipelineFinal.get() == DE_NULL);
3383
3384 // make sure all states were set
3385 DE_ASSERT(m_internalData &&
3386 (m_internalData->setupState == (PSS_VERTEX_INPUT_INTERFACE | PSS_PRE_RASTERIZATION_SHADERS |
3387 PSS_FRAGMENT_SHADER | PSS_FRAGMENT_OUTPUT_INTERFACE)));
3388
3389 // Unreference variables that are not used in Vulkan SC. No need to put this in ifdef.
3390 DE_UNREF(creationFeedback);
3391
3392 VkGraphicsPipelineCreateInfo *pointerToCreateInfo = &m_internalData->monolithicPipelineCreateInfo;
3393
3394 if (isConstructionTypeShaderObject(m_internalData->pipelineConstructionType))
3395 {
3396 #ifndef CTS_USES_VULKANSC
3397 // Dynamic states that don't require additional extensions
3398 std::vector<vk::VkDynamicState> dynamicStates = {
3399 vk::VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT,
3400 vk::VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT,
3401 vk::VK_DYNAMIC_STATE_LINE_WIDTH,
3402 vk::VK_DYNAMIC_STATE_DEPTH_BIAS,
3403 vk::VK_DYNAMIC_STATE_BLEND_CONSTANTS,
3404 vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS,
3405 vk::VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
3406 vk::VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
3407 vk::VK_DYNAMIC_STATE_STENCIL_REFERENCE,
3408 vk::VK_DYNAMIC_STATE_CULL_MODE_EXT,
3409 vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT,
3410 vk::VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT,
3411 vk::VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT,
3412 vk::VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT,
3413 vk::VK_DYNAMIC_STATE_FRONT_FACE_EXT,
3414 vk::VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT,
3415 vk::VK_DYNAMIC_STATE_STENCIL_OP_EXT,
3416 vk::VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT,
3417 vk::VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT,
3418 vk::VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT,
3419 vk::VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT,
3420 vk::VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT,
3421 vk::VK_DYNAMIC_STATE_LOGIC_OP_EXT,
3422 vk::VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT,
3423 vk::VK_DYNAMIC_STATE_TESSELLATION_DOMAIN_ORIGIN_EXT,
3424 vk::VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT,
3425 vk::VK_DYNAMIC_STATE_POLYGON_MODE_EXT,
3426 vk::VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT,
3427 vk::VK_DYNAMIC_STATE_SAMPLE_MASK_EXT,
3428 vk::VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT,
3429 vk::VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT,
3430 vk::VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT,
3431 vk::VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT,
3432 vk::VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT,
3433 vk::VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT,
3434 vk::VK_DYNAMIC_STATE_VERTEX_INPUT_EXT,
3435 };
3436
3437 vk::VkPhysicalDeviceMeshShaderFeaturesEXT meshShaderFeatures = initVulkanStructure();
3438 vk::VkPhysicalDeviceFeatures2 features = initVulkanStructure(&meshShaderFeatures);
3439 m_internalData->vki.getPhysicalDeviceFeatures2(m_internalData->physicalDevice, &features);
3440
3441 m_internalData->tessellationShaderFeature = features.features.tessellationShader;
3442 m_internalData->geometryShaderFeature = features.features.geometryShader;
3443 m_internalData->taskShaderFeature = meshShaderFeatures.taskShader;
3444 m_internalData->meshShaderFeature = meshShaderFeatures.meshShader;
3445
3446 DE_ASSERT(m_internalData->extensionEnabled("VK_EXT_shader_object"));
3447
3448 // Add dynamic states that are required for each enabled extension
3449 if (m_internalData->extensionEnabled("VK_EXT_transform_feedback"))
3450 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_RASTERIZATION_STREAM_EXT);
3451 if (m_internalData->extensionEnabled("VK_EXT_blend_operation_advanced"))
3452 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_BLEND_ADVANCED_EXT);
3453 if (m_internalData->extensionEnabled("VK_EXT_conservative_rasterization"))
3454 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_CONSERVATIVE_RASTERIZATION_MODE_EXT);
3455 if (m_internalData->extensionEnabled("VK_NV_framebuffer_mixed_samples"))
3456 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_MODULATION_MODE_NV);
3457 if (m_internalData->extensionEnabled("VK_NV_framebuffer_mixed_samples"))
3458 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_ENABLE_NV);
3459 if (m_internalData->extensionEnabled("VK_NV_framebuffer_mixed_samples"))
3460 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_NV);
3461 if (m_internalData->extensionEnabled("VK_NV_coverage_reduction_mode"))
3462 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_REDUCTION_MODE_NV);
3463 if (m_internalData->extensionEnabled("VK_NV_fragment_coverage_to_color"))
3464 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_ENABLE_NV);
3465 if (m_internalData->extensionEnabled("VK_NV_fragment_coverage_to_color"))
3466 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_LOCATION_NV);
3467 if (m_internalData->extensionEnabled("VK_EXT_depth_clip_enable"))
3468 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT);
3469 if (m_internalData->extensionEnabled("VK_EXT_depth_clip_control"))
3470 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT);
3471 if (m_internalData->extensionEnabled("VK_EXT_color_write_enable"))
3472 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT);
3473 if (m_internalData->extensionEnabled("VK_EXT_conservative_rasterization"))
3474 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_EXTRA_PRIMITIVE_OVERESTIMATION_SIZE_EXT);
3475 if (m_internalData->extensionEnabled("VK_KHR_line_rasterization") ||
3476 m_internalData->extensionEnabled("VK_EXT_line_rasterization"))
3477 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT);
3478 if (m_internalData->extensionEnabled("VK_KHR_line_rasterization") ||
3479 m_internalData->extensionEnabled("VK_EXT_line_rasterization"))
3480 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT);
3481 if (m_internalData->extensionEnabled("VK_KHR_line_rasterization") ||
3482 m_internalData->extensionEnabled("VK_EXT_line_rasterization"))
3483 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_LINE_STIPPLE_KHR);
3484 if (m_internalData->extensionEnabled("VK_EXT_provoking_vertex"))
3485 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT);
3486 if (m_internalData->extensionEnabled("VK_KHR_fragment_shading_rate"))
3487 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR);
3488 if (m_internalData->extensionEnabled("VK_NV_representative_fragment_test"))
3489 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_REPRESENTATIVE_FRAGMENT_TEST_ENABLE_NV);
3490 if (m_internalData->extensionEnabled("VK_EXT_sample_locations"))
3491 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_ENABLE_EXT);
3492 if (m_internalData->extensionEnabled("VK_EXT_sample_locations"))
3493 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT);
3494 // Not working with VK_KHR_fragment_shading_rate
3495 /*if (m_internalData->extensionEnabled("VK_NV_shading_rate_image"))
3496 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_SHADING_RATE_IMAGE_ENABLE_NV);
3497 if (m_internalData->extensionEnabled("VK_NV_shading_rate_image"))
3498 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV);
3499 if (m_internalData->extensionEnabled("VK_NV_shading_rate_image"))
3500 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV);*/
3501 if (m_internalData->extensionEnabled("VK_NV_viewport_swizzle"))
3502 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_SWIZZLE_NV);
3503 if (m_internalData->extensionEnabled("VK_NV_clip_space_w_scaling"))
3504 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_ENABLE_NV);
3505 if (m_internalData->extensionEnabled("VK_NV_clip_space_w_scaling"))
3506 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV);
3507 if (m_internalData->extensionEnabled("VK_NV_scissor_exclusive"))
3508 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_ENABLE_NV);
3509 if (m_internalData->extensionEnabled("VK_NV_scissor_exclusive"))
3510 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV);
3511 if (m_internalData->extensionEnabled("VK_EXT_discard_rectangles"))
3512 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_ENABLE_EXT);
3513 if (m_internalData->extensionEnabled("VK_EXT_discard_rectangles"))
3514 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT);
3515 if (m_internalData->extensionEnabled("VK_EXT_discard_rectangles"))
3516 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_MODE_EXT);
3517 if (m_internalData->extensionEnabled("VK_EXT_attachment_feedback_loop_dynamic_state"))
3518 dynamicStates.push_back(vk::VK_DYNAMIC_STATE_ATTACHMENT_FEEDBACK_LOOP_ENABLE_EXT);
3519
3520 // Remove dynamic states that were already set as dynamic for the pipeline
3521 // These dynamic state will already be set in the tests
3522 bool depthClampEnableDynamic = false;
3523 if (pointerToCreateInfo->pDynamicState)
3524 {
3525 for (uint32_t i = 0; i < pointerToCreateInfo->pDynamicState->dynamicStateCount; ++i)
3526 {
3527 if (pointerToCreateInfo->pDynamicState->pDynamicStates[i] == vk::VK_DYNAMIC_STATE_VIEWPORT)
3528 dynamicStates.erase(std::remove(dynamicStates.begin(), dynamicStates.end(),
3529 vk::VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT),
3530 dynamicStates.end());
3531 else if (pointerToCreateInfo->pDynamicState->pDynamicStates[i] == vk::VK_DYNAMIC_STATE_SCISSOR)
3532 dynamicStates.erase(std::remove(dynamicStates.begin(), dynamicStates.end(),
3533 vk::VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT),
3534 dynamicStates.end());
3535 else if (pointerToCreateInfo->pDynamicState->pDynamicStates[i] ==
3536 vk::VK_DYNAMIC_STATE_COLOR_BLEND_ADVANCED_EXT)
3537 {
3538 dynamicStates.erase(std::remove(dynamicStates.begin(), dynamicStates.end(),
3539 vk::VK_DYNAMIC_STATE_COLOR_BLEND_ADVANCED_EXT),
3540 dynamicStates.end());
3541 dynamicStates.erase(std::remove(dynamicStates.begin(), dynamicStates.end(),
3542 vk::VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT),
3543 dynamicStates.end());
3544 }
3545 else if (pointerToCreateInfo->pDynamicState->pDynamicStates[i] == vk::VK_DYNAMIC_STATE_VERTEX_INPUT_EXT)
3546 {
3547 dynamicStates.erase(
3548 std::remove(dynamicStates.begin(), dynamicStates.end(), vk::VK_DYNAMIC_STATE_VERTEX_INPUT_EXT),
3549 dynamicStates.end());
3550 dynamicStates.erase(std::remove(dynamicStates.begin(), dynamicStates.end(),
3551 vk::VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT),
3552 dynamicStates.end());
3553 }
3554 else
3555 dynamicStates.erase(std::remove(dynamicStates.begin(), dynamicStates.end(),
3556 pointerToCreateInfo->pDynamicState->pDynamicStates[i]),
3557 dynamicStates.end());
3558
3559 if (pointerToCreateInfo->pDynamicState->pDynamicStates[i] ==
3560 vk::VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT)
3561 depthClampEnableDynamic = true;
3562 }
3563 }
3564
3565 m_internalData->shaderObjectDynamicStates = dynamicStates;
3566
3567 // Save state needed for setting shader object dynamic state
3568 auto state = &m_internalData->pipelineCreateState;
3569 if (pointerToCreateInfo->pViewportState)
3570 {
3571 if (pointerToCreateInfo->pViewportState->pViewports)
3572 {
3573 state->viewports.resize(pointerToCreateInfo->pViewportState->viewportCount);
3574 for (uint32_t i = 0; i < pointerToCreateInfo->pViewportState->viewportCount; ++i)
3575 state->viewports[i] = pointerToCreateInfo->pViewportState->pViewports[i];
3576 }
3577
3578 if (pointerToCreateInfo->pViewportState->pScissors)
3579 {
3580 state->scissors.resize(pointerToCreateInfo->pViewportState->scissorCount);
3581 for (uint32_t i = 0; i < pointerToCreateInfo->pViewportState->scissorCount; ++i)
3582 state->scissors[i] = pointerToCreateInfo->pViewportState->pScissors[i];
3583 }
3584
3585 const auto depthClipControl = findStructure<VkPipelineViewportDepthClipControlCreateInfoEXT>(
3586 pointerToCreateInfo->pViewportState->pNext);
3587 if (depthClipControl)
3588 state->negativeOneToOne = depthClipControl->negativeOneToOne;
3589 const auto viewportShadingRate = findStructure<VkPipelineViewportShadingRateImageStateCreateInfoNV>(
3590 pointerToCreateInfo->pViewportState->pNext);
3591 if (viewportShadingRate)
3592 {
3593 state->shadingRateImageEnable = viewportShadingRate->shadingRateImageEnable;
3594 state->shadingRatePaletteCount = viewportShadingRate->viewportCount;
3595 state->shadingRatePalettes.resize(viewportShadingRate->viewportCount);
3596 state->shadingRatePaletteEntries.resize(viewportShadingRate->viewportCount);
3597 for (uint32_t i = 0; i < viewportShadingRate->viewportCount; ++i)
3598 {
3599 state->shadingRatePalettes[i] = viewportShadingRate->pShadingRatePalettes[i];
3600 state->shadingRatePaletteEntries[i].resize(
3601 viewportShadingRate->pShadingRatePalettes[i].shadingRatePaletteEntryCount);
3602 for (uint32_t j = 0; j < viewportShadingRate->pShadingRatePalettes[i].shadingRatePaletteEntryCount;
3603 ++j)
3604 state->shadingRatePaletteEntries[i][j] =
3605 viewportShadingRate->pShadingRatePalettes[i].pShadingRatePaletteEntries[j];
3606 state->shadingRatePalettes[i].pShadingRatePaletteEntries =
3607 state->shadingRatePaletteEntries[i].data();
3608 }
3609 }
3610 const auto viewportSwizzle =
3611 findStructure<VkPipelineViewportSwizzleStateCreateInfoNV>(pointerToCreateInfo->pViewportState->pNext);
3612 if (viewportSwizzle)
3613 {
3614 state->viewportSwizzles.resize(viewportSwizzle->viewportCount);
3615 for (uint32_t i = 0; i < viewportSwizzle->viewportCount; ++i)
3616 state->viewportSwizzles[i] = viewportSwizzle->pViewportSwizzles[i];
3617 }
3618 const auto viewportWScaling =
3619 findStructure<VkPipelineViewportWScalingStateCreateInfoNV>(pointerToCreateInfo->pViewportState->pNext);
3620 if (viewportWScaling)
3621 {
3622 state->viewportWScalingEnable = viewportWScaling->viewportWScalingEnable;
3623 state->viewportWScalingCount = viewportWScaling->viewportCount;
3624 state->viewportWScalings.resize(viewportWScaling->viewportCount);
3625 for (uint32_t i = 0; i < viewportWScaling->viewportCount; ++i)
3626 state->viewportWScalings[i] = viewportWScaling->pViewportWScalings[i];
3627 }
3628 const auto coarseSampleOrder = findStructure<VkPipelineViewportCoarseSampleOrderStateCreateInfoNV>(
3629 pointerToCreateInfo->pViewportState->pNext);
3630 if (coarseSampleOrder)
3631 {
3632 state->coarseSampleOrderType = coarseSampleOrder->sampleOrderType;
3633 state->coarseCustomSampleOrderCount = coarseSampleOrder->customSampleOrderCount;
3634 state->coarseCustomSampleOrders.resize(coarseSampleOrder->customSampleOrderCount);
3635 state->coarseSampleLocations.resize(coarseSampleOrder->customSampleOrderCount);
3636 for (uint32_t i = 0; i < coarseSampleOrder->customSampleOrderCount; ++i)
3637 {
3638 state->coarseCustomSampleOrders[i] = coarseSampleOrder->pCustomSampleOrders[i];
3639 state->coarseSampleLocations[i].resize(coarseSampleOrder->pCustomSampleOrders[i].sampleCount);
3640 for (uint32_t j = 0; j < coarseSampleOrder->pCustomSampleOrders[i].sampleCount; ++j)
3641 state->coarseSampleLocations[i][j] =
3642 coarseSampleOrder->pCustomSampleOrders[i].pSampleLocations[j];
3643 state->coarseCustomSampleOrders[i].pSampleLocations = state->coarseSampleLocations[i].data();
3644 }
3645 }
3646 }
3647
3648 if (pointerToCreateInfo->pRasterizationState)
3649 {
3650 state->lineWidth = pointerToCreateInfo->pRasterizationState->lineWidth;
3651 state->depthBiasConstantFactor = pointerToCreateInfo->pRasterizationState->depthBiasConstantFactor;
3652 state->depthBiasClamp = pointerToCreateInfo->pRasterizationState->depthBiasClamp;
3653 state->depthBiasSlopeFactor = pointerToCreateInfo->pRasterizationState->depthBiasSlopeFactor;
3654 state->cullMode = pointerToCreateInfo->pRasterizationState->cullMode;
3655 state->frontFace = pointerToCreateInfo->pRasterizationState->frontFace;
3656 state->depthBiasEnable = pointerToCreateInfo->pRasterizationState->depthBiasEnable;
3657 state->rasterizerDiscardEnable = pointerToCreateInfo->pRasterizationState->rasterizerDiscardEnable;
3658 const auto conservative = findStructure<VkPipelineRasterizationConservativeStateCreateInfoEXT>(
3659 pointerToCreateInfo->pRasterizationState->pNext);
3660 if (conservative)
3661 {
3662 state->conservativeRasterizationMode = conservative->conservativeRasterizationMode;
3663 state->extraPrimitiveOverestimationSize = conservative->extraPrimitiveOverestimationSize;
3664 }
3665 state->depthClampEnable = pointerToCreateInfo->pRasterizationState->depthClampEnable;
3666 const auto depthClip = findStructure<VkPipelineRasterizationDepthClipStateCreateInfoEXT>(
3667 pointerToCreateInfo->pRasterizationState->pNext);
3668 if (depthClip)
3669 state->depthClipEnable = depthClip->depthClipEnable;
3670 else
3671 state->depthClipEnable =
3672 !pointerToCreateInfo->pRasterizationState->depthClampEnable && !depthClampEnableDynamic;
3673
3674 const auto rasterizationLine = findStructure<VkPipelineRasterizationLineStateCreateInfoEXT>(
3675 pointerToCreateInfo->pRasterizationState->pNext);
3676 if (rasterizationLine)
3677 {
3678 state->lineRasterizationMode = rasterizationLine->lineRasterizationMode;
3679 state->stippledLineEnable = rasterizationLine->stippledLineEnable;
3680 state->lineStippleFactor = rasterizationLine->lineStippleFactor;
3681 state->lineStipplePattern = rasterizationLine->lineStipplePattern;
3682 }
3683 const auto rasterizationStream = findStructure<VkPipelineRasterizationStateStreamCreateInfoEXT>(
3684 pointerToCreateInfo->pRasterizationState->pNext);
3685 if (rasterizationStream)
3686 state->rasterizationStream = rasterizationStream->rasterizationStream;
3687 state->polygonMode = pointerToCreateInfo->pRasterizationState->polygonMode;
3688 const auto provokingVertex = findStructure<VkPipelineRasterizationProvokingVertexStateCreateInfoEXT>(
3689 pointerToCreateInfo->pRasterizationState->pNext);
3690 if (provokingVertex)
3691 state->provokingVertexMode = provokingVertex->provokingVertexMode;
3692 const auto depthBiasRepresentationInfo =
3693 findStructure<VkDepthBiasRepresentationInfoEXT>(pointerToCreateInfo->pRasterizationState->pNext);
3694 if (depthBiasRepresentationInfo)
3695 {
3696 state->depthBiasRepresentation = depthBiasRepresentationInfo->depthBiasRepresentation;
3697 state->depthBiasExact = depthBiasRepresentationInfo->depthBiasExact;
3698 }
3699 }
3700 if (pointerToCreateInfo->pColorBlendState)
3701 {
3702 memcpy(&state->blendConstants, pointerToCreateInfo->pColorBlendState->blendConstants, sizeof(float) * 4);
3703 state->logicOp = pointerToCreateInfo->pColorBlendState->logicOp;
3704 const auto blendAdvancedState = findStructure<VkPipelineColorBlendAdvancedStateCreateInfoEXT>(
3705 pointerToCreateInfo->pColorBlendState->pNext);
3706 if (blendAdvancedState)
3707 {
3708 state->colorBlendAdvanced.resize(pointerToCreateInfo->pColorBlendState->attachmentCount);
3709 for (uint32_t i = 0; i < pointerToCreateInfo->pColorBlendState->attachmentCount; ++i)
3710 {
3711 if (pointerToCreateInfo->pColorBlendState->pAttachments)
3712 state->colorBlendAdvanced[i].advancedBlendOp =
3713 pointerToCreateInfo->pColorBlendState->pAttachments[i].colorBlendOp;
3714 state->colorBlendAdvanced[i].srcPremultiplied = blendAdvancedState->srcPremultiplied;
3715 state->colorBlendAdvanced[i].dstPremultiplied = blendAdvancedState->dstPremultiplied;
3716 state->colorBlendAdvanced[i].blendOverlap = blendAdvancedState->blendOverlap;
3717 state->colorBlendAdvanced[i].clampResults = VK_FALSE;
3718 }
3719 }
3720 state->colorBlendEnables.resize(pointerToCreateInfo->pColorBlendState->attachmentCount);
3721 state->blendEquations.resize(pointerToCreateInfo->pColorBlendState->attachmentCount);
3722 state->colorWriteMasks.resize(pointerToCreateInfo->pColorBlendState->attachmentCount);
3723 for (uint32_t i = 0; i < (uint32_t)pointerToCreateInfo->pColorBlendState->attachmentCount; ++i)
3724 {
3725 if (pointerToCreateInfo->pColorBlendState->pAttachments)
3726 {
3727 state->colorBlendEnables[i] = pointerToCreateInfo->pColorBlendState->pAttachments[i].blendEnable;
3728 state->blendEquations[i].srcColorBlendFactor =
3729 pointerToCreateInfo->pColorBlendState->pAttachments[i].srcColorBlendFactor;
3730 state->blendEquations[i].dstColorBlendFactor =
3731 pointerToCreateInfo->pColorBlendState->pAttachments[i].dstColorBlendFactor;
3732 state->blendEquations[i].colorBlendOp =
3733 pointerToCreateInfo->pColorBlendState->pAttachments[i].colorBlendOp;
3734 state->blendEquations[i].srcAlphaBlendFactor =
3735 pointerToCreateInfo->pColorBlendState->pAttachments[i].srcAlphaBlendFactor;
3736 state->blendEquations[i].dstAlphaBlendFactor =
3737 pointerToCreateInfo->pColorBlendState->pAttachments[i].dstAlphaBlendFactor;
3738 state->blendEquations[i].alphaBlendOp =
3739 pointerToCreateInfo->pColorBlendState->pAttachments[i].alphaBlendOp;
3740 state->colorWriteMasks[i] = pointerToCreateInfo->pColorBlendState->pAttachments[i].colorWriteMask;
3741 }
3742
3743 // colorBlendOp and alphaBlendOp must not be advanced blend operations and they will be set with colorBlendAdvanced
3744 if (blendAdvancedState)
3745 {
3746 state->blendEquations[i].colorBlendOp = vk::VK_BLEND_OP_ADD;
3747 state->blendEquations[i].alphaBlendOp = vk::VK_BLEND_OP_ADD;
3748 }
3749 }
3750 state->logicOpEnable = pointerToCreateInfo->pColorBlendState->logicOpEnable;
3751 const auto colorWrite =
3752 findStructure<VkPipelineColorWriteCreateInfoEXT>(pointerToCreateInfo->pColorBlendState->pNext);
3753 if (colorWrite)
3754 {
3755 state->colorWriteEnableAttachmentCount = colorWrite->attachmentCount;
3756 state->colorWriteEnables.resize(colorWrite->attachmentCount);
3757 for (uint32_t i = 0; i < colorWrite->attachmentCount; ++i)
3758 state->colorWriteEnables[i] = colorWrite->pColorWriteEnables[i];
3759 }
3760 }
3761 if (pointerToCreateInfo->pDepthStencilState)
3762 {
3763 state->minDepthBounds = pointerToCreateInfo->pDepthStencilState->minDepthBounds;
3764 state->maxDepthBounds = pointerToCreateInfo->pDepthStencilState->maxDepthBounds;
3765 state->stencilFront = pointerToCreateInfo->pDepthStencilState->front;
3766 state->stencilBack = pointerToCreateInfo->pDepthStencilState->back;
3767 state->depthBoundsTestEnable = pointerToCreateInfo->pDepthStencilState->depthBoundsTestEnable;
3768 state->depthCompareOp = pointerToCreateInfo->pDepthStencilState->depthCompareOp;
3769 state->depthTestEnable = pointerToCreateInfo->pDepthStencilState->depthTestEnable;
3770 state->depthWriteEnable = pointerToCreateInfo->pDepthStencilState->depthWriteEnable;
3771 state->stencilTestEnable = pointerToCreateInfo->pDepthStencilState->stencilTestEnable;
3772 }
3773 if (pointerToCreateInfo->pInputAssemblyState)
3774 {
3775 state->topology = pointerToCreateInfo->pInputAssemblyState->topology;
3776 state->primitiveRestartEnable = pointerToCreateInfo->pInputAssemblyState->primitiveRestartEnable;
3777 }
3778 if (pointerToCreateInfo->pVertexInputState)
3779 {
3780 state->attributes.resize(pointerToCreateInfo->pVertexInputState->vertexAttributeDescriptionCount);
3781 state->bindings.resize(pointerToCreateInfo->pVertexInputState->vertexBindingDescriptionCount);
3782 for (uint32_t i = 0; i < pointerToCreateInfo->pVertexInputState->vertexAttributeDescriptionCount; ++i)
3783 {
3784 state->attributes[i] = initVulkanStructure();
3785 state->attributes[i].location =
3786 pointerToCreateInfo->pVertexInputState->pVertexAttributeDescriptions[i].location;
3787 state->attributes[i].binding =
3788 pointerToCreateInfo->pVertexInputState->pVertexAttributeDescriptions[i].binding;
3789 state->attributes[i].format =
3790 pointerToCreateInfo->pVertexInputState->pVertexAttributeDescriptions[i].format;
3791 state->attributes[i].offset =
3792 pointerToCreateInfo->pVertexInputState->pVertexAttributeDescriptions[i].offset;
3793 }
3794
3795 const auto divisorInfo = findStructure<VkPipelineVertexInputDivisorStateCreateInfoEXT>(
3796 pointerToCreateInfo->pVertexInputState->pNext);
3797
3798 for (uint32_t i = 0; i < pointerToCreateInfo->pVertexInputState->vertexBindingDescriptionCount; ++i)
3799 {
3800 state->bindings[i] = initVulkanStructure();
3801 state->bindings[i].binding =
3802 pointerToCreateInfo->pVertexInputState->pVertexBindingDescriptions[i].binding;
3803 state->bindings[i].stride =
3804 pointerToCreateInfo->pVertexInputState->pVertexBindingDescriptions[i].stride;
3805 state->bindings[i].inputRate =
3806 pointerToCreateInfo->pVertexInputState->pVertexBindingDescriptions[i].inputRate;
3807 state->bindings[i].divisor = 1;
3808 if (divisorInfo)
3809 {
3810 for (uint32_t j = 0; j < divisorInfo->vertexBindingDivisorCount; ++j)
3811 {
3812 if (state->bindings[i].binding == divisorInfo->pVertexBindingDivisors[j].binding)
3813 {
3814 state->bindings[i].divisor = divisorInfo->pVertexBindingDivisors[i].divisor;
3815 }
3816 }
3817 }
3818 }
3819 }
3820 if (pointerToCreateInfo->pTessellationState)
3821 {
3822 state->patchControlPoints = pointerToCreateInfo->pTessellationState->patchControlPoints;
3823 const auto tessellationDomainOrigin = findStructure<VkPipelineTessellationDomainOriginStateCreateInfo>(
3824 pointerToCreateInfo->pTessellationState->pNext);
3825 if (tessellationDomainOrigin)
3826 state->domainOrigin = tessellationDomainOrigin->domainOrigin;
3827 }
3828 if (pointerToCreateInfo->pMultisampleState)
3829 {
3830 state->alphaToCoverageEnable = pointerToCreateInfo->pMultisampleState->alphaToCoverageEnable;
3831 state->alphaToOneEnable = pointerToCreateInfo->pMultisampleState->alphaToOneEnable;
3832 const auto coverageModulation = findStructure<VkPipelineCoverageModulationStateCreateInfoNV>(
3833 pointerToCreateInfo->pMultisampleState->pNext);
3834 if (coverageModulation)
3835 {
3836 state->coverageModulationMode = coverageModulation->coverageModulationMode;
3837 state->coverageModulationTableEnable = coverageModulation->coverageModulationTableEnable;
3838 state->coverageModulationTable.resize(coverageModulation->coverageModulationTableCount);
3839 for (uint32_t i = 0; i < (uint32_t)coverageModulation->coverageModulationTableCount; ++i)
3840 state->coverageModulationTable[i] = coverageModulation->pCoverageModulationTable[i];
3841 }
3842 const auto coverageReduction = findStructure<VkPipelineCoverageReductionStateCreateInfoNV>(
3843 pointerToCreateInfo->pMultisampleState->pNext);
3844 if (coverageReduction)
3845 state->coverageReductionMode = coverageReduction->coverageReductionMode;
3846 const auto coverageToColor = findStructure<VkPipelineCoverageToColorStateCreateInfoNV>(
3847 pointerToCreateInfo->pMultisampleState->pNext);
3848 if (coverageToColor)
3849 {
3850 state->coverageToColorEnable = coverageToColor->coverageToColorEnable;
3851 state->coverageToColorLocation = coverageToColor->coverageToColorLocation;
3852 }
3853 state->rasterizationSamples = pointerToCreateInfo->pMultisampleState->rasterizationSamples;
3854 const auto sampleLocations = findStructure<VkPipelineSampleLocationsStateCreateInfoEXT>(
3855 pointerToCreateInfo->pMultisampleState->pNext);
3856 if (sampleLocations)
3857 {
3858 state->sampleLocationsEnable = sampleLocations->sampleLocationsEnable;
3859 state->sampleLocationsInfo = sampleLocations->sampleLocationsInfo;
3860 state->pSampleLocations.resize(sampleLocations->sampleLocationsInfo.sampleLocationsCount);
3861 for (uint32_t i = 0; i < sampleLocations->sampleLocationsInfo.sampleLocationsCount; ++i)
3862 state->pSampleLocations[i] = sampleLocations->sampleLocationsInfo.pSampleLocations[i];
3863 state->sampleLocationsInfo.pSampleLocations = state->pSampleLocations.data();
3864 }
3865 state->rasterizationSamples = pointerToCreateInfo->pMultisampleState->rasterizationSamples;
3866 uint32_t count =
3867 (pointerToCreateInfo->pMultisampleState->rasterizationSamples > vk::VK_SAMPLE_COUNT_32_BIT) ? 2 : 1;
3868 state->sampleMasks.resize(count, 0);
3869 for (uint32_t i = 0; i < count; ++i)
3870 if (pointerToCreateInfo->pMultisampleState->pSampleMask)
3871 state->sampleMasks[i] = pointerToCreateInfo->pMultisampleState->pSampleMask[i];
3872 else
3873 state->sampleMasks[i] =
3874 0xFF; // If pSampleMask is NULL, it is treated as if the mask has all bits set to 1
3875 }
3876 const auto representativeFragment =
3877 findStructure<VkPipelineRepresentativeFragmentTestStateCreateInfoNV>(pointerToCreateInfo->pNext);
3878 if (representativeFragment)
3879 {
3880 state->representativeFragmentTestEnable = representativeFragment->representativeFragmentTestEnable;
3881 }
3882 const auto fragmentShadingRate =
3883 findStructure<VkPipelineFragmentShadingRateStateCreateInfoKHR>(pointerToCreateInfo->pNext);
3884 if (fragmentShadingRate)
3885 {
3886 state->fragmentShadingRateSize = fragmentShadingRate->fragmentSize;
3887 state->combinerOps[0] = fragmentShadingRate->combinerOps[0];
3888 state->combinerOps[1] = fragmentShadingRate->combinerOps[1];
3889 }
3890 const auto exclusiveScissor =
3891 findStructure<VkPipelineViewportExclusiveScissorStateCreateInfoNV>(pointerToCreateInfo->pNext);
3892 if (exclusiveScissor)
3893 {
3894 state->exclusiveScissorCount = exclusiveScissor->exclusiveScissorCount;
3895 state->exclussiveScissors.resize(exclusiveScissor->exclusiveScissorCount);
3896 for (uint32_t i = 0; i < exclusiveScissor->exclusiveScissorCount; ++i)
3897 state->exclussiveScissors[i] = exclusiveScissor->pExclusiveScissors[i];
3898 }
3899 const auto discardRectangle =
3900 findStructure<VkPipelineDiscardRectangleStateCreateInfoEXT>(pointerToCreateInfo->pNext);
3901 if (discardRectangle)
3902 {
3903 state->discardRectangleEnable = discardRectangle->discardRectangleCount > 0;
3904 state->discardRectangles.resize(discardRectangle->discardRectangleCount);
3905 for (uint32_t i = 0; i < discardRectangle->discardRectangleCount; ++i)
3906 state->discardRectangles[i] = discardRectangle->pDiscardRectangles[i];
3907 state->discardRectangleMode = discardRectangle->discardRectangleMode;
3908 }
3909 if (pointerToCreateInfo->flags & VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT)
3910 state->attachmentFeedbackLoopEnable |= VK_IMAGE_ASPECT_COLOR_BIT;
3911 if (pointerToCreateInfo->flags & VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT)
3912 state->attachmentFeedbackLoopEnable |= VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
3913
3914 bool linked =
3915 m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_SHADER_OBJECT_LINKED_SPIRV ||
3916 m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_SHADER_OBJECT_LINKED_BINARY;
3917 bool binary =
3918 m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_SHADER_OBJECT_UNLINKED_BINARY ||
3919 m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_SHADER_OBJECT_LINKED_BINARY;
3920 createShaders(linked, false);
3921 if (binary)
3922 {
3923 createShaders(linked, true);
3924 }
3925 #endif
3926 }
3927 else
3928 {
3929 #ifndef CTS_USES_VULKANSC
3930 VkGraphicsPipelineCreateInfo linkedCreateInfo = initVulkanStructure();
3931 std::vector<VkPipeline> rawPipelines;
3932 VkPipelineLibraryCreateInfoKHR linkingInfo{
3933 VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR, // VkStructureType sType;
3934 creationFeedback.ptr, // const void* pNext;
3935 0u, // uint32_t libraryCount;
3936 nullptr, // const VkPipeline* pLibraries;
3937 };
3938
3939 if (isConstructionTypeLibrary(m_internalData->pipelineConstructionType))
3940 {
3941 for (const auto &pipelinePtr : m_pipelineParts)
3942 {
3943 const auto &pipeline = pipelinePtr.get();
3944 if (pipeline != DE_NULL)
3945 rawPipelines.push_back(pipeline);
3946 }
3947
3948 linkingInfo.libraryCount = static_cast<uint32_t>(rawPipelines.size());
3949 linkingInfo.pLibraries = de::dataOrNull(rawPipelines);
3950
3951 // If a test hits the following assert, it's likely missing a call
3952 // to the setMonolithicPipelineLayout() method. Related VUs:
3953 // * VUID-VkGraphicsPipelineCreateInfo-flags-06642
3954 // * VUID-VkGraphicsPipelineCreateInfo-None-07826
3955 // * VUID-VkGraphicsPipelineCreateInfo-layout-07827
3956 // * VUID-VkGraphicsPipelineCreateInfo-flags-06729
3957 // * VUID-VkGraphicsPipelineCreateInfo-flags-06730
3958 DE_ASSERT(m_internalData->monolithicPipelineCreateInfo.layout != VK_NULL_HANDLE);
3959 linkedCreateInfo.layout = m_internalData->monolithicPipelineCreateInfo.layout;
3960 linkedCreateInfo.flags = m_internalData->pipelineFlags;
3961 linkedCreateInfo.pNext = &linkingInfo;
3962
3963 pointerToCreateInfo = &linkedCreateInfo;
3964
3965 if (m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_LINK_TIME_OPTIMIZED_LIBRARY)
3966 linkedCreateInfo.flags |= VK_PIPELINE_CREATE_LINK_TIME_OPTIMIZATION_BIT_EXT;
3967
3968 if (m_internalData->failOnCompileWhenLinking)
3969 linkedCreateInfo.flags |= VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT;
3970 }
3971 else
3972 {
3973 // note: there might be other structures in the chain already
3974 void *firstStructInChain = static_cast<void *>(pointerToCreateInfo);
3975 addToChain(&firstStructInChain, creationFeedback.ptr);
3976 addToChain(&firstStructInChain, m_internalData->pRepresentativeFragmentTestState.ptr);
3977 addToChain(&firstStructInChain, m_internalData->pRenderingInputAttachmentIndex.ptr);
3978 addToChain(&firstStructInChain, m_internalData->pRenderingAttachmentLocation.ptr);
3979 addToChain(&firstStructInChain, m_internalData->pPipelineRobustnessState.ptr);
3980 }
3981
3982 VkPipelineCreateFlags2CreateInfoKHR pipelineFlags2CreateInfo = initVulkanStructure();
3983 if (m_internalData->pipelineFlags2)
3984 {
3985 void *firstStructInChain = static_cast<void *>(pointerToCreateInfo);
3986 pipelineFlags2CreateInfo.flags =
3987 m_internalData->pipelineFlags2 | translateCreateFlag(pointerToCreateInfo->flags);
3988 addToChain(&firstStructInChain, &pipelineFlags2CreateInfo);
3989 pointerToCreateInfo->flags = 0u;
3990 }
3991 #endif // CTS_USES_VULKANSC
3992
3993 pointerToCreateInfo->basePipelineHandle = basePipelineHandle;
3994 pointerToCreateInfo->basePipelineIndex = basePipelineIndex;
3995
3996 m_pipelineFinal =
3997 makeGraphicsPipeline(m_internalData->vk, m_internalData->device, pipelineCache, pointerToCreateInfo);
3998 }
3999 }
4000
isShaderObjectDynamic(vk::VkDynamicState dynamicState) const4001 bool GraphicsPipelineWrapper::isShaderObjectDynamic(vk::VkDynamicState dynamicState) const
4002 {
4003 return std::find(m_internalData->shaderObjectDynamicStates.begin(), m_internalData->shaderObjectDynamicStates.end(),
4004 dynamicState) != m_internalData->shaderObjectDynamicStates.end();
4005 }
4006
setShaderObjectDynamicStates(vk::VkCommandBuffer cmdBuffer) const4007 void GraphicsPipelineWrapper::setShaderObjectDynamicStates(vk::VkCommandBuffer cmdBuffer) const
4008 {
4009 DE_UNREF(cmdBuffer);
4010 #ifndef CTS_USES_VULKANSC
4011 const auto &vk = m_internalData->vk;
4012 const auto state = &m_internalData->pipelineCreateState;
4013
4014 // Some dynamic state only need to be set when these conditions are met
4015 const bool meshOrTask = m_internalData->meshShader.isSet() || m_internalData->taskShader.isSet();
4016 const bool tese = m_internalData->tessellationEvaluationShader.isSet();
4017 const bool topologyPatchList = !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY) ||
4018 state->topology == VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
4019 const bool rasterizerDiscardDisabled =
4020 !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE) || !state->rasterizerDiscardEnable;
4021 const bool polygonModeLine =
4022 !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_POLYGON_MODE_EXT) || state->polygonMode == vk::VK_POLYGON_MODE_LINE;
4023 const bool topologyLine = !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY) ||
4024 state->topology == vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST ||
4025 state->topology == vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY ||
4026 state->topology == vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP ||
4027 state->topology == vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY;
4028 const bool depthTestEnabled =
4029 !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE) || state->depthTestEnable;
4030 const bool depthBoundsTestEnabled =
4031 !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE) || state->depthBoundsTestEnable;
4032 const bool depthBiasEnabled =
4033 !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE) || state->depthBiasEnable;
4034 const bool stencilTestEnabled =
4035 !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE) || state->stencilTestEnable;
4036 const bool logicOpEnabled =
4037 !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT) || state->logicOpEnable;
4038 const bool discardRectangle =
4039 !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_ENABLE_EXT) || state->discardRectangleEnable;
4040 const bool sampleLocationsEnabled =
4041 !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_ENABLE_EXT) || state->sampleLocationsEnable;
4042 const bool stippledLineEnabled =
4043 !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT) || state->stippledLineEnable;
4044 bool blendFactorConstant = !isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT);
4045 for (const auto &blend : state->blendEquations)
4046 {
4047 if (blend.srcColorBlendFactor == vk::VK_BLEND_FACTOR_CONSTANT_COLOR ||
4048 blend.srcColorBlendFactor == vk::VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR ||
4049 blend.srcColorBlendFactor == vk::VK_BLEND_FACTOR_CONSTANT_ALPHA ||
4050 blend.srcColorBlendFactor == vk::VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA ||
4051 blend.dstColorBlendFactor == vk::VK_BLEND_FACTOR_CONSTANT_COLOR ||
4052 blend.dstColorBlendFactor == vk::VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR ||
4053 blend.dstColorBlendFactor == vk::VK_BLEND_FACTOR_CONSTANT_ALPHA ||
4054 blend.dstColorBlendFactor == vk::VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA ||
4055 blend.srcAlphaBlendFactor == vk::VK_BLEND_FACTOR_CONSTANT_COLOR ||
4056 blend.srcAlphaBlendFactor == vk::VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR ||
4057 blend.srcAlphaBlendFactor == vk::VK_BLEND_FACTOR_CONSTANT_ALPHA ||
4058 blend.srcAlphaBlendFactor == vk::VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA ||
4059 blend.dstAlphaBlendFactor == vk::VK_BLEND_FACTOR_CONSTANT_COLOR ||
4060 blend.dstAlphaBlendFactor == vk::VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR ||
4061 blend.dstAlphaBlendFactor == vk::VK_BLEND_FACTOR_CONSTANT_ALPHA ||
4062 blend.dstAlphaBlendFactor == vk::VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA)
4063
4064 blendFactorConstant = true;
4065 }
4066
4067 for (const auto dynamicState : m_internalData->shaderObjectDynamicStates)
4068 {
4069 switch (dynamicState)
4070 {
4071 case vk::VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT:
4072 if (!state->viewports.empty())
4073 vk.cmdSetViewportWithCount(cmdBuffer, (uint32_t)state->viewports.size(), state->viewports.data());
4074 break;
4075 case vk::VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT:
4076 if (!state->scissors.empty())
4077 vk.cmdSetScissorWithCount(cmdBuffer, (uint32_t)state->scissors.size(), state->scissors.data());
4078 break;
4079 case vk::VK_DYNAMIC_STATE_LINE_WIDTH:
4080 if (polygonModeLine || topologyLine)
4081 vk.cmdSetLineWidth(cmdBuffer, state->lineWidth);
4082 break;
4083 case vk::VK_DYNAMIC_STATE_DEPTH_BIAS:
4084 if (rasterizerDiscardDisabled && depthBiasEnabled)
4085 {
4086 if (m_internalData->extensionEnabled("VK_EXT_depth_bias_control"))
4087 {
4088 VkDepthBiasRepresentationInfoEXT depthBiasRepresentationInfo = vk::initVulkanStructure();
4089 depthBiasRepresentationInfo.depthBiasRepresentation = state->depthBiasRepresentation;
4090 depthBiasRepresentationInfo.depthBiasExact = state->depthBiasExact;
4091
4092 vk::VkDepthBiasInfoEXT depthBiasInfo = vk::initVulkanStructure(&depthBiasRepresentationInfo);
4093 depthBiasInfo.depthBiasConstantFactor = state->depthBiasConstantFactor;
4094 depthBiasInfo.depthBiasClamp = state->depthBiasClamp;
4095 depthBiasInfo.depthBiasSlopeFactor = state->depthBiasSlopeFactor;
4096 vk.cmdSetDepthBias2EXT(cmdBuffer, &depthBiasInfo);
4097 }
4098 else
4099 {
4100 vk.cmdSetDepthBias(cmdBuffer, state->depthBiasConstantFactor, state->depthBiasClamp,
4101 state->depthBiasSlopeFactor);
4102 }
4103 }
4104 break;
4105 case vk::VK_DYNAMIC_STATE_BLEND_CONSTANTS:
4106 if (rasterizerDiscardDisabled && blendFactorConstant)
4107 vk.cmdSetBlendConstants(cmdBuffer, state->blendConstants);
4108 break;
4109 case vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS:
4110 if (rasterizerDiscardDisabled && depthBoundsTestEnabled)
4111 vk.cmdSetDepthBounds(cmdBuffer, state->minDepthBounds, state->maxDepthBounds);
4112 break;
4113 case vk::VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK:
4114 {
4115 vk.cmdSetStencilCompareMask(cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, state->stencilFront.compareMask);
4116 vk.cmdSetStencilCompareMask(cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, state->stencilBack.compareMask);
4117 }
4118 break;
4119 case vk::VK_DYNAMIC_STATE_STENCIL_WRITE_MASK:
4120 {
4121 vk.cmdSetStencilWriteMask(cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, state->stencilFront.writeMask);
4122 vk.cmdSetStencilWriteMask(cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, state->stencilBack.writeMask);
4123 }
4124 break;
4125 case vk::VK_DYNAMIC_STATE_STENCIL_REFERENCE:
4126 {
4127 vk.cmdSetStencilReference(cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, state->stencilFront.reference);
4128 vk.cmdSetStencilReference(cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, state->stencilBack.reference);
4129 }
4130 break;
4131 case vk::VK_DYNAMIC_STATE_CULL_MODE_EXT:
4132 vk.cmdSetCullMode(cmdBuffer, state->cullMode);
4133 break;
4134 case vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT:
4135 if (rasterizerDiscardDisabled)
4136 vk.cmdSetDepthBoundsTestEnable(cmdBuffer, state->depthBoundsTestEnable);
4137 break;
4138 case vk::VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT:
4139 if (rasterizerDiscardDisabled && depthTestEnabled)
4140 vk.cmdSetDepthCompareOp(cmdBuffer, state->depthCompareOp);
4141 break;
4142 case vk::VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT:
4143 if (rasterizerDiscardDisabled)
4144 vk.cmdSetDepthTestEnable(cmdBuffer, state->depthTestEnable);
4145 break;
4146 case vk::VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT:
4147 if (rasterizerDiscardDisabled)
4148 vk.cmdSetDepthWriteEnable(cmdBuffer, state->depthWriteEnable);
4149 break;
4150 case vk::VK_DYNAMIC_STATE_FRONT_FACE_EXT:
4151 vk.cmdSetFrontFace(cmdBuffer, state->frontFace);
4152 break;
4153 case vk::VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT:
4154 if (!meshOrTask)
4155 vk.cmdSetPrimitiveTopology(cmdBuffer, state->topology);
4156 break;
4157 case vk::VK_DYNAMIC_STATE_STENCIL_OP_EXT:
4158 if (rasterizerDiscardDisabled && stencilTestEnabled)
4159 {
4160 vk.cmdSetStencilOp(cmdBuffer, vk::VK_STENCIL_FACE_FRONT_BIT, state->stencilFront.failOp,
4161 state->stencilFront.passOp, state->stencilFront.depthFailOp,
4162 state->stencilFront.compareOp);
4163 vk.cmdSetStencilOp(cmdBuffer, vk::VK_STENCIL_FACE_BACK_BIT, state->stencilBack.failOp,
4164 state->stencilBack.passOp, state->stencilBack.depthFailOp,
4165 state->stencilBack.compareOp);
4166 }
4167 break;
4168 case vk::VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT:
4169 if (rasterizerDiscardDisabled)
4170 vk.cmdSetStencilTestEnable(cmdBuffer, state->stencilTestEnable);
4171 break;
4172 case vk::VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT:
4173 if (!meshOrTask)
4174 vk.cmdSetVertexInputEXT(cmdBuffer, (uint32_t)state->bindings.size(), state->bindings.data(),
4175 (uint32_t)state->attributes.size(), state->attributes.data());
4176 break;
4177 case vk::VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT:
4178 if (rasterizerDiscardDisabled)
4179 vk.cmdSetDepthBiasEnable(cmdBuffer, state->depthBiasEnable);
4180 break;
4181 case vk::VK_DYNAMIC_STATE_LOGIC_OP_EXT:
4182 if (rasterizerDiscardDisabled && logicOpEnabled)
4183 vk.cmdSetLogicOpEXT(cmdBuffer, state->logicOp);
4184 break;
4185 case vk::VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT:
4186 if (topologyPatchList && !meshOrTask && tese)
4187 vk.cmdSetPatchControlPointsEXT(cmdBuffer, state->patchControlPoints);
4188 break;
4189 case vk::VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT:
4190 if (!meshOrTask)
4191 vk.cmdSetPrimitiveRestartEnable(cmdBuffer, state->primitiveRestartEnable);
4192 break;
4193 case vk::VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT:
4194 vk.cmdSetRasterizerDiscardEnable(cmdBuffer, state->rasterizerDiscardEnable);
4195 break;
4196 case vk::VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT:
4197 vk.cmdSetAlphaToCoverageEnableEXT(cmdBuffer, state->alphaToCoverageEnable);
4198 break;
4199 case vk::VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT:
4200 vk.cmdSetAlphaToOneEnableEXT(cmdBuffer, state->alphaToOneEnable);
4201 break;
4202 case vk::VK_DYNAMIC_STATE_COLOR_BLEND_ADVANCED_EXT:
4203 if (!state->colorBlendAdvanced.empty())
4204 {
4205 for (uint32_t i = 0; i < (uint32_t)state->colorBlendAdvanced.size(); ++i)
4206 if (!isShaderObjectDynamic(vk::VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT) ||
4207 state->colorBlendEnables[i])
4208 vk.cmdSetColorBlendAdvancedEXT(cmdBuffer, i, 1, &state->colorBlendAdvanced[i]);
4209 }
4210 break;
4211 case vk::VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT:
4212 if (rasterizerDiscardDisabled)
4213 {
4214 if (!state->colorBlendEnables.empty())
4215 {
4216 vk.cmdSetColorBlendEnableEXT(cmdBuffer, 0, (uint32_t)state->colorBlendEnables.size(),
4217 state->colorBlendEnables.data());
4218 }
4219 else
4220 {
4221 VkBool32 disable = VK_FALSE;
4222 vk.cmdSetColorBlendEnableEXT(cmdBuffer, 0, 1u, &disable);
4223 }
4224 }
4225 break;
4226 case vk::VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT:
4227 if (rasterizerDiscardDisabled)
4228 {
4229 if (!state->blendEquations.empty())
4230 {
4231 vk.cmdSetColorBlendEquationEXT(cmdBuffer, 0, (uint32_t)state->blendEquations.size(),
4232 state->blendEquations.data());
4233 }
4234 else
4235 {
4236 vk::VkColorBlendEquationEXT blendEquation = {
4237 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcColorBlendFactor;
4238 VK_BLEND_FACTOR_DST_ALPHA, // VkBlendFactor dstColorBlendFactor;
4239 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
4240 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcAlphaBlendFactor;
4241 VK_BLEND_FACTOR_DST_ALPHA, // VkBlendFactor dstAlphaBlendFactor;
4242 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
4243 };
4244 vk.cmdSetColorBlendEquationEXT(cmdBuffer, 0, 1u, &blendEquation);
4245 }
4246 }
4247 break;
4248 case vk::VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT:
4249 if (rasterizerDiscardDisabled)
4250 {
4251 if (!state->colorWriteMasks.empty())
4252 {
4253 vk.cmdSetColorWriteMaskEXT(cmdBuffer, 0, (uint32_t)state->colorWriteMasks.size(),
4254 state->colorWriteMasks.data());
4255 }
4256 else
4257 {
4258 VkColorComponentFlags colorWriteMask = 0u;
4259 vk.cmdSetColorWriteMaskEXT(cmdBuffer, 0, 1u, &colorWriteMask);
4260 }
4261 }
4262 break;
4263 case vk::VK_DYNAMIC_STATE_CONSERVATIVE_RASTERIZATION_MODE_EXT:
4264 vk.cmdSetConservativeRasterizationModeEXT(cmdBuffer, state->conservativeRasterizationMode);
4265 break;
4266 case vk::VK_DYNAMIC_STATE_COVERAGE_MODULATION_MODE_NV:
4267 vk.cmdSetCoverageModulationModeNV(cmdBuffer, state->coverageModulationMode);
4268 break;
4269 case vk::VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_ENABLE_NV:
4270 vk.cmdSetCoverageModulationTableEnableNV(cmdBuffer, state->coverageModulationTableEnable);
4271 break;
4272 case vk::VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_NV:
4273 if (!state->coverageModulationTable.empty())
4274 vk.cmdSetCoverageModulationTableNV(cmdBuffer, (uint32_t)state->coverageModulationTable.size(),
4275 state->coverageModulationTable.data());
4276 break;
4277 case vk::VK_DYNAMIC_STATE_COVERAGE_REDUCTION_MODE_NV:
4278 vk.cmdSetCoverageReductionModeNV(cmdBuffer, state->coverageReductionMode);
4279 break;
4280 case vk::VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_ENABLE_NV:
4281 vk.cmdSetCoverageToColorEnableNV(cmdBuffer, state->coverageToColorEnable);
4282 break;
4283 case vk::VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_LOCATION_NV:
4284 vk.cmdSetCoverageToColorLocationNV(cmdBuffer, state->coverageToColorLocation);
4285 break;
4286 case vk::VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT:
4287 if (rasterizerDiscardDisabled)
4288 vk.cmdSetDepthClampEnableEXT(cmdBuffer, state->depthClampEnable);
4289 break;
4290 case vk::VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT:
4291 vk.cmdSetDepthClipEnableEXT(cmdBuffer, state->depthClipEnable);
4292 break;
4293 case vk::VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT:
4294 vk.cmdSetDepthClipNegativeOneToOneEXT(cmdBuffer, state->negativeOneToOne);
4295 break;
4296 case vk::VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT:
4297 if (state->colorWriteEnableAttachmentCount > 0)
4298 vk.cmdSetColorWriteEnableEXT(cmdBuffer, state->colorWriteEnableAttachmentCount,
4299 state->colorWriteEnables.data());
4300 else
4301 {
4302 std::vector<VkBool32> enable(state->colorBlendEnables.empty() ? 1u : state->colorBlendEnables.size(),
4303 VK_TRUE);
4304 vk.cmdSetColorWriteEnableEXT(cmdBuffer, (uint32_t)enable.size(), enable.data());
4305 }
4306 break;
4307 case vk::VK_DYNAMIC_STATE_EXTRA_PRIMITIVE_OVERESTIMATION_SIZE_EXT:
4308 vk.cmdSetExtraPrimitiveOverestimationSizeEXT(cmdBuffer, state->extraPrimitiveOverestimationSize);
4309 break;
4310 case vk::VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT:
4311 vk.cmdSetLineRasterizationModeEXT(cmdBuffer, state->lineRasterizationMode);
4312 break;
4313 case vk::VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT:
4314 vk.cmdSetLineStippleEnableEXT(cmdBuffer, state->stippledLineEnable);
4315 break;
4316 case vk::VK_DYNAMIC_STATE_LINE_STIPPLE_EXT:
4317 if (stippledLineEnabled)
4318 vk.cmdSetLineStippleKHR(cmdBuffer, state->lineStippleFactor, state->lineStipplePattern);
4319 break;
4320 case vk::VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT:
4321 if (rasterizerDiscardDisabled)
4322 vk.cmdSetLogicOpEnableEXT(cmdBuffer, state->logicOpEnable);
4323 break;
4324 case vk::VK_DYNAMIC_STATE_POLYGON_MODE_EXT:
4325 vk.cmdSetPolygonModeEXT(cmdBuffer, state->polygonMode);
4326 break;
4327 case vk::VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT:
4328 vk.cmdSetProvokingVertexModeEXT(cmdBuffer, state->provokingVertexMode);
4329 break;
4330 case vk::VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT:
4331 vk.cmdSetRasterizationSamplesEXT(cmdBuffer, state->rasterizationSamples);
4332 break;
4333 case vk::VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR:
4334 vk.cmdSetFragmentShadingRateKHR(cmdBuffer, &state->fragmentShadingRateSize, state->combinerOps);
4335 break;
4336 case vk::VK_DYNAMIC_STATE_RASTERIZATION_STREAM_EXT:
4337 vk.cmdSetRasterizationStreamEXT(cmdBuffer, state->rasterizationStream);
4338 break;
4339 case vk::VK_DYNAMIC_STATE_REPRESENTATIVE_FRAGMENT_TEST_ENABLE_NV:
4340 vk.cmdSetRepresentativeFragmentTestEnableNV(cmdBuffer, state->representativeFragmentTestEnable);
4341 break;
4342 case vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_ENABLE_EXT:
4343 vk.cmdSetSampleLocationsEnableEXT(cmdBuffer, state->sampleLocationsEnable);
4344 break;
4345 case vk::VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT:
4346 if (sampleLocationsEnabled)
4347 vk.cmdSetSampleLocationsEXT(cmdBuffer, &state->sampleLocationsInfo);
4348 break;
4349 case vk::VK_DYNAMIC_STATE_SAMPLE_MASK_EXT:
4350 if (!state->sampleMasks.empty())
4351 vk.cmdSetSampleMaskEXT(cmdBuffer, state->rasterizationSamples, state->sampleMasks.data());
4352 break;
4353 case vk::VK_DYNAMIC_STATE_SHADING_RATE_IMAGE_ENABLE_NV:
4354 vk.cmdSetShadingRateImageEnableNV(cmdBuffer, state->shadingRateImageEnable);
4355 break;
4356 case vk::VK_DYNAMIC_STATE_TESSELLATION_DOMAIN_ORIGIN_EXT:
4357 if (tese)
4358 vk.cmdSetTessellationDomainOriginEXT(cmdBuffer, state->domainOrigin);
4359 break;
4360 case vk::VK_DYNAMIC_STATE_VIEWPORT_SWIZZLE_NV:
4361 if (!state->viewportSwizzles.empty())
4362 {
4363 vk.cmdSetViewportSwizzleNV(cmdBuffer, 0, (uint32_t)state->viewportSwizzles.size(),
4364 state->viewportSwizzles.data());
4365 }
4366 else
4367 {
4368 std::vector<vk::VkViewportSwizzleNV> idSwizzles(4u);
4369 for (auto &swizzle : idSwizzles)
4370 {
4371 swizzle = {
4372 vk::VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NV,
4373 vk::VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Y_NV,
4374 vk::VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Z_NV,
4375 vk::VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_W_NV,
4376 };
4377 }
4378 vk.cmdSetViewportSwizzleNV(cmdBuffer, 0u, (uint32_t)idSwizzles.size(), idSwizzles.data());
4379 }
4380 break;
4381 case vk::VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_ENABLE_NV:
4382 vk.cmdSetViewportWScalingEnableNV(cmdBuffer, state->viewportWScalingEnable);
4383 break;
4384 case vk::VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV:
4385 if (state->viewportWScalingCount > 0)
4386 vk.cmdSetViewportWScalingNV(cmdBuffer, 0, state->viewportWScalingCount,
4387 state->viewportWScalings.data());
4388 break;
4389 case vk::VK_DYNAMIC_STATE_VERTEX_INPUT_EXT:
4390 if (!meshOrTask)
4391 vk.cmdSetVertexInputEXT(cmdBuffer, (uint32_t)state->bindings.size(), state->bindings.data(),
4392 (uint32_t)state->attributes.size(), state->attributes.data());
4393 break;
4394 case vk::VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV:
4395 vk.cmdSetCoarseSampleOrderNV(cmdBuffer, state->coarseSampleOrderType, state->coarseCustomSampleOrderCount,
4396 state->coarseCustomSampleOrders.data());
4397 break;
4398 case vk::VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV:
4399 if (state->shadingRatePaletteCount > 0)
4400 vk.cmdSetViewportShadingRatePaletteNV(cmdBuffer, 0, state->shadingRatePaletteCount,
4401 state->shadingRatePalettes.data());
4402 break;
4403 case vk::VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_ENABLE_NV:
4404 {
4405 if (state->exclusiveScissorCount > 0)
4406 {
4407 std::vector<VkBool32> exclusiveScissorEnable(state->exclusiveScissorCount, VK_TRUE);
4408 vk.cmdSetExclusiveScissorEnableNV(cmdBuffer, 0u, state->exclusiveScissorCount,
4409 exclusiveScissorEnable.data());
4410 }
4411 else
4412 {
4413 VkBool32 enable = VK_FALSE;
4414 vk.cmdSetExclusiveScissorEnableNV(cmdBuffer, 0u, 1u, &enable);
4415 }
4416 break;
4417 }
4418 case vk::VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV:
4419 if (state->exclusiveScissorCount > 0)
4420 vk.cmdSetExclusiveScissorNV(cmdBuffer, 0u, state->exclusiveScissorCount,
4421 state->exclussiveScissors.data());
4422 break;
4423 case vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_ENABLE_EXT:
4424 vk.cmdSetDiscardRectangleEnableEXT(cmdBuffer, state->discardRectangleEnable);
4425 break;
4426 case vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT:
4427 if (discardRectangle)
4428 vk.cmdSetDiscardRectangleEXT(cmdBuffer, 0, (uint32_t)state->discardRectangles.size(),
4429 state->discardRectangles.data());
4430 break;
4431 case vk::VK_DYNAMIC_STATE_DISCARD_RECTANGLE_MODE_EXT:
4432 if (discardRectangle)
4433 vk.cmdSetDiscardRectangleModeEXT(cmdBuffer, state->discardRectangleMode);
4434 break;
4435 case vk::VK_DYNAMIC_STATE_ATTACHMENT_FEEDBACK_LOOP_ENABLE_EXT:
4436 vk.cmdSetAttachmentFeedbackLoopEnableEXT(cmdBuffer, state->attachmentFeedbackLoopEnable);
4437 break;
4438 default:
4439 break;
4440 }
4441 }
4442 #endif // CTS_USES_VULKANSC
4443 }
4444
bind(vk::VkCommandBuffer cmdBuffer) const4445 void GraphicsPipelineWrapper::bind(vk::VkCommandBuffer cmdBuffer) const
4446 {
4447 const auto &vk = m_internalData->vk;
4448 if (!isConstructionTypeShaderObject(m_internalData->pipelineConstructionType))
4449 {
4450 vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, getPipeline());
4451 }
4452 else
4453 {
4454 #ifndef CTS_USES_VULKANSC
4455 const VkShaderStageFlagBits vertStage = vk::VK_SHADER_STAGE_VERTEX_BIT;
4456 VkShaderEXT vertShader = m_internalData->vertexShader.getShader();
4457 vk.cmdBindShadersEXT(cmdBuffer, 1, &vertStage, &vertShader);
4458 const VkShaderStageFlagBits tescStage = vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
4459 VkShaderEXT tescShader = m_internalData->tessellationControlShader.getShader();
4460 vk.cmdBindShadersEXT(cmdBuffer, 1, &tescStage, &tescShader);
4461 const VkShaderStageFlagBits teseStage = vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
4462 VkShaderEXT teseShader = m_internalData->tessellationEvaluationShader.getShader();
4463 vk.cmdBindShadersEXT(cmdBuffer, 1, &teseStage, &teseShader);
4464 const VkShaderStageFlagBits geomStage = vk::VK_SHADER_STAGE_GEOMETRY_BIT;
4465 VkShaderEXT geomShader = m_internalData->geometryShader.getShader();
4466 vk.cmdBindShadersEXT(cmdBuffer, 1, &geomStage, &geomShader);
4467 const VkShaderStageFlagBits fragStage = vk::VK_SHADER_STAGE_FRAGMENT_BIT;
4468 VkShaderEXT fragShader = m_internalData->fragmentShader.getShader();
4469 vk.cmdBindShadersEXT(cmdBuffer, 1, &fragStage, &fragShader);
4470 if (m_internalData->meshShaderFeature)
4471 {
4472 const VkShaderStageFlagBits meshStage = vk::VK_SHADER_STAGE_MESH_BIT_EXT;
4473 VkShaderEXT meshShader = m_internalData->meshShader.getShader();
4474 vk.cmdBindShadersEXT(cmdBuffer, 1, &meshStage, &meshShader);
4475 }
4476 if (m_internalData->taskShaderFeature)
4477 {
4478 const VkShaderStageFlagBits taskStage = vk::VK_SHADER_STAGE_TASK_BIT_EXT;
4479 VkShaderEXT taskShader = m_internalData->taskShader.getShader();
4480 vk.cmdBindShadersEXT(cmdBuffer, 1, &taskStage, &taskShader);
4481 }
4482 // Set all dynamic state that would otherwise have been set with the pipeline
4483 setShaderObjectDynamicStates(cmdBuffer);
4484 #endif
4485 }
4486 }
4487
wasBuild() const4488 bool GraphicsPipelineWrapper::wasBuild() const
4489 {
4490 return !!m_pipelineFinal.get();
4491 }
4492
wasPipelineOrShaderObjectBuild(void) const4493 bool GraphicsPipelineWrapper::wasPipelineOrShaderObjectBuild(void) const
4494 {
4495 if (!!m_pipelineFinal.get())
4496 return true;
4497
4498 #ifndef CTS_USES_VULKANSC
4499 if (!!m_internalData->vertexShader.getShader() || !!m_internalData->tessellationControlShader.getShader() ||
4500 !!m_internalData->tessellationEvaluationShader.getShader() || !!m_internalData->geometryShader.getShader() ||
4501 !!m_internalData->fragmentShader.getShader() || !!m_internalData->taskShader.getShader() ||
4502 !!m_internalData->meshShader.getShader())
4503 return true;
4504 #endif
4505
4506 return false;
4507 }
4508
getPipeline(void) const4509 VkPipeline GraphicsPipelineWrapper::getPipeline(void) const
4510 {
4511 DE_ASSERT(m_pipelineFinal.get() != DE_NULL);
4512 return m_pipelineFinal.get();
4513 }
4514
destroyPipeline(void)4515 void GraphicsPipelineWrapper::destroyPipeline(void)
4516 {
4517 DE_ASSERT(m_pipelineFinal.get() != DE_NULL);
4518
4519 m_pipelineFinal = Move<VkPipeline>();
4520 }
4521
4522 } // namespace vk
4523