片段操作
光栅化产生的片段会经过一系列操作,以确定是否将片段着色产生的值写入帧缓冲,以及如何写入。
以下片段操作遵循光栅化顺序,并且通常按此顺序执行
光栅化生成的覆盖掩码描述了片段覆盖的每个样本的初始覆盖率。片段操作将更新覆盖掩码,以在适当的地方添加或减去覆盖率。如果片段操作导致覆盖掩码的所有位都为0
,则丢弃该片段,并且不再执行任何操作。
当本章中的片段操作之一被描述为“替换”片段着色器输出时,该输出将被无条件替换,即使之前没有片段着色器写入该输出。
如果VkPhysicalDeviceMaintenance5Properties
::earlyFragmentMultisampleCoverageAfterSampleCounting
为VK_TRUE
并且存在一个片段着色器声明了EarlyFragmentTests
执行模式,则片段着色和多重采样覆盖操作必须在采样计数之后执行。
否则,如果VkPhysicalDeviceMaintenance5Properties
::earlyFragmentMultisampleCoverageAfterSampleCounting
为VK_FALSE
并且存在一个片段着色器声明了EarlyFragmentTests
执行模式,则片段着色和多重采样覆盖操作应该在采样计数之后执行,但可以在采样计数之前执行。
如果VkPhysicalDeviceMaintenance5Properties
::earlyFragmentSampleMaskTestBeforeSampleCounting
为VK_TRUE
并且存在一个片段着色器声明了EarlyFragmentTests
执行模式,则采样掩码测试操作必须遵循上述片段操作的顺序。
否则,如果VkPhysicalDeviceMaintenance5Properties
::earlyFragmentSampleMaskTestBeforeSampleCounting
为VK_FALSE
并且存在一个片段着色器声明了EarlyFragmentTests
执行模式,则采样掩码测试操作应该遵循上述片段操作的顺序,但可以在采样计数之后执行。
如果存在一个片段着色器声明了EarlyAndLateFragmentTestsAMD
执行模式,并且它没有声明DepthReplacing
或StencilRefReplacingEXT
执行模式,则片段着色和多重采样覆盖操作将在采样计数之后执行。
对于具有以下属性的管线
-
指定了片段着色器
-
片段着色器要么指定
EarlyAndLateFragmentTestsAMD
,要么不写入存储资源; -
片段着色器指定了
StencilRefReplacingEXT
执行模式; -
两者之一
-
片段着色器指定了
StencilRefUnchangedFrontAMD
执行模式; -
片段着色器指定了
StencilRefLessFrontAMD
执行模式,并且管线使用VK_COMPARE_OP_GREATER
或VK_COMPARE_OP_GREATER_OR_EQUAL
的VkPipelineDepthStencilStateCreateInfo::front.compareOp
;或者 -
片段着色器指定了
StencilRefGreaterFrontAMD
执行模式,并且管线使用VK_COMPARE_OP_LESS
或VK_COMPARE_OP_LESS_OR_EQUAL
的VkPipelineDepthStencilStateCreateInfo::front.compareOp
;并且
-
-
两者之一
-
片段着色器指定了
StencilRefUnchangedBackAMD
执行模式; -
片段着色器指定了
StencilRefLessBackAMD
执行模式,并且管线使用VK_COMPARE_OP_GREATER
或VK_COMPARE_OP_GREATER_OR_EQUAL
的VkPipelineDepthStencilStateCreateInfo::back.compareOp
;或者 -
片段着色器指定了
StencilRefGreaterBackAMD
执行模式,并且管线使用VK_COMPARE_OP_LESS
或VK_COMPARE_OP_LESS_OR_EQUAL
的VkPipelineDepthStencilStateCreateInfo::back.compareOp
-
在片段着色之前,可以使用VkPipelineDepthStencilStateCreateInfo::front.reference
或VkPipelineDepthStencilStateCreateInfo::back.reference
指定的模板参考值执行额外的模板测试。
对于具有以下属性的管线
-
指定了片段着色器
-
片段着色器要么指定
EarlyAndLateFragmentTestsAMD
,要么不写入存储资源; -
片段着色器指定了
DepthReplacing
执行模式;并且 -
两者之一
-
片段着色器指定了
DepthUnchanged
执行模式; -
片元着色器指定了
DepthLess
执行模式,并且管线使用 VkPipelineDepthStencilStateCreateInfo::depthCompareOp
,其值为VK_COMPARE_OP_GREATER
或VK_COMPARE_OP_GREATER_OR_EQUAL
;或者 -
片元着色器指定了
DepthGreater
执行模式,并且管线使用 VkPipelineDepthStencilStateCreateInfo::depthCompareOp
,其值为VK_COMPARE_OP_LESS
或VK_COMPARE_OP_LESS_OR_EQUAL
-
一旦所有片元操作完成,被覆盖的颜色附件样本的片元着色器输出将通过帧缓冲操作。
丢弃矩形测试
丢弃矩形测试将片元覆盖的每个样本的帧缓冲坐标 (xf,yf) 与一组丢弃矩形进行比较。
每个丢弃矩形由一个 VkRect2D 定义。这些值可以通过管线创建期间的 VkPipelineDiscardRectangleStateCreateInfoEXT 结构设置,也可以通过 vkCmdSetDiscardRectangleEXT 命令动态设置。
如果 xf 在范围 [VkRect2D::offset.x
, VkRect2D::offset.x
+ VkRect2D::extent.x
) 内,并且 yf 在范围 [VkRect2D::offset.y
, VkRect2D::offset.y
+ VkRect2D::extent.y
) 内,则认为给定样本在丢弃矩形内部。如果测试设置为包含性,则不在任何丢弃矩形内的样本的覆盖率将设置为 0
。如果测试设置为排除性,则在任何丢弃矩形内的样本的覆盖率将设置为 0
。
如果未指定任何丢弃矩形,则此操作不会修改覆盖率掩码。
VkPipelineDiscardRectangleStateCreateInfoEXT
结构定义如下
// Provided by VK_EXT_discard_rectangles
typedef struct VkPipelineDiscardRectangleStateCreateInfoEXT {
VkStructureType sType;
const void* pNext;
VkPipelineDiscardRectangleStateCreateFlagsEXT flags;
VkDiscardRectangleModeEXT discardRectangleMode;
uint32_t discardRectangleCount;
const VkRect2D* pDiscardRectangles;
} VkPipelineDiscardRectangleStateCreateInfoEXT;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
是NULL
或指向扩展此结构的结构的指针。 -
flags
保留以供将来使用。 -
discardRectangleMode
是一个 VkDiscardRectangleModeEXT 值,用于确定丢弃矩形测试是包含性的还是排除性的。 -
discardRectangleCount
是要使用的丢弃矩形的数量。 -
pDiscardRectangles
是指向定义丢弃矩形的 VkRect2D 结构数组的指针。
如果为管线启用了 VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT
动态状态,则 pDiscardRectangles
成员将被忽略。 如果未为管线启用 VK_DYNAMIC_STATE_DISCARD_RECTANGLE_ENABLE_EXT
动态状态,则在 VkGraphicsPipelineCreateInfo 链中存在此结构且 discardRectangleCount
大于零,则会隐式地在管线中启用丢弃矩形,否则必须通过 vkCmdSetDiscardRectangleEnableEXT 启用或禁用丢弃矩形。 如果为管线启用了 VK_DYNAMIC_STATE_DISCARD_RECTANGLE_MODE_EXT
动态状态,则 discardRectangleMode
成员将被忽略,并且必须通过 vkCmdSetDiscardRectangleModeEXT 设置丢弃矩形模式。
当此结构包含在 VkGraphicsPipelineCreateInfo 的 pNext
链中时,它定义了丢弃矩形测试的参数。 如果未启用 VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT
动态状态,并且此结构未包含在 pNext
链中,则相当于指定此结构且 discardRectangleCount
为 0
。 如果所有 VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT
、VK_DYNAMIC_STATE_DISCARD_RECTANGLE_ENABLE_EXT
和 VK_DYNAMIC_STATE_DISCARD_RECTANGLE_MODE_EXT
动态状态都已启用,则应用程序可以从 VkGraphicsPipelineCreateInfo 的 pNext
链中省略此结构,并且仍然可以通过动态设置所有状态来使用丢弃矩形。 在这种情况下,在启用丢弃矩形进行绘制之前,必须调用 vkCmdSetDiscardRectangleEXT
为所有索引 [0, maxDiscardRectangles
) 设置丢弃矩形。可以通过将其 VkRect2D::width
和 VkRect2D::height
设置为零来使单个丢弃矩形失效。
// Provided by VK_EXT_discard_rectangles
typedef VkFlags VkPipelineDiscardRectangleStateCreateFlagsEXT;
VkPipelineDiscardRectangleStateCreateFlagsEXT
是一种用于设置掩码的位掩码类型,但目前保留以供将来使用。
VkDiscardRectangleModeEXT
的值如下:
// Provided by VK_EXT_discard_rectangles
typedef enum VkDiscardRectangleModeEXT {
VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT = 0,
VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT = 1,
} VkDiscardRectangleModeEXT;
-
VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT
指定丢弃矩形测试是包含性的。 -
VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT
指定丢弃矩形测试是排除性的。
要动态设置丢弃矩形,请调用
// Provided by VK_EXT_discard_rectangles
void vkCmdSetDiscardRectangleEXT(
VkCommandBuffer commandBuffer,
uint32_t firstDiscardRectangle,
uint32_t discardRectangleCount,
const VkRect2D* pDiscardRectangles);
-
commandBuffer
是将要记录命令的命令缓冲区。 -
firstDiscardRectangle
是命令更新其状态的第一个丢弃矩形的索引。 -
discardRectangleCount
是命令更新其状态的丢弃矩形的数量。 -
pDiscardRectangles
是指向指定丢弃矩形的 VkRect2D 结构数组的指针。
从 pDiscardRectangles
的元素 i 中获取的剔除矩形将替换索引为 firstDiscardRectangle
+ i 的剔除矩形的当前状态,其中 i 在 [0, discardRectangleCount
) 范围内。
当使用着色器对象进行绘制时,或者当图形管线创建时,在VkPipelineDynamicStateCreateInfo::pDynamicStates
中设置了 VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT
时,此命令将为后续的绘制命令设置剔除矩形。否则,此状态由用于创建当前活动管线的VkPipelineDiscardRectangleStateCreateInfoEXT::pDiscardRectangles
值指定。
要动态设置是否启用剔除矩形,请调用
// Provided by VK_EXT_discard_rectangles
void vkCmdSetDiscardRectangleEnableEXT(
VkCommandBuffer commandBuffer,
VkBool32 discardRectangleEnable);
-
commandBuffer
是将要记录命令的命令缓冲区。 -
discardRectangleEnable
指定是否启用剔除矩形。
当使用着色器对象进行绘制时,或者当图形管线创建时,在VkPipelineDynamicStateCreateInfo::pDynamicStates
中设置了 VK_DYNAMIC_STATE_DISCARD_RECTANGLE_ENABLE_EXT
时,此命令将为后续的绘制命令设置剔除矩形启用。否则,此状态由用于创建当前活动管线的VkPipelineDiscardRectangleStateCreateInfoEXT::discardRectangleCount
值隐含,其中非零的 discardRectangleCount
隐式启用剔除矩形,否则禁用它们。
要动态设置剔除矩形模式,请调用
// Provided by VK_EXT_discard_rectangles
void vkCmdSetDiscardRectangleModeEXT(
VkCommandBuffer commandBuffer,
VkDiscardRectangleModeEXT discardRectangleMode);
-
commandBuffer
是将要记录命令的命令缓冲区。 -
discardRectangleMode
指定所有剔除矩形的剔除矩形模式,可以是包含的或排除的。
当使用着色器对象进行绘制时,或者当图形管线创建时,在VkPipelineDynamicStateCreateInfo::pDynamicStates
中设置了 VK_DYNAMIC_STATE_DISCARD_RECTANGLE_MODE_EXT
时,此命令将为后续的绘制命令设置剔除矩形模式。否则,此状态由用于创建当前活动管线的VkPipelineDiscardRectangleStateCreateInfoEXT::discardRectangleMode
值指定。
剪刀测试
裁剪测试将片段覆盖的每个样本的帧缓冲区坐标 (xf,yf) 与索引等于片段 ViewportIndex
的裁剪矩形进行比较。
每个裁剪矩形由一个 VkRect2D 定义。这些值可以通过管线创建期间的 VkPipelineViewportStateCreateInfo 结构设置,也可以通过 vkCmdSetScissor 命令动态设置。
如果 xf 在范围 [VkRect2D::offset.x
, VkRect2D::offset.x
+ VkRect2D::extent.x
) 内,并且 yf 在范围 [VkRect2D::offset.y
, VkRect2D::offset.y
+ VkRect2D::extent.y
) 内,则认为给定样本位于裁剪矩形内。坐标在相应 ViewportIndex
的裁剪矩形之外的样本的覆盖率将设置为 0
。
如果启用了渲染通道变换,则 (offset.x
和 offset.y
) 以及 (extent.width
和 extent.height
) 的值将按照 渲染通道变换 中的描述进行变换,然后再参与裁剪测试。
要动态设置裁剪矩形,请调用
// Provided by VK_VERSION_1_0
void vkCmdSetScissor(
VkCommandBuffer commandBuffer,
uint32_t firstScissor,
uint32_t scissorCount,
const VkRect2D* pScissors);
-
commandBuffer
是将要记录命令的命令缓冲区。 -
firstScissor
是通过该命令更新状态的第一个裁剪的索引。 -
scissorCount
是通过该命令更新矩形的裁剪的数量。 -
pScissors
是一个指向定义裁剪矩形的 VkRect2D 结构数组的指针。
从 pScissors
的元素 i 获取的裁剪矩形将替换裁剪索引 firstScissor
+ i 的当前状态,其中 i 在 [0, scissorCount
) 中。
当使用 着色器对象 绘制,或当图形管线在 VkPipelineDynamicStateCreateInfo::pDynamicStates
中设置了 VK_DYNAMIC_STATE_SCISSOR
时创建时,此命令设置后续绘图命令的裁剪矩形。否则,此状态由用于创建当前活动管线的 VkPipelineViewportStateCreateInfo::pScissors
值指定。
独占裁剪测试
独占裁剪测试将片段覆盖的每个样本的帧缓冲区坐标 (xf,yf) 与索引等于片段 ViewportIndex
的独占裁剪矩形进行比较。
每个独占裁剪矩形由一个 VkRect2D 定义。这些值可以通过管线创建期间的 VkPipelineViewportExclusiveScissorStateCreateInfoNV 结构设置,也可以通过 vkCmdSetExclusiveScissorNV 命令动态设置。
如果 xf 在范围 [VkRect2D::offset.x
, VkRect2D::offset.x
+ VkRect2D::extent.x
) 内,并且 yf 在范围 [VkRect2D::offset.y
, VkRect2D::offset.y
+ VkRect2D::extent.y
) 内,则认为给定样本位于独占裁剪矩形内。坐标在相应 ViewportIndex
的独占裁剪矩形内的样本的覆盖率将设置为 0
。
如果未指定独占裁剪矩形,则此操作不会修改覆盖率掩码。
VkPipelineViewportExclusiveScissorStateCreateInfoNV
结构定义如下
// Provided by VK_NV_scissor_exclusive
typedef struct VkPipelineViewportExclusiveScissorStateCreateInfoNV {
VkStructureType sType;
const void* pNext;
uint32_t exclusiveScissorCount;
const VkRect2D* pExclusiveScissors;
} VkPipelineViewportExclusiveScissorStateCreateInfoNV;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
是NULL
或指向扩展此结构的结构的指针。 -
exclusiveScissorCount
是独占裁剪矩形的数量。 -
pExclusiveScissors
是一个指向定义独占裁剪矩形的 VkRect2D 结构数组的指针。
如果为管线启用了 VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV
动态状态,则会忽略 pExclusiveScissors
成员。
当此结构包含在 VkGraphicsPipelineCreateInfo 的 pNext
链中时,它定义独占裁剪测试的参数。如果此结构未包含在 pNext
链中,则等效于指定 exclusiveScissorCount
为 0
的此结构。
要动态设置独占裁剪矩形,请调用
// Provided by VK_NV_scissor_exclusive
void vkCmdSetExclusiveScissorNV(
VkCommandBuffer commandBuffer,
uint32_t firstExclusiveScissor,
uint32_t exclusiveScissorCount,
const VkRect2D* pExclusiveScissors);
-
commandBuffer
是将要记录命令的命令缓冲区。 -
firstExclusiveScissor
是第一个独占裁剪矩形的索引,该裁剪矩形的状态将由命令更新。 -
exclusiveScissorCount
是由命令更新的独占裁剪矩形的数量。 -
pExclusiveScissors
是一个指向定义独占裁剪矩形的 VkRect2D 结构数组的指针。
从 pExclusiveScissors
的元素 i 中获取的裁剪矩形将替换裁剪索引 firstExclusiveScissor
+ i 的当前状态,其中 i 在 [0, exclusiveScissorCount
) 范围内。
当使用着色器对象进行绘制时,或者当图形管线在 VkPipelineDynamicStateCreateInfo::pDynamicStates
中设置了 VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV
时,此命令将为后续的绘制命令设置独占裁剪矩形。否则,此状态由用于创建当前活动的管线的 VkPipelineViewportExclusiveScissorStateCreateInfoNV::pExclusiveScissors
值指定。
要动态设置是否启用独占裁剪,请调用
// Provided by VK_NV_scissor_exclusive
void vkCmdSetExclusiveScissorEnableNV(
VkCommandBuffer commandBuffer,
uint32_t firstExclusiveScissor,
uint32_t exclusiveScissorCount,
const VkBool32* pExclusiveScissorEnables);
-
commandBuffer
是将要记录命令的命令缓冲区。 -
firstExclusiveScissor
是第一个独占裁剪矩形的索引,该裁剪矩形的状态将由命令更新。 -
exclusiveScissorCount
是由命令更新的独占裁剪矩形的数量。 -
pExclusiveScissorEnables
是一个指向定义是否启用独占裁剪的VkBool32
值数组的指针。
从 pExclusiveScissorEnables
的元素 i 中获取的独占裁剪启用状态将替换裁剪索引 firstExclusiveScissor
+ i 的当前状态,其中 i 在 [0, exclusiveScissorCount
) 范围内。
当使用着色器对象进行绘制时,或者当图形管线在 VkPipelineDynamicStateCreateInfo::pDynamicStates
中设置了 VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_ENABLE_NV
时,此命令将为后续的绘制命令设置独占裁剪启用状态。否则,此状态由用于创建当前活动管线的 VkPipelineViewportExclusiveScissorStateCreateInfoNV::exclusiveScissorCount
值暗示,其中所有 exclusiveScissorCount
个独占裁剪都隐式启用,而其余的(最多 VkPhysicalDeviceLimits
::maxViewports
)都隐式禁用。
采样掩码测试
采样掩码测试将片段的覆盖掩码与VkPipelineMultisampleStateCreateInfo::pSampleMask
定义的采样掩码进行比较。
要动态设置采样掩码,请调用
// Provided by VK_EXT_extended_dynamic_state3, VK_EXT_shader_object
void vkCmdSetSampleMaskEXT(
VkCommandBuffer commandBuffer,
VkSampleCountFlagBits samples,
const VkSampleMask* pSampleMask);
-
commandBuffer
是将要记录命令的命令缓冲区。 -
samples
指定pSampleMask
中的采样位数。 -
pSampleMask
是一个指向VkSampleMask
值数组的指针,数组大小基于samples
参数。
当使用着色器对象进行绘制,或当图形管线在VkPipelineDynamicStateCreateInfo::pDynamicStates
中设置了VK_DYNAMIC_STATE_SAMPLE_MASK_EXT
时创建时,此命令会设置后续绘制命令的采样掩码。否则,此状态由用于创建当前活动管线的VkPipelineMultisampleStateCreateInfo::pSampleMask
值指定。
覆盖掩码的每一位都与光栅化章节中描述的采样索引相关联。如果VkPipelineMultisampleStateCreateInfo::pSampleMask
中与该采样索引相关联的位设置为0
,则覆盖掩码位设置为0
。
片段着色
片元着色器中的大多数操作不是按照光栅化顺序执行的,例外情况在以下章节中指出。
对于由片元调用的片元着色器,适用以下规则
-
如果片元操作在片元着色之前执行并丢弃了片元,则必须不执行片元着色器。
-
如果出现以下情况,则可能不执行片元着色器
-
否则,必须至少执行一个片元着色器。
如果管线中未包含片元着色器,则不执行片元着色器,并且在此片元操作期间,可能将未定义的值写入所有颜色附件输出。
出于任何数量的依赖于实现的原因,可能会为同一片元执行多个片元着色器调用。当每个片元有多个片元着色器调用时,样本到调用的关联是依赖于实现的。这些附加调用执行的存储和原子操作具有正常效果。 例如,如果子通道在其视图掩码中包含多个视图,则可以为每个视图单独调用片元着色器。 类似地,如果渲染通道具有片元密度图附件,则可以为每个覆盖的样本调用多个片元着色器调用。仅当 |
样本掩码
从Input
存储类中的SampleMask
内置变量读取将返回当前片元的覆盖掩码,该覆盖掩码由在片元着色之前执行的片元操作计算得出。
如果启用样本着色,则片元着色器将仅看到正在着色的样本的值为1
,其他位将为0
。
覆盖掩码的每一位都与光栅化章节中描述的样本索引相关联。如果与同一样本索引关联的SampleMask
中的位设置为0
,则该覆盖掩码位设置为0
。
写入到Output
存储类中的SampleMask
内置变量的值将由多重采样覆盖操作使用,编码方式与输入内置变量相同。
片元着色器图块图像读取
如果启用了VK_EXT_shader_tile_image
扩展,则实现会将帧缓冲区划分为图块网格。图块图像是帧缓冲区附件图块的视图,用于图块内具有位置的片元。
在由vkCmdBeginRenderingKHR初始化的渲染通道实例中,片元着色器调用可以通过图块图像读取片元位置的帧缓冲区颜色、深度和模板值。
即使片元着色器调用只能从相应的片元位置读取,但引入图块图像的抽象是因为以下原因
|
启用shaderTileImageColorReadAccess、shaderTileImageDepthReadAccess、shaderTileImageStencilReadAccess使片元着色器调用能够分别从颜色、深度和模板读取。
使用OpColorAttachmentReadEXT
从图块图像变量读取颜色值。图块图像变量使用Location
装饰符链接到特定的颜色附件。有关更多详细信息,请参阅片元图块图像接口。
深度值使用OpDepthAttachmentReadEXT
读取。
模板值使用OpStencilAttachmentReadEXT
读取。
要读取的样本由样本索引值指定,该值指定为OpColorAttachmentReadEXT
、OpDepthAttachmentReadEXT
或OpStencilAttachmentReadEXT
的Sample
操作数。
如果禁用样本着色,则无论片元的覆盖范围如何,片元调用可以从与该片元关联的所有样本位置读取。当VkPhysicalDeviceShaderTileImagePropertiesEXT::shaderTileImageReadSampleFromPixelRateInvocation
为VK_TRUE
时,对于VkPipelineMultisampleStateCreateInfo::rasterizationSamples
> 1,支持此功能。
如果片段着色器声明了 EarlyFragmentTests
执行模式,则只有在禁用深度写入时才允许深度读取,只有在禁用模板写入时才允许模板读取。
如果 VkPhysicalDeviceShaderTileImagePropertiesEXT::shaderTileImageReadFromHelperInvocation
为 VK_FALSE
,则从辅助调用读取的值是未定义的;否则,读取的值将受下述一致性保证的约束。
如果不存在深度附件,则 OpDepthAttachmentReadEXT
返回一个未定义的值。如果不存在模板附件,则 OpStencilAttachmentReadEXT
返回一个未定义的值。
当从颜色、深度和模板附件读取图块图像发生在光栅顺序中,并且与帧缓冲空间管线阶段对附件的访问没有数据竞争时,这些读取被认为是连贯的。下面描述了符合连贯访问条件的样本和启用条件。
-
令 Rc 为在绘制调用中从附件 A 读取的组件集合
-
令 Wc 为绘制调用写入到 A 的组件集合
符合从附件 A 进行连贯图块图像读取的样本是
-
当 Rc 与 Wc 不相交时,像素中的所有样本。
-
当 Rc 与 Wc 不相交时,片段中具有覆盖率的样本。具有覆盖率的样本由片段的覆盖率掩码确定,该覆盖率掩码由片段着色之前执行的片段操作计算得出,包括如果为绘制调用启用了早期片段测试。
片段着色器可以声明 NonCoherentColorAttachmentReadEXT
、NonCoherentDepthAttachmentReadEXT
或 NonCoherentStencilAttachmentReadEXT
执行模式,以启用非连贯图块图像读取,这需要显式的 vkCmdPipelineBarrier2 调用,以便通过图块图像读取使对附件的写入可见。
当 VkPhysicalDeviceShaderTileImagePropertiesEXT::shaderTileImageCoherentReadAccelerated
为 VK_TRUE
时,实现会优先使用连贯图块图像读取;否则,实现会优先使用非连贯图块图像读取。
在实践中,最常见的图块图像读取使用模式属于以下之一
以上所有用例都受连贯图块图像读取支持,但只有后三个用例在非连贯读取时受支持,因为没有机制在绘制调用中将非连贯读取与写入同步。 |
模板参考替换
写入 FragStencilRefEXT
内置变量将替换输入 SampleMask
中每个样本的片段模板参考值。在此片段的片段着色器之后执行的模板测试将使用此新值作为 sr。
互锁操作
OpBeginInvocationInterlockEXT
和 OpEndInvocationInterlockEXT
定义了片段着色器的一个部分,该部分对其中执行的操作施加了额外的排序约束。这些操作被定义为互锁操作。互锁操作如何相对于其他片段着色器调用进行排序取决于指定的执行模式。
如果指定了 ShadingRateInterlockOrderedEXT
执行模式,则片段着色器中的任何互锁操作必须在光栅化顺序中稍后执行且覆盖同一片段区域中至少一个样本的片段着色器调用中的互锁操作之前发生,并且必须在光栅化顺序中较早执行且覆盖同一片段区域中至少一个样本的片段着色器调用中的互锁操作之后发生。
如果指定了 ShadingRateInterlockUnorderedEXT
执行模式,则片段着色器中的任何互锁操作必须在光栅化顺序中较早或较晚执行且覆盖同一片段区域中至少一个样本的片段着色器调用中的互锁操作之前或之后发生。
如果指定了 PixelInterlockOrderedEXT
执行模式,则片段着色器中的任何互锁操作必须在光栅化顺序中稍后执行且覆盖同一像素中至少一个样本的片段着色器调用中的互锁操作之前发生,并且必须在光栅化顺序中较早执行且覆盖同一像素中至少一个样本的片段着色器调用中的互锁操作之后发生。
如果指定了 PixelInterlockUnorderedEXT
执行模式,则片段着色器中的任何互锁操作必须在光栅化顺序中较早或较晚执行且覆盖同一像素中至少一个样本的片段着色器调用中的互锁操作之前或之后发生。
如果指定了 SampleInterlockOrderedEXT
执行模式,则片段着色器中的任何互锁操作必须在光栅化顺序中稍后执行且覆盖至少一个相同样本的片段着色器调用中的互锁操作之前发生,并且必须在光栅化顺序中较早执行且覆盖至少一个相同样本的片段着色器调用中的互锁操作之后发生。
如果指定了 SampleInterlockUnorderedEXT
执行模式,则片段着色器中的任何互锁操作必须在光栅化顺序中较早或较晚执行且覆盖至少一个相同样本的片段着色器调用中的互锁操作之前或之后发生。
多重采样覆盖率
如果片段着色器处于活动状态,并且其入口点的接口包含使用 SampleMask
修饰的内置输出变量,但没有使用 OverrideCoverageNV
修饰,则覆盖掩码会与 SampleMask
内置变量的位进行 AND
运算,以生成新的覆盖掩码。 如果 SampleMask
内置变量也使用 OverrideCoverageNV
修饰,则覆盖掩码将被着色器中设置的掩码位替换。 如果启用了采样着色,则写入 SampleMask
中对应于片段着色器调用未着色的采样的位将被忽略。 如果没有活动的片段着色器,或者如果活动的片段着色器的接口中不包含 SampleMask
,则覆盖掩码不会被修改。
接下来,如果VkPipelineRasterizationStateCreateInfo结构的 lineRasterizationMode
成员为 VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH
,且VkPipelineMultisampleStateCreateInfo结构的 alphaToCoverageEnable
和 alphaToOneEnable
成员,则会根据线条覆盖率因子修改片段 alpha 值和覆盖掩码。
要动态设置 alphaToCoverageEnable
状态,请调用
// Provided by VK_EXT_extended_dynamic_state3, VK_EXT_shader_object
void vkCmdSetAlphaToCoverageEnableEXT(
VkCommandBuffer commandBuffer,
VkBool32 alphaToCoverageEnable);
-
commandBuffer
是将要记录命令的命令缓冲区。 -
alphaToCoverageEnable
指定alphaToCoverageEnable
状态。
当使用着色器对象进行绘制时,或者当图形管线创建时在VkPipelineDynamicStateCreateInfo::pDynamicStates
中设置了 VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT
时,此命令为后续绘制命令设置 alphaToCoverageEnable
状态。 否则,此状态由用于创建当前活动管线的VkPipelineMultisampleStateCreateInfo::alphaToCoverageEnable
值指定。
要动态设置 alphaToOneEnable
状态,请调用
// Provided by VK_EXT_extended_dynamic_state3, VK_EXT_shader_object
void vkCmdSetAlphaToOneEnableEXT(
VkCommandBuffer commandBuffer,
VkBool32 alphaToOneEnable);
-
commandBuffer
是将要记录命令的命令缓冲区。 -
alphaToOneEnable
指定alphaToOneEnable
状态。
当使用着色器对象进行绘制时,或者当图形管线创建时在VkPipelineDynamicStateCreateInfo::pDynamicStates
中设置了 VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT
时,此命令为后续绘制命令设置 alphaToOneEnable
状态。 否则,此状态由用于创建当前活动管线的VkPipelineMultisampleStateCreateInfo::alphaToOneEnable
值指定。
本节中的所有 alpha 值仅指具有位置和索引装饰为零的片段着色器输出的 alpha 分量(请参阅片段输出接口部分)。 如果该着色器输出具有整数或无符号整数类型,则跳过这些操作。
如果VkPipelineRasterizationStateCreateInfo结构的 lineRasterizationMode
成员为 VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH
,并且片段来自线段,则 alpha 值将被替换为乘以在平滑线光栅化期间计算出的片段的覆盖率因子。
如果启用了 alphaToCoverageEnable
,则会生成一个临时覆盖掩码,其中每个位由片段的 alpha 值确定,该掩码与片段覆盖掩码进行 AND 运算。
没有指定将 alpha 值转换为临时覆盖掩码的特定算法。 目的是使此值中 1 的数量与 alpha 值(钳制到 [0,1])成比例,所有 1 对应于值 1.0,所有 0 对应于 0.0。 该算法在不同的帧缓冲区坐标处可能不同。
在不同的帧缓冲区坐标处使用不同的算法可能有助于避免由规则覆盖采样位置引起的伪影。 |
最后,如果启用了 alphaToOneEnable
,则每个 alpha 值将替换为定点颜色附件的最大可表示 alpha 值,或者对于浮点附件,则替换为 1.0。 否则,alpha 值不会更改。
深度和模板操作
VkPipelineDepthStencilStateCreateInfo
结构定义为
// Provided by VK_VERSION_1_0
typedef struct VkPipelineDepthStencilStateCreateInfo {
VkStructureType sType;
const void* pNext;
VkPipelineDepthStencilStateCreateFlags flags;
VkBool32 depthTestEnable;
VkBool32 depthWriteEnable;
VkCompareOp depthCompareOp;
VkBool32 depthBoundsTestEnable;
VkBool32 stencilTestEnable;
VkStencilOpState front;
VkStencilOpState back;
float minDepthBounds;
float maxDepthBounds;
} VkPipelineDepthStencilStateCreateInfo;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
是NULL
或指向扩展此结构的结构的指针。 -
flags
是 VkPipelineDepthStencilStateCreateFlagBits 的位掩码,用于指定其他深度/模板状态信息。 -
depthTestEnable
控制是否启用深度测试。 -
当
depthTestEnable
为VK_TRUE
时,depthWriteEnable
控制是否启用深度写入。 当depthTestEnable
为VK_FALSE
时,始终禁用深度写入。 -
depthCompareOp
是一个 VkCompareOp 值,指定在深度测试的深度比较步骤中使用的比较运算符。 -
depthBoundsTestEnable
控制是否启用深度边界测试。 -
stencilTestEnable
控制是否启用模板测试。 -
front
和back
是 VkStencilOpState 值,控制模板测试的相应参数。 -
minDepthBounds
是深度边界测试中使用的最小深度边界。 -
maxDepthBounds
是深度边界测试中使用的最大深度边界。
// Provided by VK_VERSION_1_0
typedef VkFlags VkPipelineDepthStencilStateCreateFlags;
VkPipelineDepthStencilStateCreateFlags
是一种位掩码类型,用于设置零个或多个 VkPipelineDepthStencilStateCreateFlagBits 的掩码。
可以在 VkPipelineDepthStencilStateCreateInfo::flags
参数中设置的位是
// Provided by VK_EXT_rasterization_order_attachment_access
typedef enum VkPipelineDepthStencilStateCreateFlagBits {
// Provided by VK_EXT_rasterization_order_attachment_access
VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_EXT = 0x00000001,
// Provided by VK_EXT_rasterization_order_attachment_access
VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_EXT = 0x00000002,
// Provided by VK_ARM_rasterization_order_attachment_access
VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_ARM = VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_EXT,
// Provided by VK_ARM_rasterization_order_attachment_access
VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_ARM = VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_EXT,
} VkPipelineDepthStencilStateCreateFlagBits;
-
VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_EXT
指定对深度/模板和输入附件的深度方面的访问将具有隐式的帧缓冲区本地内存依赖项。 -
VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_EXT
指定对深度/模板和输入附件的模板方面的访问将具有隐式的帧缓冲区本地内存依赖项。
当管道中包含 VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_EXT
时,它会为该管道的绘制命令生成的每个片段形成一个帧缓冲区本地内存依赖项,其作用域如下
当管道中包含 VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_EXT
时,它会为该管道的绘制命令生成的每个片段形成一个帧缓冲区本地内存依赖项,其作用域如下
-
第一个 同步作用域 包括由所有先前片段(由 图元顺序 定义)在相应的 帧缓冲区区域 中执行的
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
管线阶段,包括由同一绘制命令生成的片段。 -
第二个 同步作用域 包括由生成的片段执行的
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
和VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
管线阶段。 -
第一个 访问作用域 包括对深度/模板附件的模板方面进行的所有写入。
-
第二个 访问作用域 包括对输入附件的模板方面进行的所有读取。
深度边界测试
深度边界测试将每个样本的帧缓冲区坐标 (xf,yf) 和 样本索引 i 处的深度/模板附件中的深度值 za 与一组深度边界进行比较。
深度边界由两个浮点值定义,分别定义最小 (minDepthBounds
) 和最大 (maxDepthBounds
) 深度值。这些值可以通过 VkPipelineDepthStencilStateCreateInfo 结构在管道创建期间设置,也可以通过 vkCmdSetDepthBoundsTestEnable 和 vkCmdSetDepthBounds 动态设置。
如果 za 在 [minDepthBounds
,maxDepthBounds
] 范围内,则认为给定样本在深度边界内。深度附件值超出深度边界的样本,其覆盖率将设置为 0
。
如果禁用了深度边界测试,或者没有深度附件,则此操作不会修改覆盖率掩码。
要动态启用或禁用深度边界测试,请调用
// Provided by VK_VERSION_1_3
void vkCmdSetDepthBoundsTestEnable(
VkCommandBuffer commandBuffer,
VkBool32 depthBoundsTestEnable);
或等效命令
// Provided by VK_EXT_extended_dynamic_state, VK_EXT_shader_object
void vkCmdSetDepthBoundsTestEnableEXT(
VkCommandBuffer commandBuffer,
VkBool32 depthBoundsTestEnable);
-
commandBuffer
是将要记录命令的命令缓冲区。 -
depthBoundsTestEnable
指定是否启用深度边界测试。
当使用 着色器对象进行绘制,或在图形管线创建时,VkPipelineDynamicStateCreateInfo::pDynamicStates
中设置了 VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE
时,此命令将为后续的绘制命令设置深度边界启用。否则,此状态由用于创建当前活动管线的 VkPipelineDepthStencilStateCreateInfo::depthBoundsTestEnable
值指定。
要动态设置深度边界范围,请调用
// Provided by VK_VERSION_1_0
void vkCmdSetDepthBounds(
VkCommandBuffer commandBuffer,
float minDepthBounds,
float maxDepthBounds);
-
commandBuffer
是将要记录命令的命令缓冲区。 -
minDepthBounds
是最小深度边界。 -
maxDepthBounds
是最大深度边界。
当使用着色器对象进行绘制,或使用 VkPipelineDynamicStateCreateInfo::pDynamicStates
中设置的 VK_DYNAMIC_STATE_DEPTH_BOUNDS
创建图形管线时,此命令为后续绘制命令设置深度边界范围。否则,此状态由用于创建当前活动管线的VkPipelineDepthStencilStateCreateInfo::minDepthBounds
和 VkPipelineDepthStencilStateCreateInfo::maxDepthBounds
值指定。
模板测试
模板测试将每个样本的帧缓冲区坐标 (xf,yf) 和样本索引 i 处的深度/模板附件中的模板附件值 sa 与模板参考值进行比较。
如果渲染通道具有片段密度映射附件,并且该片段覆盖多个像素,则在片段内覆盖样本与模板附件样本之间存在与实现相关的关联。但是,如果片段中的所有样本都被覆盖,并且模板附件值因该测试而更新,则所有模板附件样本都将被更新。
如果未启用模板测试,如 vkCmdSetStencilTestEnable 或 VkPipelineDepthStencilStateCreateInfo::stencilTestEnable
所指定,或者如果没有模板附件,则此操作不会修改覆盖率掩码。
执行的比较操作由 vkCmdSetStencilOp::compareOp
设置的 VkCompareOp 值或由管道创建期间 VkStencilOpState::compareOp
确定。
前模板状态或后模板状态的比较掩码 sc 和模板参考值 sr 确定比较操作的参数。sc 由管道创建期间的 VkPipelineDepthStencilStateCreateInfo 结构设置,或由 vkCmdSetStencilCompareMask 命令设置。sr 由 VkPipelineDepthStencilStateCreateInfo 或 vkCmdSetStencilReference 设置。
sr 和 sa 分别使用按位 AND
操作与 sc 组合,以创建掩码的参考值和附件值 s'r 和 s'a。 s'r 和 s'a 分别用作 VkCompareOp 指定的操作中的参考值和测试值。
如果比较结果为假,则样本的覆盖率设置为 0
。
根据 vkCmdSetStencilOp 或 VkPipelineDepthStencilStateCreateInfo 设置的 VkStencilOp 参数定义的模板操作,生成新的模板值 sg。如果模板测试失败,则 failOp
定义使用的模板操作。但是,如果模板测试通过,则使用的模板操作基于 深度测试 - 如果通过,则使用 VkPipelineDepthStencilStateCreateInfo::passOp
,否则使用 VkPipelineDepthStencilStateCreateInfo::depthFailOp
。
然后根据 VkPipelineDepthStencilStateCreateInfo::front
和 VkPipelineDepthStencilStateCreateInfo::back
中的 writeMask
定义的写入掩码 sw,使用生成的模板值 sg 更新模板附件值 sa,如下所示:
-
sa = (sa ∧ ¬sw) ∨ (sg ∧ sw)
要动态启用或禁用模板测试,请调用
// Provided by VK_VERSION_1_3
void vkCmdSetStencilTestEnable(
VkCommandBuffer commandBuffer,
VkBool32 stencilTestEnable);
或等效命令
// Provided by VK_EXT_extended_dynamic_state, VK_EXT_shader_object
void vkCmdSetStencilTestEnableEXT(
VkCommandBuffer commandBuffer,
VkBool32 stencilTestEnable);
-
commandBuffer
是将要记录命令的命令缓冲区。 -
stencilTestEnable
指定是否启用模板测试。
此命令设置使用着色器对象绘图时,或当图形管线使用VkPipelineDynamicStateCreateInfo::pDynamicStates
中设置的VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE
创建时,后续绘图命令的模板测试启用状态。否则,此状态由用于创建当前活动管线的VkPipelineDepthStencilStateCreateInfo::stencilTestEnable
值指定。
要动态设置模板操作,请调用
// Provided by VK_VERSION_1_3
void vkCmdSetStencilOp(
VkCommandBuffer commandBuffer,
VkStencilFaceFlags faceMask,
VkStencilOp failOp,
VkStencilOp passOp,
VkStencilOp depthFailOp,
VkCompareOp compareOp);
或等效命令
// Provided by VK_EXT_extended_dynamic_state, VK_EXT_shader_object
void vkCmdSetStencilOpEXT(
VkCommandBuffer commandBuffer,
VkStencilFaceFlags faceMask,
VkStencilOp failOp,
VkStencilOp passOp,
VkStencilOp depthFailOp,
VkCompareOp compareOp);
-
commandBuffer
是将要记录命令的命令缓冲区。 -
faceMask
是一个 VkStencilFaceFlagBits 的位掩码,指定要更新模板操作的模板状态集。 -
failOp
是一个 VkStencilOp 值,指定在模板测试失败的样本上执行的操作。 -
passOp
是一个 VkStencilOp 值,指定在通过深度测试和模板测试的样本上执行的操作。 -
depthFailOp
是一个 VkStencilOp 值,指定在通过模板测试但深度测试失败的样本上执行的操作。 -
compareOp
是一个 VkCompareOp 值,指定模板测试中使用的比较运算符。
当使用着色器对象绘图时,或当图形管线使用VkPipelineDynamicStateCreateInfo::pDynamicStates
中设置的VK_DYNAMIC_STATE_STENCIL_OP
创建时,此命令将为后续绘图命令设置模板操作。否则,此状态由用于创建当前活动管线的相应 VkPipelineDepthStencilStateCreateInfo
::failOp
、passOp
、depthFailOp
和 compareOp
值指定,适用于正面和背面。
VkStencilOpState
结构的定义如下
// Provided by VK_VERSION_1_0
typedef struct VkStencilOpState {
VkStencilOp failOp;
VkStencilOp passOp;
VkStencilOp depthFailOp;
VkCompareOp compareOp;
uint32_t compareMask;
uint32_t writeMask;
uint32_t reference;
} VkStencilOpState;
-
failOp
是一个 VkStencilOp 值,指定在模板测试失败的样本上执行的操作。 -
passOp
是一个 VkStencilOp 值,指定在通过深度测试和模板测试的样本上执行的操作。 -
depthFailOp
是一个 VkStencilOp 值,指定在通过模板测试但深度测试失败的样本上执行的操作。 -
compareOp
是一个 VkCompareOp 值,指定模板测试中使用的比较运算符。 -
compareMask
选择参与模板测试的无符号整数模板值的位。 -
writeMask
选择模板帧缓冲附件中由模板测试更新的无符号整数模板值的位。 -
reference
是一个整数模板参考值,用于无符号模板比较。
要动态设置模板比较掩码,请调用
// Provided by VK_VERSION_1_0
void vkCmdSetStencilCompareMask(
VkCommandBuffer commandBuffer,
VkStencilFaceFlags faceMask,
uint32_t compareMask);
-
commandBuffer
是将要记录命令的命令缓冲区。 -
faceMask
是 VkStencilFaceFlagBits 的位掩码,指定要更新比较掩码的模板状态集。 -
compareMask
是用作模板比较掩码的新值。
当使用着色器对象绘图时,或当图形管线使用VkPipelineDynamicStateCreateInfo::pDynamicStates
中设置的VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK
创建时,此命令将为后续绘图命令设置模板比较掩码。否则,此状态由用于创建当前活动管线的VkStencilOpState::compareMask
值指定,适用于正面和背面。
VkStencilFaceFlagBits
值如下
// Provided by VK_VERSION_1_0
typedef enum VkStencilFaceFlagBits {
VK_STENCIL_FACE_FRONT_BIT = 0x00000001,
VK_STENCIL_FACE_BACK_BIT = 0x00000002,
VK_STENCIL_FACE_FRONT_AND_BACK = 0x00000003,
// VK_STENCIL_FRONT_AND_BACK is a deprecated alias
VK_STENCIL_FRONT_AND_BACK = VK_STENCIL_FACE_FRONT_AND_BACK,
} VkStencilFaceFlagBits;
-
VK_STENCIL_FACE_FRONT_BIT
指定仅更新正面模板状态集。 -
VK_STENCIL_FACE_BACK_BIT
指定仅更新背面模板状态集。 -
VK_STENCIL_FACE_FRONT_AND_BACK
是VK_STENCIL_FACE_FRONT_BIT
和VK_STENCIL_FACE_BACK_BIT
的组合,指定更新两组模板状态。
// Provided by VK_VERSION_1_0
typedef VkFlags VkStencilFaceFlags;
VkStencilFaceFlags
是一种位掩码类型,用于设置零个或多个 VkStencilFaceFlagBits 的掩码。
要动态设置模板写入掩码,请调用
// Provided by VK_VERSION_1_0
void vkCmdSetStencilWriteMask(
VkCommandBuffer commandBuffer,
VkStencilFaceFlags faceMask,
uint32_t writeMask);
-
commandBuffer
是将要记录命令的命令缓冲区。 -
faceMask
是 VkStencilFaceFlagBits 的位掩码,指定要更新写入掩码的模板状态集,如上述 vkCmdSetStencilCompareMask 中所述。 -
writeMask
是用作模板写入掩码的新值。
当使用着色器对象绘图时,或当图形管线使用VkPipelineDynamicStateCreateInfo::pDynamicStates
中设置的VK_DYNAMIC_STATE_STENCIL_WRITE_MASK
创建时,此命令将为后续绘图命令设置模板写入掩码。否则,此状态由用于创建当前活动管线的 writeMask
值指定,适用于 VkPipelineDepthStencilStateCreateInfo::front
和 VkPipelineDepthStencilStateCreateInfo::back
面。
要动态设置模板写入掩码,请调用
// Provided by VK_VERSION_1_0
void vkCmdSetStencilReference(
VkCommandBuffer commandBuffer,
VkStencilFaceFlags faceMask,
uint32_t reference);
-
commandBuffer
是将要记录命令的命令缓冲区。 -
faceMask
是一个 VkStencilFaceFlagBits 的位掩码,指定要更新参考值的模板状态集合,如上文对 vkCmdSetStencilCompareMask 的描述。 -
reference
是用作模板参考值的新值。
当使用着色器对象进行绘制时,或者当图形管线创建时,在VkPipelineDynamicStateCreateInfo::pDynamicStates
中设置了 VK_DYNAMIC_STATE_STENCIL_REFERENCE
,此命令为后续绘制命令设置模板参考值。 否则,此状态由用于创建当前活动管线的VkPipelineDepthStencilStateCreateInfo::reference
值指定,用于正面和背面。
当此测试或某些后续测试失败或通过时,指定存储的模板值会发生什么情况的VkStencilOpState的failOp
、passOp
和depthFailOp
成员的可能值为
// Provided by VK_VERSION_1_0
typedef enum VkStencilOp {
VK_STENCIL_OP_KEEP = 0,
VK_STENCIL_OP_ZERO = 1,
VK_STENCIL_OP_REPLACE = 2,
VK_STENCIL_OP_INCREMENT_AND_CLAMP = 3,
VK_STENCIL_OP_DECREMENT_AND_CLAMP = 4,
VK_STENCIL_OP_INVERT = 5,
VK_STENCIL_OP_INCREMENT_AND_WRAP = 6,
VK_STENCIL_OP_DECREMENT_AND_WRAP = 7,
} VkStencilOp;
-
VK_STENCIL_OP_KEEP
保留当前值。 -
VK_STENCIL_OP_ZERO
将值设置为 0。 -
VK_STENCIL_OP_REPLACE
将值设置为reference
。 -
VK_STENCIL_OP_INCREMENT_AND_CLAMP
递增当前值并钳制到最大可表示的无符号值。 -
VK_STENCIL_OP_DECREMENT_AND_CLAMP
递减当前值并钳制到 0。 -
VK_STENCIL_OP_INVERT
按位反转当前值。 -
VK_STENCIL_OP_INCREMENT_AND_WRAP
递增当前值,并在超出最大值时回绕到 0。 -
VK_STENCIL_OP_DECREMENT_AND_WRAP
递减当前值,并在值低于 0 时回绕到最大可能值。
出于递增和递减的目的,模板位被视为无符号整数。
深度测试
深度测试将深度/模板附件中每个样本的帧缓冲坐标(xf,yf)处的深度值 za 与样本的深度值 zf进行比较。样本索引i。 如果没有深度附件,则跳过深度测试。
如果渲染通道具有片段密度图附件,并且该片段覆盖多个像素,则在片段内,光栅化样本到深度附件样本的关联取决于实现。 但是,如果片段中的所有样本都被覆盖,并且由于此测试而更新了深度附件值,则将更新所有深度附件样本。
深度测试分为三个阶段,如下节详述。
深度钳制和范围调整
如果启用了VkPipelineRasterizationStateCreateInfo::depthClampEnable
,则 zf 被钳制到 [zmin, zmax],其中 zmin = min(n,f), zmax = max(n,f),并且 n 和 f 分别是此片段使用的视口的 minDepth
和 maxDepth
深度范围值。 如果启用了depthClampControl
功能并且 VkPipelineViewportDepthClampControlCreateInfoEXT::depthClampMode
为 VK_DEPTH_CLAMP_MODE_USER_DEFINED_RANGE_EXT
,则 zmin 和 zmax 等于 pDepthClampRange
指向的VkDepthClampRangeEXT结构的 minDepthClamp
和 maxDepthClamp
值。
如果启用了VkPhysicalDeviceDepthClampZeroOneFeaturesKHR::depthClampZeroOne
-
如果深度附件具有浮点格式,并且启用了VK_EXT_depth_range_unrestricted,则 zf 不会更改。
-
否则,zf 被钳制到范围 [0, 1]。
否则
-
如果 zf 不在 [zmin, zmax] 范围内,则在此步骤之后,zf 是未定义的。
-
如果深度附件具有定点格式,并且 zf 不在 [0, 1] 范围内,则在此步骤之后,zf 是未定义的。
VkPipelineViewportDepthClampControlCreateInfoEXT
结构定义为
// Provided by VK_EXT_depth_clamp_control
typedef struct VkPipelineViewportDepthClampControlCreateInfoEXT {
VkStructureType sType;
const void* pNext;
VkDepthClampModeEXT depthClampMode;
const VkDepthClampRangeEXT* pDepthClampRange;
} VkPipelineViewportDepthClampControlCreateInfoEXT;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
是NULL
或指向扩展此结构的结构的指针。 -
depthClampMode
确定如何为每个视口确定钳制范围。 -
如果
depthClampMode
为VK_DEPTH_CLAMP_MODE_USER_DEFINED_RANGE_EXT
,则pDepthClampRange
为所有视口设置深度钳制范围。
此结构扩展了 VkPipelineViewportStateCreateInfo
并指定了管线中使用的深度钳制范围。 如果在下一个链中未提供此结构,则 depthClampMode
默认为 VK_DEPTH_CLAMP_MODE_VIEWPORT_RANGE_EXT
。
指定应将哪个范围用于深度钳制的 VkPipelineViewportDepthClampControlCreateInfoEXT::depthClampMode
的可能值为
// Provided by VK_EXT_depth_clamp_control
typedef enum VkDepthClampModeEXT {
VK_DEPTH_CLAMP_MODE_VIEWPORT_RANGE_EXT = 0,
VK_DEPTH_CLAMP_MODE_USER_DEFINED_RANGE_EXT = 1,
} VkDepthClampModeEXT;
-
VK_DEPTH_CLAMP_MODE_VIEWPORT_RANGE_EXT
指定深度钳制范围遵循视口深度范围。每个视口的深度钳制范围将隐式设置为 zmin = min(n,f) 和 zmax = max(n,f),其中 n 和 f 是视口的minDepth
和maxDepth
深度范围值。 -
VK_DEPTH_CLAMP_MODE_USER_DEFINED_RANGE_EXT
指定将对所有视口使用单个用户定义的深度钳制范围。用户定义的深度钳制范围由 VkDepthClampRangeEXT 的minDepthClamp
和maxDepthClamp
成员定义。
要动态设置视口深度钳制范围参数,请调用
// Provided by VK_EXT_depth_clamp_control, VK_EXT_depth_clamp_control with VK_EXT_shader_object
void vkCmdSetDepthClampRangeEXT(
VkCommandBuffer commandBuffer,
VkDepthClampModeEXT depthClampMode,
const VkDepthClampRangeEXT* pDepthClampRange);
-
commandBuffer
是将要记录命令的命令缓冲区。 -
depthClampMode
确定如何为每个视口确定钳制范围。 -
如果
depthClampMode
为VK_DEPTH_CLAMP_MODE_USER_DEFINED_RANGE_EXT
,则pDepthClampRange
为所有视口设置深度钳制范围。
当使用着色器对象进行绘制时,或者当图形管线在 VkPipelineDynamicStateCreateInfo::pDynamicStates
中设置了 VK_DYNAMIC_STATE_DEPTH_CLAMP_RANGE_EXT
时,此命令会为后续绘制命令设置视口深度钳制范围。否则,此状态由用于创建当前活动管线的 VkPipelineViewportDepthClampControlCreateInfoEXT::depthClampMode
值指定。
VkPipelineViewportDepthClampControlCreateInfoEXT 和 vkCmdSetDepthClampRangeEXT 都使用 VkDepthClampRangeEXT
来设置视口深度钳制范围参数。
VkDepthClampRangeEXT
结构的定义如下
// Provided by VK_EXT_depth_clamp_control
typedef struct VkDepthClampRangeEXT {
float minDepthClamp;
float maxDepthClamp;
} VkDepthClampRangeEXT;
-
minDepthClamp
设置视口深度钳制范围中的 zmin。 -
maxDepthClamp
设置视口深度钳制范围中的 zmax。
深度比较
如果深度测试未启用,如 vkCmdSetDepthTestEnable 或 VkPipelineDepthStencilStateCreateInfo::depthTestEnable
所指定,则跳过此步骤。
执行的比较操作由 VkCompareOp 值决定,该值由 vkCmdSetDepthCompareOp 设置,或者由管线创建期间的 VkPipelineDepthStencilStateCreateInfo::depthCompareOp
设置。 zf 和 za 在 VkCompareOp 指定的操作中分别用作参考值和测试值。
如果比较结果为假,则样本的覆盖率设置为 0
。
深度附件写入
如果启用了深度写入,如 vkCmdSetDepthWriteEnable 或 VkPipelineDepthStencilStateCreateInfo::depthWriteEnable
所指定,并且比较结果为真,则深度附件值 za 设置为样本的深度值 zf。如果没有深度附件,则不写入任何值。
要动态启用或禁用深度测试,请调用
// Provided by VK_VERSION_1_3
void vkCmdSetDepthTestEnable(
VkCommandBuffer commandBuffer,
VkBool32 depthTestEnable);
或等效命令
// Provided by VK_EXT_extended_dynamic_state, VK_EXT_shader_object
void vkCmdSetDepthTestEnableEXT(
VkCommandBuffer commandBuffer,
VkBool32 depthTestEnable);
-
commandBuffer
是将要记录命令的命令缓冲区。 -
depthTestEnable
指定是否启用深度测试。
当使用着色器对象进行绘制时,或者当图形管线在 VkPipelineDynamicStateCreateInfo::pDynamicStates
中设置了 VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE
时,此命令会为后续绘制命令设置深度测试启用状态。否则,此状态由用于创建当前活动管线的 VkPipelineDepthStencilStateCreateInfo::depthTestEnable
值指定。
要动态设置深度比较运算符,请调用
// Provided by VK_VERSION_1_3
void vkCmdSetDepthCompareOp(
VkCommandBuffer commandBuffer,
VkCompareOp depthCompareOp);
或等效命令
// Provided by VK_EXT_extended_dynamic_state, VK_EXT_shader_object
void vkCmdSetDepthCompareOpEXT(
VkCommandBuffer commandBuffer,
VkCompareOp depthCompareOp);
-
commandBuffer
是将要记录命令的命令缓冲区。 -
depthCompareOp
是一个 VkCompareOp 值,指定用于深度比较步骤的比较运算符,该步骤是深度测试的一部分。
当使用着色器对象进行绘制时,或者当图形管线在 VkPipelineDynamicStateCreateInfo::pDynamicStates
中设置了 VK_DYNAMIC_STATE_DEPTH_COMPARE_OP
时,此命令会为后续绘制命令设置深度比较运算符。否则,此状态由用于创建当前活动管线的 VkPipelineDepthStencilStateCreateInfo::depthCompareOp
值指定。
要动态设置深度写入启用状态,请调用
// Provided by VK_VERSION_1_3
void vkCmdSetDepthWriteEnable(
VkCommandBuffer commandBuffer,
VkBool32 depthWriteEnable);
或等效命令
// Provided by VK_EXT_extended_dynamic_state, VK_EXT_shader_object
void vkCmdSetDepthWriteEnableEXT(
VkCommandBuffer commandBuffer,
VkBool32 depthWriteEnable);
-
commandBuffer
是将要记录命令的命令缓冲区。 -
depthWriteEnable
指定是否启用深度写入。
当使用着色器对象进行绘制,或当使用在VkPipelineDynamicStateCreateInfo::pDynamicStates
中设置了VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE
的图形管线创建时,此命令为后续的绘制命令设置深度写入启用状态。否则,此状态由用于创建当前活动管线的VkPipelineDepthStencilStateCreateInfo::depthWriteEnable
值指定。
代表性片段测试
代表性片段测试允许实现减少为每个点、线或三角形图元执行的光栅化和片段处理工作量。对于任何产生一个或多个通过所有先前的早期片段测试的片段的图元,实现**可以**选择一个或多个“代表性”片段进行处理,并丢弃所有其他片段。对于渲染以列表、条带或扇形排列的多个点、线或三角形的绘制调用,将为每个图元独立执行代表性片段测试。由代表性片段测试丢弃的片段集合与实现相关。在某些情况下,代表性片段测试可能不会丢弃给定图元的任何片段。
如果 VkGraphicsPipelineCreateInfo 的 pNext
链包含 VkPipelineRepresentativeFragmentTestStateCreateInfoNV
结构,则该结构包含控制代表性片段测试的参数。
VkPipelineRepresentativeFragmentTestStateCreateInfoNV
结构定义为
// Provided by VK_NV_representative_fragment_test
typedef struct VkPipelineRepresentativeFragmentTestStateCreateInfoNV {
VkStructureType sType;
const void* pNext;
VkBool32 representativeFragmentTestEnable;
} VkPipelineRepresentativeFragmentTestStateCreateInfoNV;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
是NULL
或指向扩展此结构的结构的指针。 -
representativeFragmentTestEnable
控制是否启用代表性片段测试。
如果此结构未包含在 pNext
链中,则认为 representativeFragmentTestEnable
为 VK_FALSE
,并且禁用代表性片段测试。
如果活动的片段着色器未指定 EarlyFragmentTests
执行模式,则即使启用,代表性片段着色器测试也无效。
要动态设置 representativeFragmentTestEnable
状态,请调用
// Provided by VK_EXT_extended_dynamic_state3 with VK_NV_representative_fragment_test, VK_EXT_shader_object with VK_NV_representative_fragment_test
void vkCmdSetRepresentativeFragmentTestEnableNV(
VkCommandBuffer commandBuffer,
VkBool32 representativeFragmentTestEnable);
-
commandBuffer
是将要记录命令的命令缓冲区。 -
representativeFragmentTestEnable
指定representativeFragmentTestEnable
状态。
当使用着色器对象进行绘制时,或当使用在 VkPipelineDynamicStateCreateInfo::pDynamicStates
中设置了 VK_DYNAMIC_STATE_REPRESENTATIVE_FRAGMENT_TEST_ENABLE_NV
的图形管线创建时,此命令为后续的绘制命令设置 representativeFragmentTestEnable
状态。否则,此状态由用于创建当前活动管线的 VkPipelineRepresentativeFragmentTestStateCreateInfoNV::representativeFragmentTestEnable
值指定。
采样计数
遮挡查询使用查询池条目来跟踪通过所有逐片段测试的采样数。收集遮挡查询值的机制在遮挡查询中描述。
对于通过所有逐片段测试(包括裁剪、独占裁剪、采样掩码、alpha 到覆盖率、模板和深度测试)的每个片段中,覆盖率值为 1 的每个采样,遮挡查询采样计数器递增 1。
片段覆盖率到颜色
VkPipelineCoverageToColorStateCreateInfoNV
结构定义为
// Provided by VK_NV_fragment_coverage_to_color
typedef struct VkPipelineCoverageToColorStateCreateInfoNV {
VkStructureType sType;
const void* pNext;
VkPipelineCoverageToColorStateCreateFlagsNV flags;
VkBool32 coverageToColorEnable;
uint32_t coverageToColorLocation;
} VkPipelineCoverageToColorStateCreateInfoNV;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
是NULL
或指向扩展此结构的结构的指针。 -
flags
保留以供将来使用。 -
coverageToColorEnable
控制片段覆盖率值是否替换片段颜色输出。 -
coverageToColorLocation
控制替换哪个片段着色器颜色输出值。
如果VkPipelineMultisampleStateCreateInfo 的 pNext
链包含 VkPipelineCoverageToColorStateCreateInfoNV
结构,则该结构控制是否将片段覆盖率替换为片段颜色输出,如果是,则替换哪个输出。
如果 coverageToColorEnable
为 VK_TRUE
,则覆盖率掩码将替换片段着色器输出位置的颜色值的第一个分量,其中 Location
等于 coverageToColorLocation
,Index
等于零。如果颜色附件格式的位数少于覆盖率掩码,则在没有任何钳制的情况下采用采样覆盖率掩码的低位。如果颜色附件格式的位数多于覆盖率掩码,则采样覆盖率掩码的高位将填充零。
如果 coverageToColorEnable
为 VK_FALSE
,则跳过这些操作。如果 pNext
链中未包含此结构,则等同于 coverageToColorEnable
为 VK_FALSE
。
// Provided by VK_NV_fragment_coverage_to_color
typedef VkFlags VkPipelineCoverageToColorStateCreateFlagsNV;
VkPipelineCoverageToColorStateCreateFlagsNV
是用于设置掩码的位掩码类型,但目前保留供将来使用。
要动态设置 coverageToColorEnable
状态,请调用
// Provided by VK_EXT_extended_dynamic_state3 with VK_NV_fragment_coverage_to_color, VK_EXT_shader_object with VK_NV_fragment_coverage_to_color
void vkCmdSetCoverageToColorEnableNV(
VkCommandBuffer commandBuffer,
VkBool32 coverageToColorEnable);
-
commandBuffer
是将要记录命令的命令缓冲区。 -
coverageToColorEnable
指定coverageToColorEnable
状态。
当使用 着色器对象进行绘制时,或者当图形管线在 VkPipelineDynamicStateCreateInfo::pDynamicStates
中设置了 VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_ENABLE_NV
时,此命令会为后续绘制命令设置 coverageToColorEnable
状态。否则,此状态由用于创建当前活动管线的 VkPipelineCoverageToColorStateCreateInfoNV::coverageToColorEnable
值指定。
要动态设置 coverageToColorLocation
状态,请调用
// Provided by VK_EXT_extended_dynamic_state3 with VK_NV_fragment_coverage_to_color, VK_EXT_shader_object with VK_NV_fragment_coverage_to_color
void vkCmdSetCoverageToColorLocationNV(
VkCommandBuffer commandBuffer,
uint32_t coverageToColorLocation);
-
commandBuffer
是将要记录命令的命令缓冲区。 -
coverageToColorLocation
指定coverageToColorLocation
状态。
当使用 着色器对象进行绘制时,或者当图形管线在 VkPipelineDynamicStateCreateInfo::pDynamicStates
中设置了 VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_LOCATION_NV
时,此命令会为后续绘制命令设置 coverageToColorLocation
状态。否则,此状态由用于创建当前活动管线的 VkPipelineCoverageToColorStateCreateInfoNV::coverageToColorLocation
值指定。
覆盖率缩减
覆盖率缩减获取片段的覆盖信息,并将其转换为片段覆盖的每个像素中每个颜色样本的布尔覆盖值。
像素覆盖率
每个像素的覆盖率首先从总片段覆盖掩码中提取。这包括片段区域中每个像素的 rasterizationSamples
个唯一覆盖率样本,每个样本都有一个唯一的样本索引。如果片段仅包含单个像素,则该像素的覆盖率等同于片段覆盖率。
如果渲染通道具有片段密度图附件,并且片段覆盖多个像素,则以实现相关的方式生成像素覆盖率。如果片段中的所有样本都被覆盖,则每个像素覆盖率中的所有样本都将被覆盖。
颜色样本覆盖率
一旦确定了像素覆盖率,就确定了与该像素对应的每个颜色样本的覆盖率。
如果 rasterizationSamples
的数量与颜色附件中的样本数量相同,则如果具有相同样本索引 i 的像素覆盖率样本被覆盖,则颜色样本被覆盖。
否则,每个颜色样本的覆盖率按以下方式从像素覆盖率计算得出。
如果启用了 VK_AMD_mixed_attachment_samples
扩展,则对于颜色附件中存在的颜色样本,如果具有相同样本索引 i 的像素覆盖率样本被覆盖,则颜色样本被覆盖;额外的像素覆盖率样本将被丢弃。
如果 VkSubpassDescription2 或 VkRenderingInfo 的 pNext
链包含 VkMultisampledRenderToSingleSampledInfoEXT 结构,且 multisampledRenderToSingleSampledEnable
字段等于 VK_TRUE
,则样本覆盖率的计算方式就好像附件具有 VkMultisampledRenderToSingleSampledInfoEXT::rasterizationSamples
个样本。
启用 VK_NV_coverage_reduction_mode
扩展时,控制覆盖率缩减的管线状态通过 VkPipelineCoverageReductionStateCreateInfoNV
结构的成员指定。
VkPipelineCoverageReductionStateCreateInfoNV
结构的定义如下
// Provided by VK_NV_coverage_reduction_mode
typedef struct VkPipelineCoverageReductionStateCreateInfoNV {
VkStructureType sType;
const void* pNext;
VkPipelineCoverageReductionStateCreateFlagsNV flags;
VkCoverageReductionModeNV coverageReductionMode;
} VkPipelineCoverageReductionStateCreateInfoNV;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
是NULL
或指向扩展此结构的结构的指针。 -
flags
保留以供将来使用。 -
coverageReductionMode
是一个 VkCoverageReductionModeNV 值,用于控制如何从像素覆盖率生成颜色样本覆盖率。
如果此结构未包含在 pNext
链中,或者如果未启用该扩展,则默认的覆盖率降低模式推断如下:
-
如果启用了
VK_NV_framebuffer_mixed_samples
扩展,则如同coverageReductionMode
为VK_COVERAGE_REDUCTION_MODE_MERGE_NV
。 -
如果启用了
VK_AMD_mixed_attachment_samples
扩展,则如同coverageReductionMode
为VK_COVERAGE_REDUCTION_MODE_TRUNCATE_NV
。 -
如果同时启用了
VK_NV_framebuffer_mixed_samples
和VK_AMD_mixed_attachment_samples
,则默认的覆盖率降低模式取决于实现。
// Provided by VK_NV_coverage_reduction_mode
typedef VkFlags VkPipelineCoverageReductionStateCreateFlagsNV;
VkPipelineCoverageReductionStateCreateFlagsNV
是一个用于设置掩码的位掩码类型,但目前保留供将来使用。
VkPipelineCoverageReductionStateCreateInfoNV::coverageReductionMode
的可能值,指定如何从像素覆盖生成颜色采样覆盖率,如下所示:
// Provided by VK_NV_coverage_reduction_mode
typedef enum VkCoverageReductionModeNV {
VK_COVERAGE_REDUCTION_MODE_MERGE_NV = 0,
VK_COVERAGE_REDUCTION_MODE_TRUNCATE_NV = 1,
} VkCoverageReductionModeNV;
-
VK_COVERAGE_REDUCTION_MODE_MERGE_NV
指定每个颜色采样将与像素覆盖中依赖于实现的采样子集相关联。如果任何关联的采样被覆盖,则颜色采样被覆盖。 -
VK_COVERAGE_REDUCTION_MODE_TRUNCATE_NV
指定对于颜色附件中存在的颜色采样,如果具有相同 采样索引 i 的像素覆盖采样被覆盖,则颜色采样被覆盖;其他像素覆盖采样将被丢弃。
要动态设置 coverageReductionMode
状态,请调用
// Provided by VK_EXT_extended_dynamic_state3 with VK_NV_coverage_reduction_mode, VK_EXT_shader_object with VK_NV_coverage_reduction_mode
void vkCmdSetCoverageReductionModeNV(
VkCommandBuffer commandBuffer,
VkCoverageReductionModeNV coverageReductionMode);
-
commandBuffer
是将要记录命令的命令缓冲区。 -
coverageReductionMode
指定coverageReductionMode
状态。
当使用着色器对象进行绘制时,或者当图形管线在VkPipelineDynamicStateCreateInfo::pDynamicStates
中设置了 VK_DYNAMIC_STATE_COVERAGE_REDUCTION_MODE_NV
时,此命令会为后续的绘制命令设置 coverageReductionMode
状态。否则,此状态由用于创建当前活动管线的 VkPipelineCoverageReductionStateCreateInfoNV::coverageReductionMode
值指定。
要查询物理设备支持的覆盖率降低模式、光栅化采样和颜色、深度、模板附件采样计数的混合采样组合集,请调用:
// Provided by VK_NV_coverage_reduction_mode
VkResult vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV(
VkPhysicalDevice physicalDevice,
uint32_t* pCombinationCount,
VkFramebufferMixedSamplesCombinationNV* pCombinations);
-
physicalDevice
是要从中查询组合集的物理设备。 -
pCombinationCount
是一个指向整数的指针,该整数与可用或查询的组合数量有关,如下所述。 -
pCombinations
要么是NULL
,要么是指向 VkFramebufferMixedSamplesCombinationNV 值数组的指针,该数组指示支持的覆盖率降低模式、光栅化采样和颜色、深度、模板附件采样计数组合。
如果 pCombinations
为 NULL
,则给定 physicalDevice
支持的组合数量将在 pCombinationCount
中返回。 否则,pCombinationCount
必须指向应用程序设置为 pCombinations
数组中元素数量的变量,并且在返回时,该变量将被实际写入到 pCombinations
的值数量覆盖。 如果 pCombinationCount
的值小于给定 physicalDevice
支持的组合数量,则最多会将 pCombinationCount
个值写入 pCombinations
,并且将返回 VK_INCOMPLETE
而不是 VK_SUCCESS
,以指示并非所有支持的值都已返回。
VkFramebufferMixedSamplesCombinationNV
结构定义如下:
// Provided by VK_NV_coverage_reduction_mode
typedef struct VkFramebufferMixedSamplesCombinationNV {
VkStructureType sType;
void* pNext;
VkCoverageReductionModeNV coverageReductionMode;
VkSampleCountFlagBits rasterizationSamples;
VkSampleCountFlags depthStencilSamples;
VkSampleCountFlags colorSamples;
} VkFramebufferMixedSamplesCombinationNV;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
是NULL
或指向扩展此结构的结构的指针。 -
coverageReductionMode
是一个 VkCoverageReductionModeNV 值,指定覆盖率降低模式。 -
rasterizationSamples
是一个 VkSampleCountFlagBits,指定支持的组合中的光栅化采样数。 -
depthStencilSamples
指定支持的组合中深度模板附件中的采样数。值为 0 表示该组合没有深度模板附件。 -
colorSamples
指定支持的组合中颜色附件中的颜色采样数。值为 0 表示该组合没有颜色附件。
覆盖率调制
作为覆盖率降低的一部分,片段颜色值可以通过一个值进行调制(相乘),该值是与该颜色采样关联的覆盖光栅化采样的分数的函数。
控制覆盖率调制的管线状态通过 VkPipelineCoverageModulationStateCreateInfoNV
结构的成员指定。
VkPipelineCoverageModulationStateCreateInfoNV
结构定义如下:
// Provided by VK_NV_framebuffer_mixed_samples
typedef struct VkPipelineCoverageModulationStateCreateInfoNV {
VkStructureType sType;
const void* pNext;
VkPipelineCoverageModulationStateCreateFlagsNV flags;
VkCoverageModulationModeNV coverageModulationMode;
VkBool32 coverageModulationTableEnable;
uint32_t coverageModulationTableCount;
const float* pCoverageModulationTable;
} VkPipelineCoverageModulationStateCreateInfoNV;
-
sType
是一个 VkStructureType 值,用于标识此结构。 -
pNext
是NULL
或指向扩展此结构的结构的指针。 -
flags
保留以供将来使用。 -
coverageModulationMode
是一个 VkCoverageModulationModeNV 值,控制调制哪些颜色分量。 -
coverageModulationTableEnable
控制是否从pCoverageModulationTable
中的表格查找调制因子。 -
coverageModulationTableCount
是pCoverageModulationTable
中元素的数量。 -
pCoverageModulationTable
是一个调制因子表,其中包含每个覆盖样本数量的值。
如果 coverageModulationTableEnable
为 VK_FALSE
,则对于每个颜色样本,将计算像素覆盖率的相关位,并除以相关位的数量,以产生范围在 (0,1] 内的调制因子 R (值为零的样本会被颜色覆盖率为 0 杀死)。具体来说:
-
N =
rasterizationSamples
的值 -
M = 任何颜色附件的 VkAttachmentDescription::
samples
的值 -
R = popcount(关联的覆盖位) / (N / M)
如果 coverageModulationTableEnable
为 VK_TRUE
,则使用可编程查找表计算值 R。查找表具有 N / M 个元素,并且表的元素由以下方式选择:
-
R =
pCoverageModulationTable
[popcount(关联的覆盖位)-1]
请注意,该表没有 popcount(关联的覆盖位) = 0 的条目,因为此类样本会被杀死。
pCoverageModulationTable
的值**可能**被四舍五入到依赖于实现的精度,该精度至少与 1 / N 一样精细,并被限制在 [0,1] 范围内。
对于每个具有浮点或归一化颜色格式的颜色附件,每个片段输出颜色值都被复制到 M 个值,这些值**可以**各自乘以该颜色样本的关联值 R。哪些分量被调制由 coverageModulationMode
控制。
如果此结构未包含在 pNext
链中,则相当于 coverageModulationMode
为 VK_COVERAGE_MODULATION_MODE_NONE_NV
。
如果覆盖率降低模式为 VK_COVERAGE_REDUCTION_MODE_TRUNCATE_NV
,则每个颜色样本仅与一个覆盖样本相关联。在这种情况下,相当于 coverageModulationMode
为 VK_COVERAGE_MODULATION_MODE_NONE_NV
。
// Provided by VK_NV_framebuffer_mixed_samples
typedef VkFlags VkPipelineCoverageModulationStateCreateFlagsNV;
VkPipelineCoverageModulationStateCreateFlagsNV
是一个用于设置掩码的位掩码类型,但目前保留供将来使用。
VkPipelineCoverageModulationStateCreateInfoNV::coverageModulationMode
的可能值,指定哪些颜色分量被调制,为:
// Provided by VK_NV_framebuffer_mixed_samples
typedef enum VkCoverageModulationModeNV {
VK_COVERAGE_MODULATION_MODE_NONE_NV = 0,
VK_COVERAGE_MODULATION_MODE_RGB_NV = 1,
VK_COVERAGE_MODULATION_MODE_ALPHA_NV = 2,
VK_COVERAGE_MODULATION_MODE_RGBA_NV = 3,
} VkCoverageModulationModeNV;
-
VK_COVERAGE_MODULATION_MODE_NONE_NV
指定没有分量乘以调制因子。 -
VK_COVERAGE_MODULATION_MODE_RGB_NV
指定红色、绿色和蓝色分量乘以调制因子。 -
VK_COVERAGE_MODULATION_MODE_ALPHA_NV
指定 alpha 分量乘以调制因子。 -
VK_COVERAGE_MODULATION_MODE_RGBA_NV
指定所有分量都乘以调制因子。
要动态设置 coverageModulationMode
状态,请调用:
// Provided by VK_EXT_extended_dynamic_state3 with VK_NV_framebuffer_mixed_samples, VK_EXT_shader_object with VK_NV_framebuffer_mixed_samples
void vkCmdSetCoverageModulationModeNV(
VkCommandBuffer commandBuffer,
VkCoverageModulationModeNV coverageModulationMode);
-
commandBuffer
是将要记录命令的命令缓冲区。 -
coverageModulationMode
指定coverageModulationMode
状态。
当使用 着色器对象进行绘制时,或者当在 VkPipelineDynamicStateCreateInfo::pDynamicStates
中设置 VK_DYNAMIC_STATE_COVERAGE_MODULATION_MODE_NV
创建图形管线时,此命令为后续绘制命令设置 coverageModulationMode
状态。 否则,此状态由用于创建当前活动管线的 VkPipelineCoverageModulationStateCreateInfoNV::coverageModulationMode
值指定。
要动态设置 coverageModulationTableEnable
状态,请调用:
// Provided by VK_EXT_extended_dynamic_state3 with VK_NV_framebuffer_mixed_samples, VK_EXT_shader_object with VK_NV_framebuffer_mixed_samples
void vkCmdSetCoverageModulationTableEnableNV(
VkCommandBuffer commandBuffer,
VkBool32 coverageModulationTableEnable);
-
commandBuffer
是将要记录命令的命令缓冲区。 -
coverageModulationTableEnable
指定coverageModulationTableEnable
状态。
当使用 着色器对象进行绘制时,或者当在 VkPipelineDynamicStateCreateInfo::pDynamicStates
中设置 VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_ENABLE_NV
创建图形管线时,此命令为后续绘制命令设置 coverageModulationTableEnable
状态。 否则,此状态由用于创建当前活动管线的 VkPipelineCoverageModulationStateCreateInfoNV::coverageModulationTableEnable
值指定。
要动态设置 pCoverageModulationTable
状态,请调用:
// Provided by VK_EXT_extended_dynamic_state3 with VK_NV_framebuffer_mixed_samples, VK_EXT_shader_object with VK_NV_framebuffer_mixed_samples
void vkCmdSetCoverageModulationTableNV(
VkCommandBuffer commandBuffer,
uint32_t coverageModulationTableCount,
const float* pCoverageModulationTable);
-
commandBuffer
是将要记录命令的命令缓冲区。 -
coverageModulationTableCount
指定pCoverageModulationTable
中元素的数量。 -
pCoverageModulationTable
指定调制因子表,其中包含每个覆盖样本数量的值。
此命令设置后续绘图命令的调制因子表,当使用着色器对象绘图时,或者当图形管线使用在VkPipelineDynamicStateCreateInfo::pDynamicStates
中设置的VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_NV
创建时。否则,此状态由用于创建当前活动管线的VkPipelineCoverageModulationStateCreateInfoNV::coverageModulationTableCount
和VkPipelineCoverageModulationStateCreateInfoNV::pCoverageModulationTable
值指定。