Creating a graphics pipeline

A graphics pipeline consists of programmable, fixed-function pipeline stages, Render Passes, subpasses, and pipeline layouts. The programmable stages include multiple shader stages, such as the vertex, fragment, tessellation, geometry, and compute shaders. The fixed-function states consist of multiple pipeline state objects (PSOs) that represent the dynamic, vertex input, input assembly, rasterization, blending, viewport, multisampling, and depth-stencil states.

A graphics pipeline object (VkPipeline) is created using the vkCreateGraphicsPipelines() API. This API intakes the programmable stages, fixed-function pipeline stages, and pipeline layouts through a metadata control structure called VkGraphicsPipelineCreateInfo. The following is the syntax of the vkCreateGraphicsPipelines() API:

VkResult vkCreateGraphicsPipelines( 
    VkDevice                                    device, 
    VkPipelineCache                             pipelineCache, 
    uint32_t                                    createInfoCount, 
    const VkGraphicsPipelineCreateInfo*         pCreateInfos, 
    const VkAllocationCallbacks*                pAllocator, 
    VkPipeline*                                 pPipelines); 

Let's look at the various fields of the vkCreateGraphicsPipelines() API:

Parameters

Description

device

This is the logical device for which the pipeline object is to be created.

pipelineCache

This is a valid pointer to the pipeline cache object. If this value is NULL, then the pipeline cache will not be used to create the pipeline object.

createInfoCount

This represents the number of graphics pipelines (VkGraphicsPipelineCreateInfo) in the pCreateInfos array.

pCreateInfos

This is the VkGraphicsPipelineCreateInfo array.

pAllocator

This field controls host memory allocation. For more information, refer to the Host memory section in Chapter 5, Command Buffer and Memory Management in Vulkan.

pPipelines

This returns the VkPipeline object array containing the graphics pipeline objects. The number of objects depends on createInfoCount.

Here is the syntax of the metadata control structure VkGraphicsPipelineCreateInfo, we discussed earlier:

typedef struct VkGraphicsPipelineCreateInfo { 
 VkStructureType                               sType; 
 const void*                                   pNext; 
 VkPipelineCreateFlags                         flags; 
 uint32_t                                      stageCount; 
 const VkPipelineShaderStageCreateInfo*        pStages; 
 const VkPipelineVertexInputStateCreateInfo*   pVertexInputState; 
 const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; 
 const VkPipelineTessellationStateCreateInfo*  pTessellationState; 
 const VkPipelineViewportStateCreateInfo*      pViewportState; 
 const VkPipelineRasterizationStateCreateInfo* pRasterizationState; 
 const VkPipelineMultisampleStateCreateInfo*   pMultisampleState; 
 const VkPipelineDepthStencilStateCreateInfo*  pDepthStencilState; 
 const VkPipelineColorBlendStateCreateInfo*    pColorBlendState; 
 const VkPipelineDynamicStateCreateInfo*       pDynamicState; 
 VkPipelineLayout                              layout; 
 VkRenderPass                                  renderPass; 
 uint32_t                                      subpass; 
 VkPipeline                                    basePipelineHandle; 
 int32_t                                       basePipelineIndex; 
} VkGraphicsPipelineCreateInfo; 

Let's look at the various fields for this structure:

Parameters

Description

sType

This is the type information of this control structure. It must be specified as VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO.

pNext

This could be a valid pointer to an extension-specific structure or NULL.

flags

This field provides hints to help the implementation understand how the pipeline will be generated. These hints are provided using the VkPipelineCreateFlagBits enum.

The VkPipelineCreateFlagBits enum has three fields:

  • VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT: The pipelines created from this flag will not be optimized. Since there is no optimization path, the overall time to create this pipeline may be reduced.
  • VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT: The pipeline created using this flag is permitted to be the parent of the subsequent pipelines that are going to be created using the vkCreateGraphicsPipelines() API.
  • VK_PIPELINE_CREATE_DERIVATIVE_BIT: The pipeline created using this flag becomes the child of the previously created pipeline.

stageCount

This indicates the number of shaders to be used in the current pipeline.

pStages

This field indicates what all shader stages need to be included in the pipeline using an array of VkPipelineShaderStageCreateInfo. The total size of this array is equal to stageCount.

pVertexInputState

This field indicates the vertex input pipeline state through the VkPipelineVertexInputStateCreateInfo pointer object.

pInputAssemblyState

This field determines the behavior of the input assembly state using the VkPipelineInputAssemblyStateCreateInfo pointer object.

pTessellationState

This field indicates the tessellation control and evaluation shader stages' states. These states are specified using the VkPipelineTessellationStateCreateInfo pointer object. This must be NULL if the tessellation control and evaluation shader stages are not included in the pipeline.

pViewportState

This field indicates the vertex states through the VkPipelineViewportStateCreateInfo pointer object. This field must be NULL if the pipeline has rasterization disabled.

pRasterizationState

This field indicates the pipeline rasterization state using the VkPipelineRasterizationStateCreateInfo structure's pointer object.

pMultisampleState

This refers to the VkPipelineMultisampleStateCreateInfo object pointer. This field must be NULL if the pipeline has rasterization disabled.

pDepthStencilState

This field indicates the pipeline's depth/stencil state by using a pointer to the VkPipelineDepthStencilStateCreateInfo control structure. This would be NULL if rasterization is disabled or the subpass in the Render Pass does not use a depth/stencil attachment.

pColorBlendState

This is a pointer to VkPipelineColorBlendStateCreateInfo indicating the pipeline color's blend state.

This field must be NULL if the pipeline has rasterization disabled or if the subpass in the Render Pass does not use any color attachments.

pDynamicState

This is a pointer to VkPipelineDynamicStateCreateInfo, which indicates the pipeline's dynamic states. This field can be changed independently of other pipeline states. If no dynamic states are specified, then this field can be specified as NULL, notifying the pipeline that there is no dynamic states to be considered in this pipeline.

layout

This field specifies the binding locations used by the pipeline and the descriptor sets.

renderPass

This field specifies the subpasses and attachments that will be used by the pipeline.

subPass

This notifies the pipeline about the Render Pass's subpass index under which it will be used.

basePipelineHandle

This field specifies the base pipeline from where this pipeline will be derived.

basePipelineIndex

This field specifies the index of the pCreateInfos parameter in the base pipeline. It will be used to derive this pipeline object.

Implementing a graphics pipeline

Graphics pipelines are implemented in the createPipeline() function of VulkanPipeline. This function takes four parameters. The first parameter contains the vertex input and data interpretation. The second parameter contains the return value in which the array of pipelines will be created. The third parameter is a Boolean flag indicating depth testing. And the last parameter is used to specify whether to consider the vertex input or not.

The graphics pipeline consists of several pipeline state objects, render passes, shader objects, and subpasses, as shown in the following diagram. The implementation of the pipeline is done by creating a VkGraphicsPipelineCreateInfo object (pipelineInfo) and specifying all the various state objects, shader objects, and render pass object into it. Finally, the pipeline object is consumed by the vkCreateGraphicsPipelines() API to create the pipeline. The following diagram shows the graphics pipeline and all its interface controllers:

Implementing a graphics pipeline

This is the code implementation of the graphics pipeline object:

bool VulkanPipeline::createPipeline(VulkanDrawable* drawableObj, VkPipeline* pipeline, VulkanShader* shaderObj, VkBool32 includeDepth, VkBool32 includeVi) 
{ 
    // Please refer to Dynamic State for more info 
    VkPipelineDynamicStateCreateInfo dynamicState = {}; 
 
    // Please refer to Vertex Input States subsection for more info 
    VkPipelineVertexInputStateCreateInfo vertexInputStateInfo = {}; 
   . . .  
 
    // Please refer to Input Assembly States subsection for more info 
    VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo = {}; 
 
    // Please refer to Rasterization State subsection for more info 
    VkPipelineRasterizationStateCreateInfo rasterStateInfo = {}; 
 
    // Please refer to Color Blend Attachment for more info 
    VkPipelineColorBlendAttachmentState  
               colorBlendAttachmentStateInfo[1] = {}; 
 
    // Please refer to Color Blend State subsection for more info 
    VkPipelineColorBlendStateCreateInfo colorBlendStateInfo = {}; 
 
    // Please refer to Viewport State subsection for more info 
    VkPipelineViewportStateCreateInfo viewportStateInfo = {}; 
 
    // Please refer to Depth Stencil state subsection for more info 
    VkPipelineDepthStencilStateCreateInfo depthStencilStateInfo = {}; 
 
    // Please refer to Multi Sample state subsection for more info 
    VkPipelineMultisampleStateCreateInfo   multiSampleStateInfo = {}; 
 
    // Populate the VkGraphicsPipelineCreateInfo structure to specify
 
   // programmable stages, fixed-function pipeline stages render

    // pass, sub-passes and pipeline layouts 
    VkGraphicsPipelineCreateInfo pipelineInfo = {}; 
    pipelineInfo.sType                 = 
         VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; 
    pipelineInfo.pVertexInputState     = &vertexInputStateInfo;  
    pipelineInfo.pInputAssemblyState   = &inputAssemblyInfo; 
    pipelineInfo.pRasterizationState   = &rasterStateInfo; 
    pipelineInfo.pColorBlendState      = &colorBlendStateInfo; 
    pipelineInfo.pTessellationState    = NULL; 
    pipelineInfo.pMultisampleState     = &multiSampleStateInfo; 
    pipelineInfo.pDynamicState         = &dynamicState; 
    pipelineInfo.pViewportState        = &viewportStateInfo; 
    pipelineInfo.pDepthStencilState    = &depthStencilStateInfo; 
    pipelineInfo.pStages               = shaderObj->shaderStages; 
    pipelineInfo.stageCount            = 2; 
    pipelineInfo.renderPass            = appObj->rendererObj->
                                         renderPass; 
    pipelineInfo.subpass               = 0; 
 
    // Create the pipeline using the meta-data store in the

    // VkGraphicsPipelineCreateInfo object 
    if (vkCreateGraphicsPipelines(deviceObj->device, pipelineCache, 
          1, &pipelineInfo, NULL, pipeline) == VK_SUCCESS){ 
      return true; 
    } 
    else { 
      return false; 
    } 
} 

Destroying pipelines

A created pipeline can be destroyed using the vkDestroyPipeline API. This API accepts three parameters. The first parameter specifies the logical device (VkDevice) that will be used to destroy the pipeline. The second parameter is an object of pipeline (VkPipeline), which is intended to be destroyed. The third parameter pAllocator controls host memory allocation. For more information, refer to the Host memory section Chapter 5, Command Buffer and Memory Management in Vulkan:

void vkDestroyPipeline( 
   VkDevice                      device, 
   VkPipeline                    pipeline, 
   const VkAllocationCallbacks*  pAllocator); 
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.14.144.216