• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef _VKPIPELINECONSTRUCTIONUTIL_HPP
2 #define _VKPIPELINECONSTRUCTIONUTIL_HPP
3 /*------------------------------------------------------------------------
4  * Vulkan Conformance Tests
5  * ------------------------
6  *
7  * Copyright (c) 2021 The Khronos Group Inc.
8  * Copyright (c) 2023 LunarG, Inc.
9  * Copyright (c) 2023 Nintendo
10  *
11  * Licensed under the Apache License, Version 2.0 (the "License");
12  * you may not use this file except in compliance with the License.
13  * You may obtain a copy of the License at
14  *
15  *      http://www.apache.org/licenses/LICENSE-2.0
16  *
17  * Unless required by applicable law or agreed to in writing, software
18  * distributed under the License is distributed on an "AS IS" BASIS,
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  * See the License for the specific language governing permissions and
21  * limitations under the License.
22  *
23  *//*!
24  * \file
25  * \brief Wrapper that can construct monolithic pipeline or use
26           VK_EXT_graphics_pipeline_library for pipeline construction or use
27           VK_EXT_shader_object for shader objects.
28  *//*--------------------------------------------------------------------*/
29 
30 #include "vkRef.hpp"
31 #include "vkDefs.hpp"
32 #include "tcuDefs.hpp"
33 #include "deSharedPtr.hpp"
34 #include "vkPrograms.hpp"
35 #include "vkShaderObjectUtil.hpp"
36 #include <vector>
37 #include <stdexcept>
38 
39 namespace vk
40 {
41 
42 enum PipelineConstructionType
43 {
44     PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC = 0, // Construct legacy - monolithic pipeline
45     PIPELINE_CONSTRUCTION_TYPE_LINK_TIME_OPTIMIZED_LIBRARY, // Use VK_EXT_graphics_pipeline_library and construct pipeline out of several pipeline parts.
46     PIPELINE_CONSTRUCTION_TYPE_FAST_LINKED_LIBRARY, // Same as PIPELINE_CONSTRUCTION_TYPE_OPTIMISED_LIBRARY but with fast linking
47     PIPELINE_CONSTRUCTION_TYPE_SHADER_OBJECT_UNLINKED_SPIRV, // Use VK_EXT_shader_object unlinked shader objects from spirv
48     PIPELINE_CONSTRUCTION_TYPE_SHADER_OBJECT_UNLINKED_BINARY, // Use VK_EXT_shader_object unlinked shader objects from binary
49     PIPELINE_CONSTRUCTION_TYPE_SHADER_OBJECT_LINKED_SPIRV,  // Use VK_EXT_shader_object linked shader objects from spirv
50     PIPELINE_CONSTRUCTION_TYPE_SHADER_OBJECT_LINKED_BINARY, // Use VK_EXT_shader_object linked shader objects from binary
51 };
52 
53 bool isConstructionTypeLibrary(PipelineConstructionType pipelineConstructionType);
54 bool isConstructionTypeShaderObject(PipelineConstructionType pipelineConstructionType);
55 void checkPipelineConstructionRequirements(const InstanceInterface &vki, VkPhysicalDevice physicalDevice,
56                                            PipelineConstructionType pipelineConstructionType);
57 
58 // This exception may be raised in one of the intermediate steps when using shader module IDs instead of normal module objects.
59 class PipelineCompileRequiredError : public std::runtime_error
60 {
61 public:
PipelineCompileRequiredError(const std::string & msg)62     PipelineCompileRequiredError(const std::string &msg) : std::runtime_error(msg)
63     {
64     }
65 };
66 
67 // PointerWrapper template is used to hide structures that should not be visible for Vulkan SC
68 template <typename T>
69 class PointerWrapper
70 {
71 public:
PointerWrapper()72     PointerWrapper() : ptr(nullptr)
73     {
74     }
PointerWrapper(T * p0)75     PointerWrapper(T *p0) : ptr(p0)
76     {
77     }
78     T *ptr;
79 };
80 
81 template <typename T>
82 class ConstPointerWrapper
83 {
84 public:
ConstPointerWrapper()85     ConstPointerWrapper() : ptr(nullptr)
86     {
87     }
ConstPointerWrapper(const T * p0)88     ConstPointerWrapper(const T *p0) : ptr(p0)
89     {
90     }
91     const T *ptr;
92 };
93 
94 #ifndef CTS_USES_VULKANSC
95 typedef PointerWrapper<VkPipelineViewportDepthClipControlCreateInfoEXT>
96     PipelineViewportDepthClipControlCreateInfoWrapper;
97 typedef PointerWrapper<VkPipelineRenderingCreateInfoKHR> PipelineRenderingCreateInfoWrapper;
98 typedef PointerWrapper<VkRenderingAttachmentLocationInfoKHR> RenderingAttachmentLocationInfoWrapper;
99 typedef PointerWrapper<VkRenderingInputAttachmentIndexInfoKHR> RenderingInputAttachmentIndexInfoWrapper;
100 typedef PointerWrapper<VkPipelineCreationFeedbackCreateInfoEXT> PipelineCreationFeedbackCreateInfoWrapper;
101 typedef ConstPointerWrapper<VkPipelineShaderStageModuleIdentifierCreateInfoEXT>
102     PipelineShaderStageModuleIdentifierCreateInfoWrapper;
103 typedef PointerWrapper<VkPipelineRepresentativeFragmentTestStateCreateInfoNV>
104     PipelineRepresentativeFragmentTestCreateInfoWrapper;
105 typedef PointerWrapper<VkPipelineBinaryInfoKHR> PipelineBinaryInfoWrapper;
106 typedef VkPipelineCreateFlags2KHR PipelineCreateFlags2;
107 typedef VkShaderCreateFlagsEXT ShaderCreateFlags;
108 typedef PointerWrapper<VkPipelineRobustnessCreateInfoEXT> PipelineRobustnessCreateInfoWrapper;
109 #else
110 typedef PointerWrapper<void> PipelineViewportDepthClipControlCreateInfoWrapper;
111 typedef PointerWrapper<void> PipelineRenderingCreateInfoWrapper;
112 typedef PointerWrapper<void> RenderingAttachmentLocationInfoWrapper;
113 typedef PointerWrapper<void> RenderingInputAttachmentIndexInfoWrapper;
114 typedef PointerWrapper<void> PipelineCreationFeedbackCreateInfoWrapper;
115 typedef ConstPointerWrapper<void> PipelineShaderStageModuleIdentifierCreateInfoWrapper;
116 typedef PointerWrapper<void> PipelineRepresentativeFragmentTestCreateInfoWrapper;
117 typedef PointerWrapper<void> PipelineBinaryInfoWrapper;
118 typedef uint64_t PipelineCreateFlags2;
119 typedef uint32_t ShaderCreateFlags;
120 typedef PointerWrapper<void> PipelineRobustnessCreateInfoWrapper;
121 #endif
122 
123 PipelineCreateFlags2 translateCreateFlag(VkPipelineCreateFlags flagToTranslate);
124 
125 class PipelineLayoutWrapper
126 {
127 public:
128     PipelineLayoutWrapper() = default;
129     PipelineLayoutWrapper(PipelineConstructionType pipelineConstructionType, const DeviceInterface &vk, VkDevice device,
130                           const VkDescriptorSetLayout descriptorSetLayout = VK_NULL_HANDLE,
131                           const VkPushConstantRange *pushConstantRange    = nullptr);
132     PipelineLayoutWrapper(PipelineConstructionType pipelineConstructionType, const DeviceInterface &vk, VkDevice device,
133                           const std::vector<vk::Move<VkDescriptorSetLayout>> &descriptorSetLayout);
134     PipelineLayoutWrapper(PipelineConstructionType pipelineConstructionType, const DeviceInterface &vk, VkDevice device,
135                           uint32_t setLayoutCount, const VkDescriptorSetLayout *descriptorSetLayout);
136     PipelineLayoutWrapper(PipelineConstructionType pipelineConstructionType, const DeviceInterface &vk, VkDevice device,
137                           const VkPipelineLayoutCreateInfo *pCreateInfo, const VkAllocationCallbacks * = nullptr);
138     PipelineLayoutWrapper(PipelineConstructionType pipelineConstructionType, const DeviceInterface &vk,
139                           const VkDevice device, const uint32_t setLayoutCount,
140                           const VkDescriptorSetLayout *descriptorSetLayout, const uint32_t pushConstantRangeCount,
141                           const VkPushConstantRange *pPushConstantRanges,
142                           const VkPipelineLayoutCreateFlags flags = (VkPipelineLayoutCreateFlags)0u);
143     PipelineLayoutWrapper(const PipelineLayoutWrapper &rhs) = delete;
144     PipelineLayoutWrapper(PipelineLayoutWrapper &&rhs) noexcept;
145     ~PipelineLayoutWrapper() = default;
146 
operator *(void) const147     const VkPipelineLayout operator*(void) const
148     {
149         return *m_pipelineLayout;
150     }
get(void) const151     const VkPipelineLayout get(void) const
152     {
153         return *m_pipelineLayout;
154     }
155     PipelineLayoutWrapper &operator=(const PipelineLayoutWrapper &rhs) = delete;
156     PipelineLayoutWrapper &operator=(PipelineLayoutWrapper &&rhs);
destroy(void)157     void destroy(void)
158     {
159         m_pipelineLayout = vk::Move<VkPipelineLayout>{};
160     }
161 
getSetLayoutCount(void) const162     uint32_t getSetLayoutCount(void) const
163     {
164         return m_setLayoutCount;
165     }
getSetLayouts(void) const166     const VkDescriptorSetLayout *getSetLayouts(void) const
167     {
168         return m_setLayouts.data();
169     }
getSetLayout(uint32_t i)170     VkDescriptorSetLayout *getSetLayout(uint32_t i)
171     {
172         return &m_setLayouts[i];
173     }
getPushConstantRangeCount(void) const174     uint32_t getPushConstantRangeCount(void) const
175     {
176         return m_pushConstantRangeCount;
177     }
getPushConstantRanges(void) const178     const VkPushConstantRange *getPushConstantRanges(void) const
179     {
180         return m_pushConstantRanges.data();
181     }
182 
183     void bindDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, uint32_t firstSet,
184                             uint32_t descriptorSetCount, const VkDescriptorSet *pDescriptorSets,
185                             uint32_t dynamicOffsetCount, const uint32_t *pDynamicOffsets) const;
186 
187 private:
188     PipelineConstructionType m_pipelineConstructionType;
189     const DeviceInterface *m_vk;
190     VkDevice m_device;
191     VkPipelineLayoutCreateFlags m_flags;
192     uint32_t m_setLayoutCount;
193     std::vector<VkDescriptorSetLayout> m_setLayouts;
194     uint32_t m_pushConstantRangeCount;
195     std::vector<VkPushConstantRange> m_pushConstantRanges;
196     vk::Move<VkPipelineLayout> m_pipelineLayout;
197 };
198 
199 class RenderPassWrapper
200 {
201 public:
202     RenderPassWrapper() = default;
203     RenderPassWrapper(const DeviceInterface &vk, VkDevice device, const VkRenderPassCreateInfo2 *pCreateInfo,
204                       bool dynamicRendering);
205     RenderPassWrapper(PipelineConstructionType pipelineConstructionType, const DeviceInterface &vk, VkDevice device,
206                       const VkRenderPassCreateInfo *pCreateInfo);
207     RenderPassWrapper(PipelineConstructionType pipelineConstructionType, const DeviceInterface &vk, VkDevice device,
208                       const VkRenderPassCreateInfo2 *pCreateInfo);
209     RenderPassWrapper(PipelineConstructionType pipelineConstructionType, const DeviceInterface &vk,
210                       const VkDevice device, const VkFormat colorFormat = VK_FORMAT_UNDEFINED,
211                       const VkFormat depthStencilFormat             = VK_FORMAT_UNDEFINED,
212                       const VkAttachmentLoadOp loadOperation        = VK_ATTACHMENT_LOAD_OP_CLEAR,
213                       const VkImageLayout finalLayoutColor          = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
214                       const VkImageLayout finalLayoutDepthStencil   = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
215                       const VkImageLayout subpassLayoutColor        = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
216                       const VkImageLayout subpassLayoutDepthStencil = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
217                       const VkAllocationCallbacks *const allocationCallbacks = nullptr);
218 
219     RenderPassWrapper(RenderPassWrapper &&rhs) noexcept;
220     RenderPassWrapper &operator=(RenderPassWrapper &&rhs) noexcept;
221 
222     ~RenderPassWrapper() = default;
223 
operator *(void) const224     const VkRenderPass operator*(void) const
225     {
226         return *m_renderPass;
227     }
get(void) const228     const VkRenderPass get(void) const
229     {
230         return *m_renderPass;
231     }
getFramebuffer(void) const232     const VkFramebuffer getFramebuffer(void) const
233     {
234         return m_framebuffer ? *m_framebuffer : VK_NULL_HANDLE;
235     }
236     void resetLayouts(void);
237 
238     void begin(const DeviceInterface &vk, const VkCommandBuffer commandBuffer, const VkRect2D &renderArea,
239                const uint32_t clearValueCount, const VkClearValue *clearValues,
240                const VkSubpassContents contents = VK_SUBPASS_CONTENTS_INLINE, const void *pNext = nullptr) const;
241     void begin(const DeviceInterface &vk, const VkCommandBuffer commandBuffer, const VkRect2D &renderArea,
242                const VkClearValue &clearValue, const VkSubpassContents contents = VK_SUBPASS_CONTENTS_INLINE) const;
243     void begin(const DeviceInterface &vk, const VkCommandBuffer commandBuffer, const VkRect2D &renderArea,
244                const tcu::Vec4 &clearColor, const VkSubpassContents contents = VK_SUBPASS_CONTENTS_INLINE) const;
245     void begin(const DeviceInterface &vk, const VkCommandBuffer commandBuffer, const VkRect2D &renderArea,
246                const tcu::Vec4 &clearColor, const float clearDepth, const uint32_t clearStencil,
247                const VkSubpassContents contents = VK_SUBPASS_CONTENTS_INLINE) const;
248     void begin(const DeviceInterface &vk, const VkCommandBuffer commandBuffer, const VkRect2D &renderArea,
249                const VkSubpassContents contents = VK_SUBPASS_CONTENTS_INLINE) const;
250     void begin(const DeviceInterface &vk, const VkCommandBuffer commandBuffer, const VkRect2D &renderArea,
251                const tcu::UVec4 &clearColor, const VkSubpassContents contents = VK_SUBPASS_CONTENTS_INLINE) const;
252 
253     void end(const DeviceInterface &vk, const VkCommandBuffer commandBuffer) const;
254     void nextSubpass(const DeviceInterface &vk, const VkCommandBuffer commandBuffer,
255                      const VkSubpassContents contents) const;
256 
257     void createFramebuffer(const DeviceInterface &vk, const VkDevice device, const VkFramebufferCreateInfo *pCreateInfo,
258                            const std::vector<vk::VkImage> &images);
259     void createFramebuffer(const DeviceInterface &vk, const VkDevice device, const VkFramebufferCreateInfo *pCreateInfo,
260                            vk::VkImage colorImage, vk::VkImage depthStencilImage = VK_NULL_HANDLE);
261     void createFramebuffer(const DeviceInterface &vk, const VkDevice device, const VkImage colorImage,
262                            const VkImageView colorAttachment, const uint32_t width, const uint32_t height,
263                            const uint32_t layers = 1u);
264     void createFramebuffer(const DeviceInterface &vk, const VkDevice device, const uint32_t attachmentCount,
265                            const VkImage *imagesArray, const VkImageView *attachmentsArray, const uint32_t width,
266                            const uint32_t height, const uint32_t layers = 1u);
267 
268 private:
269     void beginRendering(const DeviceInterface &vk, const VkCommandBuffer commandBuffer) const;
270 
271     bool m_isDynamicRendering;
272     vk::Move<vk::VkRenderPass> m_renderPass;
273     vk::Move<vk::VkFramebuffer> m_framebuffer;
274 
275 #ifndef CTS_USES_VULKANSC
276     struct Subpass
277     {
278         struct Attachment
279         {
280             uint32_t index                               = VK_ATTACHMENT_UNUSED;
281             vk::VkRenderingAttachmentInfo attachmentInfo = {};
282             vk::VkFormat format;
283             vk::VkAttachmentLoadOp stencilLoadOp   = vk::VK_ATTACHMENT_LOAD_OP_LOAD;
284             vk::VkAttachmentStoreOp stencilStoreOp = vk::VK_ATTACHMENT_STORE_OP_STORE;
285         };
286         mutable std::vector<Attachment> m_colorAttachments;
287         mutable Attachment m_depthStencilAttachment;
288         mutable std::vector<Attachment> m_resolveAttachments;
289         mutable VkMultisampledRenderToSingleSampledInfoEXT m_msrtss    = {};
290         mutable VkSubpassDescriptionDepthStencilResolve m_dsr          = {};
291         mutable VkAttachmentReference2 m_depthStencilResolveAttachment = {};
292     };
293     struct SubpassDependency
294     {
295         SubpassDependency(const VkSubpassDependency &dependency);
296         SubpassDependency(const VkSubpassDependency2 &dependency);
297 
298         uint32_t srcSubpass;
299         uint32_t dstSubpass;
300         VkPipelineStageFlags2 srcStageMask;
301         VkPipelineStageFlags2 dstStageMask;
302         VkAccessFlags2 srcAccessMask;
303         VkAccessFlags2 dstAccessMask;
304         VkDependencyFlags dependencyFlags;
305         bool sync2;
306     };
307     std::vector<Subpass> m_subpasses;
308     std::vector<SubpassDependency> m_dependencies;
309     std::vector<vk::VkAttachmentDescription2> m_attachments;
310     std::vector<vk::VkImage> m_images;
311     std::vector<vk::VkImageView> m_imageViews;
312     mutable std::vector<vk::VkClearValue> m_clearValues;
313     mutable std::vector<vk::VkImageLayout> m_layouts;
314     mutable uint32_t m_activeSubpass = 0;
315     mutable vk::VkRenderingInfo m_renderingInfo;
316     uint32_t m_layers = 1;
317     std::vector<uint32_t> m_viewMasks;
318     mutable bool m_secondaryCommandBuffers;
319 
320     void clearAttachments(const DeviceInterface &vk, const VkCommandBuffer commandBuffer) const;
321     void updateLayout(VkImage updatedImage, VkImageLayout newLayout) const;
322     void transitionLayouts(const DeviceInterface &vk, const VkCommandBuffer commandBuffer, const Subpass &subpass,
323                            bool renderPassBegin) const;
324     void insertDependencies(const DeviceInterface &vk, const VkCommandBuffer commandBuffer, uint32_t subpassIdx) const;
325 
326 public:
327     void fillInheritanceRenderingInfo(uint32_t subpassIndex, std::vector<vk::VkFormat> *colorFormats,
328                                       vk::VkCommandBufferInheritanceRenderingInfo *inheritanceRenderingInfo) const;
329 
330 private:
331 #endif
332 };
333 
334 class ShaderWrapper
335 {
336 public:
337     ShaderWrapper();
338 
339     ShaderWrapper(const DeviceInterface &vk, VkDevice device, const vk::ProgramBinary &binary,
340                   const vk::VkShaderModuleCreateFlags createFlags = 0u);
341 
342     ShaderWrapper(const ShaderWrapper &rhs) noexcept;
343 
344     ~ShaderWrapper() = default;
345 
346     ShaderWrapper &operator=(const ShaderWrapper &rhs) noexcept;
347 
isSet(void) const348     bool isSet(void) const
349     {
350         return m_binary != nullptr;
351     }
352 
353     vk::VkShaderModule getModule(void) const;
354 
355     size_t getCodeSize(void) const;
356     void *getBinary(void) const;
357 
358     void createModule(void);
359     void setLayoutAndSpecialization(const PipelineLayoutWrapper *layout,
360                                     const VkSpecializationInfo *specializationInfo);
361 
getPipelineLayout(void) const362     const PipelineLayoutWrapper *getPipelineLayout(void) const
363     {
364         return m_layout;
365     }
getSpecializationInfo(void) const366     const VkSpecializationInfo *getSpecializationInfo(void) const
367     {
368         return m_specializationInfo;
369     }
370 
371 #ifndef CTS_USES_VULKANSC
getShader(void) const372     vk::VkShaderEXT getShader(void) const
373     {
374         return m_shader ? *m_shader : VK_NULL_HANDLE;
375     }
setShader(Move<VkShaderEXT> shader)376     void setShader(Move<VkShaderEXT> shader)
377     {
378         m_shader = shader;
379     }
380 
addFlags(const VkShaderCreateFlagsEXT flags)381     void addFlags(const VkShaderCreateFlagsEXT flags)
382     {
383         m_shaderCreateFlags |= flags;
384     }
385     void getShaderBinary(void);
getShaderBinaryDataSize(void)386     size_t getShaderBinaryDataSize(void)
387     {
388         return m_binaryDataSize;
389     }
getShaderBinaryData(void)390     void *getShaderBinaryData(void)
391     {
392         return m_binaryData.data();
393     }
394 #endif
395 
396 private:
397     const DeviceInterface *m_vk;
398     VkDevice m_device;
399     const vk::ProgramBinary *m_binary;
400     vk::VkShaderModuleCreateFlags m_moduleCreateFlags;
401     mutable vk::Move<vk::VkShaderModule> m_module;
402     const PipelineLayoutWrapper *m_layout;
403     const VkSpecializationInfo *m_specializationInfo;
404 #ifndef CTS_USES_VULKANSC
405     vk::Move<vk::VkShaderEXT> m_shader;
406     VkShaderCreateFlagsEXT m_shaderCreateFlags;
407     size_t m_binaryDataSize;
408     std::vector<uint8_t> m_binaryData;
409 #endif
410 };
411 
412 // Class that can build monolithic pipeline or fully separated pipeline libraries
413 // depending on PipelineType specified in the constructor.
414 // Rarely needed configuration was extracted to setDefault*/disable* functions while common
415 // state setup is provided as arguments of four setup* functions - one for each state group.
416 class GraphicsPipelineWrapper
417 {
418 public:
419     GraphicsPipelineWrapper(const InstanceInterface &vki, const DeviceInterface &vk, VkPhysicalDevice physicalDevice,
420                             VkDevice device, const std::vector<std::string> &deviceExtensions,
421                             const PipelineConstructionType pipelineConstructionType,
422                             const VkPipelineCreateFlags flags = 0u);
423 
424     GraphicsPipelineWrapper(GraphicsPipelineWrapper &&) noexcept;
425 
426     ~GraphicsPipelineWrapper(void) = default;
427 
428     // By default pipelineLayout used for monotlithic pipeline is taken from layout specified
429     // in setupPreRasterizationShaderState but when there are also descriptor sets needed for fragment
430     // shader bindings then separate pipeline layout for monolithic pipeline must be provided
431     GraphicsPipelineWrapper &setMonolithicPipelineLayout(const PipelineLayoutWrapper &layout);
432 
433     // By default dynamic state has to be specified before specifying other CreateInfo structures
434     GraphicsPipelineWrapper &setDynamicState(const VkPipelineDynamicStateCreateInfo *dynamicState);
435 
436     // When this wrapper is used with functionality provided by VK_KHR_pipeline_binary
437     // then we need to be able to set binaries for individual pipeline parts as well as for monolithic pipeline.
438     GraphicsPipelineWrapper &setMonolithicPipelineBinaries(PipelineBinaryInfoWrapper binaries);
439 
440     // Specify the representative fragment test state.
441     GraphicsPipelineWrapper &setRepresentativeFragmentTestState(
442         PipelineRepresentativeFragmentTestCreateInfoWrapper representativeFragmentTestState);
443 
444     // Specify pipeline robustness state
445     GraphicsPipelineWrapper &setPipelineRobustnessState(PipelineRobustnessCreateInfoWrapper pipelineRobustnessState);
446 
447     // Specifying how a pipeline is created using VkPipelineCreateFlags2CreateInfoKHR.
448     GraphicsPipelineWrapper &setPipelineCreateFlags2(PipelineCreateFlags2 pipelineFlags2);
449 
450     // Specify how shaders should be created with explicit flags. Note we could try to unify this with
451     // setPipelineCreateFlags2 but the equivalence is not direct and some flags do not map.
452     GraphicsPipelineWrapper &setShaderCreateFlags(ShaderCreateFlags shaderFlags);
453 
454     // Specify topology that is used by default InputAssemblyState in vertex input state. This needs to be
455     // specified only when there is no custom InputAssemblyState provided in setupVertexInputState and when
456     // topology is diferent then VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST which is used by default.
457     GraphicsPipelineWrapper &setDefaultTopology(const VkPrimitiveTopology topology);
458 
459     // Specify patch control points that is used by default TessellationState in pre-rasterization shader state.
460     // This can to be specified only when there is no custom TessellationState provided in
461     // setupPreRasterizationShaderState and when patchControlPoints is diferent then 3 which is used by default.
462     // A value of std::numeric_limits<uint32_t>::max() forces the tessellation state to be null.
463     GraphicsPipelineWrapper &setDefaultPatchControlPoints(const uint32_t patchControlPoints);
464 
465     // Specify tesellation domain origin, used by the tessellation state in pre-rasterization shader state.
466     GraphicsPipelineWrapper &setDefaultTessellationDomainOrigin(const VkTessellationDomainOrigin domainOrigin,
467                                                                 bool forceExtStruct = false);
468 
469     // Enable discarding of primitives that is used by default RasterizationState in pre-rasterization shader state.
470     // This can be specified only when there is no custom RasterizationState provided in setupPreRasterizationShaderState.
471     GraphicsPipelineWrapper &setDefaultRasterizerDiscardEnable(const bool rasterizerDiscardEnable = true);
472 
473     // When some states are not provided then default structures can be used. This behaviour can be turned on by one of below methods.
474     // Some tests require those states to be NULL so we can't assume using default versions.
475     GraphicsPipelineWrapper &setDefaultRasterizationState(void);
476     GraphicsPipelineWrapper &setDefaultDepthStencilState(void);
477     GraphicsPipelineWrapper &setDefaultColorBlendState(void);
478     GraphicsPipelineWrapper &setDefaultMultisampleState(void);
479     GraphicsPipelineWrapper &setDefaultVertexInputState(const bool useDefaultVertexInputState);
480 
481     // Pre-rasterization shader state uses provieded viewports and scissors to create ViewportState. By default
482     // number of viewports and scissors is same as number of items in vector but when vectors are empty then by
483     // default count of viewports/scissors is set to 1. This can be changed by below functions.
484     GraphicsPipelineWrapper &setDefaultViewportsCount(uint32_t viewportCount = 0u);
485     GraphicsPipelineWrapper &setDefaultScissorsCount(uint32_t scissorCount = 0u);
486 
487     // Pre-rasterization shader state uses default ViewportState, this method extends the internal structure.
488     GraphicsPipelineWrapper &setViewportStatePnext(const void *pNext);
489 
490 #ifndef CTS_USES_VULKANSC
491     GraphicsPipelineWrapper &setRenderingColorAttachmentsInfo(
492         PipelineRenderingCreateInfoWrapper pipelineRenderingCreateInfo);
493 #endif
494 
495     // Pre-rasterization shader state uses provieded viewports and scissors to create ViewportState. When disableViewportState
496     // is used then ViewportState won't be constructed and NULL will be used.
497     GraphicsPipelineWrapper &disableViewportState(const bool disable = true);
498 
499     // Setup vertex input state. When VertexInputState or InputAssemblyState are not provided then default structures will be used.
500     GraphicsPipelineWrapper &setupVertexInputState(
501         const VkPipelineVertexInputStateCreateInfo *vertexInputState     = nullptr,
502         const VkPipelineInputAssemblyStateCreateInfo *inputAssemblyState = nullptr,
503         const VkPipelineCache partPipelineCache                          = VK_NULL_HANDLE,
504         PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback   = PipelineCreationFeedbackCreateInfoWrapper(),
505         PipelineBinaryInfoWrapper partBinaries = PipelineBinaryInfoWrapper(), const bool useNullPtrs = false);
506 
507     // When disableShaderModules is used module attributes in VkPipelineShaderStageCreateInfo will be set to NULL.
508     // This is needed for VK_KHR_pipeline_binary tests where we need to construct a pipeline from pipeline binaries without using modules.
509     GraphicsPipelineWrapper &disableShaderModules(const bool disable = true);
510 
511     // Setup pre-rasterization shader state.
512     GraphicsPipelineWrapper &setupPreRasterizationShaderState(
513         const std::vector<VkViewport> &viewports, const std::vector<VkRect2D> &scissors,
514         const PipelineLayoutWrapper &layout, const VkRenderPass renderPass, const uint32_t subpass,
515         const ShaderWrapper vertexShaderModule,
516         const VkPipelineRasterizationStateCreateInfo *rasterizationState = nullptr,
517         const ShaderWrapper tessellationControlShader                    = ShaderWrapper(),
518         const ShaderWrapper tessellationEvalShader                       = ShaderWrapper(),
519         const ShaderWrapper geometryShader = ShaderWrapper(), const VkSpecializationInfo *specializationInfo = nullptr,
520         VkPipelineFragmentShadingRateStateCreateInfoKHR *fragmentShadingRateState = nullptr,
521         PipelineRenderingCreateInfoWrapper rendering                   = PipelineRenderingCreateInfoWrapper(),
522         const VkPipelineCache partPipelineCache                        = VK_NULL_HANDLE,
523         PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback = PipelineCreationFeedbackCreateInfoWrapper());
524 
525     GraphicsPipelineWrapper &setupPreRasterizationShaderState2(
526         const std::vector<VkViewport> &viewports, const std::vector<VkRect2D> &scissors,
527         const PipelineLayoutWrapper &layout, const VkRenderPass renderPass, const uint32_t subpass,
528         const ShaderWrapper vertexShaderModule,
529         const VkPipelineRasterizationStateCreateInfo *rasterizationState          = nullptr,
530         const ShaderWrapper tessellationControlShader                             = ShaderWrapper(),
531         const ShaderWrapper tessellationEvalShader                                = ShaderWrapper(),
532         const ShaderWrapper geometryShader                                        = ShaderWrapper(),
533         const VkSpecializationInfo *vertSpecializationInfo                        = nullptr,
534         const VkSpecializationInfo *tescSpecializationInfo                        = nullptr,
535         const VkSpecializationInfo *teseSpecializationInfo                        = nullptr,
536         const VkSpecializationInfo *geomSpecializationInfo                        = nullptr,
537         VkPipelineFragmentShadingRateStateCreateInfoKHR *fragmentShadingRateState = nullptr,
538         PipelineRenderingCreateInfoWrapper rendering                   = PipelineRenderingCreateInfoWrapper(),
539         const VkPipelineCache partPipelineCache                        = VK_NULL_HANDLE,
540         PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback = PipelineCreationFeedbackCreateInfoWrapper());
541 
542     // Note: VkPipelineShaderStageModuleIdentifierCreateInfoEXT::pIdentifier will not be copied. They need to continue to exist outside this wrapper.
543     GraphicsPipelineWrapper &setupPreRasterizationShaderState3(
544         const std::vector<VkViewport> &viewports, const std::vector<VkRect2D> &scissors,
545         const PipelineLayoutWrapper &layout, const VkRenderPass renderPass, const uint32_t subpass,
546         const ShaderWrapper vertexShaderModule,
547         PipelineShaderStageModuleIdentifierCreateInfoWrapper vertShaderModuleId =
548             PipelineShaderStageModuleIdentifierCreateInfoWrapper(),
549         const VkPipelineRasterizationStateCreateInfo *rasterizationState = nullptr,
550         const ShaderWrapper tessellationControlShader                    = ShaderWrapper(),
551         PipelineShaderStageModuleIdentifierCreateInfoWrapper tescShaderModuleId =
552             PipelineShaderStageModuleIdentifierCreateInfoWrapper(),
553         const ShaderWrapper tessellationEvalShader = ShaderWrapper(),
554         PipelineShaderStageModuleIdentifierCreateInfoWrapper teseShaderModuleId =
555             PipelineShaderStageModuleIdentifierCreateInfoWrapper(),
556         const ShaderWrapper geometryShader = ShaderWrapper(),
557         PipelineShaderStageModuleIdentifierCreateInfoWrapper geomShaderModuleId =
558             PipelineShaderStageModuleIdentifierCreateInfoWrapper(),
559         const VkSpecializationInfo *vertSpecializationInfo                        = nullptr,
560         const VkSpecializationInfo *tescSpecializationInfo                        = nullptr,
561         const VkSpecializationInfo *teseSpecializationInfo                        = nullptr,
562         const VkSpecializationInfo *geomSpecializationInfo                        = nullptr,
563         VkPipelineFragmentShadingRateStateCreateInfoKHR *fragmentShadingRateState = nullptr,
564         PipelineRenderingCreateInfoWrapper rendering                   = PipelineRenderingCreateInfoWrapper(),
565         const VkPipelineCache partPipelineCache                        = VK_NULL_HANDLE,
566         PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback = PipelineCreationFeedbackCreateInfoWrapper(),
567         PipelineBinaryInfoWrapper partBinaries                         = PipelineBinaryInfoWrapper());
568 
569 #ifndef CTS_USES_VULKANSC
570     // Setup pre-rasterization shader state, mesh shading version.
571     GraphicsPipelineWrapper &setupPreRasterizationMeshShaderState(
572         const std::vector<VkViewport> &viewports, const std::vector<VkRect2D> &scissors,
573         const PipelineLayoutWrapper &layout, const VkRenderPass renderPass, const uint32_t subpass,
574         const ShaderWrapper taskShader, const ShaderWrapper meshShader,
575         const VkPipelineRasterizationStateCreateInfo *rasterizationState          = nullptr,
576         const VkSpecializationInfo *taskSpecializationInfo                        = nullptr,
577         const VkSpecializationInfo *meshSpecializationInfo                        = nullptr,
578         VkPipelineFragmentShadingRateStateCreateInfoKHR *fragmentShadingRateState = nullptr,
579         PipelineRenderingCreateInfoWrapper rendering                  = PipelineRenderingCreateInfoWrapper(),
580         const VkPipelineCache partPipelineCache                       = VK_NULL_HANDLE,
581         VkPipelineCreationFeedbackCreateInfoEXT *partCreationFeedback = nullptr);
582 
583     GraphicsPipelineWrapper &setupPreRasterizationMeshShaderState2(
584         const std::vector<VkViewport> &viewports, const std::vector<VkRect2D> &scissors,
585         const PipelineLayoutWrapper &layout, const VkRenderPass renderPass, const uint32_t subpass,
586         const ShaderWrapper taskShader, PipelineShaderStageModuleIdentifierCreateInfoWrapper taskShaderModuleId,
587         const ShaderWrapper meshShader, PipelineShaderStageModuleIdentifierCreateInfoWrapper meshShaderModuleId,
588         const VkPipelineRasterizationStateCreateInfo *rasterizationState          = nullptr,
589         const VkSpecializationInfo *taskSpecializationInfo                        = nullptr,
590         const VkSpecializationInfo *meshSpecializationInfo                        = nullptr,
591         VkPipelineFragmentShadingRateStateCreateInfoKHR *fragmentShadingRateState = nullptr,
592         PipelineRenderingCreateInfoWrapper rendering                  = PipelineRenderingCreateInfoWrapper(),
593         const VkPipelineCache partPipelineCache                       = VK_NULL_HANDLE,
594         VkPipelineCreationFeedbackCreateInfoEXT *partCreationFeedback = nullptr);
595 #endif // CTS_USES_VULKANSC
596 
597     // Setup fragment shader state.
598     GraphicsPipelineWrapper &setupFragmentShaderState(
599         const PipelineLayoutWrapper &layout, const VkRenderPass renderPass, const uint32_t subpass,
600         const ShaderWrapper fragmentShaderModule,
601         const VkPipelineDepthStencilStateCreateInfo *depthStencilState = nullptr,
602         const VkPipelineMultisampleStateCreateInfo *multisampleState   = nullptr,
603         const VkSpecializationInfo *specializationInfo                 = nullptr,
604         const VkPipelineCache partPipelineCache                        = VK_NULL_HANDLE,
605         PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback = PipelineCreationFeedbackCreateInfoWrapper(),
606         RenderingInputAttachmentIndexInfoWrapper renderingInputAttachmentIndexInfo =
607             RenderingInputAttachmentIndexInfoWrapper());
608 
609     // Note: VkPipelineShaderStageModuleIdentifierCreateInfoEXT::pIdentifier will not be copied. They need to continue to exist outside this wrapper.
610     GraphicsPipelineWrapper &setupFragmentShaderState2(
611         const PipelineLayoutWrapper &layout, const VkRenderPass renderPass, const uint32_t subpass,
612         const ShaderWrapper fragmentShaderModule,
613         PipelineShaderStageModuleIdentifierCreateInfoWrapper fragmentShaderModuleId =
614             PipelineShaderStageModuleIdentifierCreateInfoWrapper(),
615         const VkPipelineDepthStencilStateCreateInfo *depthStencilState = nullptr,
616         const VkPipelineMultisampleStateCreateInfo *multisampleState   = nullptr,
617         const VkSpecializationInfo *specializationInfo                 = nullptr,
618         const VkPipelineCache partPipelineCache                        = VK_NULL_HANDLE,
619         PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback = PipelineCreationFeedbackCreateInfoWrapper(),
620         RenderingInputAttachmentIndexInfoWrapper renderingInputAttachmentIndexInfo =
621             RenderingInputAttachmentIndexInfoWrapper(),
622         PipelineBinaryInfoWrapper partBinaries = PipelineBinaryInfoWrapper());
623 
624     // Setup fragment output state.
625     GraphicsPipelineWrapper &setupFragmentOutputState(
626         const VkRenderPass renderPass, const uint32_t subpass = 0u,
627         const VkPipelineColorBlendStateCreateInfo *colorBlendState     = nullptr,
628         const VkPipelineMultisampleStateCreateInfo *multisampleState   = nullptr,
629         const VkPipelineCache partPipelineCache                        = VK_NULL_HANDLE,
630         PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback = PipelineCreationFeedbackCreateInfoWrapper(),
631         RenderingAttachmentLocationInfoWrapper renderingAttachmentLocationInfo =
632             RenderingAttachmentLocationInfoWrapper(),
633         PipelineBinaryInfoWrapper partBinaries = PipelineBinaryInfoWrapper());
634 
635     // Build pipeline object out of provided state.
636     void buildPipeline(
637         const VkPipelineCache pipelineCache = VK_NULL_HANDLE, const VkPipeline basePipelineHandle = VK_NULL_HANDLE,
638         const int32_t basePipelineIndex                            = 0,
639         PipelineCreationFeedbackCreateInfoWrapper creationFeedback = PipelineCreationFeedbackCreateInfoWrapper(),
640         void *pNext                                                = nullptr);
641     // Create shader objects if used
642 #ifndef CTS_USES_VULKANSC
643     vk::VkShaderStageFlags getNextStages(vk::VkShaderStageFlagBits shaderStage, bool tessellationShaders,
644                                          bool geometryShaders, bool link);
645     vk::VkShaderCreateInfoEXT makeShaderCreateInfo(VkShaderStageFlagBits stage, ShaderWrapper &shader, bool link,
646                                                    bool binary, ShaderWrapper &other);
647     void createShaders(bool linked, bool binary);
648 #endif
649 
650     // Bind pipeline or shader objects
651     void bind(vk::VkCommandBuffer cmdBuffer) const;
652 
653     // Returns true when pipeline was build using buildPipeline method.
654     bool wasBuild(void) const;
655     // Returns true when pipeline or shader objects was built.
656     bool wasPipelineOrShaderObjectBuild(void) const;
657 
658     // Get compleate pipeline. GraphicsPipelineWrapper preserves ovnership and will destroy pipeline in its destructor.
659     vk::VkPipeline getPipeline(void) const;
660 
661     // Get partial pipeline. GraphicsPipelineWrapper preserves ovnership and will desroy pipeline in its destructor.
662     vk::VkPipeline getPartialPipeline(uint32_t part) const;
663 
664     // Get compleate pipeline create info.
665     const VkGraphicsPipelineCreateInfo &getPipelineCreateInfo(void) const;
666 
667     // Get partial pipeline create info.
668     const VkGraphicsPipelineCreateInfo &getPartialPipelineCreateInfo(uint32_t part) const;
669 
670 #ifndef CTS_USES_VULKANSC
671     // Get particular shader. GraphicsPipelineWrapper preserves ovnership and will destroy shaders in its destructor.
672     vk::VkShaderEXT getShader(VkShaderStageFlagBits stage) const;
673 #endif
674 
675     // Destroy compleate pipeline - pipeline parts are not destroyed.
676     void destroyPipeline(void);
677 
678 protected:
679     // No default constructor - use parametrized constructor or emplace_back in case of vectors.
680     GraphicsPipelineWrapper() = default;
681 
682     // Dynamic states that are only dynamic in shader objects
683     bool isShaderObjectDynamic(vk::VkDynamicState dynamicState) const;
684     void setShaderObjectDynamicStates(vk::VkCommandBuffer cmdBuffer) const;
685 
686     struct InternalData;
687 
688 protected:
689     static constexpr size_t kMaxPipelineParts = 4u;
690 
691     // Store partial pipelines when non monolithic construction was used.
692     Move<VkPipeline> m_pipelineParts[kMaxPipelineParts];
693 
694     // Store monolithic pipeline or linked pipeline libraries.
695     Move<VkPipeline> m_pipelineFinal;
696 
697     // Store internal data that is needed only for pipeline construction.
698     de::SharedPtr<InternalData> m_internalData;
699 };
700 
701 std::vector<VkDynamicState> getShaderObjectDynamicStatesFromExtensions(const std::vector<std::string> &extensions);
702 
703 } // namespace vk
704 
705 #endif // _VKPIPELINECONSTRUCTIONUTIL_HPP
706