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 |
|
This is the logical device for which the pipeline object is to be created. |
|
This is a valid pointer to the pipeline cache object. If this value is |
|
This represents the number of graphics pipelines ( |
|
This is the |
|
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. |
|
This returns the |
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 |
|
This is the type information of this control structure. It must be specified as |
|
This could be a valid pointer to an extension-specific structure or |
|
This field provides hints to help the implementation understand how the pipeline will be generated. These hints are provided using the
The
|
|
This indicates the number of shaders to be used in the current pipeline. |
|
This field indicates what all shader stages need to be included in the pipeline using an array of |
|
This field indicates the vertex input pipeline state through the |
|
This field determines the behavior of the input assembly state using the |
|
This field indicates the tessellation control and evaluation shader stages' states. These states are specified using the |
|
This field indicates the vertex states through the |
|
This field indicates the pipeline rasterization state using the |
|
This refers to the |
|
This field indicates the pipeline's depth/stencil state by using a pointer to the |
|
This is a pointer to
This field must be
|
|
This is a pointer to |
|
This field specifies the binding locations used by the pipeline and the descriptor sets. |
|
This field specifies the subpasses and attachments that will be used by the pipeline. |
|
This notifies the pipeline about the Render Pass's subpass index under which it will be used. |
|
This field specifies the base pipeline from where this pipeline will be derived. |
|
This field specifies the index of the |
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:
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; } }
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);
3.14.144.216