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