xref: /aosp_15_r20/external/deqp/external/vulkancts/framework/vulkan/vkPipelineConstructionUtil.hpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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(DE_NULL)
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(DE_NULL)
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 VkPipelineCreateFlags2KHR PipelineCreateFlags2;
106 typedef PointerWrapper<VkPipelineRobustnessCreateInfoEXT> PipelineRobustnessCreateInfoWrapper;
107 #else
108 typedef PointerWrapper<void> PipelineViewportDepthClipControlCreateInfoWrapper;
109 typedef PointerWrapper<void> PipelineRenderingCreateInfoWrapper;
110 typedef PointerWrapper<void> RenderingAttachmentLocationInfoWrapper;
111 typedef PointerWrapper<void> RenderingInputAttachmentIndexInfoWrapper;
112 typedef PointerWrapper<void> PipelineCreationFeedbackCreateInfoWrapper;
113 typedef ConstPointerWrapper<void> PipelineShaderStageModuleIdentifierCreateInfoWrapper;
114 typedef PointerWrapper<void> PipelineRepresentativeFragmentTestCreateInfoWrapper;
115 typedef uint64_t PipelineCreateFlags2;
116 typedef PointerWrapper<void> PipelineRobustnessCreateInfoWrapper;
117 #endif
118 
119 PipelineCreateFlags2 translateCreateFlag(VkPipelineCreateFlags flagToTranslate);
120 
121 class PipelineLayoutWrapper
122 {
123 public:
124     PipelineLayoutWrapper() = default;
125     PipelineLayoutWrapper(PipelineConstructionType pipelineConstructionType, const DeviceInterface &vk, VkDevice device,
126                           const VkDescriptorSetLayout descriptorSetLayout = DE_NULL,
127                           const VkPushConstantRange *pushConstantRange    = DE_NULL);
128     PipelineLayoutWrapper(PipelineConstructionType pipelineConstructionType, const DeviceInterface &vk, VkDevice device,
129                           const std::vector<vk::Move<VkDescriptorSetLayout>> &descriptorSetLayout);
130     PipelineLayoutWrapper(PipelineConstructionType pipelineConstructionType, const DeviceInterface &vk, VkDevice device,
131                           uint32_t setLayoutCount, const VkDescriptorSetLayout *descriptorSetLayout);
132     PipelineLayoutWrapper(PipelineConstructionType pipelineConstructionType, const DeviceInterface &vk, VkDevice device,
133                           const VkPipelineLayoutCreateInfo *pCreateInfo, const VkAllocationCallbacks * = DE_NULL);
134     PipelineLayoutWrapper(PipelineConstructionType pipelineConstructionType, const DeviceInterface &vk,
135                           const VkDevice device, const uint32_t setLayoutCount,
136                           const VkDescriptorSetLayout *descriptorSetLayout, const uint32_t pushConstantRangeCount,
137                           const VkPushConstantRange *pPushConstantRanges,
138                           const VkPipelineLayoutCreateFlags flags = (VkPipelineLayoutCreateFlags)0u);
139     PipelineLayoutWrapper(const PipelineLayoutWrapper &rhs) = delete;
140     PipelineLayoutWrapper(PipelineLayoutWrapper &&rhs) noexcept;
141     ~PipelineLayoutWrapper() = default;
142 
operator *(void) const143     const VkPipelineLayout operator*(void) const
144     {
145         return *m_pipelineLayout;
146     }
get(void) const147     const VkPipelineLayout get(void) const
148     {
149         return *m_pipelineLayout;
150     }
151     PipelineLayoutWrapper &operator=(const PipelineLayoutWrapper &rhs) = delete;
152     PipelineLayoutWrapper &operator=(PipelineLayoutWrapper &&rhs);
destroy(void)153     void destroy(void)
154     {
155         m_pipelineLayout = vk::Move<VkPipelineLayout>{};
156     }
157 
getSetLayoutCount(void) const158     uint32_t getSetLayoutCount(void) const
159     {
160         return m_setLayoutCount;
161     }
getSetLayouts(void) const162     const VkDescriptorSetLayout *getSetLayouts(void) const
163     {
164         return m_setLayouts.data();
165     }
getSetLayout(uint32_t i)166     VkDescriptorSetLayout *getSetLayout(uint32_t i)
167     {
168         return &m_setLayouts[i];
169     }
getPushConstantRangeCount(void) const170     uint32_t getPushConstantRangeCount(void) const
171     {
172         return m_pushConstantRangeCount;
173     }
getPushConstantRanges(void) const174     const VkPushConstantRange *getPushConstantRanges(void) const
175     {
176         return m_pushConstantRanges.data();
177     }
178 
179     void bindDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, uint32_t firstSet,
180                             uint32_t descriptorSetCount, const VkDescriptorSet *pDescriptorSets,
181                             uint32_t dynamicOffsetCount, const uint32_t *pDynamicOffsets) const;
182 
183 private:
184     PipelineConstructionType m_pipelineConstructionType;
185     const DeviceInterface *m_vk;
186     VkDevice m_device;
187     VkPipelineLayoutCreateFlags m_flags;
188     uint32_t m_setLayoutCount;
189     std::vector<VkDescriptorSetLayout> m_setLayouts;
190     uint32_t m_pushConstantRangeCount;
191     std::vector<VkPushConstantRange> m_pushConstantRanges;
192     vk::Move<VkPipelineLayout> m_pipelineLayout;
193 };
194 
195 class RenderPassWrapper
196 {
197 public:
198     RenderPassWrapper() = default;
199     RenderPassWrapper(const DeviceInterface &vk, VkDevice device, const VkRenderPassCreateInfo2 *pCreateInfo,
200                       bool dynamicRendering);
201     RenderPassWrapper(PipelineConstructionType pipelineConstructionType, const DeviceInterface &vk, VkDevice device,
202                       const VkRenderPassCreateInfo *pCreateInfo);
203     RenderPassWrapper(PipelineConstructionType pipelineConstructionType, const DeviceInterface &vk, VkDevice device,
204                       const VkRenderPassCreateInfo2 *pCreateInfo);
205     RenderPassWrapper(PipelineConstructionType pipelineConstructionType, const DeviceInterface &vk,
206                       const VkDevice device, const VkFormat colorFormat = VK_FORMAT_UNDEFINED,
207                       const VkFormat depthStencilFormat             = VK_FORMAT_UNDEFINED,
208                       const VkAttachmentLoadOp loadOperation        = VK_ATTACHMENT_LOAD_OP_CLEAR,
209                       const VkImageLayout finalLayoutColor          = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
210                       const VkImageLayout finalLayoutDepthStencil   = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
211                       const VkImageLayout subpassLayoutColor        = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
212                       const VkImageLayout subpassLayoutDepthStencil = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
213                       const VkAllocationCallbacks *const allocationCallbacks = DE_NULL);
214 
215     RenderPassWrapper(RenderPassWrapper &&rhs) noexcept;
216     RenderPassWrapper &operator=(RenderPassWrapper &&rhs) noexcept;
217 
218     ~RenderPassWrapper() = default;
219 
operator *(void) const220     const VkRenderPass operator*(void) const
221     {
222         return *m_renderPass;
223     }
get(void) const224     const VkRenderPass get(void) const
225     {
226         return *m_renderPass;
227     }
getFramebuffer(void) const228     const VkFramebuffer getFramebuffer(void) const
229     {
230         return m_framebuffer ? *m_framebuffer : VK_NULL_HANDLE;
231     }
232     void resetLayouts(void);
233 
234     void begin(const DeviceInterface &vk, const VkCommandBuffer commandBuffer, const VkRect2D &renderArea,
235                const uint32_t clearValueCount, const VkClearValue *clearValues,
236                const VkSubpassContents contents = VK_SUBPASS_CONTENTS_INLINE, const void *pNext = DE_NULL) const;
237     void begin(const DeviceInterface &vk, const VkCommandBuffer commandBuffer, const VkRect2D &renderArea,
238                const VkClearValue &clearValue, const VkSubpassContents contents = VK_SUBPASS_CONTENTS_INLINE) const;
239     void begin(const DeviceInterface &vk, const VkCommandBuffer commandBuffer, const VkRect2D &renderArea,
240                const tcu::Vec4 &clearColor, const VkSubpassContents contents = VK_SUBPASS_CONTENTS_INLINE) const;
241     void begin(const DeviceInterface &vk, const VkCommandBuffer commandBuffer, const VkRect2D &renderArea,
242                const tcu::Vec4 &clearColor, const float clearDepth, const uint32_t clearStencil,
243                const VkSubpassContents contents = VK_SUBPASS_CONTENTS_INLINE) const;
244     void begin(const DeviceInterface &vk, const VkCommandBuffer commandBuffer, const VkRect2D &renderArea,
245                const VkSubpassContents contents = VK_SUBPASS_CONTENTS_INLINE) const;
246     void begin(const DeviceInterface &vk, const VkCommandBuffer commandBuffer, const VkRect2D &renderArea,
247                const tcu::UVec4 &clearColor, const VkSubpassContents contents = VK_SUBPASS_CONTENTS_INLINE) const;
248 
249     void end(const DeviceInterface &vk, const VkCommandBuffer commandBuffer) const;
250     void nextSubpass(const DeviceInterface &vk, const VkCommandBuffer commandBuffer,
251                      const VkSubpassContents contents) const;
252 
253     void createFramebuffer(const DeviceInterface &vk, const VkDevice device, const VkFramebufferCreateInfo *pCreateInfo,
254                            const std::vector<vk::VkImage> &images);
255     void createFramebuffer(const DeviceInterface &vk, const VkDevice device, const VkFramebufferCreateInfo *pCreateInfo,
256                            vk::VkImage colorImage, vk::VkImage depthStencilImage = VK_NULL_HANDLE);
257     void createFramebuffer(const DeviceInterface &vk, const VkDevice device, const VkImage colorImage,
258                            const VkImageView colorAttachment, const uint32_t width, const uint32_t height,
259                            const uint32_t layers = 1u);
260     void createFramebuffer(const DeviceInterface &vk, const VkDevice device, const uint32_t attachmentCount,
261                            const VkImage *imagesArray, const VkImageView *attachmentsArray, const uint32_t width,
262                            const uint32_t height, const uint32_t layers = 1u);
263 
264 private:
265     void beginRendering(const DeviceInterface &vk, const VkCommandBuffer commandBuffer) const;
266 
267     bool m_isDynamicRendering;
268     vk::Move<vk::VkRenderPass> m_renderPass;
269     vk::Move<vk::VkFramebuffer> m_framebuffer;
270 
271 #ifndef CTS_USES_VULKANSC
272     struct Subpass
273     {
274         struct Attachment
275         {
276             uint32_t index                               = VK_ATTACHMENT_UNUSED;
277             vk::VkRenderingAttachmentInfo attachmentInfo = {};
278             vk::VkFormat format;
279             vk::VkAttachmentLoadOp stencilLoadOp   = vk::VK_ATTACHMENT_LOAD_OP_LOAD;
280             vk::VkAttachmentStoreOp stencilStoreOp = vk::VK_ATTACHMENT_STORE_OP_STORE;
281         };
282         mutable std::vector<Attachment> m_colorAttachments;
283         mutable Attachment m_depthStencilAttachment;
284         mutable std::vector<Attachment> m_resolveAttachments;
285         mutable VkMultisampledRenderToSingleSampledInfoEXT m_msrtss    = {};
286         mutable VkSubpassDescriptionDepthStencilResolve m_dsr          = {};
287         mutable VkAttachmentReference2 m_depthStencilResolveAttachment = {};
288     };
289     struct SubpassDependency
290     {
291         SubpassDependency(const VkSubpassDependency &dependency);
292         SubpassDependency(const VkSubpassDependency2 &dependency);
293 
294         uint32_t srcSubpass;
295         uint32_t dstSubpass;
296         VkPipelineStageFlags2 srcStageMask;
297         VkPipelineStageFlags2 dstStageMask;
298         VkAccessFlags2 srcAccessMask;
299         VkAccessFlags2 dstAccessMask;
300         VkDependencyFlags dependencyFlags;
301         bool sync2;
302     };
303     std::vector<Subpass> m_subpasses;
304     std::vector<SubpassDependency> m_dependencies;
305     std::vector<vk::VkAttachmentDescription2> m_attachments;
306     std::vector<vk::VkImage> m_images;
307     std::vector<vk::VkImageView> m_imageViews;
308     mutable std::vector<vk::VkClearValue> m_clearValues;
309     mutable std::vector<vk::VkImageLayout> m_layouts;
310     mutable uint32_t m_activeSubpass = 0;
311     mutable vk::VkRenderingInfo m_renderingInfo;
312     uint32_t m_layers = 1;
313     std::vector<uint32_t> m_viewMasks;
314     mutable bool m_secondaryCommandBuffers;
315 
316     void clearAttachments(const DeviceInterface &vk, const VkCommandBuffer commandBuffer) const;
317     void updateLayout(VkImage updatedImage, VkImageLayout newLayout) const;
318     void transitionLayouts(const DeviceInterface &vk, const VkCommandBuffer commandBuffer, const Subpass &subpass,
319                            bool renderPassBegin) const;
320     void insertDependencies(const DeviceInterface &vk, const VkCommandBuffer commandBuffer, uint32_t subpassIdx) const;
321 
322 public:
323     void fillInheritanceRenderingInfo(uint32_t subpassIndex, std::vector<vk::VkFormat> *colorFormats,
324                                       vk::VkCommandBufferInheritanceRenderingInfo *inheritanceRenderingInfo) const;
325 
326 private:
327 #endif
328 };
329 
330 class ShaderWrapper
331 {
332 public:
333     ShaderWrapper();
334 
335     ShaderWrapper(const DeviceInterface &vk, VkDevice device, const vk::ProgramBinary &binary,
336                   const vk::VkShaderModuleCreateFlags createFlags = 0u);
337 
338     ShaderWrapper(const ShaderWrapper &rhs) noexcept;
339 
340     ~ShaderWrapper() = default;
341 
342     ShaderWrapper &operator=(const ShaderWrapper &rhs) noexcept;
343 
isSet(void) const344     bool isSet(void) const
345     {
346         return m_binary != DE_NULL;
347     }
348 
349     vk::VkShaderModule getModule(void) const;
350 
351     size_t getCodeSize(void) const;
352     void *getBinary(void) const;
353 
354     void createModule(void);
355     void setLayoutAndSpecialization(const PipelineLayoutWrapper *layout,
356                                     const VkSpecializationInfo *specializationInfo);
357 
getPipelineLayout(void) const358     const PipelineLayoutWrapper *getPipelineLayout(void) const
359     {
360         return m_layout;
361     }
getSpecializationInfo(void) const362     const VkSpecializationInfo *getSpecializationInfo(void) const
363     {
364         return m_specializationInfo;
365     }
366 
367 #ifndef CTS_USES_VULKANSC
getShader(void) const368     vk::VkShaderEXT getShader(void) const
369     {
370         return m_shader ? *m_shader : VK_NULL_HANDLE;
371     }
setShader(Move<VkShaderEXT> shader)372     void setShader(Move<VkShaderEXT> shader)
373     {
374         m_shader = shader;
375     }
376 
addFlags(const VkShaderCreateFlagsEXT flags)377     void addFlags(const VkShaderCreateFlagsEXT flags)
378     {
379         m_shaderCreateFlags |= flags;
380     }
381     void getShaderBinary(void);
getShaderBinaryDataSize(void)382     size_t getShaderBinaryDataSize(void)
383     {
384         return m_binaryDataSize;
385     }
getShaderBinaryData(void)386     void *getShaderBinaryData(void)
387     {
388         return m_binaryData.data();
389     }
390 #endif
391 
392 private:
393     const DeviceInterface *m_vk;
394     VkDevice m_device;
395     const vk::ProgramBinary *m_binary;
396     vk::VkShaderModuleCreateFlags m_moduleCreateFlags;
397     mutable vk::Move<vk::VkShaderModule> m_module;
398     const PipelineLayoutWrapper *m_layout;
399     const VkSpecializationInfo *m_specializationInfo;
400 #ifndef CTS_USES_VULKANSC
401     vk::Move<vk::VkShaderEXT> m_shader;
402     VkShaderCreateFlagsEXT m_shaderCreateFlags;
403     size_t m_binaryDataSize;
404     std::vector<uint8_t> m_binaryData;
405 #endif
406 };
407 
408 // Class that can build monolithic pipeline or fully separated pipeline libraries
409 // depending on PipelineType specified in the constructor.
410 // Rarely needed configuration was extracted to setDefault*/disable* functions while common
411 // state setup is provided as arguments of four setup* functions - one for each state group.
412 class GraphicsPipelineWrapper
413 {
414 public:
415     GraphicsPipelineWrapper(const InstanceInterface &vki, const DeviceInterface &vk, VkPhysicalDevice physicalDevice,
416                             VkDevice device, const std::vector<std::string> &deviceExtensions,
417                             const PipelineConstructionType pipelineConstructionType,
418                             const VkPipelineCreateFlags flags = 0u);
419 
420     GraphicsPipelineWrapper(GraphicsPipelineWrapper &&) noexcept;
421 
422     ~GraphicsPipelineWrapper(void) = default;
423 
424     // By default pipelineLayout used for monotlithic pipeline is taken from layout specified
425     // in setupPreRasterizationShaderState but when there are also descriptor sets needed for fragment
426     // shader bindings then separate pipeline layout for monolithic pipeline must be provided
427     GraphicsPipelineWrapper &setMonolithicPipelineLayout(const PipelineLayoutWrapper &layout);
428 
429     // By default dynamic state has to be specified before specifying other CreateInfo structures
430     GraphicsPipelineWrapper &setDynamicState(const VkPipelineDynamicStateCreateInfo *dynamicState);
431 
432     // Specify the representative fragment test state.
433     GraphicsPipelineWrapper &setRepresentativeFragmentTestState(
434         PipelineRepresentativeFragmentTestCreateInfoWrapper representativeFragmentTestState);
435 
436     // Specify pipeline robustness state
437     GraphicsPipelineWrapper &setPipelineRobustnessState(PipelineRobustnessCreateInfoWrapper pipelineRobustnessState);
438 
439     // Specifying how a pipeline is created using VkPipelineCreateFlags2CreateInfoKHR.
440     GraphicsPipelineWrapper &setPipelineCreateFlags2(PipelineCreateFlags2 pipelineFlags2);
441 
442     // Specify topology that is used by default InputAssemblyState in vertex input state. This needs to be
443     // specified only when there is no custom InputAssemblyState provided in setupVertexInputState and when
444     // topology is diferent then VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST which is used by default.
445     GraphicsPipelineWrapper &setDefaultTopology(const VkPrimitiveTopology topology);
446 
447     // Specify patch control points that is used by default TessellationState in pre-rasterization shader state.
448     // This can to be specified only when there is no custom TessellationState provided in
449     // setupPreRasterizationShaderState and when patchControlPoints is diferent then 3 which is used by default.
450     // A value of std::numeric_limits<uint32_t>::max() forces the tessellation state to be null.
451     GraphicsPipelineWrapper &setDefaultPatchControlPoints(const uint32_t patchControlPoints);
452 
453     // Specify tesellation domain origin, used by the tessellation state in pre-rasterization shader state.
454     GraphicsPipelineWrapper &setDefaultTessellationDomainOrigin(const VkTessellationDomainOrigin domainOrigin,
455                                                                 bool forceExtStruct = false);
456 
457     // Enable discarding of primitives that is used by default RasterizationState in pre-rasterization shader state.
458     // This can be specified only when there is no custom RasterizationState provided in setupPreRasterizationShaderState.
459     GraphicsPipelineWrapper &setDefaultRasterizerDiscardEnable(const bool rasterizerDiscardEnable = true);
460 
461     // When some states are not provided then default structures can be used. This behaviour can be turned on by one of below methods.
462     // Some tests require those states to be NULL so we can't assume using default versions.
463     GraphicsPipelineWrapper &setDefaultRasterizationState(void);
464     GraphicsPipelineWrapper &setDefaultDepthStencilState(void);
465     GraphicsPipelineWrapper &setDefaultColorBlendState(void);
466     GraphicsPipelineWrapper &setDefaultMultisampleState(void);
467     GraphicsPipelineWrapper &setDefaultVertexInputState(const bool useDefaultVertexInputState);
468 
469     // Pre-rasterization shader state uses provieded viewports and scissors to create ViewportState. By default
470     // number of viewports and scissors is same as number of items in vector but when vectors are empty then by
471     // default count of viewports/scissors is set to 1. This can be changed by below functions.
472     GraphicsPipelineWrapper &setDefaultViewportsCount(uint32_t viewportCount = 0u);
473     GraphicsPipelineWrapper &setDefaultScissorsCount(uint32_t scissorCount = 0u);
474 
475     // Pre-rasterization shader state uses default ViewportState, this method extends the internal structure.
476     GraphicsPipelineWrapper &setViewportStatePnext(const void *pNext);
477 
478 #ifndef CTS_USES_VULKANSC
479     GraphicsPipelineWrapper &setRenderingColorAttachmentsInfo(
480         PipelineRenderingCreateInfoWrapper pipelineRenderingCreateInfo);
481 #endif
482 
483     // Pre-rasterization shader state uses provieded viewports and scissors to create ViewportState. When disableViewportState
484     // is used then ViewportState won't be constructed and NULL will be used.
485     GraphicsPipelineWrapper &disableViewportState(const bool disable = true);
486 
487     // Setup vertex input state. When VertexInputState or InputAssemblyState are not provided then default structures will be used.
488     GraphicsPipelineWrapper &setupVertexInputState(
489         const VkPipelineVertexInputStateCreateInfo *vertexInputState     = nullptr,
490         const VkPipelineInputAssemblyStateCreateInfo *inputAssemblyState = nullptr,
491         const VkPipelineCache partPipelineCache                          = DE_NULL,
492         PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback   = PipelineCreationFeedbackCreateInfoWrapper(),
493         const bool useNullPtrs                                           = false);
494 
495     // Setup pre-rasterization shader state.
496     GraphicsPipelineWrapper &setupPreRasterizationShaderState(
497         const std::vector<VkViewport> &viewports, const std::vector<VkRect2D> &scissors,
498         const PipelineLayoutWrapper &layout, const VkRenderPass renderPass, const uint32_t subpass,
499         const ShaderWrapper vertexShaderModule,
500         const VkPipelineRasterizationStateCreateInfo *rasterizationState = DE_NULL,
501         const ShaderWrapper tessellationControlShader                    = ShaderWrapper(),
502         const ShaderWrapper tessellationEvalShader                       = ShaderWrapper(),
503         const ShaderWrapper geometryShader = ShaderWrapper(), const VkSpecializationInfo *specializationInfo = DE_NULL,
504         VkPipelineFragmentShadingRateStateCreateInfoKHR *fragmentShadingRateState = nullptr,
505         PipelineRenderingCreateInfoWrapper rendering                   = PipelineRenderingCreateInfoWrapper(),
506         const VkPipelineCache partPipelineCache                        = DE_NULL,
507         PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback = PipelineCreationFeedbackCreateInfoWrapper());
508 
509     GraphicsPipelineWrapper &setupPreRasterizationShaderState2(
510         const std::vector<VkViewport> &viewports, const std::vector<VkRect2D> &scissors,
511         const PipelineLayoutWrapper &layout, const VkRenderPass renderPass, const uint32_t subpass,
512         const ShaderWrapper vertexShaderModule,
513         const VkPipelineRasterizationStateCreateInfo *rasterizationState          = nullptr,
514         const ShaderWrapper tessellationControlShader                             = ShaderWrapper(),
515         const ShaderWrapper tessellationEvalShader                                = ShaderWrapper(),
516         const ShaderWrapper geometryShader                                        = ShaderWrapper(),
517         const VkSpecializationInfo *vertSpecializationInfo                        = nullptr,
518         const VkSpecializationInfo *tescSpecializationInfo                        = nullptr,
519         const VkSpecializationInfo *teseSpecializationInfo                        = nullptr,
520         const VkSpecializationInfo *geomSpecializationInfo                        = nullptr,
521         VkPipelineFragmentShadingRateStateCreateInfoKHR *fragmentShadingRateState = nullptr,
522         PipelineRenderingCreateInfoWrapper rendering                   = PipelineRenderingCreateInfoWrapper(),
523         const VkPipelineCache partPipelineCache                        = DE_NULL,
524         PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback = PipelineCreationFeedbackCreateInfoWrapper());
525 
526     // Note: VkPipelineShaderStageModuleIdentifierCreateInfoEXT::pIdentifier will not be copied. They need to continue to exist outside this wrapper.
527     GraphicsPipelineWrapper &setupPreRasterizationShaderState3(
528         const std::vector<VkViewport> &viewports, const std::vector<VkRect2D> &scissors,
529         const PipelineLayoutWrapper &layout, const VkRenderPass renderPass, const uint32_t subpass,
530         const ShaderWrapper vertexShaderModule,
531         PipelineShaderStageModuleIdentifierCreateInfoWrapper vertShaderModuleId =
532             PipelineShaderStageModuleIdentifierCreateInfoWrapper(),
533         const VkPipelineRasterizationStateCreateInfo *rasterizationState = nullptr,
534         const ShaderWrapper tessellationControlShader                    = ShaderWrapper(),
535         PipelineShaderStageModuleIdentifierCreateInfoWrapper tescShaderModuleId =
536             PipelineShaderStageModuleIdentifierCreateInfoWrapper(),
537         const ShaderWrapper tessellationEvalShader = ShaderWrapper(),
538         PipelineShaderStageModuleIdentifierCreateInfoWrapper teseShaderModuleId =
539             PipelineShaderStageModuleIdentifierCreateInfoWrapper(),
540         const ShaderWrapper geometryShader = ShaderWrapper(),
541         PipelineShaderStageModuleIdentifierCreateInfoWrapper geomShaderModuleId =
542             PipelineShaderStageModuleIdentifierCreateInfoWrapper(),
543         const VkSpecializationInfo *vertSpecializationInfo                        = nullptr,
544         const VkSpecializationInfo *tescSpecializationInfo                        = nullptr,
545         const VkSpecializationInfo *teseSpecializationInfo                        = nullptr,
546         const VkSpecializationInfo *geomSpecializationInfo                        = nullptr,
547         VkPipelineFragmentShadingRateStateCreateInfoKHR *fragmentShadingRateState = nullptr,
548         PipelineRenderingCreateInfoWrapper rendering                   = PipelineRenderingCreateInfoWrapper(),
549         const VkPipelineCache partPipelineCache                        = DE_NULL,
550         PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback = PipelineCreationFeedbackCreateInfoWrapper());
551 
552 #ifndef CTS_USES_VULKANSC
553     // Setup pre-rasterization shader state, mesh shading version.
554     GraphicsPipelineWrapper &setupPreRasterizationMeshShaderState(
555         const std::vector<VkViewport> &viewports, const std::vector<VkRect2D> &scissors,
556         const PipelineLayoutWrapper &layout, const VkRenderPass renderPass, const uint32_t subpass,
557         const ShaderWrapper taskShader, const ShaderWrapper meshShader,
558         const VkPipelineRasterizationStateCreateInfo *rasterizationState          = nullptr,
559         const VkSpecializationInfo *taskSpecializationInfo                        = nullptr,
560         const VkSpecializationInfo *meshSpecializationInfo                        = nullptr,
561         VkPipelineFragmentShadingRateStateCreateInfoKHR *fragmentShadingRateState = nullptr,
562         PipelineRenderingCreateInfoWrapper rendering                  = PipelineRenderingCreateInfoWrapper(),
563         const VkPipelineCache partPipelineCache                       = DE_NULL,
564         VkPipelineCreationFeedbackCreateInfoEXT *partCreationFeedback = nullptr);
565 #endif // CTS_USES_VULKANSC
566 
567     // Setup fragment shader state.
568     GraphicsPipelineWrapper &setupFragmentShaderState(
569         const PipelineLayoutWrapper &layout, const VkRenderPass renderPass, const uint32_t subpass,
570         const ShaderWrapper fragmentShaderModule,
571         const VkPipelineDepthStencilStateCreateInfo *depthStencilState = DE_NULL,
572         const VkPipelineMultisampleStateCreateInfo *multisampleState   = DE_NULL,
573         const VkSpecializationInfo *specializationInfo = DE_NULL, const VkPipelineCache partPipelineCache = DE_NULL,
574         PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback = PipelineCreationFeedbackCreateInfoWrapper(),
575         RenderingInputAttachmentIndexInfoWrapper renderingInputAttachmentIndexInfo =
576             RenderingInputAttachmentIndexInfoWrapper());
577 
578     // Note: VkPipelineShaderStageModuleIdentifierCreateInfoEXT::pIdentifier will not be copied. They need to continue to exist outside this wrapper.
579     GraphicsPipelineWrapper &setupFragmentShaderState2(
580         const PipelineLayoutWrapper &layout, const VkRenderPass renderPass, const uint32_t subpass,
581         const ShaderWrapper fragmentShaderModule,
582         PipelineShaderStageModuleIdentifierCreateInfoWrapper fragmentShaderModuleId =
583             PipelineShaderStageModuleIdentifierCreateInfoWrapper(),
584         const VkPipelineDepthStencilStateCreateInfo *depthStencilState = nullptr,
585         const VkPipelineMultisampleStateCreateInfo *multisampleState   = nullptr,
586         const VkSpecializationInfo *specializationInfo = nullptr, const VkPipelineCache partPipelineCache = DE_NULL,
587         PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback = PipelineCreationFeedbackCreateInfoWrapper(),
588         RenderingInputAttachmentIndexInfoWrapper renderingInputAttachmentIndexInfo =
589             RenderingInputAttachmentIndexInfoWrapper());
590 
591     // Setup fragment output state.
592     GraphicsPipelineWrapper &setupFragmentOutputState(
593         const VkRenderPass renderPass, const uint32_t subpass = 0u,
594         const VkPipelineColorBlendStateCreateInfo *colorBlendState     = DE_NULL,
595         const VkPipelineMultisampleStateCreateInfo *multisampleState   = DE_NULL,
596         const VkPipelineCache partPipelineCache                        = DE_NULL,
597         PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback = PipelineCreationFeedbackCreateInfoWrapper(),
598         RenderingAttachmentLocationInfoWrapper renderingAttachmentLocationInfo =
599             RenderingAttachmentLocationInfoWrapper());
600 
601     // Build pipeline object out of provided state.
602     void buildPipeline(
603         const VkPipelineCache pipelineCache = DE_NULL, const VkPipeline basePipelineHandle = DE_NULL,
604         const int32_t basePipelineIndex                            = 0,
605         PipelineCreationFeedbackCreateInfoWrapper creationFeedback = PipelineCreationFeedbackCreateInfoWrapper());
606     // Create shader objects if used
607 #ifndef CTS_USES_VULKANSC
608     vk::VkShaderStageFlags getNextStages(vk::VkShaderStageFlagBits shaderStage, bool tessellationShaders,
609                                          bool geometryShaders, bool link);
610     vk::VkShaderCreateInfoEXT makeShaderCreateInfo(VkShaderStageFlagBits stage, ShaderWrapper &shader, bool link,
611                                                    bool binary, ShaderWrapper &other);
612     void createShaders(bool linked, bool binary);
613 #endif
614 
615     // Bind pipeline or shader objects
616     void bind(vk::VkCommandBuffer cmdBuffer) const;
617 
618     // Returns true when pipeline was build using buildPipeline method.
619     bool wasBuild(void) const;
620     // Returns true when pipeline or shader objects was built.
621     bool wasPipelineOrShaderObjectBuild(void) const;
622 
623     // Get compleate pipeline. GraphicsPipelineWrapper preserves ovnership and will destroy pipeline in its destructor.
624     vk::VkPipeline getPipeline(void) const;
625 
626     // Destroy compleate pipeline - pipeline parts are not destroyed.
627     void destroyPipeline(void);
628 
629 protected:
630     // No default constructor - use parametrized constructor or emplace_back in case of vectors.
631     GraphicsPipelineWrapper() = default;
632 
633     // Dynamic states that are only dynamic in shader objects
634     bool isShaderObjectDynamic(vk::VkDynamicState dynamicState) const;
635     void setShaderObjectDynamicStates(vk::VkCommandBuffer cmdBuffer) const;
636 
637     struct InternalData;
638 
639 protected:
640     static constexpr size_t kMaxPipelineParts = 4u;
641 
642     // Store partial pipelines when non monolithic construction was used.
643     Move<VkPipeline> m_pipelineParts[kMaxPipelineParts];
644 
645     // Store monolithic pipeline or linked pipeline libraries.
646     Move<VkPipeline> m_pipelineFinal;
647 
648     // Store internal data that is needed only for pipeline construction.
649     de::SharedPtr<InternalData> m_internalData;
650 };
651 
652 } // namespace vk
653 
654 #endif // _VKPIPELINECONSTRUCTIONUTIL_HPP
655