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