Skip to content

Latest commit

 

History

History
379 lines (279 loc) · 27.5 KB

09 - 管线.md

File metadata and controls

379 lines (279 loc) · 27.5 KB

09 - 管线

下图显示了 Vulkan 管线的框图。一些 Vulkan 命令指定了要绘制的几何对象或要执行的计算工作,而其他命令则指定了控制不同管线阶段如何处理对象的状态,或控制作为图像和缓冲区组织的内存之间的数据传输。命令实际上是通过处理管线发送的,管线可以是图形管线、光线跟踪管线或计算管线。

图形管线可在两种模式下运行,即图元着色管线或网格着色管线。

图元着色

图形管线的第一阶段(输入组装器)根据所请求的图元拓扑,将顶点组装成几何图元,如点、线和三角形。在下一阶段(顶点着色器),可对顶点进行变换,计算每个顶点的位置和属性。如果支持细分和/或几何着色器,它们就可以从单个输入图元生成多个图元,在此过程中可能会改变图元拓扑结构或生成额外的属性数据。

簇剔除着色

使用簇剔除着色器时,一个类似于计算的着色器将执行基于簇的剔除,一组新的内置输出变量用于表达可见簇,此外,一个新的内置函数用于将这些变量从簇剔除着色器发射到输入组装器(IA)阶段,然后 IA 可以使用这些变量获取可见簇的顶点并驱动顶点着色器工作。

网格着色

使用网格着色管线时,输入图元不是隐式组装的,而是通过(网格着色器)显式组装的。网格管线的工作由应用程序绘制一组网格任务启动。

如果激活了可选的任务着色器,则每个任务都会触发一个任务着色器工作组的执行,该工作组会在任务完成后生成一组新的任务。这些生成的每个任务(或如果没有任务着色器,则原始派发的每个任务)都会触发执行一个网格着色器工作组,该工作组会生成一个输出网格,该网格中的图元数量可变,这些图元由存储在输出网格中的顶点组装而成。

Common

最后生成的图元会被裁剪到裁剪体积(裁切空间,NDC 标准设备化空间),为下一阶段的光栅化做准备。光栅化器会根据点、线段或三角形的二维描述,生成一系列与帧缓冲区区域相关的片段。这些片段由片段操作处理,以确定是否将生成的值写入帧缓冲器。片段着色确定要写入帧缓冲器附件的值。然后,帧缓冲器操作会读取和写入渲染通道实例中给定子通道的帧缓冲器颜色和深度/模板附件。这些附件可在同一渲染通道稍后的子通道中用作片段着色器的输入附件。

计算管线是一条独立于图形管线的管线,它在一维、二维或三维工作组上运行,可以从缓冲区和图像内存中读取和写入。

这种排序只是作为一种描述 Vulkan 的工具,而不是 Vulkan 实现方式的严格规则,我们只是将其作为一种组织管线各种操作的手段来呈现。管线阶段之间的实际排序保证将在同步章节中详细说明。

每个管线都由一个整体对象控制,该对象是根据对所有着色器阶段和任何相关固定功能阶段的描述创建的。将整个管线连接在一起可以根据其输入/输出优化着色器,并消除昂贵的绘制时间状态验证。

使用 vkCmdBindPipeline 可将管线对象绑定到当前状态。在绑定流水线对象时,任何指定为动态的管线对象状态都不会应用到当前状态,而是由动态状态设置命令来设置。

任何状态(包括动态状态)都不会从一个命令缓冲区继承到另一个命令缓冲区。

计算、光线跟踪和图形管线分别由 VkPipeline 句柄表示:

// Provided by VK_VERSION_1_0
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipeline)

多管线创建

可通过 vkCreateExecutionGraphPipelinesAMDX、vkCreateRayTracingPipelinesKHR、vkCreateRayTracingPipelinesNV、vkCreateComputePipelines 和 vkCreateGraphicsPipelines 等命令在一次调用中创建多个管线。

创建命令会传递一个由 Vk*PipelineCreateInfo 结构组成的数组 pCreateInfos,其中指定了要创建的每个管线的参数,并返回 pPipelines 中相应的数组句柄。pPipelines 中的每个元素索引 i 都是根据 pCreateInfos 中相应的元素 i 创建的。

应用程序可以将类似的管线分组,在一次调用中创建,我们鼓励实现者在创建分组时寻找重复使用的机会。

当尝试在单个命令中创建多个管线时,可能会导致其中一部分管线创建失败。在这种情况下,pPipelines 的相应元素将被设置为 VK_NULL_HANDLE。如果在参数有效的情况下仍无法创建管线(例如,由于内存不足错误),创建管线命令返回的 VkResult 代码将说明原因。该实现将尝试创建所有管线,并只为那些实际创建失败的管线返回 VK_NULL_HANDLE 值。

如果在其 VkPipelineCreateInfo 中设置了 VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT 的管线创建失败,则 pPipelines 数组中索引大于或等于失败管线索引的管线将被设置为 VK_NULL_HANDLE。

如果创建多个管线失败,返回的 VkResult 必须是其中任何一个未成功创建的管线的返回值。应用程序可以通过遍历 pPipelines 数组并销毁每个非 VK_NULL_HANDLE 的元素来可靠地清理失败的调用。

如果整个命令失败且未创建任何管线,则 pPipelines 的所有元素都将被设置为 VK_NULL_HANDLE。

计算管线

计算管线由单个静态计算着色器级和管线布局组成。

计算流水线代表一个计算着色器,创建方法是调用 vkCreateComputePipelines,在 VkComputePipelineCreateInfo 结构中包含的 VkPipelineShaderStageCreateInfo 结构中使用 module 和 pName 从着色器模块中选择一个入口点,其中该入口点定义了一个有效的计算着色器。

计算管线API 要创建计算管线,请调用
// Provided by VK_VERSION_1_0
VkResult vkCreateComputePipelines(
    VkDevice                                    device,
    VkPipelineCache                             pipelineCache,
    uint32_t                                    createInfoCount,
    const VkComputePipelineCreateInfo*          pCreateInfos,
    const VkAllocationCallbacks*                pAllocator,
    VkPipeline*                                 pPipelines);
  • device 是创建计算管线的逻辑设备。
  • pipelineCache 是 VK_NULL_HANDLE,表示已禁用管道缓存;或者是一个有效管道缓存对象的句柄,在这种情况下,将在命令执行期间启用该缓存。
  • createInfoCount 是 pCreateInfos 和 pPipelines 数组的长度。
  • pCreateInfos 是指向 VkComputePipelineCreateInfo 结构数组的指针。
  • pAllocator 控制主机内存分配,详见 "内存分配 "一章。
  • pPipelines 是指向 VkPipeline 句柄数组的指针,由此产生的计算管线对象将在其中返回。

管线的创建和返回方法如多重管线创建所述。

VkComputePipelineCreateInfo 结构定义如下:

// Provided by VK_VERSION_1_0
typedef struct VkComputePipelineCreateInfo {
    VkStructureType                    sType;
    const void*                        pNext;
    VkPipelineCreateFlags              flags;
    VkPipelineShaderStageCreateInfo    stage;
    VkPipelineLayout                   layout;
    VkPipeline                         basePipelineHandle;
    int32_t                            basePipelineIndex;
} VkComputePipelineCreateInfo;
  • sType 是标识此结构的 VkStructureType 值。
  • pNext 是 NULL 或指向扩展此结构的结构的指针。
  • flags 是 VkPipelineCreateFlagBits 的位掩码,用于指定生成管线的方式。
  • stage 是描述计算着色器的 VkPipelineShaderStageCreateInfo 结构。
  • layout 是对管线和与管线一起使用的描述符集所使用的绑定位置的描述。
  • basePipelineHandle 是派生的管线。
  • basePipelineIndex 是 pCreateInfos 参数中的一个索引,用作派生的管线。

关于参数 basePipelineHandle 和 basePipelineIndex 的更多详情,请参阅管线派生。

如果 pNext 链中存在 VkPipelineCreateFlags2CreateInfoKHR 结构,则将使用该结构中的 VkPipelineCreateFlags2CreateInfoKHR::flags 而不是此结构中的 flags。

VkPipelineShaderStageCreateInfo 结构定义如下:

// Provided by VK_VERSION_1_0
typedef struct VkPipelineShaderStageCreateInfo {
    VkStructureType                     sType;
    const void*                         pNext;
    VkPipelineShaderStageCreateFlags    flags;
    VkShaderStageFlagBits               stage;
    VkShaderModule                      module;
    const char*                         pName;
    const VkSpecializationInfo*         pSpecializationInfo;
} VkPipelineShaderStageCreateInfo;
  • sType 是标识此结构的 VkStructureType 值。
  • pNext 是 NULL 或指向扩展此结构的结构的指针。
  • flags 是 VkPipelineShaderStageCreateFlagBits 的位掩码,指定如何生成管线着色器阶段。
  • stage 是一个 VkShaderStageFlagBits 值,指定一个管线阶段。
  • module 是一个 VkShaderModule 对象,包含此阶段的着色器代码。
  • pName 是指向空尾 UTF-8 字符串的指针,指定此阶段着色器的入口点名称。
  • pSpecializationInfo 是指向 VkSpecializationInfo 结构的指针(如 "特性化常量 "中所述),或者是 NULL。

如果 module 不是 VK_NULL_HANDLE,则管线使用的着色器代码由 module 定义。如果 module 为 VK_NULL_HANDLE,则着色器代码由链式 VkShaderModuleCreateInfo(如果存在)定义。

如果启用了着色器模块标识符(shaderModuleIdentifier)功能,应用程序就可以省略阶段的着色器代码,转而提供模块标识符。方法是在 pNext 链中包含一个标识符大小不等于 0 的 VkPipelineShaderStageModuleIdentifierCreateInfoEXT 结构。以这种方式创建的着色器阶段等同于使用具有相同标识符的着色器模块创建的阶段。通过标识符,执行程序可以在不使用有效 SPIR-V 模块的情况下查找管线。如果未找到管线,则无法进行管线编译,并且必须按照 VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT 的规定使实现失败。

当使用标识符代替着色器模块时,实现可能会因任何原因导致 VK_PIPELINE_COMPILE_REQUIRED 管线编译失败。

[!note] 之所以放宽对实现用 VkPipelineShaderStageModuleIdentifierCreateInfoEXT 返回管线的要求,是因为层或工具可能会拦截管线创建调用,并需要完整的 SPIR-V 上下文才能正确运行。如果管线存在于缓存中,ICD 不会导致管线编译失败。

使用 VK_PIPELINE_CREATE_LIBRARY_BIT_KHR 创建管线时,应用程序可以使用标识符。创建此类管线时,可能会返回 VK_SUCCESS,但随后在 VkPipelineLibraryCreateInfoKHR 结构中引用管线时会失败。应用程序必须允许在使用 VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT 的链接步骤期间管线编译失败,因为在链接步骤之前可能无法确定是否可以通过标识符创建管线。

// Provided by VK_VERSION_1_0
typedef VkFlags VkPipelineShaderStageCreateFlags;

VkPipelineShaderStageCreateFlags 是一种位掩码类型,用于设置零个或多个 VkPipelineShaderStageCreateFlagBits 的掩码。

指定如何创建流水线着色器阶段的 VkPipelineShaderStageCreateInfo 的 flags 成员的可能值是

// Provided by VK_VERSION_1_0
typedef enum VkPipelineShaderStageCreateFlagBits {
  // Provided by VK_VERSION_1_3
    VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT = 0x00000001,
  // Provided by VK_VERSION_1_3
    VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT = 0x00000002,
  // Provided by VK_EXT_subgroup_size_control
    VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT_EXT = VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT,
  // Provided by VK_EXT_subgroup_size_control
    VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT = VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT,
} VkPipelineShaderStageCreateFlagBits;

VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT 指定子组大小可以在着色器阶段变化。

VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT 指定子组大小必须在任务、网格或计算阶段的所有调用激活时启动。

[!note] 如果指定了 VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT_EXT 和 VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT,并且 minSubgroupSize 不等于 maxSubgroupSize 且未指定所需的子组大小、 那么保证本地工作组大小的 "X "维度是子组大小的倍数的唯一方法就是使其成为 maxSubgroupSize 的倍数。在这些条件下,可以保证完整的子组,但不能保证任何特定的子组大小。

可由命令和结构设置的、指定一个或多个着色器阶段的位有

// Provided by VK_VERSION_1_0
typedef enum VkShaderStageFlagBits {
    VK_SHADER_STAGE_VERTEX_BIT = 0x00000001,
    VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT = 0x00000002,
    VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT = 0x00000004,
    VK_SHADER_STAGE_GEOMETRY_BIT = 0x00000008,
    VK_SHADER_STAGE_FRAGMENT_BIT = 0x00000010,
    VK_SHADER_STAGE_COMPUTE_BIT = 0x00000020,
    VK_SHADER_STAGE_ALL_GRAPHICS = 0x0000001F,
    VK_SHADER_STAGE_ALL = 0x7FFFFFFF,
} VkShaderStageFlagBits;

图形管线

图形管线由多个着色器阶段、多个固定功能管线阶段和一个管线布局组成。

图形管线API 要创建图形管线,请调用
// Provided by VK_VERSION_1_0
VkResult vkCreateGraphicsPipelines(
    VkDevice                                    device,
    VkPipelineCache                             pipelineCache,
    uint32_t                                    createInfoCount,
    const VkGraphicsPipelineCreateInfo*         pCreateInfos,
    const VkAllocationCallbacks*                pAllocator,
    VkPipeline*                                 pPipelines);
  • device 是创建图形管线的逻辑设备。
  • pipelineCache 是 VK_NULL_HANDLE,表示已禁用流水线缓存;或者是一个有效流水线缓存对象的句柄,在这种情况下,在命令执行期间将启用该缓存。
  • createInfoCount 是 pCreateInfos 和 pPipelines 数组的长度。
  • pCreateInfos 是指向 VkGraphicsPipelineCreateInfo 结构数组的指针。
  • pAllocator 控制主机内存分配,详见内存分配一章。
  • pPipelines 是指向 VkPipeline 句柄数组的指针,图形流水线对象将在其中返回。

VkGraphicsPipelineCreateInfo 结构包括一个 VkPipelineShaderStageCreateInfo 结构数组,用于每个所需的活动着色器阶段,以及所有相关固定功能阶段的创建信息和管线布局。

管线的创建和返回与多管线创建的描述相同。

[!note] 隐式缓存可能由实现或层提供。因此,为 pCreateInfos 的任何元素设置 VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT 标志仍然有效,同时为 pipelineCache 传递 VK_NULL_HANDLE。

VkGraphicsPipelineCreateInfo 结构定义如下:

// Provided by VK_VERSION_1_0
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;
  • sType 是标识此结构的 VkStructureType 值。
  • pNext 是 NULL 或指向扩展此结构的结构的指针。
  • flags 是 VkPipelineCreateFlagBits 的位掩码,用于指定生成管线的方式。
  • stageCount 是 pStages 数组中的条目数。
  • pStages 是指向 stageCount VkPipelineShaderStageCreateInfo 结构数组的指针,该结构描述了要包含在图形管线中的着色器阶段集。
  • pVertexInputState 是指向 VkPipelineVertexInputStateCreateInfo 结构的指针。如果管线包含网格着色器阶段,则该指针将被忽略。如果管线是在设置了 VK_DYNAMIC_STATE_VERTEX_INPUT_EXT 动态状态的情况下创建的,则可以为 NULL。
  • pInputAssemblyState 是指向 VkPipelineInputAssemblyStateCreateInfo 结构的指针,该结构用于确定顶点着色的输入装配行为,如 "绘图命令 "中所述。如果启用了 VK_EXT_extended_dynamic_state3 扩展,则在创建管线时同时设置了 VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE 和 VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY 动态状态,且 dynamicPrimitiveTopologyUnrestricted 为 VK_TRUE,则它可以为 NULL。如果管线包含网格着色器阶段,则忽略该状态。
  • pTessellationState 是指向 VkPipelineTessellationStateCreateInfo 结构的指针,该结构定义了细分着色器使用的细分状态。如果管线是在设置了 VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT 动态状态的情况下创建的,则可以为 NULL。
  • pViewportState 是指向 VkPipelineViewportStateCreateInfo 结构的指针,该结构定义了启用光栅化时使用的视口状态。如果启用了 VK_EXT_extended_dynamic_state3 扩展,则在创建管线时同时设置了 VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT 和 VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT 动态状态的情况下,它可以是 NULL。
  • pRasterizationState 是指向定义光栅化状态的 VkPipelineRasterizationStateCreateInfo 结构的指针。 VK_DYNAMIC_STATE_POLYGON_MODE_EXT、VK_DYNAMIC_STATE_CULL_MODE、VK_DYNAMIC_STATE_FRONT_FACE、VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE、VK_DYNAMIC_STATE_DEPTH_BIAS 和 VK_DYNAMIC_STATE_LINE_WIDTH 动态状态。
  • pMultisampleState 是指向 VkPipelineMultisampleStateCreateInfo 结构的指针,该结构定义了启用光栅化时使用的多采样状态。如果启用了 VK_EXT_extended_dynamic_state3 扩展,则在创建管线时使用了所有 VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT、VK_DYNAMIC_STATE_SAMPLE_MASK_EXT、 和 VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT 动态状态,并且设备上禁用了 alphaToOne 或设置了 VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT,在这种情况下,VkPipelineMultisampleStateCreateInfo.:sampleShadingEnable(:sampleShadingEnable)将被禁用: :sampleShadingEnable 假设为 VK_FALSE。
  • pDepthStencilState 是指向 VkPipelineDepthStencilStateCreateInfo 结构的指针,该结构定义了渲染过程中访问深度或模板附件时启用光栅化时使用的深度/模板状态。 VK_DYNAMIC_STATE_DEPTH_COMPARE_OP、VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE、VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE、VK_DYNAMIC_STATE_STENCIL_OP 和 VK_DYNAMIC_STATE_DEPTH_BOUNDS 动态状态。
  • pColorBlendState 是指向 VkPipelineColorBlendStateCreateInfo 结构的指针,该结构定义了光栅化启用时用于渲染器期间访问的任何颜色附件的颜色混合状态。如果启用了 VK_EXT_extended_dynamic_state3 扩展,则在创建管线时使用了所有 VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT、VK_DYNAMIC_STATE_LOGIC_OP_EXT、 VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT, VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT, VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT, 和 VK_DYNAMIC_STATE_BLEND_CONSTANTS 动态状态。
  • pDynamicState 是指向 VkPipelineDynamicStateCreateInfo 结构的指针,该结构定义了管线状态对象的哪些属性是动态的,可以独立于管线状态进行更改。它可以是 NULL,这意味着管线中没有任何状态被视为动态。
  • layout 是对管线和与管线一起使用的描述符集所使用的绑定位置的描述。
  • 渲染通道(renderPass)是指向渲染通道对象的句柄,该对象描述了管道的使用环境。管线只能与所提供的渲染通道实例兼容。更多信息,请参阅渲染通道兼容性。
  • subpass 是使用此管线的渲染通道中子通道的索引。
  • basePipelineHandle 是派生管道的名称。
  • basePipelineIndex(基准管线索引)是 pCreateInfos 参数的索引,用作派生管线。

关于参数 basePipelineHandle 和 basePipelineIndex 的更多详情,请参阅管线派生。

如果任何着色器阶段编译失败,编译日志将反馈给应用程序,并生成 VK_ERROR_INVALID_SHADER_NV。

[!note] 使用 VK_EXT_extended_dynamic_state3,上面的许多 VkGraphicsPipelineCreateInfo 成员都可能是 NULL,因为它们的所有状态都是动态的,因此会被忽略。这是可选项,因此如果应用程序需要设置 pNext 或 flags 字段来指定其他扩展的状态,仍可使用有效指针。

图形管线所需的状态分为顶点输入状态、光栅化前着色器状态、片段着色器状态和片段输出状态。

顶点输入状态

顶点输入状态由

  • VkPipelineVertexInputStateCreateInfo
  • VkPipelineInputAssemblyStateCreateInfo

如果此管线直接或通过将其作为管线库而指定了预光栅化状态,且其 pStages 包括顶点着色器,则必须指定此状态才能创建完整的图形管线。

如果一个管线在 VkGraphicsPipelineLibraryCreateInfoEXT::flags 中明确或默认包含 VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT,并且满足完整图形管线需要此状态的条件,或者此管线未以任何方式指定预光栅化状态,则该管线必须直接指定此状态。

预光栅化着色器状态

预光栅化着色器状态由以下内容定义:

  • 以下条目的 VkPipelineShaderStageCreateInfo 入口:
    • 顶点着色器
    • 细分控制着色器
    • 细分评估着色器
    • 几何着色器
    • 任务着色器
    • 网格着色器
  • 在 VkPipelineLayout 中,如果指定了 VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT,则所有描述符集都与光栅化前着色器绑定。
    • 如果未指定 VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT,则必须指定完整的管线布局。
  • VkPipelineViewportStateCreateInfo
  • VkPipelineRasterizationStateCreateInfo
  • VkPipelineTessellationStateCreateInfo
  • VkRenderPass 和子通道参数
  • VkPipelineRenderingCreateInfo 的 viewMask 参数(格式被忽略)
  • VkPipelineDiscardRectangleStateCreateInfoEXT
  • VkPipelineFragmentShadingRateStateCreateInfoKHR

必须指定此状态才能创建完整的图形管线。

如果 pNext 链包含一个 VkGraphicsPipelineLibraryCreateInfoEXT 结构,其 flags 中包含 VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT,或者未指定该结构并默认包含该值,则必须在管线中指定此状态。

片段着色器状态

片段着色器状态由以下内容定义:

  • 片段着色器的 VkPipelineShaderStageCreateInfo 入口
    • 在 VkPipelineLayout 中,如果指定了 VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT,则所有描述符集都与片段着色器绑定。
  • 如果未指定 VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT,则必须指定完整的管线布局。
  • VkPipelineMultisampleStateCreateInfo(如果已启用样本着色或 renderpass 不是 VK_NULL_HANDLE)。
  • VkPipelineDepthStencilStateCreateInfo
  • VkRenderPass 和子通道参数
  • VkPipelineRenderingCreateInfo 的 viewMask 参数(格式被忽略)
  • VkPipelineFragmentShadingRateStateCreateInfoKHR
  • VkPipelineFragmentShadingRateStateCreateInfoNV
  • VkPipelineRepresentativeFragmentTestStateCreateInfoNV
  • 包含/未包含 VK_PIPELINE_RASTERIZATION_STATE_CREATE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR 标志
  • 包含/不包含 VK_PIPELINE_RASTERIZATION_STATE_CREATE_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT 标志
  • VkRenderingInputAttachmentIndexInfoKHR

如果管线直接或通过将其作为管线库包含而指定了预光栅化状态,并且 rasterizerDiscardEnable 设置为 VK_FALSE 或使用了 VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE,则必须指定此状态才能创建完整的图形管线。

如果某个管线在 VkGraphicsPipelineLibraryCreateInfoEXT::flags 中明确或默认包含 VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT,并且满足完整图形管线需要此状态的条件,或者此管线未以任何方式指定预光栅化状态,则该管线必须直接指定此状态。

片段输出状态

片段输出状态由

  • VkPipelineColorBlendStateCreateInfo
  • VkRenderPass 和子通道参数
  • VkPipelineMultisampleStateCreateInfo
  • VkPipelineRenderingCreateInfo
  • VkAttachmentSampleCountInfoAMD
  • VkAttachmentSampleCountInfoNV
  • VkExternalFormatANDROID
  • 包含/未包含 VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT 和 VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT 标志
  • 包含/不包含 VK_PIPELINE_CREATE_2_ENABLE_LEGACY_DITHERING_BIT_EXT 标志
  • VkRenderingAttachmentLocationInfoKHR

如果管线直接或通过将其作为管线库包含而指定了预光栅化状态,并且 rasterizerDiscardEnable 设置为 VK_FALSE 或使用了 VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE,则必须指定此状态才能创建完整的图形管线。

如果一个管线在 VkGraphicsPipelineLibraryCreateInfoEXT::flags 中明确或默认包含 VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT,并且满足完整图形管线需要此状态的条件,或者此管线没有以任何方式指定预光栅化状态,则该管线必须直接指定此状态。

动态状态

如果通过 pDynamicState 设置的动态状态值所对应的状态不是由用于创建管线的状态子集之一静态设置的,则该值必须被忽略。此外,设置动态状态值不得修改链接库中的状态是静态的还是动态的;这在创建链接库时就已设置且不可更改。例如,如果管线只包含光栅化前着色器状态,那么任何与深度或模板测试相对应的动态状态值都不会产生任何影响。任何启用了动态状态的链接库都必须在该动态状态适用的所有其他链接库中启用相同的动态状态。

图形管线库布局

如果使用 VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT 创建的管线布局将不同的子集链接在一起,则最终有效的管线布局实际上就是链接的管线布局的联合体。为该管线绑定描述符集时,所使用的管线布局必须与该联合相兼容。在使用 VK_PIPELINE_CREATE_LINK_TIME_OPTIMIZATION_BIT_EXT 进行链接时,可以通过提供一个与此联合体兼容的 VkPipelineLayout(VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT 除外)来重写此管线布局、 或在没有 VK_PIPELINE_CREATE_LINK_TIME_OPTIMIZATION_BIT_EXT 的情况下进行链接时,提供与此联合完全兼容的 VkPipelineLayout。

如果 pNext 链中存在 VkPipelineCreateFlags2CreateInfoKHR 结构,则将使用该结构中的 VkPipelineCreateFlags2CreateInfoKHR::flags 代替本结构中的 flags。

有效的图形管线阶段组合

图形管线着色器组