下图展示了Vulkan pipeline。一些命令用于指定绘制的几何体或者要执行的计算工作,一些命令用于设置一些状态,以控制各个pipeline阶段如何处理对象,或控制image和buffer的memory transfer。command通过一个有效的(graphics/compute)pipeline传递

graphics pipeline的第一阶段(Input Assembler)将顶点组装成基本几何体。在下一阶段(VS)中,变换顶点,计算每个顶点的位置和属性。如果支持tessellation或者gs,则可以将单个输入的基本几何体生成多个基本几何体。并可能会改变基本几何体,或者在此过程中生成其他属性数据。

The final resulting primitives are clipped to a clip volume in preparation for the next stage, Rasterization. The rasterizer produces a series of fragments associated with a region of the framebuffer, from a two-dimensional description of a point, line segment, or triangle. These fragments are processed by fragment operations to determine whether generated values will be written to the framebuffer. fragment shading determines the values to be written to the framebuffer attachments. Framebuffer operations then read and write the color and depth/stencil attachments of the framebuffer for a given subpass of a render pass instance. The attachments can be used as input attachments in the fragment shader in a later subpass of the same render pass.

The compute pipeline is a separate pipeline from the graphics pipeline, which operates on one-, two-, or three-dimensional workgroups which can read from and write to buffer and image memory.

This ordering is meant only as a tool for describing Vulkan, not as a strict rule of how Vulkan is implemented, and we present it only as a means to organize the various operations of the pipelines. Actual ordering guarantees between pipeline stages are explained in detail in the synchronization chapter.

Vulkan

每个pipeline都是由一个包含所有shader stages和fixed-function stages的描述控制。将这个pipeline连载一起,可以根据shader的输入/输出优化shader,避免消耗昂贵的绘制时间做状态验证。

pipeline object是通过vkCmdBindPipeline绑定到当前state。绑定的时候,指定为动态的任何管道对象都不会应用于当前状态,除非通过dynamic state setting command。

没有状态(包括dynamic state),从一个command buffer继承到另一个command buffer

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

该API用于创建一个 compute pipeline。

第一个输入参数,为用于创建 compute pipeline 的logical device

第二个输入参数,要么是 VK_NULL_HANDLE,表示不开启pipeline cache,要么是一个pipeline cache的handle,表示在命令执行期间,开启cache

第三个输入参数,createInfoCount 为 pCreateInfos 和 pPipelines 的尺寸,必须大于0

第四个输入参数,为一个 VkComputePipelineCreateInfo 的结构体数组,用于表明该 compute pipeline 的属性

第五个输入参数,用于内存分配

第六个输入参数,用于获取生成的 compute pipeline object数组

typedef struct VkComputePipelineCreateInfo { VkStructureType sType; //当前结构体的类型,必须是 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO const void* pNext; //NULL,或者扩展该结构体的另外一个结构体,必须为 NULL VkPipelineCreateFlags flags; //a bitmask of VkPipelineCreateFlagBits ,指定pipeline是如何创建的 VkPipelineShaderStageCreateInfo stage; //一个 VkPipelineShaderStageCreateInfo 结构体,用于描述CS VkPipelineLayout layout; //pipeline 以及 pipeline使用的descriptor set 使用的 binding locations的描述 VkPipeline basePipelineHandle; //继承自哪个pipeline,后面会详细介绍 int32_t basePipelineIndex; //作为 pCreateInfos 的index,指定继承自哪个pipeline,后面会详细介绍 } VkComputePipelineCreateInfo;

typedef enum VkPipelineCreateFlagBits { VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT = 0x00000001, //指出创建的pipeline不需要优化,使用该flag可能会减少创建pipeline的时间 VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT = 0x00000002, //指出创建的pipeline可以作为父pipeline,被用于之后创建的pipeline。 VK_PIPELINE_CREATE_DERIVATIVE_BIT = 0x00000004, //指出创建的pipeline为之前创建的父pipeline的子。 // Provided by VK_VERSION_1_1 VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT = 0x00000008, //指出任何shader输入中的ViewIndex会被赋值成DeviceIndex // Provided by VK_VERSION_1_1 VK_PIPELINE_CREATE_DISPATCH_BASE_BIT = 0x00000010, // VK_PIPELINE_CREATE_DISPATCH_BASE = VK_PIPELINE_CREATE_DISPATCH_BASE_BIT, //指出该compute pipeline可以被 vkCmdDispatchBase 附带一个非0 base workgroup使用 } VkPipelineCreateFlagBits;

typedef struct VkPipelineShaderStageCreateInfo { VkStructureType sType; //当前结构体的类型,必须是 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO const void* pNext; //NULL,或者扩展该结构体的另外一个结构体,必须为 NULL VkPipelineShaderStageCreateFlags flags; //a bitmask of VkPipelineShaderStageCreateFlagBits ,指出该pipeline shader stage是如何被创建的,必须为0 VkShaderStageFlagBits stage; //一个 VkShaderStageFlagBits 值,指定一个pipeline stage VkShaderModule module; //一个 VkShaderModule 值,包含该stage 的shader const char* pName; //一个string,指定该阶段 shader 的entry point name const VkSpecializationInfo* pSpecializationInfo; //一个 VkSpecializationInfo 结构体,或者NULL } VkPipelineShaderStageCreateInfo;

typedef enum VkPipelineShaderStageCreateFlagBits { } VkPipelineShaderStageCreateFlagBits;

typedef enum VkShaderStageFlagBits { VK_SHADER_STAGE_VERTEX_BIT = 0x00000001, //vs 阶段 VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT = 0x00000002, //TESSELLATION_CONTROL 阶段 VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT = 0x00000004, //TESSELLATION_EVALUATION 阶段 VK_SHADER_STAGE_GEOMETRY_BIT = 0x00000008, //gs 阶段 VK_SHADER_STAGE_FRAGMENT_BIT = 0x00000010, //ps 阶段 VK_SHADER_STAGE_COMPUTE_BIT = 0x00000020, //cs 阶段 VK_SHADER_STAGE_ALL_GRAPHICS = 0x0000001F, //以上所有graphics stage的组合(除了cs) VK_SHADER_STAGE_ALL = 0x7FFFFFFF, //当前device支持的所有 shader 阶段,包括extension对应的额外阶段.在vulkan1.0中只包含 5个 graphics阶段。 } VkShaderStageFlagBits;

可能会出现的错误:VK_ERROR_OUT_OF_HOST_MEMORY、VK_ERROR_OUT_OF_DEVICE_MEMORY

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

graphics pipeline包含若干个shader stage,若干个fixed-function pipeline stage,以及一个pipeline layout

该API用于创建一个 graphics pipeline。

第一个输入参数,为用于创建 graphics pipeline 的logical device

第二个输入参数,要么是 VK_NULL_HANDLE,表示不开启pipeline cache,要么是一个pipeline cache的handle,表示在命令执行期间,开启cache

第三个输入参数,createInfoCount 为 pCreateInfos 和 pPipelines 的尺寸,必须大于0

第四个输入参数,为一个 VkGraphicsPipelineCreateInfo 的结构体数组,用于表明该 graphics pipeline 的属性。包含一组包含所有active shader stages的shader,以及所所有fixed-function stages和pipeline layout。

第五个输入参数,用于内存分配

第六个输入参数,用于获取生成的 graphics pipeline object数组

typedef struct VkGraphicsPipelineCreateInfo { VkStructureType sType; //当前结构体的类型,必须是 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO const void* pNext; //NULL,或者扩展该结构体的另外一个结构体,必须是NULL VkPipelineCreateFlags flags; //a bitmask of VkPipelineCreateFlagBits ,指定pipeline是如何创建的 uint32_t stageCount; //pStages中 entries的数量,必须大于0 const VkPipelineShaderStageCreateInfo* pStages; //一个 stageCount 个 VkPipelineShaderStageCreateInfo 结构体的数组,用于描述 graphics pipeline中的一组 shader stage const VkPipelineVertexInputStateCreateInfo* pVertexInputState; //一个 VkPipelineVertexInputStateCreateInfo 结构体 const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; //一个 VkPipelineInputAssemblyStateCreateInfo 结构体,描述input assembly的行为 const VkPipelineTessellationStateCreateInfo* pTessellationState; //一个 VkPipelineTessellationStateCreateInfo 结构体,如果管线中不包含 ts ,则忽略。 const VkPipelineViewportStateCreateInfo* pViewportState; //一个 VkPipelineViewportStateCreateInfo 结构体,如果管线中关闭了光栅化,则忽略。 const VkPipelineRasterizationStateCreateInfo* pRasterizationState; //一个 VkPipelineRasterizationStateCreateInfo 结构体 const VkPipelineMultisampleStateCreateInfo* pMultisampleState; //一个 VkPipelineMultisampleStateCreateInfo 结构体,如果管线中关闭了光栅化,则忽略。 const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; //一个 VkPipelineDepthStencilStateCreateInfo 结构体,如果管线中关闭了光栅化,或者render pass中的该subpass没有使用depth/stencil attachment,则忽略。 const VkPipelineColorBlendStateCreateInfo* pColorBlendState; //一个 VkPipelineColorBlendStateCreateInfo 结构体,如果管线中关闭了光栅化,或者render pass中的该subpass没有使用color attachment,则忽略。 const VkPipelineDynamicStateCreateInfo* pDynamicState; //一个 VkPipelineDynamicStateCreateInfo 结构体,用于指出 pipeline stage objec中哪些属性是dynamic,可以独立于pipeline state进行更新。可以是NULL,意味着该pipeline中没有state为dynamic VkPipelineLayout layout; //pipeline 以及 pipeline使用的descriptor set 使用的 binding locations的描述 VkRenderPass renderPass; //指定 pipeline所使用的render pass,该pipeline只能用于与该render pss兼容的render pass。 uint32_t subpass; //指定 pipeline用于render pass中的哪个subpass VkPipeline basePipelineHandle; //继承自哪个pipeline int32_t basePipelineIndex; //作为 pCreateInfos 的index,指定继承自哪个pipeline } VkGraphicsPipelineCreateInfo;

typedef struct VkPipelineVertexInputStateCreateInfo { VkStructureType sType; //当前结构体的类型,必须是 const void* pNext; //NULL,或者扩展该结构体的另外一个结构体 VkPipelineVertexInputStateCreateFlags flags; //reserve for future use uint32_t vertexBindingDescriptionCount; //pVertexBindingDescriptions 中 vertex binding description的数量 const VkVertexInputBindingDescription* pVertexBindingDescriptions; //一个指向 VkVertexInputBindingDescription 数组的指针 uint32_t vertexAttributeDescriptionCount; //pVertexAttributeDescriptions 中 vertex attribute description的数量 const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; //一个指向 VkVertexInputAttributeDescription 数组的指针 } VkPipelineVertexInputStateCreateInfo;

typedef struct VkVertexInputBindingDescription { uint32_t binding; //该结构体描述的binding number uint32_t stride; //buffer中两个连续元素之间的距离,以bytes为单位 VkVertexInputRate inputRate; //一个 VkVertexInputRate 值,表明 vertex attribute addressing是vertex index还是instance index的function } VkVertexInputBindingDescription;

typedef enum VkVertexInputRate { VK_VERTEX_INPUT_RATE_VERTEX = 0, //指出 vertex attribute addressing是vertex index的function VK_VERTEX_INPUT_RATE_INSTANCE = 1, //指出 vertex attribute addressing是instance index的function } VkVertexInputRate;

typedef struct VkVertexInputAttributeDescription { uint32_t location; //该attibute的shader binding location number uint32_t binding; //该attribute获取数据的binding number VkFormat format; //该 vertex attribute data的size和type uint32_t offset; //为该attribute距离vertex input binding第一个元素起始点的offset,以bytes为单位 } VkVertexInputAttributeDescription;

typedef struct VkPipelineInputAssemblyStateCreateInfo { VkStructureType sType; //当前结构体的类型,必须是 const void* pNext; //NULL,或者扩展该结构体的另外一个结构体 VkPipelineInputAssemblyStateCreateFlags flags; //reserved for future use VkPrimitiveTopology topology; //一个 VkPrimitiveTopology 结构体 VkBool32 primitiveRestartEnable; //管理是否需要一个特殊vertex index值用于在图元装配的时候restart。只有当使用index draw的时候生效(vkCmdDrawIndexed、vkCmdDrawIndexedIndirect)。当 vkCmdBindIndexBuffer 的 indexType 为 VK_INDEX_TYPE_UINT32 该值为 0xFFFFFFFF,当 indexType 为 VK_INDEX_TYPE_UINT16 该值为 0xFFFF。primitive restart在 "list" topologies时不被允许。 } VkPipelineInputAssemblyStateCreateInfo;

typedef enum VkPrimitiveTopology { VK_PRIMITIVE_TOPOLOGY_POINT_LIST = 0, VK_PRIMITIVE_TOPOLOGY_LINE_LIST = 1, VK_PRIMITIVE_TOPOLOGY_LINE_STRIP = 2, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST = 3, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP = 4, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN = 5, VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY = 6, VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY = 7, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY = 8, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY = 9, VK_PRIMITIVE_TOPOLOGY_PATCH_LIST = 10, } VkPrimitiveTopology;

typedef struct VkPipelineTessellationStateCreateInfo { VkStructureType sType; const void* pNext; VkPipelineTessellationStateCreateFlags flags; uint32_t patchControlPoints; } VkPipelineTessellationStateCreateInfo;

typedef struct VkPipelineViewportStateCreateInfo { VkStructureType sType; //当前结构体的类型,必须是 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO const void* pNext; //NULL,或者扩展该结构体的另外一个结构体,必须为 NULL VkPipelineViewportStateCreateFlags flags; //reserved for future use,必须为0 uint32_t viewportCount; //pipeline用到的viewports的数量 const VkViewport* pViewports; //一个 VkViewport 结构体的数组,定义了viewport transforms,如果viewport state为dynamic,则该值可以被忽略 uint32_t scissorCount; //scissors的数量,必须和viewports的数量相同 const VkRect2D* pScissors; //一个指向 VkRect2D 结构体数组的指针,定义了对应viewport的scissor矩阵。如果scissor state为dynamic,则该值可以被忽略 } VkPipelineViewportStateCreateInfo;

typedef struct VkPipelineRasterizationStateCreateInfo { VkStructureType sType; //当前结构体的类型,必须是 const void* pNext; //NULL,或者扩展该结构体的另外一个结构体 VkPipelineRasterizationStateCreateFlags flags; //reserved for future use, VkBool32 depthClampEnable; //控制是否clamp fragment的depth value。开启该功能,则关闭 clipping primitive to the z planes of the frustrum VkBool32 rasterizerDiscardEnable; //控制在光栅化之前,是否立即丢弃图元 VkPolygonMode polygonMode; //控制三角形的渲染模式 VkCullModeFlags cullMode; //primitive culling的时候三角形的facing direction VkFrontFace frontFace; //一个 VkFrontFace 值用于指定 front-facing triangle的方向 VkBool32 depthBiasEnable; //是否开启fragment depth bias float depthBiasConstantFactor; //一个 scalar factor 控制一个depth 常数被附加到每个fragment上 float depthBiasClamp; //最大/最小depth bias of a fragment float depthBiasSlopeFactor; //a scalar factor applied to a fragment’s slope in depth bias calculations. float lineWidth; //the width of rasterized line segments } VkPipelineRasterizationStateCreateInfo;

typedef enum VkPolygonMode { VK_POLYGON_MODE_FILL = 0, //specifies that polygons are rendered using the polygon rasterization rules in this section. VK_POLYGON_MODE_LINE = 1, //指出 polygon edges draw as line VK_POLYGON_MODE_POINT = 2, //指出 polygon draw as point } VkPolygonMode;

typedef struct VkPipelineMultisampleStateCreateInfo { VkStructureType sType; //当前结构体的类型,必须是 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO const void* pNext; //NULL,或者扩展该结构体的另外一个结构体,必须为 NULL VkPipelineMultisampleStateCreateFlags flags; //reserved for future use,必须为0 VkSampleCountFlagBits rasterizationSamples; //一个 VkSampleCountFlagBits 值用于指出光栅化时sample的数量 VkBool32 sampleShadingEnable; //用于开启 Sample Shading float minSampleShading; //当 sampleShadingEnable 为 VK_TRUE 的时候,为 sample shading 指定一个 a minimum fraction const VkSampleMask* pSampleMask; //在sample mask test时用到的一个 VkSampleMask 数组 VkBool32 alphaToCoverageEnable; //controls whether a temporary coverage value is generated based on the alpha component of the fragment’s first color output as specified in the Multisample Coverage section VkBool32 alphaToOneEnable; //controls whether the alpha component of the fragment’s first color output is replaced with one as described in Multisample Coverage. } VkPipelineMultisampleStateCreateInfo;

typedef struct VkPipelineDepthStencilStateCreateInfo { VkStructureType sType; //当前结构体的类型,必须是 const void* pNext; //NULL,或者扩展该结构体的另外一个结构体 VkPipelineDepthStencilStateCreateFlags flags; //reserved for future use VkBool32 depthTestEnable; //controls whether depth testing is enabled. VkBool32 depthWriteEnable; //controls whether depth writes are enabled when depthTestEnable is VK_TRUE. Depth writes are always disabled when depthTestEnable is VK_FALSE. VkCompareOp depthCompareOp; //the comparison operator used in the depth test VkBool32 depthBoundsTestEnable; //controls whether depth bounds testing is enabled VkBool32 stencilTestEnable; //controls whether stencil testing is enabled VkStencilOpState front; //control the parameters of the stencil test VkStencilOpState back; //control the parameters of the stencil test float minDepthBounds; //is the minimum depth bound used in the depth bounds test. float maxDepthBounds; //is the maximum depth bound used in the depth bounds test. } VkPipelineDepthStencilStateCreateInfo;

typedef struct VkPipelineColorBlendStateCreateInfo { VkStructureType sType; //当前结构体的类型,必须是 const void* pNext; //NULL,或者扩展该结构体的另外一个结构体 VkPipelineColorBlendStateCreateFlags flags; //reserved for future use VkBool32 logicOpEnable; //controls whether to apply Logical Operations. VkLogicOp logicOp; //selects which logical operation to apply. uint32_t attachmentCount; //is the number of VkPipelineColorBlendAttachmentState elements in pAttachments const VkPipelineColorBlendAttachmentState* pAttachments; //is a pointer to an array of per target attachment states. float blendConstants[4]; //is a pointer to an array of four values used as the R, G, B, and A components of the blend constant that are used in blending, depending on the blend factor. } VkPipelineColorBlendStateCreateInfo;

typedef struct VkPipelineDynamicStateCreateInfo { VkStructureType sType; //当前结构体的类型,必须是 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO const void* pNext; //NULL,或者扩展该结构体的另外一个结构体,必须是 NULL VkPipelineDynamicStateCreateFlags flags; //reserved for future use,必须为0 uint32_t dynamicStateCount; //is the number of elements in the pDynamicStates array. const VkDynamicState* pDynamicStates; //is a pointer to an array of VkDynamicState values specifying which pieces of pipeline state will use the values from dynamic state commands rather than from pipeline state creation info. } VkPipelineDynamicStateCreateInfo;

typedef enum VkDynamicState { VK_DYNAMIC_STATE_VIEWPORT = 0, VK_DYNAMIC_STATE_SCISSOR = 1, VK_DYNAMIC_STATE_LINE_WIDTH = 2, VK_DYNAMIC_STATE_DEPTH_BIAS = 3, VK_DYNAMIC_STATE_BLEND_CONSTANTS = 4, VK_DYNAMIC_STATE_DEPTH_BOUNDS = 5, VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK = 6, VK_DYNAMIC_STATE_STENCIL_WRITE_MASK = 7, VK_DYNAMIC_STATE_STENCIL_REFERENCE = 8, } VkDynamicState;

可能会出现的错误:VK_ERROR_OUT_OF_HOST_MEMORY、VK_ERROR_OUT_OF_DEVICE_MEMORY

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

VkResult vkCreateRayTracingPipelinesKHR( VkDevice device, VkDeferredOperationKHR deferredOperation, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkRayTracingPipelineCreateInfoKHR* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines);

VkResult vkGetRayTracingShaderGroupHandlesKHR( VkDevice device, VkPipeline pipeline, uint32_t firstGroup, uint32_t groupCount, size_t dataSize, void* pData);

VkResult vkGetRayTracingShaderGroupHandlesNV( VkDevice device, VkPipeline pipeline, uint32_t firstGroup, uint32_t groupCount, size_t dataSize, void* pData);

VkResult vkGetRayTracingCaptureReplayShaderGroupHandlesKHR( VkDevice device, VkPipeline pipeline, uint32_t firstGroup, uint32_t groupCount, size_t dataSize, void* pData);

VkResult vkCompileDeferredNV( VkDevice device, VkPipeline pipeline, uint32_t shader);

VkDeviceSize vkGetRayTracingShaderGroupStackSizeKHR( VkDevice device, VkPipeline pipeline, uint32_t group, VkShaderGroupShaderKHR groupShader);

void vkCmdSetRayTracingPipelineStackSizeKHR( VkCommandBuffer commandBuffer, uint32_t pipelineStackSize);

void vkDestroyPipeline( VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks* pAllocator);

Multiple Pipeline Creation

Pipeline Derivatives

Specialization Constants

VkResult vkCreatePipelineCache( VkDevice device, const VkPipelineCacheCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPipelineCache* pPipelineCache);

Pipeline cache objects使得pipeline可以在pipelines甚至两次运行应用程序中reuse。reuse between pipelines是通过将同一个pipeline cache object在创建multiple related pipelines的时候使用。reuse across runs of an application是通过在一次运行中生成pipeline cache contents,save the contents,然后在下次运行的时候通过它们来preinitialize。pipeline cache object的内容根据implementation控制。应用程序可以管理pipeline cache消耗的host memory,并控制pipeline cache object 对应的数据量

该API用于创建一个pipeline cache object。

第一个输入参数,为用于创建 pipeline cache object 的logical device

第二个输入参数,为一个 VkPipelineCacheCreateInfo 的结构体数组,用于表明该 pipeline cache object 的初始化属性。

第三个输入参数,用于内存分配

第四个输入参数,用于获取生成的 pipeline cache object 数组

typedef struct VkPipelineCacheCreateInfo { VkStructureType sType; //当前结构体的类型,必须是 VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO const void* pNext; //NULL,或者扩展该结构体的另外一个结构体,必须为NULL VkPipelineCacheCreateFlags flags; //reserved for future,必须为0 size_t initialDataSize; //pInitialData的尺寸,以bytes为单位(通过 vkGetPipelineCacheData获取)。如果 initialDataSize 为0,则pipeline cache则被初始化为空 const void* pInitialData; //一个指向之前创建好的pipeline cache data(通过 vkGetPipelineCacheData 获取)。如果pipeline cache data为incompatible with the device,则pipeline cache将被以初始化为empty。如果 initialDataSize 为0,则 pInitialData 被忽略。 } VkPipelineCacheCreateInfo;

Applications can track and manage the total host memory size of a pipeline cache object using the pAllocator. Applications can limit the amount of data retrieved from a pipeline cache object in vkGetPipelineCacheData. Implementations should not internally limit the total number of entries added to a pipeline cache object or the total host memory consumed

创建好后,a pipeline cache可以被传入 vkCreateGraphicsPipelines 和 vkCreateComputePipelines 命令。如果pipeline cache不为 VK_NULL_HANDLE,则implementation会query it,看看是否可以reuse,以及会update it with new content。这些命令对pipeline cache object的使用为internally synchronized,同一个pipeline cache object可以被多条thread同时使用。

Implementation应该尽一切努力将任何关键部分限制为对cache的实际访问,这笔vkCreate*Pipeline命令的时间要短得多。

可能会出现的错误:VK_ERROR_OUT_OF_HOST_MEMORY、VK_ERROR_OUT_OF_DEVICE_MEMORY

VkResult vkMergePipelineCaches( VkDevice device, VkPipelineCache dstCache, uint32_t srcCacheCount, const VkPipelineCache* pSrcCaches);

该API用于merge pipeline cache object

第一个输入参数,为拥有 pipeline cache object 的logical device

第二个输入参数,为merge result into的pipeline cache的handle。不应该出现在source caches的list中

第三个输入参数,为 pSrcCaches 数组的尺寸,必须大于0

第四个输入参数,为一个pipeline cache handle数组,将被merge 到 dstCache。dstCache原先的内容在merge后还在。

merge操作的细节为 implementation dependent,但是implementation应该需要在merge的时候删除重复条目

		Host access to dstCache must be externally synchronized
	

可能会出现的错误:VK_ERROR_OUT_OF_HOST_MEMORY、VK_ERROR_OUT_OF_DEVICE_MEMORY

VkResult vkGetPipelineCacheData( VkDevice device, VkPipelineCache pipelineCache, size_t* pDataSize, void* pData);

该API用于从pipeline cache object获取数据

第一个输入参数,为拥有 pipeline cache object 的logical device

第二个输入参数,为获取信息的 pipeline cache object

第三个输入参数,为获取到的 pData 的尺寸。当 pData 为NULL的时候,这里获得pipeline cache所能拿到的最大尺寸。否则,pDataSize为pData的尺寸

第四个输入参数,为一个指向一个buffer的指针。如果 pDataSize 比较小,则最多只有 pDataSize 的数据被存到 pData。并返回 VK_INCOMPLETE。这里获取的数据,可以传给 vkCreatePipelineCache 的 VkPipelineCacheCreateInfo::pInitialData 数据。

可能会出现的错误:VK_ERROR_OUT_OF_HOST_MEMORY、VK_ERROR_OUT_OF_DEVICE_MEMORY

void vkDestroyPipelineCache( VkDevice device, VkPipelineCache pipelineCache, const VkAllocationCallbacks* pAllocator);

该API用于删除一个pipeline cache

第一个输入参数,为拥有 pipeline cache object 的logical device

第二个输入参数,为即将被删除的pipeline cache object

第三个输入参数,用于内存分配。如果在创建的时候使用了 VkAllocationCallbacks , 那么在destroy 的时候也要提供一个相应的callback。反之,这里的第三个参数必须是NULL。

		Host access to pipelineCache must be externally synchronized
	

void vkCmdBindPipeline( VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline);

该API用于,pipeline创建好之后,绑定到command buffer上

第一个输入参数,为pipeline即将绑定的command buffer,必须处于recording阶段

第二个输入参数,为一个 VkPipelineBindPoint 值,表明pipeline绑定的point

第三个输入参数,为要绑定的pipeline

绑定后,a pipeline binding影响command buffer中对应pipeline之后的命令,直到一个相同类型的pipeline绑定到该bind point。不与指定pipeline类型交互的command不会受到pipeline state的影响

typedef enum VkPipelineBindPoint { VK_PIPELINE_BIND_POINT_GRAPHICS = 0, //指出绑定到a compute pipeline,绑定到这个上面,会影响所有的draw command,对应的pool必须支持compute操作 VK_PIPELINE_BIND_POINT_COMPUTE = 1, //指出绑定到a graphics pipeline,绑定到这个上面,会影响所有的dispatch command,对应的pool必须支持graphics操作 } VkPipelineBindPoint;

Vulkan
		Host access to commandBuffer must be externally synchronized
		Host access to the VkCommandPool that commandBuffer was allocated from must be externally synchronized
	

void vkCmdBindPipelineShaderGroupNV( VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline, uint32_t groupIndex);

Dynamic State

VkResult vkGetPipelineExecutablePropertiesKHR( VkDevice device, const VkPipelineInfoKHR* pPipelineInfo, uint32_t* pExecutableCount, VkPipelineExecutablePropertiesKHR* pProperties);

VkResult vkGetPipelineExecutableStatisticsKHR( VkDevice device, const VkPipelineExecutableInfoKHR* pExecutableInfo, uint32_t* pStatisticCount, VkPipelineExecutableStatisticKHR* pStatistics);

VkResult vkGetPipelineExecutableInternalRepresentationsKHR( VkDevice device, const VkPipelineExecutableInfoKHR* pExecutableInfo, uint32_t* pInternalRepresentationCount, VkPipelineExecutableInternalRepresentationKHR* pInternalRepresentations);

VkResult vkGetShaderInfoAMD( VkDevice device, VkPipeline pipeline, VkShaderStageFlagBits shaderStage, VkShaderInfoTypeAMD infoType, size_t* pInfoSize, void* pInfo);

本节教程就到此结束,希望大家继续阅读我之后的教程。

谢谢大家,再见!


原创技术文章,撰写不易,转载请注明出处:电子设备中的画家|王烁 于 2021 年 5 月 10 日发表,原文链接(http://geekfaner.com/shineengine/blog20_Vulkanv1.2_6.html)