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