光栅化

光栅化是将图元转换为二维图像的过程。此图像的每个离散位置都包含诸如深度、颜色或其他属性之类的相关数据。

光栅化图元首先确定帧缓冲坐标中整数网格的哪些正方形被该图元占据,并为每个此类正方形分配一个或多个深度值。下面描述了点、线和多边形的此过程。

网格正方形,包括其 (x,y) 帧缓冲坐标、z(深度)以及片段着色器添加的相关数据,称为片段。片段由其左上角定位,该左上角位于整数网格坐标上。

光栅化操作还指片段的采样位置,这些采样位置与片段左上角偏移了分数的值。点、线和三角形的光栅化规则包括测试每个采样位置是否在图元内部。片段实际上不必是正方形,并且光栅化规则不受片段纵横比的影响。但是,显示非正方形网格会导致光栅化的点和线段在一个方向上看起来比另一个方向更粗。

我们假设片段是正方形的,因为它简化了抗锯齿和纹理处理。光栅化后,片段由片段操作处理。

几个因素会影响光栅化,包括 VkPipelineRasterizationStateCreateInfoVkPipelineMultisampleStateCreateInfo 的成员。

VkPipelineRasterizationStateCreateInfo 结构定义如下:

// Provided by VK_VERSION_1_0
typedef struct VkPipelineRasterizationStateCreateInfo {
    VkStructureType                            sType;
    const void*                                pNext;
    VkPipelineRasterizationStateCreateFlags    flags;
    VkBool32                                   depthClampEnable;
    VkBool32                                   rasterizerDiscardEnable;
    VkPolygonMode                              polygonMode;
    VkCullModeFlags                            cullMode;
    VkFrontFace                                frontFace;
    VkBool32                                   depthBiasEnable;
    float                                      depthBiasConstantFactor;
    float                                      depthBiasClamp;
    float                                      depthBiasSlopeFactor;
    float                                      lineWidth;
} VkPipelineRasterizationStateCreateInfo;
  • sType 是一个 VkStructureType 值,用于标识此结构。

  • pNextNULL 或指向扩展此结构的结构的指针。

  • flags 保留供将来使用。

  • depthClampEnable 控制是否如 深度测试中所述来钳制片段的深度值。如果管线不是使用 VkPipelineRasterizationDepthClipStateCreateInfoEXT 创建的,则启用深度钳制也会禁用将图元裁剪到视锥体的 z 平面,如 图元裁剪中所述。否则,深度裁剪由 VkPipelineRasterizationDepthClipStateCreateInfoEXT 中设置的状态控制。

  • rasterizerDiscardEnable 控制是否在光栅化阶段之前立即丢弃图元。

  • polygonMode 是三角形渲染模式。请参阅 VkPolygonMode

  • cullMode 是用于图元剔除的三角形朝向方向。请参阅 VkCullModeFlagBits

  • frontFace 是一个 VkFrontFace 值,用于指定用于剔除的正面三角形方向。

  • depthBiasEnable 控制是否偏置片段深度值。

  • depthBiasConstantFactor 是一个标量因子,用于控制添加到每个片段的常量深度值。

  • depthBiasClamp 是片段的最大(或最小)深度偏置。

  • depthBiasSlopeFactor 是一个标量因子,应用于深度偏置计算中片段的斜率。

  • lineWidth 是光栅化线段的宽度。

应用程序可以还将 VkPipelineRasterizationStateRasterizationOrderAMD 结构添加到 VkPipelineRasterizationStateCreateInfo 结构的 pNext 链。此结构启用选择使用相应的图形管线渲染时要使用的光栅化顺序,如 光栅化顺序中所述。

有效使用
  • VUID-VkPipelineRasterizationStateCreateInfo-depthClampEnable-00782
    如果未启用 depthClamp 功能,则 depthClampEnable 必须VK_FALSE

  • VUID-VkPipelineRasterizationStateCreateInfo-polygonMode-01507
    如果未启用 fillModeNonSolid 功能,则 polygonMode 必须VK_POLYGON_MODE_FILLVK_POLYGON_MODE_FILL_RECTANGLE_NV

  • VUID-VkPipelineRasterizationStateCreateInfo-polygonMode-01414
    如果未启用 VK_NV_fill_rectangle 扩展,则 polygonMode 必须 不为 VK_POLYGON_MODE_FILL_RECTANGLE_NV

  • VUID-VkPipelineRasterizationStateCreateInfo-pointPolygons-04458
    如果启用了 VK_KHR_portability_subset 扩展,并且 VkPhysicalDevicePortabilitySubsetFeaturesKHR::pointPolygonsVK_FALSE,并且 rasterizerDiscardEnableVK_FALSE,则 polygonMode 必须 不为 VK_POLYGON_MODE_POINT

有效用法(隐式)
// Provided by VK_VERSION_1_0
typedef VkFlags VkPipelineRasterizationStateCreateFlags;

VkPipelineRasterizationStateCreateFlags 是用于设置掩码的位掩码类型,但当前保留供将来使用。

如果 VkPipelineRasterizationStateCreateInfopNext 链包含 VkPipelineRasterizationDepthClipStateCreateInfoEXT 结构,则该结构控制是否启用或禁用深度裁剪。

VkPipelineRasterizationDepthClipStateCreateInfoEXT 结构定义为

// Provided by VK_EXT_depth_clip_enable
typedef struct VkPipelineRasterizationDepthClipStateCreateInfoEXT {
    VkStructureType                                        sType;
    const void*                                            pNext;
    VkPipelineRasterizationDepthClipStateCreateFlagsEXT    flags;
    VkBool32                                               depthClipEnable;
} VkPipelineRasterizationDepthClipStateCreateInfoEXT;
  • sType 是一个 VkStructureType 值,用于标识此结构。

  • pNextNULL 或指向扩展此结构的结构的指针。

  • flags 保留供将来使用。

  • depthClipEnable 控制是否启用 图元裁剪 中所述的深度裁剪。

有效用法(隐式)
  • VUID-VkPipelineRasterizationDepthClipStateCreateInfoEXT-sType-sType
    sType 必须VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT

  • VUID-VkPipelineRasterizationDepthClipStateCreateInfoEXT-flags-zerobitmask
    flags 必须0

// Provided by VK_EXT_depth_clip_enable
typedef VkFlags VkPipelineRasterizationDepthClipStateCreateFlagsEXT;

VkPipelineRasterizationDepthClipStateCreateFlagsEXT 是用于设置掩码的位掩码类型,但当前保留供将来使用。

VkPipelineMultisampleStateCreateInfo 结构定义为

// Provided by VK_VERSION_1_0
typedef struct VkPipelineMultisampleStateCreateInfo {
    VkStructureType                          sType;
    const void*                              pNext;
    VkPipelineMultisampleStateCreateFlags    flags;
    VkSampleCountFlagBits                    rasterizationSamples;
    VkBool32                                 sampleShadingEnable;
    float                                    minSampleShading;
    const VkSampleMask*                      pSampleMask;
    VkBool32                                 alphaToCoverageEnable;
    VkBool32                                 alphaToOneEnable;
} VkPipelineMultisampleStateCreateInfo;
  • sType 是一个 VkStructureType 值,用于标识此结构。

  • pNextNULL 或指向扩展此结构的结构的指针。

  • flags 保留供将来使用。

  • rasterizationSamples 是一个 VkSampleCountFlagBits 值,指定光栅化中使用的样本数。如果管道是使用设置的 VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT 动态状态创建的,则此值将被忽略,不用于设置光栅化中使用的样本数,但如果未设置 VK_DYNAMIC_STATE_SAMPLE_MASK_EXT 动态状态,则它仍用于定义如下所述的 pSampleMask 数组的大小。

  • sampleShadingEnable 可以用于启用 样本着色

  • 如果 sampleShadingEnableVK_TRUE,则 minSampleShading 指定样本着色的最小比例。

  • pSampleMask 是指向用于 样本掩码测试VkSampleMask 值数组的指针。

  • alphaToCoverageEnable 控制是否基于片段的第一个颜色输出的 alpha 分量生成临时覆盖值,如 多重采样覆盖 部分中所指定。

  • alphaToOneEnable 控制是否将片段的第一个颜色输出的 alpha 分量替换为 1,如 多重采样覆盖 中所述。

样本掩码中的每个位都与唯一的 样本索引 相关联,如 覆盖掩码 所定义。样本掩码中掩码字 w 的每个位 b 对应于样本索引 i,其中 i = 32 × w + bpSampleMask 的长度等于 ⌈ rasterizationSamples / 32 ⌉ 个字。

如果 pSampleMaskNULL,则将其视为掩码的所有位都设置为 1

有效使用
  • VUID-VkPipelineMultisampleStateCreateInfo-sampleShadingEnable-00784
    如果未启用 sampleRateShading 功能,则 sampleShadingEnable 必须VK_FALSE

  • VUID-VkPipelineMultisampleStateCreateInfo-alphaToOneEnable-00785
    如果未启用 alphaToOne 功能,则 alphaToOneEnable 必须VK_FALSE

  • VUID-VkPipelineMultisampleStateCreateInfo-minSampleShading-00786
    minSampleShading 必须[0,1] 范围内

  • VUID-VkPipelineMultisampleStateCreateInfo-rasterizationSamples-01415
    如果启用了 VK_NV_framebuffer_mixed_samples 扩展,并且如果子通道有任何颜色附件且 rasterizationSamples 大于颜色样本的数量,则 sampleShadingEnable 必须VK_FALSE

有效用法(隐式)
  • VUID-VkPipelineMultisampleStateCreateInfo-sType-sType
    sType 必须VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO

  • VUID-VkPipelineMultisampleStateCreateInfo-pNext-pNext
    pNext 链中任何结构(包括此结构)的每个 pNext 成员必须NULL 或指向 VkPipelineCoverageModulationStateCreateInfoNVVkPipelineCoverageReductionStateCreateInfoNVVkPipelineCoverageToColorStateCreateInfoNVVkPipelineSampleLocationsStateCreateInfoEXT 的有效实例的指针。

  • VUID-VkPipelineMultisampleStateCreateInfo-sType-unique
    pNext 链中每个结构的 sType必须是唯一的

  • VUID-VkPipelineMultisampleStateCreateInfo-flags-zerobitmask
    flags 必须0

  • VUID-VkPipelineMultisampleStateCreateInfo-rasterizationSamples-parameter
    rasterizationSamples 必须为有效的 VkSampleCountFlagBits 值。

  • VUID-VkPipelineMultisampleStateCreateInfo-pSampleMask-parameter
    If pSampleMask is not NULL, pSampleMask must be a valid pointer to an array of VkSampleMask values

// Provided by VK_VERSION_1_0
typedef VkFlags VkPipelineMultisampleStateCreateFlags;

VkPipelineMultisampleStateCreateFlags 是用于设置掩码的位掩码类型,但目前保留供将来使用。

样本掩码数组的元素类型为 VkSampleMask,每个元素代表 32 位覆盖信息。

// Provided by VK_VERSION_1_0
typedef uint32_t VkSampleMask;

光栅化仅生成覆盖帧缓冲区内一个或多个像素的片段。 帧缓冲区外的像素永远不会被视为片段的覆盖范围。 由下面描述的任何图元光栅化规则的应用产生的,但位于帧缓冲区之外的片段不会被生成,也不会被管道的任何后续阶段处理,包括任何片段操作

幸存的片段由片段着色器处理。 片段着色器确定片段的关联数据,并且可以修改或替换其指定的深度值。

光栅化前丢弃图元

如果启用 VkPipelineRasterizationStateCreateInforasterizerDiscardEnable 成员,则在光栅化之前丢弃图元。启用后,图元在光栅化之前由管道中最后一个活动的着色器阶段处理后会被丢弃。

动态启用是否在光栅化阶段之前丢弃图元,请调用

// Provided by VK_VERSION_1_3
void vkCmdSetRasterizerDiscardEnable(
    VkCommandBuffer                             commandBuffer,
    VkBool32                                    rasterizerDiscardEnable);

或等效命令

// Provided by VK_EXT_extended_dynamic_state2, VK_EXT_shader_object
void vkCmdSetRasterizerDiscardEnableEXT(
    VkCommandBuffer                             commandBuffer,
    VkBool32                                    rasterizerDiscardEnable);
  • commandBuffer 是将记录命令的命令缓冲区。

  • rasterizerDiscardEnable 控制是否在光栅化阶段之前立即丢弃图元。

当使用 着色器对象进行绘制时,或者当使用 VkPipelineDynamicStateCreateInfo::pDynamicStates 中设置的 VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE 创建图形管线时,此命令将为后续绘制命令设置丢弃启用。 否则,此状态由用于创建当前活动管线的 VkPipelineRasterizationStateCreateInfo::rasterizerDiscardEnable 值指定。

有效使用
有效用法(隐式)
  • VUID-vkCmdSetRasterizerDiscardEnable-commandBuffer-parameter
    commandBuffer 必须是有效的 VkCommandBuffer 句柄。

  • VUID-vkCmdSetRasterizerDiscardEnable-commandBuffer-recording
    commandBuffer 必须处于录制状态

  • VUID-vkCmdSetRasterizerDiscardEnable-commandBuffer-cmdpool
    commandBuffer 分配的 VkCommandPool 必须支持图形操作。

  • VUID-vkCmdSetRasterizerDiscardEnable-videocoding
    此命令必须仅在视频编码范围之外调用。

主机同步
  • commandBuffer 的主机访问必须进行外部同步。

  • 对从其分配 commandBufferVkCommandPool 的主机访问必须进行外部同步。

命令属性
命令缓冲区级别 渲染通道范围 视频编码范围 支持的队列类型 命令类型

主要
次要

两者

外部

图形

状态

控制用于光栅化的顶点流

默认情况下,来自最后一个光栅化前着色器阶段输出的顶点数据被定向到顶点流零。几何着色器可以将图元发射到多个独立的顶点流。几何着色器发射的每个顶点都指向其中一个顶点流。当每个顶点流上接收到顶点时,它们将被排列成几何着色器输出图元类型指定的图元。着色语言指令 OpEndPrimitiveOpEndStreamPrimitive 可以用于结束在给定顶点流上组装的图元并启动相同类型的新空图元。一个实现支持多达 VkPhysicalDeviceTransformFeedbackPropertiesEXT::maxTransformFeedbackStreams 个流,至少为 1。单个流的编号为 0 到 maxTransformFeedbackStreams 减 1。对于发射顶点的流的顺序没有要求,并且发射到每个顶点流的顶点数量可以完全独立,仅受 VkPhysicalDeviceTransformFeedbackPropertiesEXT::maxTransformFeedbackStreamDataSizeVkPhysicalDeviceTransformFeedbackPropertiesEXT::maxTransformFeedbackBufferDataSize 限制。来自所有顶点流的图元被传递到变换反馈阶段,以便按照最后一个 光栅化前着色器阶段着色器的图形管线中输出接口变量上的 XfbBufferXfbStrideOffsets 装饰所指定的方式捕获到变换反馈缓冲区。要使用除零以外的顶点流,或者使用多个流,必须指定 GeometryStreams 功能。

默认情况下,来自顶点流零的图元被光栅化。如果该实现支持 VkPhysicalDeviceTransformFeedbackPropertiesEXT::transformFeedbackRasterizationStreamSelect 属性,则可以光栅化除零以外的顶点流。

默认情况下,将顶点发射到多个顶点流的几何着色器仅限于使用 OutputPoints 输出图元类型。如果实现支持 VkPhysicalDeviceTransformFeedbackPropertiesEXT::transformFeedbackStreamsLinesTriangles 属性,则除了 OutputPoints 之外,还可以发射 OutputLineStripOutputTriangleStrip

用于光栅化的顶点流通过将 VkPipelineRasterizationStateStreamCreateInfoEXT 结构添加到 VkPipelineRasterizationStateCreateInfo 结构的 pNext 链中来指定。

VkPipelineRasterizationStateStreamCreateInfoEXT 结构的定义如下:

// Provided by VK_EXT_transform_feedback
typedef struct VkPipelineRasterizationStateStreamCreateInfoEXT {
    VkStructureType                                     sType;
    const void*                                         pNext;
    VkPipelineRasterizationStateStreamCreateFlagsEXT    flags;
    uint32_t                                            rasterizationStream;
} VkPipelineRasterizationStateStreamCreateInfoEXT;
  • sType 是一个 VkStructureType 值,用于标识此结构。

  • pNextNULL 或指向扩展此结构的结构的指针。

  • flags 保留供将来使用。

  • rasterizationStream 是为光栅化选择的顶点流。

如果此结构不存在,则假定 rasterizationStream 为零。

有效使用
  • VUID-VkPipelineRasterizationStateStreamCreateInfoEXT-geometryStreams-02324
    必须启用 VkPhysicalDeviceTransformFeedbackFeaturesEXT::geometryStreams

  • VUID-VkPipelineRasterizationStateStreamCreateInfoEXT-rasterizationStream-02325
    rasterizationStream 必须小于 VkPhysicalDeviceTransformFeedbackPropertiesEXT::maxTransformFeedbackStreams

  • VUID-VkPipelineRasterizationStateStreamCreateInfoEXT-rasterizationStream-02326
    如果 VkPhysicalDeviceTransformFeedbackPropertiesEXT::transformFeedbackRasterizationStreamSelectVK_FALSE,则 rasterizationStream 必须为零。

有效用法(隐式)
  • VUID-VkPipelineRasterizationStateStreamCreateInfoEXT-sType-sType
    sType 必须是 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_STREAM_CREATE_INFO_EXT

  • VUID-VkPipelineRasterizationStateStreamCreateInfoEXT-flags-zerobitmask
    flags 必须0

// Provided by VK_EXT_transform_feedback
typedef VkFlags VkPipelineRasterizationStateStreamCreateFlagsEXT;

VkPipelineRasterizationStateStreamCreateFlagsEXT 是用于设置掩码的位掩码类型,但目前保留供将来使用。

动态设置 rasterizationStream 状态,请调用:

// Provided by VK_EXT_extended_dynamic_state3 with VK_EXT_transform_feedback, VK_EXT_shader_object with VK_EXT_transform_feedback
void vkCmdSetRasterizationStreamEXT(
    VkCommandBuffer                             commandBuffer,
    uint32_t                                    rasterizationStream);
  • commandBuffer 是将记录命令的命令缓冲区。

  • rasterizationStream 指定 rasterizationStream 状态。

当使用着色器对象进行绘制,或者当图形管线在 VkPipelineDynamicStateCreateInfo::pDynamicStates 中设置了 VK_DYNAMIC_STATE_RASTERIZATION_STREAM_EXT 时创建时,此命令会设置后续绘制命令的 rasterizationStream 状态。否则,此状态由用于创建当前活动管线的 VkPipelineRasterizationStateStreamCreateInfoEXT::rasterizationStream 值指定。

有效使用
  • VUID-vkCmdSetRasterizationStreamEXT-None-09423
    以下条件中必须至少有一个为真:

  • VUID-vkCmdSetRasterizationStreamEXT-transformFeedback-07411
    必须启用 transformFeedback 功能。

  • VUID-vkCmdSetRasterizationStreamEXT-rasterizationStream-07412
    rasterizationStream 必须小于 VkPhysicalDeviceTransformFeedbackPropertiesEXT::maxTransformFeedbackStreams

  • VUID-vkCmdSetRasterizationStreamEXT-rasterizationStream-07413
    如果 VkPhysicalDeviceTransformFeedbackPropertiesEXT::transformFeedbackRasterizationStreamSelectVK_FALSE,则 rasterizationStream 必须为零。

有效用法(隐式)
  • VUID-vkCmdSetRasterizationStreamEXT-commandBuffer-parameter
    commandBuffer 必须是有效的 VkCommandBuffer 句柄。

  • VUID-vkCmdSetRasterizationStreamEXT-commandBuffer-recording
    commandBuffer 必须处于录制状态

  • VUID-vkCmdSetRasterizationStreamEXT-commandBuffer-cmdpool
    commandBuffer 分配的 VkCommandPool 必须支持图形操作。

  • VUID-vkCmdSetRasterizationStreamEXT-videocoding
    此命令必须仅在视频编码范围之外调用。

主机同步
  • commandBuffer 的主机访问必须进行外部同步。

  • 对从其分配 commandBufferVkCommandPool 的主机访问必须进行外部同步。

命令属性
命令缓冲区级别 渲染通道范围 视频编码范围 支持的队列类型 命令类型

主要
次要

两者

外部

图形

状态

光栅化顺序

渲染通道实例的子通道中,对于给定的 (x,y,layer,sample) 采样位置,对于包括该采样位置的每个单独的图元,以下操作保证按照光栅化顺序执行:

  1. 按照定义的顺序执行片段操作

  2. 混合逻辑操作和颜色写入。

子通道中每个图元的这些操作的执行顺序由应用程序确定。

用于图形管线的光栅化顺序通过将 VkPipelineRasterizationStateRasterizationOrderAMD 结构添加到 VkPipelineRasterizationStateCreateInfo 结构的 pNext 链中来指定。

VkPipelineRasterizationStateRasterizationOrderAMD 结构的定义如下:

// Provided by VK_AMD_rasterization_order
typedef struct VkPipelineRasterizationStateRasterizationOrderAMD {
    VkStructureType            sType;
    const void*                pNext;
    VkRasterizationOrderAMD    rasterizationOrder;
} VkPipelineRasterizationStateRasterizationOrderAMD;
  • sType 是一个 VkStructureType 值,用于标识此结构。

  • pNextNULL 或指向扩展此结构的结构的指针。

  • rasterizationOrder 是一个 VkRasterizationOrderAMD 值,指定要使用的图元光栅化顺序。

有效用法(隐式)
  • VUID-VkPipelineRasterizationStateRasterizationOrderAMD-sType-sType
    sType 必须是 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_RASTERIZATION_ORDER_AMD

  • VUID-VkPipelineRasterizationStateRasterizationOrderAMD-rasterizationOrder-parameter
    rasterizationOrder 必须是有效的 VkRasterizationOrderAMD 值。

如果未启用 VK_AMD_rasterization_order 设备扩展,或者应用程序未通过指定 VkPipelineRasterizationStateRasterizationOrderAMD 结构来请求特定的光栅化顺序,则图形管线使用的光栅化顺序默认为 VK_RASTERIZATION_ORDER_STRICT_AMD

指定图元光栅化顺序的 VkPipelineRasterizationStateRasterizationOrderAMD::rasterizationOrder 的可能值如下:

// Provided by VK_AMD_rasterization_order
typedef enum VkRasterizationOrderAMD {
    VK_RASTERIZATION_ORDER_STRICT_AMD = 0,
    VK_RASTERIZATION_ORDER_RELAXED_AMD = 1,
} VkRasterizationOrderAMD;
  • VK_RASTERIZATION_ORDER_STRICT_AMD 指定子通道中每个图元的操作必须按照 图元顺序发生。

  • VK_RASTERIZATION_ORDER_RELAXED_AMD 指定子通道中每个图元的操作可能不会按照 图元顺序发生。

多重采样

多重采样是一种对所有 Vulkan 图元(点、线和多边形)进行抗锯齿的机制。该技术是在每个像素处对所有图元进行多次采样。每个帧缓冲附件中的每个采样都有存储颜色、深度和/或模板值的空间,因此每个片段操作独立应用于每个采样。颜色采样值稍后可以解析为单个颜色(有关如何将多重采样图像解析为非多重采样图像的更多详细信息,请参阅解析多重采样图像渲染通道章节)。

Vulkan 定义单采样模式的光栅化规则,其方式等效于在每个片段中心具有单个采样的多重采样模式。

每个片段都包含一个覆盖掩码,其中每个片段的每个采样点都有一个位,以及每个采样点的一些深度值和相关数据。

可以理解为每个像素都关联有 rasterizationSamples 个位置。这些位置是精确的位置,而不是区域或面积,每个位置都称为采样点。与像素关联的采样点必须位于被认为是像素边界的单位正方形内或边界上。此外,对于帧缓冲区中的每个像素,采样点的相对位置可能相同,也可能不同。

如果渲染通道具有片段密度图附件,则每个片段只有 rasterizationSamples 个关联位置,而无论片段区域覆盖了多少像素。片段采样位置的定义就像片段的面积为 (1,1) 一样,并且其采样点必须位于这些边界内。它们在帧缓冲区中的实际位置是通过将采样位置按片段面积缩放来计算的。每个像素存储多个采样的附件位于像素采样位置。否则,片段的采样位置通常用于评估相关数据和片段操作。

如果当前管线包含一个片段着色器,其接口中有一个或多个变量用 SampleInput 修饰,则这些变量关联的数据将为每个采样点单独分配。每个采样点的值必须在采样点的位置进行评估。与任何其他未用 SampleInput 修饰的变量关联的数据无需为每个采样点单独评估。

会为每个片段生成一个覆盖掩码,该掩码基于该片段中确定位于生成该片段的图元区域内的采样点。

片段密度图定义的单像素片段和多像素片段有一组采样点。由着色率图像定义的多像素片段每个像素都有一组采样点。通过设置片段着色率定义的多像素片段每个像素都有一组采样点。每组采样点都具有由 VkPipelineMultisampleStateCreateInfo::rasterizationSamples 确定的采样点数量。集合中的每个采样点都被分配一个唯一的采样索引 i,范围为 [0, rasterizationSamples)

动态设置 rasterizationSamples,请调用

// Provided by VK_EXT_extended_dynamic_state3, VK_EXT_shader_object
void vkCmdSetRasterizationSamplesEXT(
    VkCommandBuffer                             commandBuffer,
    VkSampleCountFlagBits                       rasterizationSamples);
  • commandBuffer 是将记录命令的命令缓冲区。

  • rasterizationSamples 指定 rasterizationSamples

在使用着色器对象进行绘制时,或者在图形管线创建时,在 VkPipelineDynamicStateCreateInfo::pDynamicStates 中设置了 VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT 时,此命令将为后续的绘制命令设置 rasterizationSamples。否则,此状态由用于创建当前活动管线的 VkPipelineMultisampleStateCreateInfo::rasterizationSamples 值指定。

有效使用
有效用法(隐式)
  • VUID-vkCmdSetRasterizationSamplesEXT-commandBuffer-parameter
    commandBuffer 必须是有效的 VkCommandBuffer 句柄。

  • VUID-vkCmdSetRasterizationSamplesEXT-rasterizationSamples-parameter
    rasterizationSamples 必须为有效的 VkSampleCountFlagBits 值。

  • VUID-vkCmdSetRasterizationSamplesEXT-commandBuffer-recording
    commandBuffer 必须处于录制状态

  • VUID-vkCmdSetRasterizationSamplesEXT-commandBuffer-cmdpool
    commandBuffer 分配的 VkCommandPool 必须支持图形操作。

  • VUID-vkCmdSetRasterizationSamplesEXT-videocoding
    此命令必须仅在视频编码范围之外调用。

主机同步
  • commandBuffer 的主机访问必须进行外部同步。

  • 对从其分配 commandBufferVkCommandPool 的主机访问必须进行外部同步。

命令属性
命令缓冲区级别 渲染通道范围 视频编码范围 支持的队列类型 命令类型

主要
次要

两者

外部

图形

状态

片段中的每个采样点还被分配了一个唯一的覆盖索引 j,范围为 [0, n × rasterizationSamples),其中 n 是片段中集合的数量。如果片段包含一组采样点,则覆盖索引始终等于采样索引。如果使用了着色率图像并且一个片段覆盖了多个像素,则覆盖索引的确定方式如 VkPipelineViewportCoarseSampleOrderStateCreateInfoNVvkCmdSetCoarseSampleOrderNV 中定义的那样。

如果设置了片段着色率,则覆盖索引 j 被确定为像素索引 p采样索引 i 和光栅化采样点数量 r 的函数,如下所示:

j = i + r × ((fw × fh) - 1 - p)

其中,像素索引 p 被确定为像素的帧缓冲区位置 (x,y) 和片段大小 (fw,fh) 的函数,如下所示:

px = x % fw

py = y % fh

p = px + (py × fw)

下表说明了多像素片段的像素索引

表 1. 像素索引 - 1 宽
1x1 1x2 1x4

pixel index 1x1

pixel index 1x2

pixel index 1x4

表 2. 像素索引 - 2 宽
2x1 2x2 2x4

pixel index 2x1

pixel index 2x2

pixel index 2x4

表 3. 像素索引 - 4 宽
4x1 4x2 4x4

pixel index 4x1

pixel index 4x2

pixel index 4x4

覆盖掩码包括 B 位,打包到 W 个字中,定义为:

B = n × rasterizationSamples

W = ⌈B/32⌉

如果覆盖索引 j = 32×w + b 的采样点被覆盖,则覆盖掩码字 w 中的位 b1,否则为 0

如果 VkPhysicalDeviceLimitsstandardSampleLocations 成员为 VK_TRUE,则采样计数 VK_SAMPLE_COUNT_1_BITVK_SAMPLE_COUNT_2_BITVK_SAMPLE_COUNT_4_BITVK_SAMPLE_COUNT_8_BITVK_SAMPLE_COUNT_16_BIT 具有下表中列出的采样位置,表中第 i 个条目对应于采样索引 iVK_SAMPLE_COUNT_32_BITVK_SAMPLE_COUNT_64_BIT 没有标准的采样位置。位置是相对于片段左上角的原点定义的。

表 4. 标准采样位置
采样计数 采样位置

VK_SAMPLE_COUNT_1_BIT

(0.5,0.5)

sample count 1

VK_SAMPLE_COUNT_2_BIT

(0.75,0.75)
(0.25,0.25)

sample count 2

VK_SAMPLE_COUNT_4_BIT

(0.375, 0.125)
(0.875, 0.375)
(0.125, 0.625)
(0.625, 0.875)

sample count 4

VK_SAMPLE_COUNT_8_BIT

(0.5625, 0.3125)
(0.4375, 0.6875)
(0.8125, 0.5625)
(0.3125, 0.1875)
(0.1875, 0.8125)
(0.0625, 0.4375)
(0.6875, 0.9375)
(0.9375, 0.0625)

sample count 8

VK_SAMPLE_COUNT_16_BIT

(0.5625, 0.5625)
(0.4375, 0.3125)
(0.3125, 0.625)
(0.75, 0.4375)
(0.1875, 0.375)
(0.625, 0.8125)
(0.8125, 0.6875)
(0.6875, 0.1875)
(0.375, 0.875)
(0.5, 0.0625)
(0.25, 0.125)
(0.125, 0.75)
(0.0, 0.5)
(0.9375, 0.25)
(0.875, 0.9375)
(0.0625, 0.0)

sample count 16

使用每个像素多个采样点创建的颜色图像使用一种压缩技术,其中每个像素都关联有两个数据数组。第一个数组包含每个采样点一个元素,其中每个元素存储一个索引,指向定义像素片段掩码的第二个数组。第二个数组包含每个颜色片段一个元素,并且每个元素以图像的格式存储一个唯一的颜色值。使用这种压缩技术,并不总是需要为每个颜色采样点实际使用唯一的存储位置:当多个采样点共享相同的颜色值时,片段掩码可能有两个采样点引用相同的颜色片段。颜色片段的数量由用于创建图像的 VkImageCreateInfo 结构的 samples 成员确定。 VK_AMD_shader_fragment_mask 设备扩展提供了着色器指令,使应用程序能够直接访问片段掩码和各个颜色片段值。

fragment mask
图 1. 片段掩码

自定义采样位置

应用程序可以控制用于光栅化的采样位置。

如果在管线创建时指定的 VkPipelineMultisampleStateCreateInfo 结构的 pNext 链中包含 VkPipelineSampleLocationsStateCreateInfoEXT 结构,那么该结构将控制管线光栅化图元时使用的采样位置。

VkPipelineSampleLocationsStateCreateInfoEXT 结构的定义如下:

// Provided by VK_EXT_sample_locations
typedef struct VkPipelineSampleLocationsStateCreateInfoEXT {
    VkStructureType             sType;
    const void*                 pNext;
    VkBool32                    sampleLocationsEnable;
    VkSampleLocationsInfoEXT    sampleLocationsInfo;
} VkPipelineSampleLocationsStateCreateInfoEXT;
  • sType 是一个 VkStructureType 值,用于标识此结构。

  • pNextNULL 或指向扩展此结构的结构的指针。

  • sampleLocationsEnable 控制是否使用自定义采样位置。如果 sampleLocationsEnableVK_FALSE,则使用默认的采样位置,并忽略 sampleLocationsInfo 中指定的值。

  • 如果 sampleLocationsEnableVK_TRUE 且图形管线不是使用 VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT 创建的,则 sampleLocationsInfo 是光栅化期间要使用的采样位置。

有效用法(隐式)
  • VUID-VkPipelineSampleLocationsStateCreateInfoEXT-sType-sType
    sType 必须VK_STRUCTURE_TYPE_PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT

  • VUID-VkPipelineSampleLocationsStateCreateInfoEXT-sampleLocationsInfo-parameter
    sampleLocationsInfo 必须是有效的 VkSampleLocationsInfoEXT 结构

VkSampleLocationsInfoEXT 结构的定义如下:

// Provided by VK_EXT_sample_locations
typedef struct VkSampleLocationsInfoEXT {
    VkStructureType               sType;
    const void*                   pNext;
    VkSampleCountFlagBits         sampleLocationsPerPixel;
    VkExtent2D                    sampleLocationGridSize;
    uint32_t                      sampleLocationsCount;
    const VkSampleLocationEXT*    pSampleLocations;
} VkSampleLocationsInfoEXT;
  • sType 是一个 VkStructureType 值,用于标识此结构。

  • pNextNULL 或指向扩展此结构的结构的指针。

  • sampleLocationsPerPixel 是一个 VkSampleCountFlagBits 值,指定每个像素的采样位置数。

  • sampleLocationGridSize 是用于选择自定义采样位置的采样位置网格的大小。

  • sampleLocationsCountpSampleLocations 中采样位置的数量。

  • pSampleLocations 是指向 sampleLocationsCountVkSampleLocationEXT 结构数组的指针。

此结构可以用于指定渲染时要使用的采样位置,或者用于指定深度/模板图像子资源上次渲染时使用的采样位置集,以便进行使用 VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT 创建的深度/模板图像的布局转换。

pSampleLocations 中的采样位置为 sampleLocationGridSize 中指定大小的网格中的每个像素指定 sampleLocationsPerPixel 个采样位置。像素网格位置 (x,y) 处的第 i 个采样的采样位置取自 pSampleLocations[(x + y × sampleLocationGridSize.width) × sampleLocationsPerPixel + i]

如果渲染通道具有片段密度图,则实现将为片段选择采样位置,并且可能会忽略 pSampleLocations 的内容。

有效使用
  • VUID-VkSampleLocationsInfoEXT-sampleLocationsPerPixel-01526
    sampleLocationsPerPixel 必须是有效的 VkSampleCountFlagBits 值,该值在 VkPhysicalDeviceSampleLocationsPropertiesEXT::sampleLocationSampleCounts 中设置

  • VUID-VkSampleLocationsInfoEXT-sampleLocationsCount-01527
    sampleLocationsCount 必须等于 sampleLocationsPerPixel × sampleLocationGridSize.width × sampleLocationGridSize.height

有效用法(隐式)
  • VUID-VkSampleLocationsInfoEXT-sType-sType
    sType 必须VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT

  • VUID-VkSampleLocationsInfoEXT-pSampleLocations-parameter
    如果 sampleLocationsCount 不为 0,则 pSampleLocations 必须是指向 sampleLocationsCountVkSampleLocationEXT 结构数组的有效指针

VkSampleLocationEXT 结构的定义如下:

// Provided by VK_EXT_sample_locations
typedef struct VkSampleLocationEXT {
    float    x;
    float    y;
} VkSampleLocationEXT;
  • x 是采样位置的水平坐标。

  • y 是采样位置的垂直坐标。

采样位置坐标的域空间在帧缓冲区空间内的像素中具有左上角原点。

VkSampleLocationEXT 结构中指定的值始终被限制在与实现相关的采样位置坐标范围 [sampleLocationCoordinateRange[0],sampleLocationCoordinateRange[1]] 内,该范围可以使用 VkPhysicalDeviceSampleLocationsPropertiesEXT 查询。

动态设置 sampleLocationsEnable 状态,请调用:

// Provided by VK_EXT_extended_dynamic_state3 with VK_EXT_sample_locations, VK_EXT_sample_locations with VK_EXT_shader_object
void vkCmdSetSampleLocationsEnableEXT(
    VkCommandBuffer                             commandBuffer,
    VkBool32                                    sampleLocationsEnable);
  • commandBuffer 是将记录命令的命令缓冲区。

  • sampleLocationsEnable 指定 sampleLocationsEnable 状态。

当使用 着色器对象 绘图时,或者当图形管线在 VkPipelineDynamicStateCreateInfo::pDynamicStates 中设置了 VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_ENABLE_EXT 时创建时,此命令将为后续绘图命令设置 sampleLocationsEnable 状态。否则,此状态由用于创建当前活动管线的 VkPipelineSampleLocationsStateCreateInfoEXT::sampleLocationsEnable 值指定。

有效使用
有效用法(隐式)
  • VUID-vkCmdSetSampleLocationsEnableEXT-commandBuffer-parameter
    commandBuffer 必须是有效的 VkCommandBuffer 句柄。

  • VUID-vkCmdSetSampleLocationsEnableEXT-commandBuffer-recording
    commandBuffer 必须处于录制状态

  • VUID-vkCmdSetSampleLocationsEnableEXT-commandBuffer-cmdpool
    commandBuffer 分配的 VkCommandPool 必须支持图形操作。

  • VUID-vkCmdSetSampleLocationsEnableEXT-videocoding
    此命令必须仅在视频编码范围之外调用。

主机同步
  • commandBuffer 的主机访问必须进行外部同步。

  • 对从其分配 commandBufferVkCommandPool 的主机访问必须进行外部同步。

命令属性
命令缓冲区级别 渲染通道范围 视频编码范围 支持的队列类型 命令类型

主要
次要

两者

外部

图形

状态

动态设置用于光栅化的采样位置,请调用:

// Provided by VK_EXT_sample_locations
void vkCmdSetSampleLocationsEXT(
    VkCommandBuffer                             commandBuffer,
    const VkSampleLocationsInfoEXT*             pSampleLocationsInfo);
  • commandBuffer 是将记录命令的命令缓冲区。

  • pSampleLocationsInfo 是要设置的采样位置状态。

当使用 着色器对象 绘图时,或者当图形管线在 VkPipelineDynamicStateCreateInfo::pDynamicStates 中设置了 VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT 且绑定图形管线的 VkPipelineSampleLocationsStateCreateInfoEXT::sampleLocationsEnable 属性为 VK_TRUE 时,此命令将为后续绘图命令设置自定义采样位置。否则,此状态由用于创建当前活动管线的 VkPipelineSampleLocationsStateCreateInfoEXT::sampleLocationsInfo 值指定。

有效使用
  • VUID-vkCmdSetSampleLocationsEXT-variableSampleLocations-01530
    如果 VkPhysicalDeviceSampleLocationsPropertiesEXT::variableSampleLocationsVK_FALSE,则当前的渲染通道必须通过指定一个 VkRenderPassSampleLocationsBeginInfoEXT 结构体来开始,该结构体的 pPostSubpassSampleLocations 成员包含一个 subpassIndex 与当前子通道索引匹配的元素,并且该元素的 sampleLocationsInfo 成员必须pSampleLocationsInfo 指向的采样位置状态匹配。

有效用法(隐式)
  • VUID-vkCmdSetSampleLocationsEXT-commandBuffer-parameter
    commandBuffer 必须是有效的 VkCommandBuffer 句柄。

  • VUID-vkCmdSetSampleLocationsEXT-pSampleLocationsInfo-parameter
    pSampleLocationsInfo 必须是一个指向有效的 VkSampleLocationsInfoEXT 结构的有效指针。

  • VUID-vkCmdSetSampleLocationsEXT-commandBuffer-recording
    commandBuffer 必须处于录制状态

  • VUID-vkCmdSetSampleLocationsEXT-commandBuffer-cmdpool
    commandBuffer 分配的 VkCommandPool 必须支持图形操作。

  • VUID-vkCmdSetSampleLocationsEXT-videocoding
    此命令必须仅在视频编码范围之外调用。

主机同步
  • commandBuffer 的主机访问必须进行外部同步。

  • 对从其分配 commandBufferVkCommandPool 的主机访问必须进行外部同步。

命令属性
命令缓冲区级别 渲染通道范围 视频编码范围 支持的队列类型 命令类型

主要
次要

两者

外部

图形

状态

片段着色率

VkPhysicalDeviceFragmentShadingRateFeaturesKHR 公告的功能允许应用程序控制给定片段着色器调用的着色率

片段着色率与多重采样密切相关,并且实现的可用速率集合可能受到采样率的限制。

要查询可用的着色率,请调用

// Provided by VK_KHR_fragment_shading_rate
VkResult vkGetPhysicalDeviceFragmentShadingRatesKHR(
    VkPhysicalDevice                            physicalDevice,
    uint32_t*                                   pFragmentShadingRateCount,
    VkPhysicalDeviceFragmentShadingRateKHR*     pFragmentShadingRates);
  • physicalDevice 是要查询其属性的物理设备的句柄。

  • pFragmentShadingRateCount 是指向与可用或查询的片段着色率数量相关的整数的指针,如下所述。

  • pFragmentShadingRates 要么为 NULL,要么是指向 VkPhysicalDeviceFragmentShadingRateKHR 结构体数组的指针。

如果 pFragmentShadingRatesNULL,则可用片段着色率的数量将返回在 pFragmentShadingRateCount 中。否则,pFragmentShadingRateCount 必须指向应用程序设置为 pFragmentShadingRates 数组中元素数量的变量,并且在返回时,该变量将被实际写入到 pFragmentShadingRates 的结构体数量覆盖。如果 pFragmentShadingRateCount 小于可用片段着色率的数量,则最多将写入 pFragmentShadingRateCount 个结构体,并且将返回 VK_INCOMPLETE 而不是 VK_SUCCESS,以表明并非所有可用的片段着色率都被返回。

返回的片段着色率数组必须按照从最大 fragmentSize.width 值到最小值的顺序排列,并且每个具有相同 fragmentSize.width 值的片段着色率集合必须按照从最大 fragmentSize.height 到最小值的顺序排列。数组中的任何两个条目必须不具有相同的 fragmentSize 值。

对于数组中的任何条目,还适用以下规则

实现必须至少支持以下着色率

sampleCounts fragmentSize

VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT

{2,2}

VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT

{2,1}

~0

{1,1}

如果 framebufferColorSampleCounts 包括 VK_SAMPLE_COUNT_2_BIT,则所需的速率必须还包括 VK_SAMPLE_COUNT_2_BIT

包含 {1,1} 片段大小是为了完整性;它对不设置片段大小的渲染支持没有实际影响。所有采样计数和渲染通道变换都支持此速率。

返回的片段着色率集合必须以本机(旋转)坐标系返回。对于使用不等于 VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR 的渲染通道 transform 进行的栅格化,应用程序必须将返回的片段着色率变换到当前(未旋转)坐标系,以获得该变换的支持速率。

例如,考虑一个实现返回支持 4x2 但不支持 2x4 的受支持片段着色率集。这意味着对于变换 VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHRVK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR,2x4 是支持的速率,但 4x2 是不支持的速率。

有效用法(隐式)
  • VUID-vkGetPhysicalDeviceFragmentShadingRatesKHR-physicalDevice-parameter
    physicalDevice 必须是一个有效的 VkPhysicalDevice 句柄

  • VUID-vkGetPhysicalDeviceFragmentShadingRatesKHR-pFragmentShadingRateCount-parameter
    pFragmentShadingRateCount 必须是指向 uint32_t 值的有效指针

  • VUID-vkGetPhysicalDeviceFragmentShadingRatesKHR-pFragmentShadingRates-parameter
    如果 pFragmentShadingRateCount 引用的值不是 0,并且 pFragmentShadingRates 不是 NULL,则 pFragmentShadingRates 必须是指向 pFragmentShadingRateCountVkPhysicalDeviceFragmentShadingRateKHR 结构体的数组的有效指针

返回值
成功
  • VK_SUCCESS

  • VK_INCOMPLETE

失败
  • VK_ERROR_OUT_OF_HOST_MEMORY

VkPhysicalDeviceFragmentShadingRateKHR 结构定义如下:

// Provided by VK_KHR_fragment_shading_rate
typedef struct VkPhysicalDeviceFragmentShadingRateKHR {
    VkStructureType       sType;
    void*                 pNext;
    VkSampleCountFlags    sampleCounts;
    VkExtent2D            fragmentSize;
} VkPhysicalDeviceFragmentShadingRateKHR;
  • sType 是一个 VkStructureType 值,用于标识此结构。

  • pNextNULL 或指向扩展此结构的结构的指针。

  • sampleCounts 是一个位掩码,表示 fragmentSize 描述的着色率支持的采样计数。

  • fragmentSize 是一个 VkExtent2D,描述了受支持着色率的宽度和高度。

有效用法(隐式)
  • VUID-VkPhysicalDeviceFragmentShadingRateKHR-sType-sType
    sType 必须VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_KHR

  • VUID-VkPhysicalDeviceFragmentShadingRateKHR-pNext-pNext
    pNext 必须NULL

片元着色率可以在三个点设置,三个速率组合起来以确定最终的着色率。

管线片元着色率

管线片元着色率 可以通过在图形管线中设置速率,或通过 vkCmdSetFragmentShadingRateKHR 动态设置,从而在每次绘制时设置。

VkPipelineFragmentShadingRateStateCreateInfoKHR 结构定义如下:

// Provided by VK_KHR_fragment_shading_rate
typedef struct VkPipelineFragmentShadingRateStateCreateInfoKHR {
    VkStructureType                       sType;
    const void*                           pNext;
    VkExtent2D                            fragmentSize;
    VkFragmentShadingRateCombinerOpKHR    combinerOps[2];
} VkPipelineFragmentShadingRateStateCreateInfoKHR;
  • sType 是一个 VkStructureType 值,用于标识此结构。

  • pNextNULL 或指向扩展此结构的结构的指针。

  • fragmentSize 指定一个 VkExtent2D 结构,其中包含用于定义使用此管线的绘制命令的管线片元着色率的片元大小。

  • combinerOps 指定一个 VkFragmentShadingRateCombinerOpKHR 值,该值确定 管线图元附件着色率 如何为使用创建的管线的绘制命令生成的片元进行 组合

如果 VkGraphicsPipelineCreateInfopNext 链中包含 VkPipelineFragmentShadingRateStateCreateInfoKHR 结构,则该结构包含控制管线片元着色率的参数。

如果此结构不存在,则认为 fragmentSize 等于 (1,1),并且认为 combinerOps 的两个元素都等于 VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR

有效用法(隐式)
  • VUID-VkPipelineFragmentShadingRateStateCreateInfoKHR-sType-sType
    sType 必须VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR

动态设置管线片元着色率和组合器操作,请调用:

// Provided by VK_KHR_fragment_shading_rate
void vkCmdSetFragmentShadingRateKHR(
    VkCommandBuffer                             commandBuffer,
    const VkExtent2D*                           pFragmentSize,
    const VkFragmentShadingRateCombinerOpKHR    combinerOps[2]);

当使用着色器对象进行绘制,或者当图形管线创建时,在VkPipelineDynamicStateCreateInfo::pDynamicStates 中设置了 VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR 时,此命令为后续绘制命令设置管线片元着色率和组合器操作。否则,此状态由用于创建当前活动管线的 VkPipelineFragmentShadingRateStateCreateInfoKHR 值指定。

有效使用
  • VUID-vkCmdSetFragmentShadingRateKHR-pipelineFragmentShadingRate-04507
    如果 pipelineFragmentShadingRate 功能未启用,则 pFragmentSize->width 必须1

  • VUID-vkCmdSetFragmentShadingRateKHR-pipelineFragmentShadingRate-04508
    如果 pipelineFragmentShadingRate 功能未启用,则 pFragmentSize->height 必须1

  • VUID-vkCmdSetFragmentShadingRateKHR-pipelineFragmentShadingRate-04509
    必须启用 pipelineFragmentShadingRate primitiveFragmentShadingRate attachmentFragmentShadingRate 功能之一

  • VUID-vkCmdSetFragmentShadingRateKHR-primitiveFragmentShadingRate-04510
    如果 primitiveFragmentShadingRate 功能未启用,则 combinerOps[0] 必须VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR

  • VUID-vkCmdSetFragmentShadingRateKHR-attachmentFragmentShadingRate-04511
    如果 attachmentFragmentShadingRate 功能未启用,则 combinerOps[1] 必须VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR

  • VUID-vkCmdSetFragmentShadingRateKHR-fragmentSizeNonTrivialCombinerOps-04512
    如果不支持 fragmentSizeNonTrivialCombinerOps 限制,则 combinerOps 的元素必须VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHRVK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR

  • VUID-vkCmdSetFragmentShadingRateKHR-pFragmentSize-04513
    pFragmentSize->width 必须大于或等于 1

  • VUID-vkCmdSetFragmentShadingRateKHR-pFragmentSize-04514
    pFragmentSize->height 必须大于或等于 1

  • VUID-vkCmdSetFragmentShadingRateKHR-pFragmentSize-04515
    pFragmentSize->width 必须是 2 的幂值

  • VUID-vkCmdSetFragmentShadingRateKHR-pFragmentSize-04516
    pFragmentSize->height 必须是 2 的幂值

  • VUID-vkCmdSetFragmentShadingRateKHR-pFragmentSize-04517
    pFragmentSize->width 必须小于或等于 4

  • VUID-vkCmdSetFragmentShadingRateKHR-pFragmentSize-04518
    pFragmentSize->height 必须小于或等于 4

有效用法(隐式)
  • VUID-vkCmdSetFragmentShadingRateKHR-commandBuffer-parameter
    commandBuffer 必须是有效的 VkCommandBuffer 句柄。

  • VUID-vkCmdSetFragmentShadingRateKHR-pFragmentSize-parameter
    pFragmentSize 必须是指向有效的 VkExtent2D 结构的有效指针

  • VUID-vkCmdSetFragmentShadingRateKHR-combinerOps-parameter
    combinerOps 的每个元素必须是有效的 VkFragmentShadingRateCombinerOpKHR 值。

  • VUID-vkCmdSetFragmentShadingRateKHR-commandBuffer-recording
    commandBuffer 必须处于录制状态

  • VUID-vkCmdSetFragmentShadingRateKHR-commandBuffer-cmdpool
    commandBuffer 分配的 VkCommandPool 必须支持图形操作。

  • VUID-vkCmdSetFragmentShadingRateKHR-videocoding
    此命令必须仅在视频编码范围之外调用。

主机同步
  • commandBuffer 的主机访问必须进行外部同步。

  • 对从其分配 commandBufferVkCommandPool 的主机访问必须进行外部同步。

命令属性
命令缓冲区级别 渲染通道范围 视频编码范围 支持的队列类型 命令类型

主要
次要

两者

外部

图形

状态

图元片元着色率

图元片元着色率 可以通过最后一个活动的光栅化前着色器阶段中的 PrimitiveShadingRateKHR 内建变量设置。如果最后一个光栅化前着色器阶段正在使用 MeshEXT Execution Model,则与给定图元相关的速率来源于写入每个图元的 PrimitiveShadingRateKHR 的值。否则,与给定图元相关的速率来源于该图元的起始顶点写入 PrimitiveShadingRateKHR 的值。

附件片元着色率

附件着色率 可以通过在子通道中包含 VkFragmentShadingRateAttachmentInfoKHR 来设置,以定义一个片元着色率附件。帧缓冲中的每个像素都根据以下公式,通过片元着色率附件中的相应纹素分配一个附件片元着色率:

x' = floor(x / regionx)

y' = floor(y / regiony)

其中 x'y' 是片元着色率附件中纹素的坐标,xy 是帧缓冲中像素的坐标,regionxregiony 是每个纹素对应的区域大小,由 VkFragmentShadingRateAttachmentInfoKHRshadingRateAttachmentTexelSize 成员定义。

如果 启用了多视口,并且着色率附件具有多个图层,则使用 layer = ViewIndex 选择着色率附件纹素。如果禁用了多视口,并且着色率附件和帧缓冲都具有多个图层,则使用 layer = Layer 选择着色率附件纹素。否则,layer = 0

纹素是从片元着色率附件图像中读取的,作为纹理输入操作,不使用采样器,使用整数坐标 i = x'j = y'k = 0l = layers = 0。片元大小被编码到该操作结果的第一个分量中,如下所示:

sizew = 2((texel/4)&3)

sizeh = 2(texel&3)

其中 texel 是返回值的第一个分量中的值,sizewsizeh 是片元大小的宽度和高度,从纹素解码而来。

如果未指定片元着色率附件,则此大小计算为 sizew = sizeh = 1。应用程序必须不能通过此方法指定大于 4 的宽度或高度。

SPIR-V 中的片元着色率枚举遵循上述编码。

合并片元着色率

用于片元着色的最终速率 (Cxy') 必须是由 vkGetPhysicalDeviceFragmentShadingRatesKHR 返回的用于光栅化所使用的采样计数和渲染通道变换的速率之一。

如果满足以下任何条件,则实现会将 Cxy' 设置为 {1,1}

否则,将合并每个指定的着色率,然后用于推导 Cxy' 的值。由于有三种指定着色率的方法,因此指定了两种合并操作 - 在管线图元着色率之间,以及该结果与附件着色率之间。

每个合并操作所使用的公式由 VkFragmentShadingRateCombinerOpKHR 定义

// Provided by VK_KHR_fragment_shading_rate
typedef enum VkFragmentShadingRateCombinerOpKHR {
    VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR = 0,
    VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR = 1,
    VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MIN_KHR = 2,
    VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_KHR = 3,
    VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_KHR = 4,
} VkFragmentShadingRateCombinerOpKHR;
  • VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR 指定的合并操作为 combine(Axy,Bxy) = Axy

  • VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR 指定的合并操作为 combine(Axy,Bxy) = Bxy

  • VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MIN_KHR 指定的合并操作为 combine(Axy,Bxy) = min(Axy,Bxy)

  • VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_KHR 指定的合并操作为 combine(Axy,Bxy) = max(Axy,Bxy)

  • VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_KHR 指定组合操作为 combine(Axy,Bxy) = Axy*Bxy

其中 combine(Axy,Bxy) 是组合操作,而 AxyBxy 是该操作的输入。

如果 fragmentShadingRateStrictMultiplyCombinerVK_FALSE,则在同一维度上,使用 VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_KHR 并将 A 和 B 的值都设置为 1 将导致该维度产生值 2。 有关详细信息,请参阅 fragmentShadingRateStrictMultiplyCombiner 的定义。

这些操作以分量方式执行。

这用于使用以下等式生成组合的片元区域:

Cxy = combine(Axy,Bxy)

其中 Cxy 是组合的片元区域结果,而 AxyBxy 是被组合的片元着色率的片元区域。

执行两个组合操作,首先将 Axy 等于管线片元着色率,并将 Bxy 等于图元片元着色率,使用 combinerOps[0] 选择的 combine() 操作。然后执行第二个组合,将 Axy 等于第一个组合的结果,并将 Bxy 等于附件片元着色率,使用 combinerOps[1] 选择的 combine() 操作。第二个组合的结果用作最终片元着色率,并通过ShadingRateKHR 内置变量报告。

如果 VkPhysicalDeviceMaintenance6Properties::fragmentShadingRateClampCombinerInputsVK_TRUE,则实现**应该**钳制组合器操作 AxyBxy 的输入,并且**必须**这样做。所有实现**必须**钳制第二个组合器操作的结果。

表示 AxyBxyCxy 的任何一个的片元着色率 Rxy 按如下方式钳制。如果 RxyvkGetPhysicalDeviceFragmentShadingRatesKHR 针对光栅化使用的样本计数和渲染通道转换返回的速率之一,则钳制的着色率 Rxy'Rxy。否则,钳制的着色率将从 vkGetPhysicalDeviceFragmentShadingRatesKHR 针对光栅化使用的样本计数和渲染通道转换返回的速率中选择。从支持速率列表中,按顺序应用以下步骤以选择单个值:

  1. 仅保留满足 Rx' ≤ RxRy' ≤ Ry 的速率。

    • 实现**可能**还会保留满足 Rx' ≤ RyRy' ≤ Rx 的速率。

  2. 仅保留具有最高区域(Rx' × Ry')的速率。

  3. 仅保留具有最低纵横比(Rx' + Ry')的速率。

  4. 在剩余宽速率(例如 4x1)和高速率(例如 1x4)的情况下,实现**可能**选择任一速率。但是,对于相同的着色率,渲染通道转换和组合器操作,在VkDevice的生命周期内,**必须**一致地选择此速率。

扩展片元着色率

VkPhysicalDeviceFragmentShadingRateEnumsFeaturesNV 公告的功能支持超出指定一个片元着色器调用覆盖片元中所有像素的额外的片元着色率,其大小由片元着色率指示。

如果启用了fragmentShadingRateEnums 功能,则可以使用定义为 VkFragmentShadingRateNV 枚举类型指定片元着色率:

// Provided by VK_NV_fragment_shading_rate_enums
typedef enum VkFragmentShadingRateNV {
    VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_PIXEL_NV = 0,
    VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_1X2_PIXELS_NV = 1,
    VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_2X1_PIXELS_NV = 4,
    VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_2X2_PIXELS_NV = 5,
    VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_2X4_PIXELS_NV = 6,
    VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_4X2_PIXELS_NV = 9,
    VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_4X4_PIXELS_NV = 10,
    VK_FRAGMENT_SHADING_RATE_2_INVOCATIONS_PER_PIXEL_NV = 11,
    VK_FRAGMENT_SHADING_RATE_4_INVOCATIONS_PER_PIXEL_NV = 12,
    VK_FRAGMENT_SHADING_RATE_8_INVOCATIONS_PER_PIXEL_NV = 13,
    VK_FRAGMENT_SHADING_RATE_16_INVOCATIONS_PER_PIXEL_NV = 14,
    VK_FRAGMENT_SHADING_RATE_NO_INVOCATIONS_NV = 15,
} VkFragmentShadingRateNV;
  • VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_PIXEL_NV 指定的片元大小为 1x1 像素。

  • VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_1X2_PIXELS_NV 指定的片元大小为 1x2 像素。

  • VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_2X1_PIXELS_NV 指定的片元大小为 2x1 像素。

  • VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_2X2_PIXELS_NV 指定的片元大小为 2x2 像素。

  • VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_2X4_PIXELS_NV 指定的片元大小为 2x4 像素。

  • VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_4X2_PIXELS_NV 指定的片元大小为 4x2 像素。

  • VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_4X4_PIXELS_NV 指定的片元大小为 4x4 像素。

  • VK_FRAGMENT_SHADING_RATE_2_INVOCATIONS_PER_PIXEL_NV 指定的片元大小为 1x1 像素,每个片元有两个片元着色器调用。

  • VK_FRAGMENT_SHADING_RATE_4_INVOCATIONS_PER_PIXEL_NV 指定的片元大小为 1x1 像素,每个片元有四个片元着色器调用。

  • VK_FRAGMENT_SHADING_RATE_8_INVOCATIONS_PER_PIXEL_NV 指定的片元大小为 1x1 像素,每个片元有八个片元着色器调用。

  • VK_FRAGMENT_SHADING_RATE_16_INVOCATIONS_PER_PIXEL_NV 指定的片元大小为 1x1 像素,每个片元有十六个片元着色器调用。

  • VK_FRAGMENT_SHADING_RATE_NO_INVOCATIONS_NV 指定应丢弃使用该着色率的图元的任何部分,而不调用任何片元着色器。

要将着色率 VK_FRAGMENT_SHADING_RATE_2_INVOCATIONS_PER_PIXEL_NVVK_FRAGMENT_SHADING_RATE_4_INVOCATIONS_PER_PIXEL_NVVK_FRAGMENT_SHADING_RATE_8_INVOCATIONS_PER_PIXEL_NVVK_FRAGMENT_SHADING_RATE_16_INVOCATIONS_PER_PIXEL_NV 用作管线、图元或附件着色率,**必须**启用supersampleFragmentShadingRates功能。要将着色率 VK_FRAGMENT_SHADING_RATE_NO_INVOCATIONS_NV 用作管线、图元或附件着色率,**必须**启用noInvocationFragmentShadingRates功能。

使用片元着色率枚举时,可以通过在图形管线中设置速率,或通过 vkCmdSetFragmentShadingRateEnumNV 动态设置管线片元着色率(在每次绘制的基础上)。

VkPipelineFragmentShadingRateEnumStateCreateInfoNV 结构定义为

// Provided by VK_NV_fragment_shading_rate_enums
typedef struct VkPipelineFragmentShadingRateEnumStateCreateInfoNV {
    VkStructureType                       sType;
    const void*                           pNext;
    VkFragmentShadingRateTypeNV           shadingRateType;
    VkFragmentShadingRateNV               shadingRate;
    VkFragmentShadingRateCombinerOpKHR    combinerOps[2];
} VkPipelineFragmentShadingRateEnumStateCreateInfoNV;

如果 VkGraphicsPipelineCreateInfopNext 链包含 VkPipelineFragmentShadingRateEnumStateCreateInfoNV 结构,则该结构包含控制管线片元着色率的参数。

如果此结构不存在,则认为 shadingRateType 等于 VK_FRAGMENT_SHADING_RATE_TYPE_FRAGMENT_SIZE_NV,认为 shadingRate 等于 VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_PIXEL_NV,并且认为 combinerOps 的两个元素都等于 VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR

有效用法(隐式)
  • VUID-VkPipelineFragmentShadingRateEnumStateCreateInfoNV-sType-sType
    sType 必须VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_ENUM_STATE_CREATE_INFO_NV

VkFragmentShadingRateTypeNV 枚举类型指定图形管线是从 VkPipelineFragmentShadingRateEnumStateCreateInfoNV 结构体还是从 VkPipelineFragmentShadingRateStateCreateInfoKHR 结构体获取其管线片段着色率和组合器。

// Provided by VK_NV_fragment_shading_rate_enums
typedef enum VkFragmentShadingRateTypeNV {
    VK_FRAGMENT_SHADING_RATE_TYPE_FRAGMENT_SIZE_NV = 0,
    VK_FRAGMENT_SHADING_RATE_TYPE_ENUMS_NV = 1,
} VkFragmentShadingRateTypeNV;

动态设置管线片元着色率和组合器操作,请调用:

// Provided by VK_NV_fragment_shading_rate_enums
void vkCmdSetFragmentShadingRateEnumNV(
    VkCommandBuffer                             commandBuffer,
    VkFragmentShadingRateNV                     shadingRate,
    const VkFragmentShadingRateCombinerOpKHR    combinerOps[2]);

当使用 着色器对象进行绘制,或者在创建图形管线时,在 VkPipelineDynamicStateCreateInfo::pDynamicStates 中设置了 VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR 时,此命令将为后续绘制命令设置管线片段着色率和组合器操作。否则,此状态由用于创建当前活动管线的 VkPipelineFragmentShadingRateEnumStateCreateInfoNV 值指定。

此命令允许指定超出 vkCmdSetFragmentShadingRateKHR 支持的其他着色率。有关更多信息,请参阅 VK_NV_fragment_shading_rate_enums 附录。

有效使用
  • VUID-vkCmdSetFragmentShadingRateEnumNV-pipelineFragmentShadingRate-04576
    如果未启用 pipelineFragmentShadingRate 功能,则 shadingRate 必须VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_PIXEL_NV

  • VUID-vkCmdSetFragmentShadingRateEnumNV-supersampleFragmentShadingRates-04577
    如果未启用 supersampleFragmentShadingRates 功能,则 shadingRate 不能VK_FRAGMENT_SHADING_RATE_2_INVOCATIONS_PER_PIXEL_NVVK_FRAGMENT_SHADING_RATE_4_INVOCATIONS_PER_PIXEL_NVVK_FRAGMENT_SHADING_RATE_8_INVOCATIONS_PER_PIXEL_NVVK_FRAGMENT_SHADING_RATE_16_INVOCATIONS_PER_PIXEL_NV

  • VUID-vkCmdSetFragmentShadingRateEnumNV-noInvocationFragmentShadingRates-04578
    如果未启用 noInvocationFragmentShadingRates 功能,则 shadingRate 不能VK_FRAGMENT_SHADING_RATE_NO_INVOCATIONS_NV

  • VUID-vkCmdSetFragmentShadingRateEnumNV-fragmentShadingRateEnums-04579
    必须启用 fragmentShadingRateEnums 功能

  • VUID-vkCmdSetFragmentShadingRateEnumNV-pipelineFragmentShadingRate-04580
    必须启用 pipelineFragmentShadingRate primitiveFragmentShadingRate attachmentFragmentShadingRate 功能之一

  • VUID-vkCmdSetFragmentShadingRateEnumNV-primitiveFragmentShadingRate-04581
    如果 primitiveFragmentShadingRate 功能未启用,则 combinerOps[0] 必须VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR

  • VUID-vkCmdSetFragmentShadingRateEnumNV-attachmentFragmentShadingRate-04582
    如果 attachmentFragmentShadingRate 功能未启用,则 combinerOps[1] 必须VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR

  • VUID-vkCmdSetFragmentShadingRateEnumNV-fragmentSizeNonTrivialCombinerOps-04583
    如果不支持 fragmentSizeNonTrivialCombinerOps 限制,则 combinerOps 的元素必须VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHRVK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR

有效用法(隐式)
  • VUID-vkCmdSetFragmentShadingRateEnumNV-commandBuffer-parameter
    commandBuffer 必须是有效的 VkCommandBuffer 句柄。

  • VUID-vkCmdSetFragmentShadingRateEnumNV-shadingRate-parameter
    shadingRate 必须是一个有效的 VkFragmentShadingRateNV

  • VUID-vkCmdSetFragmentShadingRateEnumNV-combinerOps-parameter
    combinerOps 的每个元素必须是有效的 VkFragmentShadingRateCombinerOpKHR 值。

  • VUID-vkCmdSetFragmentShadingRateEnumNV-commandBuffer-recording
    commandBuffer 必须处于录制状态

  • VUID-vkCmdSetFragmentShadingRateEnumNV-commandBuffer-cmdpool
    commandBuffer 分配的 VkCommandPool 必须支持图形操作。

  • VUID-vkCmdSetFragmentShadingRateEnumNV-videocoding
    此命令必须仅在视频编码范围之外调用。

主机同步
  • commandBuffer 的主机访问必须进行外部同步。

  • 对从其分配 commandBufferVkCommandPool 的主机访问必须进行外部同步。

命令属性
命令缓冲区级别 渲染通道范围 视频编码范围 支持的队列类型 命令类型

主要
次要

两者

外部

图形

状态

当启用 supersampleFragmentShadingRatesnoInvocationFragmentShadingRates 功能时,着色率组合器操作的行为会扩展为支持这些功能启用的着色率。图元和附件着色率值被解释为 VkFragmentShadingRateNV 值,并且组合器的行为修改如下:

  • 对于 VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MIN_KHRVK_FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_KHRVK_FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_KHR,如果 AxyBxy 中任何一个是 VK_FRAGMENT_SHADING_RATE_NO_INVOCATIONS_NV,则 combine(Axy,Bxy) 产生一个着色率 VK_FRAGMENT_SHADING_RATE_NO_INVOCATIONS_NV,而不管另一个输入着色率如何。

  • 对于 VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MIN_KHRcombine(Axy,Bxy) 产生的着色率,其片段大小是 AxyBxy 的片段大小中较小的一个,其调用计数是 AxyBxy 的调用计数中较大的一个。

  • 对于 VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_KHRcombine(Axy,Bxy) 产生的着色率,其片段大小是 AxyBxy 的片段大小中较大的一个,其调用计数是 AxyBxy 的调用计数中较小的一个。

  • 对于 VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_KHRcombine(Axy,Bxy) 产生的着色率,其片段大小和调用计数分别是 AxyBxy 的片段大小和调用计数的乘积。如果生成的着色率在每个片段中都有多个像素和多个调用,则实现可以通过减少像素和调用计数来调整着色率。

如果来自组合器的最终着色率为 VK_FRAGMENT_SHADING_RATE_NO_INVOCATIONS_NV,则不会为使用该着色率的任何图元部分生成任何片段。

如果来自组合器的最终着色率指定每个片段有多个片段着色器调用,则该片段将按照 采样着色 中的方式用多个唯一采样进行处理,其中调用的总数从着色率中获取,然后钳制到 rasterizationSamplesmaxFragmentShadingRateInvocationCount

着色率图像

shadingRateImage 功能允许管线使用着色率图像来控制片段区域以及每个片段启动的最少片段着色器调用次数。当启用着色率图像时,光栅化器通过从着色率图像中获取一个值,并使用每个视口的着色率调色板将其转换为着色率,从而确定由图元覆盖的帧缓冲区的每个区域的基本着色率。然后调整这个基本着色率以得出最终着色率。最终着色率指定了在该区域生成的片段要使用的片段区域和片段着色器调用计数。

如果 VkPipelineViewportStateCreateInfopNext 链包含 VkPipelineViewportShadingRateImageStateCreateInfoNV 结构体,则该结构体包含控制着色率的参数。

VkPipelineViewportShadingRateImageStateCreateInfoNV 结构体定义如下:

// Provided by VK_NV_shading_rate_image
typedef struct VkPipelineViewportShadingRateImageStateCreateInfoNV {
    VkStructureType                  sType;
    const void*                      pNext;
    VkBool32                         shadingRateImageEnable;
    uint32_t                         viewportCount;
    const VkShadingRatePaletteNV*    pShadingRatePalettes;
} VkPipelineViewportShadingRateImageStateCreateInfoNV;
  • sType 是一个 VkStructureType 值,用于标识此结构。

  • pNextNULL 或指向扩展此结构的结构的指针。

  • shadingRateImageEnable 指定在光栅化期间是否使用着色率图像和调色板。

  • viewportCount 指定用于转换存储在着色率图像中的值的每个视口的调色板的数量。

  • pShadingRatePalettes 是指向一个 VkShadingRatePaletteNV 结构体数组的指针,该数组为每个视口定义调色板。如果着色率调色板状态是动态的,则忽略此成员。

如果此结构体不存在,则认为 shadingRateImageEnableVK_FALSE,并且不使用着色率图像和调色板。

有效使用
  • VUID-VkPipelineViewportShadingRateImageStateCreateInfoNV-viewportCount-02054
    如果未启用 multiViewport 功能,则 viewportCount 必须01

  • VUID-VkPipelineViewportShadingRateImageStateCreateInfoNV-viewportCount-02055
    viewportCount 必须小于或等于 VkPhysicalDeviceLimits::maxViewports

  • VUID-VkPipelineViewportShadingRateImageStateCreateInfoNV-shadingRateImageEnable-02056
    如果 shadingRateImageEnableVK_TRUE,则 viewportCount 必须大于或等于 VkPipelineViewportStateCreateInfoviewportCount 成员。

有效用法(隐式)
  • VUID-VkPipelineViewportShadingRateImageStateCreateInfoNV-sType-sType
    sType 必须VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SHADING_RATE_IMAGE_STATE_CREATE_INFO_NV

当在绑定的管线中启用着色率图像使用时,管线会使用以下命令指定的着色率图像:

// Provided by VK_NV_shading_rate_image
void vkCmdBindShadingRateImageNV(
    VkCommandBuffer                             commandBuffer,
    VkImageView                                 imageView,
    VkImageLayout                               imageLayout);
  • commandBuffer 是将记录命令的命令缓冲区。

  • imageView 是一个图像视图句柄,用于指定着色率图像。imageView 可以VK_NULL_HANDLE,这相当于指定一个填充了零值的图像视图。

  • imageLayout 是当访问着色率图像时,可以从 imageView 访问的图像子资源所处的布局。

有效使用
  • VUID-vkCmdBindShadingRateImageNV-None-02058
    必须启用 shadingRateImage 功能。

  • VUID-vkCmdBindShadingRateImageNV-imageView-02059
    如果 imageView 不是 VK_NULL_HANDLE,则它必须是类型为 VK_IMAGE_VIEW_TYPE_2DVK_IMAGE_VIEW_TYPE_2D_ARRAY 的有效的 VkImageView 句柄。

  • VUID-vkCmdBindShadingRateImageNV-imageView-02060
    如果 imageView 不是 VK_NULL_HANDLE,则它必须具有 VK_FORMAT_R8_UINT 格式。

  • VUID-vkCmdBindShadingRateImageNV-imageView-02061
    如果 imageView 不是 VK_NULL_HANDLE,则创建它时使用的 usage必须包含 VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV

  • VUID-vkCmdBindShadingRateImageNV-imageView-02062
    如果 imageView 不是 VK_NULL_HANDLE,则 imageLayout 必须与访问子资源时可以从 imageView 访问的每个子资源的实际 VkImageLayout 匹配。

  • VUID-vkCmdBindShadingRateImageNV-imageLayout-02063
    如果 imageView 不是 VK_NULL_HANDLE,则 imageLayout 必须VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NVVK_IMAGE_LAYOUT_GENERAL

有效用法(隐式)
  • VUID-vkCmdBindShadingRateImageNV-commandBuffer-parameter
    commandBuffer 必须是有效的 VkCommandBuffer 句柄。

  • VUID-vkCmdBindShadingRateImageNV-imageView-parameter
    如果 imageView 不是 VK_NULL_HANDLE,则 imageView 必须是有效的 VkImageView 句柄。

  • VUID-vkCmdBindShadingRateImageNV-imageLayout-parameter
    imageLayout 必须是有效的 VkImageLayout 值。

  • VUID-vkCmdBindShadingRateImageNV-commandBuffer-recording
    commandBuffer 必须处于录制状态

  • VUID-vkCmdBindShadingRateImageNV-commandBuffer-cmdpool
    commandBuffer 分配的 VkCommandPool 必须支持图形操作。

  • VUID-vkCmdBindShadingRateImageNV-videocoding
    此命令必须仅在视频编码范围之外调用。

  • VUID-vkCmdBindShadingRateImageNV-commonparent
    commandBufferimageView 中有效的非忽略参数的句柄必须已从同一个 VkDevice 创建、分配或检索。

主机同步
  • commandBuffer 的主机访问必须进行外部同步。

  • 对从其分配 commandBufferVkCommandPool 的主机访问必须进行外部同步。

命令属性
命令缓冲区级别 渲染通道范围 视频编码范围 支持的队列类型 命令类型

主要
次要

两者

外部

图形

状态

When the shading rate image is enabled in the current pipeline, rasterizing a primitive covering the pixel with coordinates (x,y) will fetch a shading rate index value from the shading rate image bound by vkCmdBindShadingRateImageNV. If the shading rate image view has a type of VK_IMAGE_VIEW_TYPE_2D, the lookup will use texel coordinates (u,v) where \(u = \left\lfloor \frac{x}{twidth} \right\rfloor\), \(v = \left\lfloor \frac{y}{theight} \right\rfloor\), and and are the width and height of the implementation-dependent shading rate texel size. If the shading rate image view has a type of VK_IMAGE_VIEW_TYPE_2D_ARRAY, the lookup will use texel coordinates (u,v) to extract a texel from the layer l, where l is the layer of the framebuffer being rendered to. If l is greater than or equal to the number of layers in the image view, layer zero will be used.

如果绑定的着色率图像视图不是 VK_NULL_HANDLE,并且包含层 *l*(如果适用)中坐标为 (*u*, *v*) 的纹素,则该纹素的单个无符号整数分量将用作着色率索引。如果 (*u*, *v*) 坐标在着色率图像视图使用的子资源的范围之外,或者如果图像视图是 VK_NULL_HANDLE,则着色率索引为零。如果着色率图像视图有多个 mipmap 级别,则将使用 VkImageSubresourceRange::baseMipLevel 标识的基本级别。

着色率索引使用一个名为着色率图像调色板的查找表映射到基本着色率。每个视口都有一个单独的调色板。每个调色板中的条目数由实现相关的着色率图像调色板大小给出。

动态设置 shadingRateImageEnable 状态,请调用

// Provided by VK_EXT_extended_dynamic_state3 with VK_NV_shading_rate_image, VK_EXT_shader_object with VK_NV_shading_rate_image
void vkCmdSetShadingRateImageEnableNV(
    VkCommandBuffer                             commandBuffer,
    VkBool32                                    shadingRateImageEnable);
  • commandBuffer 是将记录命令的命令缓冲区。

  • shadingRateImageEnable 指定 shadingRateImageEnable 状态。

当使用着色器对象进行绘制时,或者当使用在VkPipelineDynamicStateCreateInfo::pDynamicStates中设置了VK_DYNAMIC_STATE_SHADING_RATE_IMAGE_ENABLE_NV的图形管线创建时,此命令为后续的绘图命令设置 shadingRateImageEnable 状态。 否则,此状态由用于创建当前活动管线的VkPipelineViewportShadingRateImageStateCreateInfoNV::shadingRateImageEnable 值指定。

有效使用
有效用法(隐式)
  • VUID-vkCmdSetShadingRateImageEnableNV-commandBuffer-parameter
    commandBuffer 必须是有效的 VkCommandBuffer 句柄。

  • VUID-vkCmdSetShadingRateImageEnableNV-commandBuffer-recording
    commandBuffer 必须处于录制状态

  • VUID-vkCmdSetShadingRateImageEnableNV-commandBuffer-cmdpool
    commandBuffer 分配的 VkCommandPool 必须支持图形操作。

  • VUID-vkCmdSetShadingRateImageEnableNV-videocoding
    此命令必须仅在视频编码范围之外调用。

主机同步
  • commandBuffer 的主机访问必须进行外部同步。

  • 对从其分配 commandBufferVkCommandPool 的主机访问必须进行外部同步。

命令属性
命令缓冲区级别 渲染通道范围 视频编码范围 支持的队列类型 命令类型

主要
次要

两者

外部

图形

状态

动态设置每个视口的着色率图像调色板,请调用

// Provided by VK_NV_shading_rate_image
void vkCmdSetViewportShadingRatePaletteNV(
    VkCommandBuffer                             commandBuffer,
    uint32_t                                    firstViewport,
    uint32_t                                    viewportCount,
    const VkShadingRatePaletteNV*               pShadingRatePalettes);
  • commandBuffer 是将记录命令的命令缓冲区。

  • firstViewport 是此命令更新其着色率调色板的第一个视口的索引。

  • viewportCount 是此命令更新其着色率调色板的视口数。

  • pShadingRatePalettes 是一个指向 VkShadingRatePaletteNV 结构的数组的指针,这些结构定义了每个视口的调色板。

当使用着色器对象进行绘制时,或者当使用在VkPipelineDynamicStateCreateInfo::pDynamicStates中设置了VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV的图形管线创建时,此命令为后续的绘图命令设置每个视口的着色率图像调色板。 否则,此状态由用于创建当前活动管线的VkPipelineViewportShadingRateImageStateCreateInfoNV::pShadingRatePalettes值指定。

有效使用
  • VUID-vkCmdSetViewportShadingRatePaletteNV-None-02064
    必须启用 shadingRateImage 功能。

  • VUID-vkCmdSetViewportShadingRatePaletteNV-firstViewport-02067
    firstViewportviewportCount 的总和**必须**介于 1VkPhysicalDeviceLimits::maxViewports 之间(包括两者)

  • VUID-vkCmdSetViewportShadingRatePaletteNV-firstViewport-02068
    如果未启用multiViewport功能,则 firstViewport **必须**为 0

  • VUID-vkCmdSetViewportShadingRatePaletteNV-viewportCount-02069
    如果未启用multiViewport功能,则 viewportCount **必须**为 1

有效用法(隐式)
  • VUID-vkCmdSetViewportShadingRatePaletteNV-commandBuffer-parameter
    commandBuffer 必须是有效的 VkCommandBuffer 句柄。

  • VUID-vkCmdSetViewportShadingRatePaletteNV-pShadingRatePalettes-parameter
    pShadingRatePalettes **必须**是指向 viewportCount 个有效 VkShadingRatePaletteNV 结构的数组的有效指针

  • VUID-vkCmdSetViewportShadingRatePaletteNV-commandBuffer-recording
    commandBuffer 必须处于录制状态

  • VUID-vkCmdSetViewportShadingRatePaletteNV-commandBuffer-cmdpool
    commandBuffer 分配的 VkCommandPool 必须支持图形操作。

  • VUID-vkCmdSetViewportShadingRatePaletteNV-videocoding
    此命令必须仅在视频编码范围之外调用。

  • VUID-vkCmdSetViewportShadingRatePaletteNV-viewportCount-arraylength
    viewportCount **必须**大于 0

主机同步
  • commandBuffer 的主机访问必须进行外部同步。

  • 对从其分配 commandBufferVkCommandPool 的主机访问必须进行外部同步。

命令属性
命令缓冲区级别 渲染通道范围 视频编码范围 支持的队列类型 命令类型

主要
次要

两者

外部

图形

状态

VkShadingRatePaletteNV 结构指定单个着色率图像调色板的内容,定义如下:

// Provided by VK_NV_shading_rate_image
typedef struct VkShadingRatePaletteNV {
    uint32_t                              shadingRatePaletteEntryCount;
    const VkShadingRatePaletteEntryNV*    pShadingRatePaletteEntries;
} VkShadingRatePaletteNV;
  • shadingRatePaletteEntryCount 指定着色率图像调色板中的条目数。

  • pShadingRatePaletteEntries 是一个指向 VkShadingRatePaletteEntryNV 枚举数组的指针,这些枚举定义了每个调色板条目的着色率。

有效使用
  • VUID-VkShadingRatePaletteNV-shadingRatePaletteEntryCount-02071
    shadingRatePaletteEntryCount **必须**介于 1VkPhysicalDeviceShadingRateImagePropertiesNV::shadingRatePaletteSize 之间(包括两者)

有效用法(隐式)
  • VUID-VkShadingRatePaletteNV-pShadingRatePaletteEntries-parameter
    pShadingRatePaletteEntries **必须**是指向 shadingRatePaletteEntryCount 个有效 VkShadingRatePaletteEntryNV 值的数组的有效指针

  • VUID-VkShadingRatePaletteNV-shadingRatePaletteEntryCount-arraylength
    shadingRatePaletteEntryCount **必须**大于 0

为了确定基本着色率图像,着色率索引 *i* 被映射到与该片段所使用的视口对应的调色板的数组 pShadingRatePaletteEntries 中的数组元素 *i*。 如果 *i* 大于或等于调色板大小 shadingRatePaletteEntryCount,则基本着色率**未定义**。

支持的着色率图像调色板条目由 VkShadingRatePaletteEntryNV 定义

// Provided by VK_NV_shading_rate_image
typedef enum VkShadingRatePaletteEntryNV {
    VK_SHADING_RATE_PALETTE_ENTRY_NO_INVOCATIONS_NV = 0,
    VK_SHADING_RATE_PALETTE_ENTRY_16_INVOCATIONS_PER_PIXEL_NV = 1,
    VK_SHADING_RATE_PALETTE_ENTRY_8_INVOCATIONS_PER_PIXEL_NV = 2,
    VK_SHADING_RATE_PALETTE_ENTRY_4_INVOCATIONS_PER_PIXEL_NV = 3,
    VK_SHADING_RATE_PALETTE_ENTRY_2_INVOCATIONS_PER_PIXEL_NV = 4,
    VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_PIXEL_NV = 5,
    VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X1_PIXELS_NV = 6,
    VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_1X2_PIXELS_NV = 7,
    VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X2_PIXELS_NV = 8,
    VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X2_PIXELS_NV = 9,
    VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X4_PIXELS_NV = 10,
    VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X4_PIXELS_NV = 11,
} VkShadingRatePaletteEntryNV;

下表显示了使用指示的着色率生成的每个片段的宽度和高度(以像素为单位),以及为每个片段启动的最大片段着色器调用次数。当处理着色率为 VK_SHADING_RATE_PALETTE_ENTRY_NO_INVOCATIONS_NV 的图元区域时,将不会在该区域中生成任何片段。

着色率 宽度 高度 调用

VK_SHADING_RATE_PALETTE_ENTRY_NO_INVOCATIONS_NV

0

0

0

VK_SHADING_RATE_PALETTE_ENTRY_16_INVOCATIONS_PER_PIXEL_NV

1

1

16

VK_SHADING_RATE_PALETTE_ENTRY_8_INVOCATIONS_PER_PIXEL_NV

1

1

8

VK_SHADING_RATE_PALETTE_ENTRY_4_INVOCATIONS_PER_PIXEL_NV

1

1

4

VK_SHADING_RATE_PALETTE_ENTRY_2_INVOCATIONS_PER_PIXEL_NV

1

1

2

VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_PIXEL_NV

1

1

1

VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X1_PIXELS_NV

2

1

1

VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_1X2_PIXELS_NV

1

2

1

VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X2_PIXELS_NV

2

2

1

VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X2_PIXELS_NV

4

2

1

VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X4_PIXELS_NV

2

4

1

VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X4_PIXELS_NV

4

4

1

当禁用着色率图像时,将使用 VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_PIXEL_NV 的着色率作为基本着色率。

一旦确定了基础着色率,就会对其进行调整以产生最终的着色率。首先,如果基础着色率对每个片元使用多个像素,则实现可能会减少片元区域,以确保一个片元中所有像素的覆盖样本总数不超过与实现相关的最大值

如果当前管线中启用了采样着色,并且在禁用着色率图像时,每个片元将导致处理n (n > 1) 个唯一样本,则会以依赖于实现的方式调整着色率,以增加由图元产生的片元着色器调用次数。如果着色率指示每个片元fs 个像素,且fs 大于 n,则会调整片元区域,使每个片元大约有 个像素。否则,如果着色率指示每个片元ipf 次调用,则片元区域将调整为单个像素,每个片元大约有 次调用。

如果由于使用以 SampleIdSamplePosition 修饰的片元着色器输入变量而发生采样着色,则会忽略着色率。每个片元将只有一个像素,并会生成多达 rasterizationSamples 个片元着色器调用,就像在使用 采样着色 而不使用着色率图像时一样。

最后,如果着色率指定每个片元有多个片元着色器调用,则着色率中的调用总数将被限制为不大于 rasterizationSamples

当覆盖像素 (x,y) 的图元的最终着色率的片元区域为 , 则该像素的片元将覆盖满足以下方程的所有坐标为 (x',y') 的像素

此组合片元被认为具有多个覆盖采样;此片元中的采样总数由 \(samples = fw \times fh \times rs\) 给出,其中 rs 表示管道创建时指定的 VkPipelineMultisampleStateCreateInfo::rasterizationSamples 的值。片元中的覆盖采样集是片元中每个像素的每个像素覆盖采样的并集。组合片元中每个像素内的覆盖采样位置和顺序按照 多重采样自定义采样位置 中所述进行分配。属于组合片元的像素集中的每个覆盖采样都被分配一个唯一的 覆盖索引,范围为 [0,samples-1]。如果支持 shadingRateCoarseSampleOrder 特性,则可以为片元区域和覆盖采样计数的每种组合指定覆盖采样的顺序。如果不支持此特性,则采样顺序是实现相关的。

如果 VkPipelineViewportStateCreateInfopNext 链包含 VkPipelineViewportCoarseSampleOrderStateCreateInfoNV 结构,则该结构包含控制大于一个像素的片元中覆盖采样顺序的参数。

VkPipelineViewportCoarseSampleOrderStateCreateInfoNV 结构的定义如下:

// Provided by VK_NV_shading_rate_image
typedef struct VkPipelineViewportCoarseSampleOrderStateCreateInfoNV {
    VkStructureType                       sType;
    const void*                           pNext;
    VkCoarseSampleOrderTypeNV             sampleOrderType;
    uint32_t                              customSampleOrderCount;
    const VkCoarseSampleOrderCustomNV*    pCustomSampleOrders;
} VkPipelineViewportCoarseSampleOrderStateCreateInfoNV;
  • sType 是一个 VkStructureType 值,用于标识此结构。

  • pNextNULL 或指向扩展此结构的结构的指针。

  • sampleOrderType 指定用于对大于一个像素的片元中的覆盖采样进行排序的机制。

  • customSampleOrderCount 指定在排序覆盖采样时要使用的自定义采样顺序的数量。

  • pCustomSampleOrders 是指向 customSampleOrderCountVkCoarseSampleOrderCustomNV 结构的数组的指针,每个结构指定片元区域和覆盖采样计数的单个组合的覆盖采样顺序。

如果不存在此结构,则认为 sampleOrderTypeVK_COARSE_SAMPLE_ORDER_TYPE_DEFAULT_NV

如果 sampleOrderTypeVK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV,则在 pCustomSampleOrders 中未枚举的片元区域和覆盖采样计数的任何组合使用的覆盖采样顺序将与 VK_COARSE_SAMPLE_ORDER_TYPE_DEFAULT_NV 使用的覆盖采样顺序相同。

如果管道创建时使用了 VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV,则忽略此结构(如果存在)的内容,并且覆盖采样顺序改为由 vkCmdSetCoarseSampleOrderNV 指定。

有效使用
  • VUID-VkPipelineViewportCoarseSampleOrderStateCreateInfoNV-sampleOrderType-02072
    如果 sampleOrderType 不是 VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV,则 customSamplerOrderCount 必须0

  • VUID-VkPipelineViewportCoarseSampleOrderStateCreateInfoNV-pCustomSampleOrders-02234
    数组 pCustomSampleOrders 必须不包含 shadingRatesampleCount 成员的值都匹配的两个结构

有效用法(隐式)
  • VUID-VkPipelineViewportCoarseSampleOrderStateCreateInfoNV-sType-sType
    sType 必须VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_COARSE_SAMPLE_ORDER_STATE_CREATE_INFO_NV

  • VUID-VkPipelineViewportCoarseSampleOrderStateCreateInfoNV-sampleOrderType-parameter
    sampleOrderType 必须是有效的 VkCoarseSampleOrderTypeNV

  • VUID-VkPipelineViewportCoarseSampleOrderStateCreateInfoNV-pCustomSampleOrders-parameter
    如果 customSampleOrderCount 不为 0,则 pCustomSampleOrders 必须是指向 customSampleOrderCount 个有效的 VkCoarseSampleOrderCustomNV 结构的数组的有效指针

类型 VkCoarseSampleOrderTypeNV 指定用于对大于一个像素的片元中的覆盖采样进行排序的技术,并定义为

// Provided by VK_NV_shading_rate_image
typedef enum VkCoarseSampleOrderTypeNV {
    VK_COARSE_SAMPLE_ORDER_TYPE_DEFAULT_NV = 0,
    VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV = 1,
    VK_COARSE_SAMPLE_ORDER_TYPE_PIXEL_MAJOR_NV = 2,
    VK_COARSE_SAMPLE_ORDER_TYPE_SAMPLE_MAJOR_NV = 3,
} VkCoarseSampleOrderTypeNV;
  • VK_COARSE_SAMPLE_ORDER_TYPE_DEFAULT_NV 指定覆盖采样将以实现定义的方式排序。

  • VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV 指定覆盖采样将根据 VkPipelineViewportCoarseSampleOrderStateCreateInfoNVpCustomSampleOrders 成员或 vkCmdSetCoarseSampleOrderNVpCustomSampleOrders 成员中提供的自定义排序数组进行排序。

  • VK_COARSE_SAMPLE_ORDER_TYPE_PIXEL_MAJOR_NV 指定覆盖采样将按顺序排序,首先按像素坐标(按行主序),然后按采样索引排序。

  • VK_COARSE_SAMPLE_ORDER_TYPE_SAMPLE_MAJOR_NV 指定覆盖采样将按顺序排序,首先按采样索引排序,然后按像素坐标(按行主序)排序。

When using a coarse sample order of VK_COARSE_SAMPLE_ORDER_TYPE_PIXEL_MAJOR_NV for a fragment with an upper-left corner of with a width of \(fw \times fh\) and samples per pixel, coverage index of the fragment will be assigned to sample index of pixel as follows

当使用粗采样顺序 VK_COARSE_SAMPLE_ORDER_TYPE_SAMPLE_MAJOR_NV 时,覆盖索引 将按如下方式分配

VkCoarseSampleOrderCustomNV 结构的定义如下:

// Provided by VK_NV_shading_rate_image
typedef struct VkCoarseSampleOrderCustomNV {
    VkShadingRatePaletteEntryNV        shadingRate;
    uint32_t                           sampleCount;
    uint32_t                           sampleLocationCount;
    const VkCoarseSampleLocationNV*    pSampleLocations;
} VkCoarseSampleOrderCustomNV;
  • shadingRate 是一个着色率调色板条目,用于标识片段区域和每个像素覆盖采样计数组合的片段宽度和高度,以进行控制。

  • sampleCount 标识片段区域和覆盖采样计数组合的每个像素覆盖采样计数,以进行控制。

  • sampleLocationCount 指定自定义排序中采样位置的数量。

  • pSampleLocations 是指向 VkCoarseSampleLocationNV 结构数组的指针,该数组指定自定义排序中每个采样位置的位置。

VkCoarseSampleOrderCustomNV 结构与 VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV 的覆盖采样排序类型一起使用,以指定片段宽度、片段高度和覆盖采样计数的一个组合的覆盖采样顺序。

当使用自定义采样排序时,pSampleLocations 中的元素 *j* 指定一个特定的像素位置和采样索引,该位置和索引对应于多像素片段中的覆盖索引 *j*。

有效使用
  • VUID-VkCoarseSampleOrderCustomNV-shadingRate-02073
    shadingRate **必须**是一个生成具有多个像素的片段的着色率

  • VUID-VkCoarseSampleOrderCustomNV-sampleCount-02074
    sampleCount **必须**对应于 VkSampleCountFlags 中枚举的采样计数,该采样计数对应的位在 VkPhysicalDeviceLimits::framebufferNoAttachmentsSampleCounts 中设置

  • VUID-VkCoarseSampleOrderCustomNV-sampleLocationCount-02075
    sampleLocationCount **必须**等于 sampleCountshadingRate 的片段宽度和 shadingRate 的片段高度的乘积

  • VUID-VkCoarseSampleOrderCustomNV-sampleLocationCount-02076
    sampleLocationCount **必须**小于或等于 VkPhysicalDeviceShadingRateImagePropertiesNV::shadingRateMaxCoarseSamples 的值

  • VUID-VkCoarseSampleOrderCustomNV-pSampleLocations-02077
    数组 pSampleLocations **必须**为结构 VkCoarseSampleOrderCustomNVpixelXpixelYsample 的有效值的所有组合包含恰好一个条目

有效用法(隐式)
  • VUID-VkCoarseSampleOrderCustomNV-shadingRate-parameter
    shadingRate **必须**是有效的 VkShadingRatePaletteEntryNV

  • VUID-VkCoarseSampleOrderCustomNV-pSampleLocations-parameter
    pSampleLocations **必须**是指向 sampleLocationCount VkCoarseSampleLocationNV 结构数组的有效指针

  • VUID-VkCoarseSampleOrderCustomNV-sampleLocationCount-arraylength
    sampleLocationCount **必须**大于 0

VkCoarseSampleLocationNV 结构标识一个特定像素和采样索引,该索引用于大于一个像素的片段中的覆盖采样之一。此结构的定义如下:

// Provided by VK_NV_shading_rate_image
typedef struct VkCoarseSampleLocationNV {
    uint32_t    pixelX;
    uint32_t    pixelY;
    uint32_t    sample;
} VkCoarseSampleLocationNV;
  • pixelX 被添加到每个片段最左上角像素的 x 坐标,以标识包含覆盖采样的像素。

  • pixelY 被添加到每个片段最左上角像素的 y 坐标,以标识包含覆盖采样的像素。

  • sample 是由 pixelXpixelY 标识的像素中的覆盖采样的编号。

有效使用
  • VUID-VkCoarseSampleLocationNV-pixelX-02078
    pixelX **必须**小于片段的宽度(以像素为单位)

  • VUID-VkCoarseSampleLocationNV-pixelY-02079
    pixelY **必须**小于片段的高度(以像素为单位)

  • VUID-VkCoarseSampleLocationNV-sample-02080
    sample **必须**小于属于该片段的每个像素中的覆盖采样数

动态设置大于一个像素的片段中的覆盖采样顺序,请调用

// Provided by VK_NV_shading_rate_image
void vkCmdSetCoarseSampleOrderNV(
    VkCommandBuffer                             commandBuffer,
    VkCoarseSampleOrderTypeNV                   sampleOrderType,
    uint32_t                                    customSampleOrderCount,
    const VkCoarseSampleOrderCustomNV*          pCustomSampleOrders);
  • commandBuffer 是将记录命令的命令缓冲区。

  • sampleOrderType 指定用于对大于一个像素的片元中的覆盖采样进行排序的机制。

  • customSampleOrderCount 指定在排序覆盖采样时要使用的自定义采样顺序的数量。

  • pCustomSampleOrders 是指向 VkCoarseSampleOrderCustomNV 结构体数组的指针,每个结构体指定了单个片段区域和覆盖样本计数的组合的覆盖样本顺序。

如果 sampleOrderTypeVK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV,则在 pCustomSampleOrders 中未枚举的片元区域和覆盖采样计数的任何组合使用的覆盖采样顺序将与 VK_COARSE_SAMPLE_ORDER_TYPE_DEFAULT_NV 使用的覆盖采样顺序相同。

当使用着色器对象进行绘制时,或者当图形管线在 VkPipelineDynamicStateCreateInfo::pDynamicStates 中设置了 VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV 时,此命令会为后续绘制命令设置覆盖样本的顺序。 否则,此状态由用于创建当前活动管线的 VkPipelineViewportCoarseSampleOrderStateCreateInfoNV 值指定。

有效使用
  • VUID-vkCmdSetCoarseSampleOrderNV-sampleOrderType-02081
    如果 sampleOrderType 不是 VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV,则 customSamplerOrderCount 必须0

  • VUID-vkCmdSetCoarseSampleOrderNV-pCustomSampleOrders-02235
    数组 pCustomSampleOrders 必须不包含 shadingRatesampleCount 成员的值都匹配的两个结构

有效用法(隐式)
  • VUID-vkCmdSetCoarseSampleOrderNV-commandBuffer-parameter
    commandBuffer 必须是有效的 VkCommandBuffer 句柄。

  • VUID-vkCmdSetCoarseSampleOrderNV-sampleOrderType-parameter
    sampleOrderType 必须是有效的 VkCoarseSampleOrderTypeNV

  • VUID-vkCmdSetCoarseSampleOrderNV-pCustomSampleOrders-parameter
    如果 customSampleOrderCount 不为 0,则 pCustomSampleOrders 必须是指向 customSampleOrderCount 个有效的 VkCoarseSampleOrderCustomNV 结构的数组的有效指针

  • VUID-vkCmdSetCoarseSampleOrderNV-commandBuffer-recording
    commandBuffer 必须处于录制状态

  • VUID-vkCmdSetCoarseSampleOrderNV-commandBuffer-cmdpool
    commandBuffer 分配的 VkCommandPool 必须支持图形操作。

  • VUID-vkCmdSetCoarseSampleOrderNV-videocoding
    此命令必须仅在视频编码范围之外调用。

主机同步
  • commandBuffer 的主机访问必须进行外部同步。

  • 对从其分配 commandBufferVkCommandPool 的主机访问必须进行外部同步。

命令属性
命令缓冲区级别 渲染通道范围 视频编码范围 支持的队列类型 命令类型

主要
次要

两者

外部

图形

状态

如果覆盖像素(xy)的图元的最终着色率导致每个像素 n 个调用(n > 1),则会为该片段生成 n 个单独的片段着色器调用。片段中的每个覆盖样本将以依赖于实现的方式分配给 n 个片段着色器调用之一。每个着色器调用的片段输出接口的输出将被广播到与该调用关联的所有帧缓冲区样本。如果与片段着色器调用关联的覆盖样本均未被图元覆盖,则实现可以丢弃这些样本的片段着色器调用。

如果覆盖像素(xy)的图元的最终着色率导致一个片段包含多个像素,则将为组合片段中的所有像素生成一组片段着色器调用。来自片段输出接口的输出将广播到属于该片段的所有被覆盖的帧缓冲区样本。如果片段着色器执行代码丢弃了该片段,则不会更新该片段的任何样本。

样本着色

样本着色可以用于指定每个片段要处理的最小唯一样本数。如果启用了样本着色,则实现必须为每个片段至少调用片段着色器 max(⌈ VkPipelineMultisampleStateCreateInfo::minSampleShading × VkPipelineMultisampleStateCreateInfo::rasterizationSamples ⌉, 1) 次。如果 VkPipelineMultisampleStateCreateInfo::sampleShadingEnableVK_TRUE,则启用样本着色。

如果片段着色器入口点静态使用SampleIdSamplePositionBuiltIn 修饰的输入变量,则启用样本着色,并且使用值 1.0 代替 minSampleShading。如果片段着色器入口点静态使用Sample 修饰的输入变量,则可以启用样本着色,并且如果启用,则使用值 1.0 代替 minSampleShading。 如果启用了 VK_AMD_mixed_attachment_samples 扩展,并且子通道使用颜色附件,则使用用于创建每个颜色附件的 samples 值代替 rasterizationSamples

如果着色器使用 Sample 修饰输入变量,并且该值对着色器的输出产生有意义的影响,则将启用样本着色,以确保实际上对每个样本进行插值。 这是规范固有的,这里没有明确说明 - 如果应用程序只是声明了这样的变量,则是否启用样本着色是实现定义的。可以通过在着色器中使用原子操作或使用管道统计查询来查询片段调用的数量来查看其效果,即使着色器本身不使用任何每个样本变量也是如此。

如果片段调用少于被覆盖的样本,则只要被覆盖的样本至少都被着色一次,并且每个不是辅助调用的调用都至少覆盖一个样本,则实现可以以任何方式将这些样本包含在片段着色器调用中。

重心插值

启用 fragmentShaderBarycentric 功能后,PerVertexKHR 插值修饰可以与片段着色器输入一起使用,以指示修饰的输入在片段中没有关联的数据。此类输入只能在片段着色器中使用数组索引进行访问,该数组索引的值(0、1 或 2)标识生成片段的图元的顶点之一。读取丢失顶点的每个顶点值(例如,直线图元的第三个顶点)将从具有最高索引的有效顶点返回值。这意味着点图元的索引 1 和 2 的每个顶点值将等于索引 0 的值,而直线图元的索引 2 的每个顶点值将等于索引 1 的值。

细分曲面几何着色网格着色未激活时,使用 PerVertexKHR 修饰的片段着色器输入将从生成片段的图元的其中一个顶点获取值,该顶点由 SPIR-V 代码访问输入时提供的额外索引标识。如果传递给绘制调用的 n 个顶点编号为 0 到 n-1,并且绘制调用生成的点、线和三角形图元使用从零开始的连续整数编号,则下表指示当provoking vertex modeVK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT 时,索引值 0、1 和 2 所使用的原始顶点编号。如果使用任何其他顶点索引值访问使用 PerVertexKHR 修饰的输入,或者在光栅化多边形时访问,并且当前活动管线的VkPipelineRasterizationStateCreateInfo::polygonMode属性不是 VK_POLYGON_MODE_FILL,则返回一个未定义的值。

图元拓扑 顶点 0 顶点 1 顶点 2

VK_PRIMITIVE_TOPOLOGY_POINT_LIST

i

i

i

VK_PRIMITIVE_TOPOLOGY_LINE_LIST

2i

2i+1

2i+1

VK_PRIMITIVE_TOPOLOGY_LINE_STRIP

i

i+1

i+1

VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST

3i

3i+1

3i+2

VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP(偶数)

i

i+1

i+2

VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP(奇数)

i

i+2

i+1

VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN

i+1

i+2

0

VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY

4i+1

4i+2

4i+2

VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY

i+1

i+2

i+2

VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY

6i

6i+2

6i+4

VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY(偶数)

2i

2i+2

2i+4

VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY(奇数)

2i

2i+4

2i+2

当 provoking vertex mode 为 VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT 时,使用的原始顶点编号与上面的相同,但下表中指出的情况除外。

图元拓扑 顶点 0 顶点 1 顶点 2

VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP(奇数,并且VkPhysicalDeviceFragmentShaderBarycentricPropertiesKHRtriStripVertexOrderIndependentOfProvokingVertexVK_FALSE

i+1

i

i+2

VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN

0

i+1

i+2

VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY(奇数)

2i+2

2i

2i+4

当几何或网格着色激活时,片段着色器处理的图元是从几何或网格着色器发出的顶点组装而成的。在这种情况下,用于使用 PerVertexKHR 修饰的片段着色器输入的顶点是通过将着色器生成的图元视为好像它们是由绘制调用指定的,并参考上表来得出的。

当使用细分曲面而不使用几何着色时,细分器以实现相关的方式生成图元。虽然对于使用 PerVertexKHR 修饰的输入没有定义的顶点排序,但在这种情况下使用的顶点排序将与用于得出使用 BaryCoordKHRBaryCoordNoPerspKHR 修饰的输入的值的排序保持一致。

使用 BaryCoordKHRBaryCoordNoPerspKHR 修饰的片段着色器输入保存三组件向量,其中包含重心权重,指示片段相对于其图元的顶点的屏幕空间位置的位置。对于点图元,此类变量始终被赋值为 (1,0,0)。对于线图元,内置是通过内插属性获得的,该属性的顶点编号为 0 和 1 的值分别为 (1,0,0)(0,1,0)。对于多边形图元,内置是通过内插属性获得的,该属性的顶点编号为 0、1 和 2 的值分别为 (1,0,0)(0,1,0)(0,0,1)。对于 BaryCoordKHR,这些值是使用透视内插获得的。对于 BaryCoordNoPerspKHR,这些值是使用线性内插获得的。当光栅化多边形时,并且当前活动管线的VkPipelineRasterizationStateCreateInfo::polygonMode属性不是 VK_POLYGON_MODE_FILL时,BaryCoordKHRBaryCoordNoPerspKHR 的值是未定义的。

通过生成一组以点顶点为中心的方形形状的片段来绘制点。每个顶点都有一个关联的点大小,用于控制该正方形的宽度/高度。点大小取自(可能被裁剪的)着色器内置变量 PointSize,该变量由以下着色器写入:

  • 几何着色器(如果激活);

  • 细分曲面计算着色器(如果激活且没有几何着色器激活);

  • 否则为顶点着色器

并钳制到实现相关的点大小范围 [pointSizeRange[0],pointSizeRange[1]]。写入 PointSize 的值必须大于零。如果启用了maintenance5 功能,并且没有写入 PointSize 的值,则点大小将采用默认值 1.0。

并非所有点大小都需要支持,但必须支持大小 1.0。支持的大小范围和该范围内均匀间隔的梯度大小取决于实现。范围和梯度是从VkPhysicalDeviceLimitspointSizeRangepointSizeGranularity 成员中获得的。例如,如果大小范围是从 0.1 到 2.0,并且梯度大小为 0.1,则支持大小 0.1、0.2、…、1.9、2.0。可能还支持其他点大小。没有要求这些大小均匀间隔。如果请求了不支持的大小,则会使用最近的支持大小。

此外,如果渲染通道具有片段密度图附件,则实现可能会将点大小舍入为片段宽度或高度的倍数。

基本点光栅化

点光栅化为每个帧缓冲像素的片段区域组生成一个片段,该组具有与以点的 (xf,yf) 为中心的区域相交的一个或多个采样点。该区域是一个边长等于当前点大小的正方形。与该区域相交的采样点对应的覆盖位为 1,其他覆盖位为 0。光栅化点产生的所有片段都被分配相同的关联数据,这些数据是与该点对应的顶点的数据。但是,片段着色器内置变量 PointCoord 包含点精灵纹理坐标。 st 点精灵纹理坐标在点上水平从左到右和垂直从上到下从零到一变化。以下公式用于评估 st

其中 size 是点的大小; (xp,yp) 是评估点精灵坐标的位置 - 这可能是片段中心的帧缓冲区坐标,或者是采样点的位置;而 (xf,yf) 是点的顶点的精确、未舍入的帧缓冲区坐标。

线段

线段光栅化选项由 VkPipelineRasterizationLineStateCreateInfo 结构体控制。

VkPipelineRasterizationLineStateCreateInfo 结构体定义如下:

// Provided by VK_VERSION_1_4
typedef struct VkPipelineRasterizationLineStateCreateInfo {
    VkStructureType            sType;
    const void*                pNext;
    VkLineRasterizationMode    lineRasterizationMode;
    VkBool32                   stippledLineEnable;
    uint32_t                   lineStippleFactor;
    uint16_t                   lineStipplePattern;
} VkPipelineRasterizationLineStateCreateInfo;

或等效于:

// Provided by VK_KHR_line_rasterization
typedef VkPipelineRasterizationLineStateCreateInfo VkPipelineRasterizationLineStateCreateInfoKHR;

或等效于:

// Provided by VK_EXT_line_rasterization
typedef VkPipelineRasterizationLineStateCreateInfo VkPipelineRasterizationLineStateCreateInfoEXT;
  • sType 是一个 VkStructureType 值,用于标识此结构。

  • pNextNULL 或指向扩展此结构的结构的指针。

  • lineRasterizationMode 是一个 VkLineRasterizationMode 值,用于选择线光栅化的样式。

  • stippledLineEnable 启用虚线光栅化

  • lineStippleFactor 是虚线光栅化中使用的重复因子。

  • lineStipplePattern 是虚线光栅化中使用的位模式。

如果 stippledLineEnableVK_FALSE,则 lineStippleFactorlineStipplePattern 的值将被忽略。

有效使用
  • VUID-VkPipelineRasterizationLineStateCreateInfo-lineRasterizationMode-02768
    如果 lineRasterizationModeVK_LINE_RASTERIZATION_MODE_RECTANGULAR,则 rectangularLines 特性必须启用。

  • VUID-VkPipelineRasterizationLineStateCreateInfo-lineRasterizationMode-02769
    如果 lineRasterizationModeVK_LINE_RASTERIZATION_MODE_BRESENHAM,则 bresenhamLines 特性必须启用。

  • VUID-VkPipelineRasterizationLineStateCreateInfo-lineRasterizationMode-02770
    如果 lineRasterizationModeVK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH,则 smoothLines 特性必须启用。

  • VUID-VkPipelineRasterizationLineStateCreateInfo-stippledLineEnable-02771
    如果 stippledLineEnableVK_TRUElineRasterizationModeVK_LINE_RASTERIZATION_MODE_RECTANGULAR,则 stippledRectangularLines 特性必须启用。

  • VUID-VkPipelineRasterizationLineStateCreateInfo-stippledLineEnable-02772
    如果 stippledLineEnableVK_TRUElineRasterizationModeVK_LINE_RASTERIZATION_MODE_BRESENHAM,则 stippledBresenhamLines 特性必须启用。

  • VUID-VkPipelineRasterizationLineStateCreateInfo-stippledLineEnable-02773
    如果 stippledLineEnableVK_TRUElineRasterizationModeVK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH,则 stippledSmoothLines 特性必须启用。

  • VUID-VkPipelineRasterizationLineStateCreateInfo-stippledLineEnable-02774
    如果 stippledLineEnableVK_TRUElineRasterizationModeVK_LINE_RASTERIZATION_MODE_DEFAULT,则 stippledRectangularLines 特性必须启用,并且 VkPhysicalDeviceLimits::strictLines 必须VK_TRUE

有效用法(隐式)
  • VUID-VkPipelineRasterizationLineStateCreateInfo-sType-sType
    sType 必须VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO

  • VUID-VkPipelineRasterizationLineStateCreateInfo-lineRasterizationMode-parameter
    lineRasterizationMode 必须为有效的 VkLineRasterizationMode 值。

VkPipelineRasterizationLineStateCreateInfo::lineRasterizationMode 的可能值(用于指定线光栅化模式)如下:

// Provided by VK_VERSION_1_4
typedef enum VkLineRasterizationMode {
    VK_LINE_RASTERIZATION_MODE_DEFAULT = 0,
    VK_LINE_RASTERIZATION_MODE_RECTANGULAR = 1,
    VK_LINE_RASTERIZATION_MODE_BRESENHAM = 2,
    VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH = 3,
  // Provided by VK_EXT_line_rasterization
    VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT = VK_LINE_RASTERIZATION_MODE_DEFAULT,
  // Provided by VK_EXT_line_rasterization
    VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT = VK_LINE_RASTERIZATION_MODE_RECTANGULAR,
  // Provided by VK_EXT_line_rasterization
    VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT = VK_LINE_RASTERIZATION_MODE_BRESENHAM,
  // Provided by VK_EXT_line_rasterization
    VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT = VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH,
  // Provided by VK_KHR_line_rasterization
    VK_LINE_RASTERIZATION_MODE_DEFAULT_KHR = VK_LINE_RASTERIZATION_MODE_DEFAULT,
  // Provided by VK_KHR_line_rasterization
    VK_LINE_RASTERIZATION_MODE_RECTANGULAR_KHR = VK_LINE_RASTERIZATION_MODE_RECTANGULAR,
  // Provided by VK_KHR_line_rasterization
    VK_LINE_RASTERIZATION_MODE_BRESENHAM_KHR = VK_LINE_RASTERIZATION_MODE_BRESENHAM,
  // Provided by VK_KHR_line_rasterization
    VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_KHR = VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH,
} VkLineRasterizationMode;

或等效于:

// Provided by VK_KHR_line_rasterization
typedef VkLineRasterizationMode VkLineRasterizationModeKHR;

或等效于:

// Provided by VK_EXT_line_rasterization
typedef VkLineRasterizationMode VkLineRasterizationModeEXT;
  • 如果 VkPhysicalDeviceLimits::strictLinesVK_TRUE,则 VK_LINE_RASTERIZATION_MODE_DEFAULT 等效于 VK_LINE_RASTERIZATION_MODE_RECTANGULAR,否则,线将绘制为非 strictLines 的平行四边形。这两种模式都在基本线段光栅化中定义。

  • VK_LINE_RASTERIZATION_MODE_RECTANGULAR 指定线绘制为从线挤出的矩形。

  • VK_LINE_RASTERIZATION_MODE_BRESENHAM 指定线通过确定该线相交并退出的像素菱形来绘制,如Bresenham 线段光栅化中定义的那样。

  • VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH 指定线绘制为从线挤出的矩形,并带有 alpha 衰减,如平滑线中定义的那样。

动态设置 lineRasterizationMode 状态,请调用:

// Provided by VK_EXT_extended_dynamic_state3 with VK_EXT_line_rasterization, VK_EXT_line_rasterization with VK_EXT_shader_object
void vkCmdSetLineRasterizationModeEXT(
    VkCommandBuffer                             commandBuffer,
    VkLineRasterizationModeEXT                  lineRasterizationMode);
  • commandBuffer 是将记录命令的命令缓冲区。

  • lineRasterizationMode 指定 lineRasterizationMode 状态。

当使用 着色器对象进行绘制时,或者当图形管线在 VkPipelineDynamicStateCreateInfo::pDynamicStates 中设置了 VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT 时,此命令将为后续的绘制命令设置 lineRasterizationMode 状态。否则,此状态由用于创建当前活动管线的 VkPipelineRasterizationLineStateCreateInfo::lineRasterizationMode 值指定。

有效使用
  • VUID-vkCmdSetLineRasterizationModeEXT-None-09423
    以下条件中必须至少有一个为真:

  • VUID-vkCmdSetLineRasterizationModeEXT-lineRasterizationMode-07418
    如果 lineRasterizationModeVK_LINE_RASTERIZATION_MODE_RECTANGULAR,则 rectangularLines 特性必须启用。

  • VUID-vkCmdSetLineRasterizationModeEXT-lineRasterizationMode-07419
    如果 lineRasterizationModeVK_LINE_RASTERIZATION_MODE_BRESENHAM,则 bresenhamLines 特性必须启用。

  • VUID-vkCmdSetLineRasterizationModeEXT-lineRasterizationMode-07420
    如果 lineRasterizationModeVK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH,则 smoothLines 特性必须启用。

有效用法(隐式)
  • VUID-vkCmdSetLineRasterizationModeEXT-commandBuffer-parameter
    commandBuffer 必须是有效的 VkCommandBuffer 句柄。

  • VUID-vkCmdSetLineRasterizationModeEXT-lineRasterizationMode-parameter
    lineRasterizationMode 必须为有效的 VkLineRasterizationModeEXT 值。

  • VUID-vkCmdSetLineRasterizationModeEXT-commandBuffer-recording
    commandBuffer 必须处于录制状态

  • VUID-vkCmdSetLineRasterizationModeEXT-commandBuffer-cmdpool
    commandBuffer 分配的 VkCommandPool 必须支持图形操作。

  • VUID-vkCmdSetLineRasterizationModeEXT-videocoding
    此命令必须仅在视频编码范围之外调用。

主机同步
  • commandBuffer 的主机访问必须进行外部同步。

  • 对从其分配 commandBufferVkCommandPool 的主机访问必须进行外部同步。

命令属性
命令缓冲区级别 渲染通道范围 视频编码范围 支持的队列类型 命令类型

主要
次要

两者

外部

图形

状态

动态设置 stippledLineEnable 状态,请调用:

// Provided by VK_EXT_extended_dynamic_state3 with VK_EXT_line_rasterization, VK_EXT_line_rasterization with VK_EXT_shader_object
void vkCmdSetLineStippleEnableEXT(
    VkCommandBuffer                             commandBuffer,
    VkBool32                                    stippledLineEnable);
  • commandBuffer 是将记录命令的命令缓冲区。

  • stippledLineEnable 指定 stippledLineEnable 状态。

当使用 着色器对象进行绘制时,或者当图形管线在 VkPipelineDynamicStateCreateInfo::pDynamicStates 中设置了 VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT 时,此命令将为后续的绘制命令设置 stippledLineEnable 状态。否则,此状态由用于创建当前活动管线的 VkPipelineRasterizationLineStateCreateInfo::stippledLineEnable 值指定。

有效使用
有效用法(隐式)
  • VUID-vkCmdSetLineStippleEnableEXT-commandBuffer-parameter
    commandBuffer 必须是有效的 VkCommandBuffer 句柄。

  • VUID-vkCmdSetLineStippleEnableEXT-commandBuffer-recording
    commandBuffer 必须处于录制状态

  • VUID-vkCmdSetLineStippleEnableEXT-commandBuffer-cmdpool
    commandBuffer 分配的 VkCommandPool 必须支持图形操作。

  • VUID-vkCmdSetLineStippleEnableEXT-videocoding
    此命令必须仅在视频编码范围之外调用。

主机同步
  • commandBuffer 的主机访问必须进行外部同步。

  • 对从其分配 commandBufferVkCommandPool 的主机访问必须进行外部同步。

命令属性
命令缓冲区级别 渲染通道范围 视频编码范围 支持的队列类型 命令类型

主要
次要

两者

外部

图形

状态

动态设置线宽,请调用

// Provided by VK_VERSION_1_0
void vkCmdSetLineWidth(
    VkCommandBuffer                             commandBuffer,
    float                                       lineWidth);
  • commandBuffer 是将记录命令的命令缓冲区。

  • lineWidth 是光栅化线段的宽度。

此命令设置后续绘制命令的线宽,当使用着色器对象绘制时,或者当图形管线在VkPipelineDynamicStateCreateInfo::pDynamicStates中设置了VK_DYNAMIC_STATE_LINE_WIDTH时创建。否则,此状态由用于创建当前激活管线的VkPipelineRasterizationStateCreateInfo::lineWidth值指定。

有效使用
  • VUID-vkCmdSetLineWidth-lineWidth-00788
    如果wideLines功能未启用,则lineWidth必须1.0

有效用法(隐式)
  • VUID-vkCmdSetLineWidth-commandBuffer-parameter
    commandBuffer 必须是有效的 VkCommandBuffer 句柄。

  • VUID-vkCmdSetLineWidth-commandBuffer-recording
    commandBuffer 必须处于录制状态

  • VUID-vkCmdSetLineWidth-commandBuffer-cmdpool
    commandBuffer 分配的 VkCommandPool 必须支持图形操作。

  • VUID-vkCmdSetLineWidth-videocoding
    此命令必须仅在视频编码范围之外调用。

主机同步
  • commandBuffer 的主机访问必须进行外部同步。

  • 对从其分配 commandBufferVkCommandPool 的主机访问必须进行外部同步。

命令属性
命令缓冲区级别 渲染通道范围 视频编码范围 支持的队列类型 命令类型

主要
次要

两者

外部

图形

状态

并非所有线宽都需要支持线段栅格化,但必须提供宽度为 1.0 的抗锯齿线段。范围和梯度从VkPhysicalDeviceLimitslineWidthRangelineWidthGranularity成员获得。例如,如果大小范围从 0.1 到 2.0,梯度大小为 0.1,则支持大小 0.1、0.2、…​、1.9、2.0。可能还支持其他线宽。这些宽度不必均匀间隔。如果请求不支持的宽度,则会使用最接近的支持宽度。

此外,如果渲染通道具有片段密度图附件,则线宽可能会被实现舍入为片段宽度或高度的倍数。

基本线段栅格化

如果VkPipelineRasterizationLineStateCreateInfolineRasterizationMode成员是VK_LINE_RASTERIZATION_MODE_RECTANGULAR,则栅格化的线段会产生与以线段为中心的矩形相交的片段。两条边与指定的线段平行;每条边都以垂直于线方向的距离,距离该线段当前宽度的一半。另两条边穿过线端点,并且垂直于指定线段的方向。与矩形相交的样本点对应的覆盖位为 1,其他覆盖位为 0。

接下来,我们指定如何获取与每个栅格化片段关联的数据。令pr = (xd, yd)为评估关联数据的帧缓冲区坐标。这可能是片段的中心或片段内样本的位置。当rasterizationSamplesVK_SAMPLE_COUNT_1_BIT时,必须使用片段中心。令pa = (xa, ya)pb = (xb,yb)分别为线段的初始和最终端点。设置

(请注意,t = 0pa处,t = 1pb处。另请注意,此计算将从papr的向量投影到直线上,从而计算出片段沿直线的归一化距离。)

如果strictLinesVK_TRUE,则使用透视或线性插值栅格化线段。

线段的透视插值以考虑视口的透视的方式正确地插值两个值,通过线段的裁剪坐标实现。插值后的值f可以通过以下方式确定

其中fafb分别是与线段的起始和结束端点关联的数据;wawb分别是线段的起始和结束端点的裁剪w坐标。

线段的线性插值直接插值两个值,并且插值后的值f可以通过以下方式确定

f = (1 - t) fa + t fb

其中fafb分别是与线段的起始和结束端点关联的数据。

使用透视插值确定样本的裁剪坐标w。使用线性插值确定样本的深度值z。片段着色器输入值的插值由插值装饰确定。

以上描述记录了首选的线栅格化方法,当lineRasterizationModeVK_LINE_RASTERIZATION_MODE_RECTANGULAR时,必须使用该方法。

默认情况下,当strictLinesVK_FALSE,或者启用了relaxedLineRasterization功能,并且lineRasterizationModeVK_LINE_RASTERIZATION_MODE_DEFAULT时,线的边缘将生成为围绕原始线的平行四边形。主轴的选择方法是:找出线起点和终点之间距离最大的轴。如果两个方向上的差值相等,则选择 X 轴作为主轴。边缘 2 和 3 与次轴对齐,并以线端点为中心,如图 20。非严格线所示,并且每个边缘的长度为lineWidth。边缘 0 和 1 与直线平行,并连接边缘 2 和 3 的端点。与平行四边形相交的样本点对应的覆盖位为 1,其他覆盖位为 0。

正好落在平行四边形边缘上的样本遵循多边形栅格化规则。

插值就像平行四边形被分解为两个三角形一样发生,其中每对位于线端点的顶点都具有相同的属性。

non strict lines
图 2. 非严格线

strictLinesVK_FALSE或启用relaxedLineRasterization功能,并且lineRasterizationModeVK_LINE_RASTERIZATION_MODE_DEFAULT_EXT时,实现可能会以下列方式偏离上述非严格线算法

  • 实现方式可以改为根据基本线段光栅化中的公式,使用原始线段端点对每个片段进行插值。

  • 非抗锯齿、非严格线段的光栅化可以使用Bresenham线段光栅化中定义的规则执行。

如果VkPhysicalDeviceMaintenance5Properties::nonStrictSinglePixelWideLinesUseParallelogramVK_TRUElineRasterizationModeVK_LINE_RASTERIZATION_MODE_DEFAULT_EXT,且strictLinesVK_FALSE,则宽度为1.0的非严格线将光栅化为平行四边形,否则使用Bresenham算法进行光栅化。

如果VkPhysicalDeviceMaintenance5Properties::nonStrictWideLinesUseParallelogramVK_TRUElineRasterizationModeVK_LINE_RASTERIZATION_MODE_DEFAULT_EXT,且strictLinesVK_FALSE,则宽度大于1.0的非严格线将光栅化为平行四边形,否则使用Bresenham算法进行光栅化。

Bresenham线段光栅化

如果lineRasterizationModeVK_LINE_RASTERIZATION_MODE_BRESENHAM,则以下规则将替换基本线段光栅化中定义的线光栅化规则。

非严格线也可能对非抗锯齿线遵循这些光栅化规则。

如果启用了relaxedLineRasterization特性,且lineRasterizationModeVK_LINE_RASTERIZATION_MODE_DEFAULT_EXT,则实现必须对宽度为1.0的非抗锯齿线遵循这些光栅化规则。

线段光栅化首先将线段表征为x-主导y-主导。x-主导线段的斜率在闭区间[-1,1]内;所有其他线段都是y-主导的(斜率由线段的端点确定)。我们仅针对x-主导线段指定光栅化,除非y-主导线段的修改不是显而易见的。

理想情况下,Vulkan使用菱形退出规则来确定通过光栅化线段生成的片段。对于中心位于帧缓冲区坐标xfyf的每个片段f,定义一个菱形区域,它是四个半平面的交集

本质上,以pa开始并以pb结束的线段会生成与Rf相交的片段f,除非pb包含在Rf中。

bresenham
图3. Bresenham算法的可视化

为了避免当端点位于Rf的边界上时出现困难,我们(原则上)将提供的端点扰动一个很小的量。令papb分别具有帧缓冲区坐标(xa, ya)(xb, yb)。获取扰动后的端点pa',由(xa, ya) - (ε, ε2)给出,以及pb',由(xb, yb) - (ε, ε2)给出。光栅化以pa开始并以pb结束的线段会生成与pa'开始并以pb'结束的线段相交的片段f,除非pb'包含在Rf中。ε的选择要足够小,使得当用δ替换ε时,对于任何0 < δ ≤ ε,光栅化线段产生的片段相同。

papb位于片段中心时,这种片段表征会简化为Bresenham算法,但有一个修改:此描述中生成的线是“半开的”,这意味着不绘制最终片段(对应于pb)。这意味着当光栅化一系列连接的线段时,共享的端点将仅生成一次而不是两次(就像使用Bresenham算法会发生的那样)。

实现方式可以使用其他线段光栅化算法,但须遵守以下规则

  • 该算法生成的片段的坐标在x或y帧缓冲区坐标中与菱形退出规则生成的相应片段的偏差不得超过一个单位。

  • 该算法生成的片段总数与菱形退出规则生成的片段总数之差不得超过一个。

  • 对于x-主导线,不得生成位于同一帧缓冲区坐标列中的两个片段(对于y-主导线,不得生成位于同一帧缓冲区坐标行中的两个片段)。

  • 如果两个线段共享一个公共端点,并且两个线段要么都是x-主导的(都是从左到右或都是从右到左),要么都是y-主导的(都是从下到上或都是从上到下),则光栅化这两个线段不得生成重复的片段。片段也不得被省略,以免中断连接线段的连续性。

Bresenham线的实际宽度w由将线宽度四舍五入到最接近的整数来确定,将其钳制为实现相关的lineWidthRange(两个值都四舍五入到最接近的整数),然后将其钳制为不小于1。

宽度不为 1 的 Bresenham 线段的光栅化是通过在次要方向上偏移它们(对于 x 为主方向的线,次要方向是 y,对于 y 为主方向的线,次要方向是 x),并在次要方向上生成一行或一列片段来实现的。如果线段的端点在帧缓冲区坐标中由 (x0, y0)(x1, y1) 给出,则端点为 和 \((x_1, y_1 - \frac{w-1}{2})\) 的线段会被光栅化,但不是单个片段,而是在每个 x(对于 y 为主方向是 y)位置生成一个高度为 w 的片段列(对于 y 为主方向的线段,则生成长度为 w 的片段行)。此列的最低片段是通过使用修改后的坐标光栅化宽度为 1 的线段而产生的片段。

宽线的首选属性插值方法是为上述行或列中的所有片段生成相同的属性值,就好像调整后的线用于插值并将这些值复制到其他片段一样,但 FragCoord 除外,它会像往常一样进行插值。实现**可能**改为根据基本线段光栅化中的公式对每个片段进行插值,使用原始线段端点。

当光栅化 Bresenham 线时,采样位置**可能**全部被视为位于像素中心(这**可能**会影响属性和深度插值)。

上述采样位置**不**用于确定覆盖率,它们仅用于诸如属性插值之类的事情。确定覆盖率的光栅化规则是根据线是否与**像素**相交来定义的,而不是用于其他图元类型的点采样规则。因此,这些规则独立于采样位置。这样做的一个结果是,无论光栅化采样数量如何,Bresenham 线都覆盖相同的像素,并覆盖这些像素中的所有采样(除非被屏蔽或丢弃)。

线段虚线

如果 VkPipelineRasterizationLineStateCreateInfostippledLineEnable 成员为 VK_TRUE,则使用由 lineStippleFactorlineStipplePattern 确定的 *线段虚线* 来光栅化线。lineStipplePattern 是一个无符号 16 位整数,用于确定在光栅化线时要绘制或丢弃哪些片段。lineStippleFactor 是一个计数,用于修改有效的线段虚线,方法是使 lineStipplePattern 中的每个位被使用 lineStippleFactor 次。

线段虚线会丢弃光栅化产生的部分片段。掩码是通过使用三个参数实现的:16 位线段虚线模式 p、线段虚线因子 r 和整数虚线计数器 s。设

如果 p 的第 b 位为 1,则生成一个片元,否则丢弃。p 的位的编号从 0 开始,0 为最低有效位,15 为最高有效位。

s 的初始值为零。对于 VK_LINE_RASTERIZATION_MODE_BRESENHAM 直线,每生成一个线段的片元(片元按照从起点到终点的顺序生成)后,s 就会递增。对于 VK_LINE_RASTERIZATION_MODE_RECTANGULARVK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH 直线,矩形区域被细分为相邻的单位长度矩形,并且每个矩形 s 递增一次。如果 s 的值使得 p 的第 b 位为零,则丢弃该矩形。如果线段中的最后一个矩形长度小于单位长度,则剩余部分可能会使用相同的 s 值延续到线带中的下一个线段(这是首选行为,以使点画图案在整个线带中看起来更加一致)。

在每个线带的开始处(对于线带),以及在一组独立线段中的每个线段之前,s 将重置为 0。

如果线段已被裁剪,则线段开始时的 s 值取决于具体实现。

动态设置线点画状态,请调用

// Provided by VK_VERSION_1_4
void vkCmdSetLineStipple(
    VkCommandBuffer                             commandBuffer,
    uint32_t                                    lineStippleFactor,
    uint16_t                                    lineStipplePattern);

或等效命令

// Provided by VK_KHR_line_rasterization
void vkCmdSetLineStippleKHR(
    VkCommandBuffer                             commandBuffer,
    uint32_t                                    lineStippleFactor,
    uint16_t                                    lineStipplePattern);

或等效命令

// Provided by VK_EXT_line_rasterization
void vkCmdSetLineStippleEXT(
    VkCommandBuffer                             commandBuffer,
    uint32_t                                    lineStippleFactor,
    uint16_t                                    lineStipplePattern);
  • commandBuffer 是将记录命令的命令缓冲区。

  • lineStippleFactor 是虚线光栅化中使用的重复因子。

  • lineStipplePattern 是虚线光栅化中使用的位模式。

在使用着色器对象进行绘制时,或者在创建图形管线时在 VkPipelineDynamicStateCreateInfo::pDynamicStates 中设置了 VK_DYNAMIC_STATE_LINE_STIPPLE 时,此命令会设置后续绘制命令的线点画状态。否则,此状态由用于创建当前活动管线的 VkPipelineRasterizationLineStateCreateInfo::lineStippleFactorVkPipelineRasterizationLineStateCreateInfo::lineStipplePattern 值指定。

有效使用
  • VUID-vkCmdSetLineStipple-lineStippleFactor-02776
    lineStippleFactor 必须[1,256] 范围内

有效用法(隐式)
  • VUID-vkCmdSetLineStipple-commandBuffer-parameter
    commandBuffer 必须是有效的 VkCommandBuffer 句柄。

  • VUID-vkCmdSetLineStipple-commandBuffer-recording
    commandBuffer 必须处于录制状态

  • VUID-vkCmdSetLineStipple-commandBuffer-cmdpool
    commandBuffer 分配的 VkCommandPool 必须支持图形操作。

  • VUID-vkCmdSetLineStipple-videocoding
    此命令必须仅在视频编码范围之外调用。

主机同步
  • commandBuffer 的主机访问必须进行外部同步。

  • 对从其分配 commandBufferVkCommandPool 的主机访问必须进行外部同步。

命令属性
命令缓冲区级别 渲染通道范围 视频编码范围 支持的队列类型 命令类型

主要
次要

两者

外部

图形

状态

平滑直线

如果 VkPipelineRasterizationLineStateCreateInfolineRasterizationMode 成员是 VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH,则将直线视为与 VK_LINE_RASTERIZATION_MODE_RECTANGULAR 直线具有相同几何形状的矩形。确定覆盖哪些像素的规则取决于具体实现,并且可能包括没有覆盖任何采样位置或者矩形根本没有与像素相交的附近像素。对于被视为覆盖的每个像素,片元会计算一个覆盖率值,该值近似于矩形与像素正方形的交集面积,并且该覆盖率值在片段着色后乘以颜色位置 0 的 alpha 值,如 多重采样覆盖率中所述。

光栅化规则和面积计算的细节有意保持模糊,以便允许实现生成美观的覆盖率和值。

多边形

多边形是由三角形条带、三角形扇或一系列独立三角形分解而来的。与点和线段一样,多边形光栅化由 VkPipelineRasterizationStateCreateInfo 结构中的几个变量控制。

基本多边形光栅化

多边形光栅化的第一步是确定三角形是背面还是正面。此确定基于在帧缓冲区坐标中计算的(裁剪或未裁剪)多边形面积的符号进行。计算此面积的一种方法是

其中 n 顶点多边形的第 i 个顶点的 xy 帧缓冲坐标(为了计算的目的,顶点编号从零开始),i ⊕ 1(i + 1) mod n

a 的符号的解释由当前活动的管线的 VkPipelineRasterizationStateCreateInfo::frontFace 属性决定。可能的值有

// Provided by VK_VERSION_1_0
typedef enum VkFrontFace {
    VK_FRONT_FACE_COUNTER_CLOCKWISE = 0,
    VK_FRONT_FACE_CLOCKWISE = 1,
} VkFrontFace;
  • VK_FRONT_FACE_COUNTER_CLOCKWISE 指定具有正面积的三角形被认为是正面朝向的。

  • VK_FRONT_FACE_CLOCKWISE 指定具有负面积的三角形被认为是正面朝向的。

任何不是正面朝向的三角形都是背面朝向的,包括零面积的三角形。

动态设置正面朝向,请调用

// Provided by VK_VERSION_1_3
void vkCmdSetFrontFace(
    VkCommandBuffer                             commandBuffer,
    VkFrontFace                                 frontFace);

或等效命令

// Provided by VK_EXT_extended_dynamic_state, VK_EXT_shader_object
void vkCmdSetFrontFaceEXT(
    VkCommandBuffer                             commandBuffer,
    VkFrontFace                                 frontFace);
  • commandBuffer 是将记录命令的命令缓冲区。

  • frontFace 是一个 VkFrontFace 值,用于指定用于剔除的正面三角形方向。

当使用着色器对象进行绘制时,或者当图形管线在 VkPipelineDynamicStateCreateInfo::pDynamicStates 中设置了 VK_DYNAMIC_STATE_FRONT_FACE 时创建时,此命令为后续的绘制命令设置正面朝向。否则,此状态由用于创建当前活动管线的 VkPipelineRasterizationStateCreateInfo::frontFace 值指定。

有效使用
有效用法(隐式)
  • VUID-vkCmdSetFrontFace-commandBuffer-parameter
    commandBuffer 必须是有效的 VkCommandBuffer 句柄。

  • VUID-vkCmdSetFrontFace-frontFace-parameter
    frontFace 必须 是一个有效的 VkFrontFace

  • VUID-vkCmdSetFrontFace-commandBuffer-recording
    commandBuffer 必须处于录制状态

  • VUID-vkCmdSetFrontFace-commandBuffer-cmdpool
    commandBuffer 分配的 VkCommandPool 必须支持图形操作。

  • VUID-vkCmdSetFrontFace-videocoding
    此命令必须仅在视频编码范围之外调用。

主机同步
  • commandBuffer 的主机访问必须进行外部同步。

  • 对从其分配 commandBufferVkCommandPool 的主机访问必须进行外部同步。

命令属性
命令缓冲区级别 渲染通道范围 视频编码范围 支持的队列类型 命令类型

主要
次要

两者

外部

图形

状态

一旦确定了三角形的朝向,它们将根据当前活动管线的 VkPipelineRasterizationStateCreateInfo::cullMode 属性进行剔除。可能的值有

// Provided by VK_VERSION_1_0
typedef enum VkCullModeFlagBits {
    VK_CULL_MODE_NONE = 0,
    VK_CULL_MODE_FRONT_BIT = 0x00000001,
    VK_CULL_MODE_BACK_BIT = 0x00000002,
    VK_CULL_MODE_FRONT_AND_BACK = 0x00000003,
} VkCullModeFlagBits;
  • VK_CULL_MODE_NONE 指定不丢弃任何三角形

  • VK_CULL_MODE_FRONT_BIT 指定丢弃正面朝向的三角形

  • VK_CULL_MODE_BACK_BIT 指定丢弃背面朝向的三角形

  • VK_CULL_MODE_FRONT_AND_BACK 指定丢弃所有三角形。

在剔除之后,会为任何未被丢弃的三角形生成片段。

// Provided by VK_VERSION_1_0
typedef VkFlags VkCullModeFlags;

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

动态设置剔除模式,请调用

// Provided by VK_VERSION_1_3
void vkCmdSetCullMode(
    VkCommandBuffer                             commandBuffer,
    VkCullModeFlags                             cullMode);

或等效命令

// Provided by VK_EXT_extended_dynamic_state, VK_EXT_shader_object
void vkCmdSetCullModeEXT(
    VkCommandBuffer                             commandBuffer,
    VkCullModeFlags                             cullMode);
  • commandBuffer 是将记录命令的命令缓冲区。

  • cullMode 指定用于绘制的剔除模式属性。

此命令设置使用着色器对象进行绘制时,或在图形管线创建时,在 VkPipelineDynamicStateCreateInfo::pDynamicStates 中设置了 VK_DYNAMIC_STATE_CULL_MODE 之后,后续绘图命令的剔除模式。否则,此状态由用于创建当前活动管线的 VkPipelineRasterizationStateCreateInfo::cullMode 值指定。

有效使用
有效用法(隐式)
  • VUID-vkCmdSetCullMode-commandBuffer-parameter
    commandBuffer 必须是有效的 VkCommandBuffer 句柄。

  • VUID-vkCmdSetCullMode-cullMode-parameter
    cullMode 必须VkCullModeFlagBits 值的有效组合

  • VUID-vkCmdSetCullMode-commandBuffer-recording
    commandBuffer 必须处于录制状态

  • VUID-vkCmdSetCullMode-commandBuffer-cmdpool
    commandBuffer 分配的 VkCommandPool 必须支持图形操作。

  • VUID-vkCmdSetCullMode-videocoding
    此命令必须仅在视频编码范围之外调用。

主机同步
  • commandBuffer 的主机访问必须进行外部同步。

  • 对从其分配 commandBufferVkCommandPool 的主机访问必须进行外部同步。

命令属性
命令缓冲区级别 渲染通道范围 视频编码范围 支持的队列类型 命令类型

主要
次要

两者

外部

图形

状态

用于确定多边形光栅化产生哪些片元的规则称为点采样。通过取多边形顶点的 x 和 y 帧缓冲区坐标形成的二维投影。对于任何采样点位于此多边形内的像素的任何片元区域组,都会生成片元。与满足点采样标准的采样点对应的覆盖位为 1,其他覆盖位为 0。对于采样位置位于多边形边缘的采样点,会进行特殊处理。在这种情况下,如果两个多边形位于一个公共边缘的两侧(具有相同的端点),并且采样点位于该公共边缘上,则在光栅化期间,正好其中一个多边形必须为该片元产生覆盖采样点。至于由光栅化多边形产生的每个片元的关联数据,我们首先指定如何为三角形中的片元生成这些值。

重心坐标 是一组三个数字,abc,每个数字都在 [0,1] 范围内,且 a + b + c = 1。这些坐标唯一指定三角形内或三角形边界上的任何点 p,如下所示

p = a pa + b pb + c pc

其中 papbpc 是三角形的顶点。abc 由以下公式确定

其中 A(lmn) 表示顶点为 lmn 的三角形在帧缓冲区坐标中的面积。

papbpc 处的关联数据表示为 fafbfc

三角形的透视插值通过三角形的裁剪坐标,以考虑视口透视的方式正确地插值三个值。插值的值 f 可以通过以下公式确定

其中 wawbwc 分别是 papbpc 的裁剪 w 坐标。abc 是数据生成位置的重心坐标。

三角形的线性插值直接插值三个值,插值的值 f 可以通过以下公式确定

f = a fa + b fb + c fc

其中 fafbfc 分别是与 papbpc 关联的数据。

使用透视插值确定样本的裁剪坐标w。使用线性插值确定样本的深度值z。片段着色器输入值的插值由插值装饰确定。

对于具有三个以上边的多边形,例如通过裁剪三角形产生的多边形,必须使用多边形顶点处的数据值的凸组合来获得分配给光栅化算法产生的每个片元的值。也就是说,必须在每个片元都存在以下情况

其中 n 是多边形中顶点的数量,fi 是顶点 if 的值。对于每个 i0 ≤ ai ≤ 1 ai 的值可能因片段而异,但在顶点 i 处,ai = 1 且对于 j ≠ iaj = 0

一种实现所需行为的算法是将多边形三角化(不添加任何顶点),然后如前所述分别处理每个三角形。一个扫描线光栅化器,它沿每条边线性插值数据,然后从边到边线性插值每个水平跨度上的数据,也满足限制条件(在这种情况下,透视插值的分子和分母是独立迭代的,并且为每个片段执行除法)。

多边形模式

当前活动管道的 VkPipelineRasterizationStateCreateInfo::polygonMode 属性的可能值,指定多边形的栅格化方法为:

// Provided by VK_VERSION_1_0
typedef enum VkPolygonMode {
    VK_POLYGON_MODE_FILL = 0,
    VK_POLYGON_MODE_LINE = 1,
    VK_POLYGON_MODE_POINT = 2,
  // Provided by VK_NV_fill_rectangle
    VK_POLYGON_MODE_FILL_RECTANGLE_NV = 1000153000,
} VkPolygonMode;
  • VK_POLYGON_MODE_POINT 指定将多边形顶点绘制为点。

  • VK_POLYGON_MODE_LINE 指定将多边形边绘制为线段。

  • VK_POLYGON_MODE_FILL 指定使用本节中的多边形栅格化规则渲染多边形。

  • VK_POLYGON_MODE_FILL_RECTANGLE_NV 指定使用多边形栅格化规则渲染多边形,该规则经过修改,如果采样位置位于投影后三角形的轴对齐边界框内,则将该采样视为在图元内。请注意,当对这些图元进行着色时,属性插值中使用的重心权重可以超出 [0,1] 的范围。对边界框的边界边上的采样位置进行特殊处理。在这种情况下,如果两个矩形位于一个公共边的两侧(具有相同的端点),并且采样位置位于该边上,那么在栅格化期间,恰好一个三角形必须生成覆盖该采样的片段。

    VK_POLYGON_MODE_FILL_RECTANGLE_NV 模式下渲染的多边形可能会被视锥或用户剪裁平面剪裁。如果应用剪裁,则会剔除三角形而不是剪裁。

    对于 VK_POLYGON_MODE_FILL_RECTANGLE_NV 模式,使用三角形的顶点确定面积计算和朝向性。

这些模式仅影响多边形的最终栅格化:特别是,多边形的顶点会被着色,并且多边形在应用这些模式之前会被剪裁并可能被剔除。

如果 VkPhysicalDeviceMaintenance5Properties::polygonModePointSizeVK_TRUE,则当 多边形模式VK_POLYGON_MODE_POINT 时,多边形最终栅格化的点大小取自 PointSize

否则,如果 VkPhysicalDeviceMaintenance5Properties::polygonModePointSizeVK_FALSE,则当 多边形模式VK_POLYGON_MODE_POINT 时,多边形最终栅格化的点大小为 1.0。

动态设置多边形模式,请调用

// Provided by VK_EXT_extended_dynamic_state3, VK_EXT_shader_object
void vkCmdSetPolygonModeEXT(
    VkCommandBuffer                             commandBuffer,
    VkPolygonMode                               polygonMode);
  • commandBuffer 是将记录命令的命令缓冲区。

  • polygonMode 指定多边形模式。

当使用着色器对象绘制时,或当图形管道使用 VkPipelineDynamicStateCreateInfo::pDynamicStates 中设置的 VK_DYNAMIC_STATE_POLYGON_MODE_EXT 创建时,此命令会为后续绘制命令设置多边形模式。否则,此状态由用于创建当前活动管道的 VkPipelineRasterizationStateCreateInfo::polygonMode 值指定。

有效使用
  • VUID-vkCmdSetPolygonModeEXT-None-09423
    以下条件中必须至少有一个为真:

  • VUID-vkCmdSetPolygonModeEXT-fillModeNonSolid-07424
    如果未启用 fillModeNonSolid 功能,则 polygonMode 必须VK_POLYGON_MODE_FILLVK_POLYGON_MODE_FILL_RECTANGLE_NV

  • VUID-vkCmdSetPolygonModeEXT-polygonMode-07425
    如果未启用 VK_NV_fill_rectangle 扩展,则 polygonMode 必须 不为 VK_POLYGON_MODE_FILL_RECTANGLE_NV

有效用法(隐式)
  • VUID-vkCmdSetPolygonModeEXT-commandBuffer-parameter
    commandBuffer 必须是有效的 VkCommandBuffer 句柄。

  • VUID-vkCmdSetPolygonModeEXT-polygonMode-parameter
    polygonMode 必须 是一个有效的 VkPolygonMode

  • VUID-vkCmdSetPolygonModeEXT-commandBuffer-recording
    commandBuffer 必须处于录制状态

  • VUID-vkCmdSetPolygonModeEXT-commandBuffer-cmdpool
    commandBuffer 分配的 VkCommandPool 必须支持图形操作。

  • VUID-vkCmdSetPolygonModeEXT-videocoding
    此命令必须仅在视频编码范围之外调用。

主机同步
  • commandBuffer 的主机访问必须进行外部同步。

  • 对从其分配 commandBufferVkCommandPool 的主机访问必须进行外部同步。

命令属性
命令缓冲区级别 渲染通道范围 视频编码范围 支持的队列类型 命令类型

主要
次要

两者

外部

图形

状态

深度偏移

多边形光栅化生成的所有片元的深度值可以通过一个单独的深度偏移值 进行偏移(调整)。该偏移值针对该多边形计算得出。

启用深度偏移

深度偏移计算通过 vkCmdSetDepthBiasEnablevkCmdSetDepthBiasEnableEXT 设置的 depthBiasEnable 启用,或者通过用于创建当前激活管线的相应 VkPipelineRasterizationStateCreateInfo::depthBiasEnable 值启用。如果深度偏移启用为 VK_FALSE,则不应用任何偏移,并且片元的深度值保持不变。

动态启用是否偏移片元深度值,请调用

// Provided by VK_VERSION_1_3
void vkCmdSetDepthBiasEnable(
    VkCommandBuffer                             commandBuffer,
    VkBool32                                    depthBiasEnable);

或等效命令

// Provided by VK_EXT_extended_dynamic_state2, VK_EXT_shader_object
void vkCmdSetDepthBiasEnableEXT(
    VkCommandBuffer                             commandBuffer,
    VkBool32                                    depthBiasEnable);
  • commandBuffer 是将记录命令的命令缓冲区。

  • depthBiasEnable 控制是否偏置片段深度值。

当使用着色器对象进行绘制时,或者当图形管线在 VkPipelineDynamicStateCreateInfo::pDynamicStates 中设置了 VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE 时创建时,此命令设置后续绘制命令的深度偏移启用。否则,此状态由用于创建当前激活管线的 VkPipelineRasterizationStateCreateInfo::depthBiasEnable 值指定。

有效使用
有效用法(隐式)
  • VUID-vkCmdSetDepthBiasEnable-commandBuffer-parameter
    commandBuffer 必须是有效的 VkCommandBuffer 句柄。

  • VUID-vkCmdSetDepthBiasEnable-commandBuffer-recording
    commandBuffer 必须处于录制状态

  • VUID-vkCmdSetDepthBiasEnable-commandBuffer-cmdpool
    commandBuffer 分配的 VkCommandPool 必须支持图形操作。

  • VUID-vkCmdSetDepthBiasEnable-videocoding
    此命令必须仅在视频编码范围之外调用。

主机同步
  • commandBuffer 的主机访问必须进行外部同步。

  • 对从其分配 commandBufferVkCommandPool 的主机访问必须进行外部同步。

命令属性
命令缓冲区级别 渲染通道范围 视频编码范围 支持的队列类型 命令类型

主要
次要

两者

外部

图形

状态

深度偏移计算

深度偏移取决于三个参数

  • depthBiasSlopeFactor 缩放多边形的最大深度斜率 m

  • depthBiasConstantFactor 缩放深度附件的参数 r

  • 缩放后的项相加,生成一个值,然后将其钳制为 depthBiasClamp 指定的最小值或最大值

depthBiasSlopeFactordepthBiasConstantFactordepthBiasClamp 可以为正、负或零。这些参数的设置如下面针对 vkCmdSetDepthBiasvkCmdSetDepthBias2EXT 所述。

三角形的最大深度斜率 m

其中 (xf, yf, zf) 是三角形上的一个点。 m 可以近似为

在深度偏移表示为 VK_DEPTH_BIAS_REPRESENTATION_FLOAT_EXT 的管线中,对于给定的图元,r 定义为

r = 1

否则,r 是取决于深度附件表示的最小可分辨差异。如果 VkDepthBiasRepresentationInfoEXT::depthBiasExactVK_FALSE,则它是样本深度 zf 值中的最小差异,该差异保证在多边形光栅化和深度附件中保持不同。由两个具有其他相同顶点但 zf 值相差 r 的多边形的光栅化生成的所有片元对都将具有不同的深度值。

对于定点深度附件表示,或者在深度偏移表示为 VK_DEPTH_BIAS_REPRESENTATION_LEAST_REPRESENTABLE_VALUE_FORCE_UNORM_EXT 的管线中,r 在整个深度附件范围内是恒定的。如果 VkDepthBiasRepresentationInfoEXT::depthBiasExactVK_TRUE,则其值必须

r = 2-n

否则,其值取决于实现,但必须最大为

r = 2 × 2-n

其中 n 是在使用定点附件时用于深度方面的位数,或者在使用浮点附件时是尾数位数加 1。

否则,对于浮点深度附件,没有单个最小可分辨差异。在这种情况下,给定多边形的最小可分辨差异取决于图元跨越的 z 值范围中的最大指数 e。如果 n 是浮点尾数中的位数,则给定图元的最小可分辨差异 r 定义为

r = 2e-n

如果使用 VK_POLYGON_MODE_FILL_RECTANGLE_NV 多边形模式光栅化三角形,则对于三角形外部的样本(深度值已外推),此最小可分辨差异可能无法分辨。

如果不存在深度附件,则 r未定义的

多边形的偏移值 o

m 如上所述计算。如果深度附件使用定点表示,则 m 是范围 [0,1] 内深度值的函数,并且 o 应用于相同范围内的深度值。

无论多边形模式如何,深度偏移都应用于光栅化器接收的三角形拓扑图元。深度偏移可以也应用于光栅化器接收的线和点拓扑图元。

动态设置深度偏移参数,请调用

// Provided by VK_VERSION_1_0
void vkCmdSetDepthBias(
    VkCommandBuffer                             commandBuffer,
    float                                       depthBiasConstantFactor,
    float                                       depthBiasClamp,
    float                                       depthBiasSlopeFactor);
  • commandBuffer 是将记录命令的命令缓冲区。

  • depthBiasConstantFactor 是一个标量因子,用于控制添加到每个片段的常量深度值。

  • depthBiasClamp 是片段的最大(或最小)深度偏置。

  • depthBiasSlopeFactor 是一个标量因子,应用于深度偏置计算中片段的斜率。

此命令设置使用着色器对象绘制时,或在VkPipelineDynamicStateCreateInfo::pDynamicStates中设置了VK_DYNAMIC_STATE_DEPTH_BIAS来创建图形管线时,后续绘制命令的深度偏移参数。否则,此状态由用于创建当前活动管线的相应VkPipelineRasterizationStateCreateInfo::depthBiasConstantFactordepthBiasClampdepthBiasSlopeFactor 值指定。

调用此函数等效于调用 vkCmdSetDepthBias2EXT,且 VkDepthBiasInfoEXT 的 pNext 链中没有 VkDepthBiasRepresentationInfoEXT

有效使用
  • VUID-vkCmdSetDepthBias-depthBiasClamp-00790
    如果未启用 depthBiasClamp 功能,则 depthBiasClamp 必须0.0

有效用法(隐式)
  • VUID-vkCmdSetDepthBias-commandBuffer-parameter
    commandBuffer 必须是有效的 VkCommandBuffer 句柄。

  • VUID-vkCmdSetDepthBias-commandBuffer-recording
    commandBuffer 必须处于录制状态

  • VUID-vkCmdSetDepthBias-commandBuffer-cmdpool
    commandBuffer 分配的 VkCommandPool 必须支持图形操作。

  • VUID-vkCmdSetDepthBias-videocoding
    此命令必须仅在视频编码范围之外调用。

主机同步
  • commandBuffer 的主机访问必须进行外部同步。

  • 对从其分配 commandBufferVkCommandPool 的主机访问必须进行外部同步。

命令属性
命令缓冲区级别 渲染通道范围 视频编码范围 支持的队列类型 命令类型

主要
次要

两者

外部

图形

状态

VkDepthBiasRepresentationInfoEXT 结构定义如下:

// Provided by VK_EXT_depth_bias_control
typedef struct VkDepthBiasRepresentationInfoEXT {
    VkStructureType                 sType;
    const void*                     pNext;
    VkDepthBiasRepresentationEXT    depthBiasRepresentation;
    VkBool32                        depthBiasExact;
} VkDepthBiasRepresentationInfoEXT;
  • sType 是一个 VkStructureType 值,用于标识此结构。

  • pNextNULL 或指向扩展此结构的结构的指针。

  • depthBiasRepresentation 是一个 VkDepthBiasRepresentationEXT 值,指定深度偏移表示形式。

  • depthBiasExact 指定不允许实现缩放深度偏移值以确保最小可分辨距离。

有效使用
  • VUID-VkDepthBiasRepresentationInfoEXT-leastRepresentableValueForceUnormRepresentation-08947
    如果未启用 leastRepresentableValueForceUnormRepresentation 功能,则 depthBiasRepresentation 必须不是 VK_DEPTH_BIAS_REPRESENTATION_LEAST_REPRESENTABLE_VALUE_FORCE_UNORM_EXT

  • VUID-VkDepthBiasRepresentationInfoEXT-floatRepresentation-08948
    如果未启用 floatRepresentation 功能,则 depthBiasRepresentation 必须不是 VK_DEPTH_BIAS_REPRESENTATION_FLOAT_EXT

  • VUID-VkDepthBiasRepresentationInfoEXT-depthBiasExact-08949
    如果未启用 depthBiasExact 功能,则 depthBiasExact 必须VK_FALSE

有效用法(隐式)
  • VUID-VkDepthBiasRepresentationInfoEXT-sType-sType
    sType 必须VK_STRUCTURE_TYPE_DEPTH_BIAS_REPRESENTATION_INFO_EXT

  • VUID-VkDepthBiasRepresentationInfoEXT-depthBiasRepresentation-parameter
    depthBiasRepresentation 必须是一个有效的 VkDepthBiasRepresentationEXT

指定深度偏移表示形式的 VkDepthBiasRepresentationInfoEXT::depthBiasRepresentation 的可能值如下:

// Provided by VK_EXT_depth_bias_control
typedef enum VkDepthBiasRepresentationEXT {
    VK_DEPTH_BIAS_REPRESENTATION_LEAST_REPRESENTABLE_VALUE_FORMAT_EXT = 0,
    VK_DEPTH_BIAS_REPRESENTATION_LEAST_REPRESENTABLE_VALUE_FORCE_UNORM_EXT = 1,
    VK_DEPTH_BIAS_REPRESENTATION_FLOAT_EXT = 2,
} VkDepthBiasRepresentationEXT;
  • VK_DEPTH_BIAS_REPRESENTATION_LEAST_REPRESENTABLE_VALUE_FORMAT_EXT 指定深度偏移表示形式是格式的 r 的一个因子,如深度偏移计算中所述。

  • VK_DEPTH_BIAS_REPRESENTATION_LEAST_REPRESENTABLE_VALUE_FORCE_UNORM_EXT 指定深度偏移表示形式是常数 r 的一个因子,该常数 r 由格式的位大小或尾数定义,如深度偏移计算中所述。

  • VK_DEPTH_BIAS_REPRESENTATION_FLOAT_EXT 指定深度偏移表示形式是常数 r 的一个因子,该常数 r 等于 1。

VkDepthBiasInfoEXT 结构定义如下:

// Provided by VK_EXT_depth_bias_control
typedef struct VkDepthBiasInfoEXT {
    VkStructureType    sType;
    const void*        pNext;
    float              depthBiasConstantFactor;
    float              depthBiasClamp;
    float              depthBiasSlopeFactor;
} VkDepthBiasInfoEXT;
  • sType 是一个 VkStructureType 值,用于标识此结构。

  • pNextNULL 或指向扩展此结构的结构的指针。

  • depthBiasConstantFactor 是一个标量因子,用于控制添加到每个片段的常量深度值。

  • depthBiasClamp 是片段的最大(或最小)深度偏置。

  • depthBiasSlopeFactor 是一个标量因子,应用于深度偏置计算中片段的斜率。

如果 pNext 不包含 VkDepthBiasRepresentationInfoEXT 结构,则此命令等效于包含一个 depthBiasExact 设置为 VK_FALSEdepthBiasRepresentation 设置为 VK_DEPTH_BIAS_REPRESENTATION_LEAST_REPRESENTABLE_VALUE_FORMAT_EXTVkDepthBiasRepresentationInfoEXT

有效使用
  • VUID-VkDepthBiasInfoEXT-depthBiasClamp-08950
    如果未启用 depthBiasClamp 功能,则 depthBiasClamp 必须0.0

有效用法(隐式)
  • VUID-VkDepthBiasInfoEXT-sType-sType
    sType 必须VK_STRUCTURE_TYPE_DEPTH_BIAS_INFO_EXT

  • VUID-VkDepthBiasInfoEXT-pNext-pNext
    pNext 必须NULL 或指向 VkDepthBiasRepresentationInfoEXT 的有效实例的指针

  • VUID-VkDepthBiasInfoEXT-sType-unique
    pNext 链中每个结构的 sType必须是唯一的

动态设置深度偏移参数,请调用

// Provided by VK_EXT_depth_bias_control
void vkCmdSetDepthBias2EXT(
    VkCommandBuffer                             commandBuffer,
    const VkDepthBiasInfoEXT*                   pDepthBiasInfo);
  • commandBuffer 是将记录命令的命令缓冲区。

  • pDepthBiasInfo 是指向 VkDepthBiasInfoEXT 结构的指针,该结构指定深度偏移参数。

此命令的功能与 vkCmdSetDepthBias 相同,但包含可扩展的子结构,包括 sTypepNext 参数,从而使其更容易扩展。

有效用法(隐式)
  • VUID-vkCmdSetDepthBias2EXT-commandBuffer-parameter
    commandBuffer 必须是有效的 VkCommandBuffer 句柄。

  • VUID-vkCmdSetDepthBias2EXT-pDepthBiasInfo-parameter
    pDepthBiasInfo 必须是指向有效 VkDepthBiasInfoEXT 结构的有效指针

  • VUID-vkCmdSetDepthBias2EXT-commandBuffer-recording
    commandBuffer 必须处于录制状态

  • VUID-vkCmdSetDepthBias2EXT-commandBuffer-cmdpool
    commandBuffer 分配的 VkCommandPool 必须支持图形操作。

  • VUID-vkCmdSetDepthBias2EXT-videocoding
    此命令必须仅在视频编码范围之外调用。

主机同步
  • commandBuffer 的主机访问必须进行外部同步。

  • 对从其分配 commandBufferVkCommandPool 的主机访问必须进行外部同步。

命令属性
命令缓冲区级别 渲染通道范围 视频编码范围 支持的队列类型 命令类型

主要
次要

两者

外部

图形

状态

保守光栅化

如果 VkPipelineRasterizationStateCreateInfopNext 链包含 VkPipelineRasterizationConservativeStateCreateInfoEXT 结构,则该结构包含控制保守光栅化的参数。

VkPipelineRasterizationConservativeStateCreateInfoEXT 定义如下:

// Provided by VK_EXT_conservative_rasterization
typedef struct VkPipelineRasterizationConservativeStateCreateInfoEXT {
    VkStructureType                                           sType;
    const void*                                               pNext;
    VkPipelineRasterizationConservativeStateCreateFlagsEXT    flags;
    VkConservativeRasterizationModeEXT                        conservativeRasterizationMode;
    float                                                     extraPrimitiveOverestimationSize;
} VkPipelineRasterizationConservativeStateCreateInfoEXT;
  • sType 是一个 VkStructureType 值,用于标识此结构。

  • pNextNULL 或指向扩展此结构的结构的指针。

  • flags 保留供将来使用。

  • conservativeRasterizationMode 是要使用的保守光栅化模式。

  • extraPrimitiveOverestimationSize 是在屏幕空间中,在 VkPhysicalDeviceConservativeRasterizationPropertiesEXT::primitiveOverestimationSize 中指定的基本高估之外,在每个边缘保守光栅化期间增加生成基元的额外像素大小(以 XY 方向相等)。如果 conservativeRasterizationMode 不是 VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT,则忽略此值。

如果此结构未包含在 pNext 链中,则 conservativeRasterizationMode 将被视为 VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT,并且保守光栅化将被禁用。

通过在 VkPipelineRasterizationConservativeStateCreateInfoEXT 中将 conservativeRasterizationMode 设置为 VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXTVK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT可以使多边形光栅化变为保守的。

如果支持 conservativePointAndLineRasterization,则保守光栅化可以应用于线和点图元,否则必须禁用。

有效使用
  • VUID-VkPipelineRasterizationConservativeStateCreateInfoEXT-extraPrimitiveOverestimationSize-01769
    extraPrimitiveOverestimationSize 必须0.0VkPhysicalDeviceConservativeRasterizationPropertiesEXT::maxExtraPrimitiveOverestimationSize (包含) 的范围内。

有效用法(隐式)
  • VUID-VkPipelineRasterizationConservativeStateCreateInfoEXT-sType-sType
    sType 必须VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT

  • VUID-VkPipelineRasterizationConservativeStateCreateInfoEXT-flags-zerobitmask
    flags 必须0

  • VUID-VkPipelineRasterizationConservativeStateCreateInfoEXT-conservativeRasterizationMode-parameter
    conservativeRasterizationMode 必须是有效的 VkConservativeRasterizationModeEXT 值。

// Provided by VK_EXT_conservative_rasterization
typedef VkFlags VkPipelineRasterizationConservativeStateCreateFlagsEXT;

VkPipelineRasterizationConservativeStateCreateFlagsEXT 是用于设置掩码的位掩码类型,但目前保留供将来使用。

VkPipelineRasterizationConservativeStateCreateInfoEXT::conservativeRasterizationMode 的可能值,指定了保守光栅化模式如下:

// Provided by VK_EXT_conservative_rasterization
typedef enum VkConservativeRasterizationModeEXT {
    VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT = 0,
    VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT = 1,
    VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT = 2,
} VkConservativeRasterizationModeEXT;
  • VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT 指定禁用保守光栅化,并按正常方式进行光栅化。

  • VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT 指定启用过高估计模式的保守光栅化。

  • VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT 指定启用低估模式的保守光栅化。

动态设置 conservativeRasterizationMode,请调用

// Provided by VK_EXT_conservative_rasterization with VK_EXT_extended_dynamic_state3, VK_EXT_conservative_rasterization with VK_EXT_shader_object
void vkCmdSetConservativeRasterizationModeEXT(
    VkCommandBuffer                             commandBuffer,
    VkConservativeRasterizationModeEXT          conservativeRasterizationMode);
  • commandBuffer 是将记录命令的命令缓冲区。

  • conservativeRasterizationMode 指定 conservativeRasterizationMode 状态。

当使用着色器对象进行绘制,或者当图形管线在VkPipelineDynamicStateCreateInfo::pDynamicStates中设置了 VK_DYNAMIC_STATE_CONSERVATIVE_RASTERIZATION_MODE_EXT 时,此命令会为后续的绘制命令设置 conservativeRasterizationMode 状态。否则,此状态由用于创建当前活动管线的 VkPipelineRasterizationConservativeStateCreateInfoEXT::conservativeRasterizationMode 值指定。

有效使用
有效用法(隐式)
  • VUID-vkCmdSetConservativeRasterizationModeEXT-commandBuffer-parameter
    commandBuffer 必须是有效的 VkCommandBuffer 句柄。

  • VUID-vkCmdSetConservativeRasterizationModeEXT-conservativeRasterizationMode-parameter
    conservativeRasterizationMode 必须是有效的 VkConservativeRasterizationModeEXT 值。

  • VUID-vkCmdSetConservativeRasterizationModeEXT-commandBuffer-recording
    commandBuffer 必须处于录制状态

  • VUID-vkCmdSetConservativeRasterizationModeEXT-commandBuffer-cmdpool
    commandBuffer 分配的 VkCommandPool 必须支持图形操作。

  • VUID-vkCmdSetConservativeRasterizationModeEXT-videocoding
    此命令必须仅在视频编码范围之外调用。

主机同步
  • commandBuffer 的主机访问必须进行外部同步。

  • 对从其分配 commandBufferVkCommandPool 的主机访问必须进行外部同步。

命令属性
命令缓冲区级别 渲染通道范围 视频编码范围 支持的队列类型 命令类型

主要
次要

两者

外部

图形

状态

动态设置 extraPrimitiveOverestimationSize,请调用

// Provided by VK_EXT_conservative_rasterization with VK_EXT_extended_dynamic_state3, VK_EXT_conservative_rasterization with VK_EXT_shader_object
void vkCmdSetExtraPrimitiveOverestimationSizeEXT(
    VkCommandBuffer                             commandBuffer,
    float                                       extraPrimitiveOverestimationSize);
  • commandBuffer 是将记录命令的命令缓冲区。

  • extraPrimitiveOverestimationSize 指定 extraPrimitiveOverestimationSize

当使用着色器对象进行绘制,或者当图形管线在VkPipelineDynamicStateCreateInfo::pDynamicStates中设置了 VK_DYNAMIC_STATE_EXTRA_PRIMITIVE_OVERESTIMATION_SIZE_EXT 时,此命令会为后续的绘制命令设置 extraPrimitiveOverestimationSize 状态。否则,此状态由用于创建当前活动管线的 VkPipelineRasterizationConservativeStateCreateInfoEXT::extraPrimitiveOverestimationSize 值指定。

有效使用
  • VUID-vkCmdSetExtraPrimitiveOverestimationSizeEXT-None-09423
    以下条件中必须至少有一个为真:

  • VUID-vkCmdSetExtraPrimitiveOverestimationSizeEXT-extraPrimitiveOverestimationSize-07428
    extraPrimitiveOverestimationSize 必须0.0VkPhysicalDeviceConservativeRasterizationPropertiesEXT::maxExtraPrimitiveOverestimationSize (包含) 的范围内。

有效用法(隐式)
  • VUID-vkCmdSetExtraPrimitiveOverestimationSizeEXT-commandBuffer-parameter
    commandBuffer 必须是有效的 VkCommandBuffer 句柄。

  • VUID-vkCmdSetExtraPrimitiveOverestimationSizeEXT-commandBuffer-recording
    commandBuffer 必须处于录制状态

  • VUID-vkCmdSetExtraPrimitiveOverestimationSizeEXT-commandBuffer-cmdpool
    commandBuffer 分配的 VkCommandPool 必须支持图形操作。

  • VUID-vkCmdSetExtraPrimitiveOverestimationSizeEXT-videocoding
    此命令必须仅在视频编码范围之外调用。

主机同步
  • commandBuffer 的主机访问必须进行外部同步。

  • 对从其分配 commandBufferVkCommandPool 的主机访问必须进行外部同步。

命令属性
命令缓冲区级别 渲染通道范围 视频编码范围 支持的队列类型 命令类型

主要
次要

两者

外部

图形

状态

当启用过高估计的保守光栅化时,不是在单个样本位置评估覆盖率,而是确定像素的任何部分(包括其边缘和角)是否被图元覆盖。如果像素的任何部分被覆盖,则会启用与该像素对应的片段的 覆盖掩码 的所有位。如果渲染通道具有片段密度图附件,并且启用了该片段的 覆盖掩码 的任何位,则会启用该片段的 覆盖掩码 的所有位。

为了评估哪些像素被图元覆盖,实现可以在图元的每个边缘将图元的大小增加最多 VkPhysicalDeviceConservativeRasterizationPropertiesEXT::primitiveOverestimationSize 个像素。这可能会增加此图元生成的片段数,并表示对像素覆盖率的过高估计。

通过将 extraPrimitiveOverestimationSize 值设置为大于 0.0 的值,并以 VkPhysicalDeviceConservativeRasterizationPropertiesEXT::extraPrimitiveOverestimationSizeGranularity 为步长,最多可增加到 VkPhysicalDeviceConservativeRasterizationPropertiesEXT::extraPrimitiveOverestimationSize,从而可以进一步增加此过高估计大小。这可能会进一步增加此图元生成的片段数。

用于保守光栅化的过高估计大小的实际精度在不同实现之间可能会有所不同,并且产生的结果可能仅近似于 primitiveOverestimationSizeextraPrimitiveOverestimationSizeGranularity 属性。当渲染通道具有片段密度图并且片段区域覆盖多个像素时,实现可能会特别更改这些近似值。

对于三角形,如果启用了 VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT,则当图元区域覆盖片段区域内任何像素的任何部分(包括其边缘或角落)时,将生成片段。 基本多边形光栅化 中描述的平局打破规则在保守光栅化期间不适用,并且会为从多边形共享边缘生成的所有片段设置覆盖率。在光栅化后评估为零面积的退化三角形,即使对于包含零面积多边形的顶点或边缘的像素,如果 VkPhysicalDeviceConservativeRasterizationPropertiesEXT::degenerateTrianglesRasterizedVK_FALSE,则会被剔除;如果 degenerateTrianglesRasterizedVK_TRUE,则会生成片段。这些退化三角形的片段输入值会从激发顶点获取其属性和深度值。退化三角形被认为是背面朝向的,如果需要,应用程序**可以**启用背面剔除。无论如何,在光栅化之前面积为零的三角形**可能**会被剔除。

对于直线,如果启用了 VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT 并且实现设置了 VkPhysicalDeviceConservativeRasterizationPropertiesEXT::conservativePointAndLineRasterizationVK_TRUE,则当直线覆盖片段区域内任何像素的任何部分(包括其边缘或角落)时,将生成片段。在光栅化后评估为零长度的退化直线,如果 VkPhysicalDeviceConservativeRasterizationPropertiesEXT::degenerateLinesRasterizedVK_FALSE,则会被剔除;如果 degenerateLinesRasterizedVK_TRUE,则会生成片段。这些退化直线的片段输入值会从激发顶点获取其属性和深度值。无论如何,在光栅化之前长度为零的直线**可能**会被剔除。

对于点,如果启用了 VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT 并且实现设置了 VkPhysicalDeviceConservativeRasterizationPropertiesEXT::conservativePointAndLineRasterizationVK_TRUE,则当点正方形覆盖片段区域内任何像素的任何部分(包括其边缘或角落)时,将生成片段。

当启用低估保守光栅化时,不是在单独的采样位置评估覆盖率,而是确定像素的全部(包括其边缘和角落)是否被图元覆盖。如果整个像素被覆盖,则会生成片段,其中其 覆盖率掩码 的所有位都对应于启用的像素;否则,即使像素的某些部分被覆盖,该像素也不会被认为是覆盖的。如果片段区域内的像素未被认为是覆盖的,则会丢弃该片段。如果渲染通道具有片段密度图附件,并且片段区域内的任何像素未被认为是覆盖的,则即使某些像素被认为是覆盖的,也会丢弃该片段。

对于三角形,如果启用了 VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT,则仅当片段区域内的任何像素被生成的图元完全覆盖(包括其边缘和角落)时,才会生成片段。

对于直线,如果启用了 VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT,则当片段区域内的任何像素(包括其边缘和角落)被直线完全覆盖时,才会生成片段。

对于点,如果启用了 VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT,则仅当点正方形覆盖片段区域内任何像素正方形的全部(包括其边缘或角落)时,才会生成片段。

如果渲染通道具有片段密度图并且启用了 VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT,则仅当片段区域内所有像素的全部都被生成的图元、直线或点覆盖时,才会生成片段。

对于高估和低估保守光栅化模式,如果实现启用 VkPhysicalDeviceConservativeRasterizationPropertiesEXT::fullyCoveredFragmentShaderInputVariable 特性,则片段的所有像素正方形被生成的图元完全覆盖**必须**将 FullyCoveredEXT 设置为 VK_TRUE

当使用 着色率图像 或设置 片段着色率 导致片段覆盖多个像素时,保守光栅化的覆盖率仍然以每个像素为基础进行评估,并且可能会导致具有部分覆盖率的片段。 对于以 FullyCoveredEXT 修饰的片段着色器输入,当且仅当片段中的所有像素都被生成的图元完全覆盖时,才认为片段被完全覆盖。