Fragment Operations
Fragments produced by rasterization go through a number of operations to determine whether or how values produced by fragment shading are written to the framebuffer.
The following fragment operations adhere to rasterization order, and are typically performed in this order:
The coverage mask generated by
rasterization describes the initial coverage of each sample covered by the
fragment.
Fragment operations will update the coverage mask to add or subtract
coverage where appropriate.
If a fragment operation results in all bits of the coverage mask being 0
,
the fragment is discarded, and no further operations are performed.
When one of the fragment operations in this chapter is described as “replacing” a fragment shader output, that output is replaced unconditionally, even if no fragment shader previously wrote to that output.
If there is a fragment shader and it declares the
PostDepthCoverage
execution mode, the sample mask test is instead performed after the depth test.
If
VkPhysicalDeviceMaintenance5Properties
::earlyFragmentMultisampleCoverageAfterSampleCounting
is VK_TRUE
and there is a fragment shader which
declares the EarlyFragmentTests
execution mode, fragment shading and multisample coverage operations
must be performed after sample counting.
Otherwise, if
VkPhysicalDeviceMaintenance5Properties
::earlyFragmentMultisampleCoverageAfterSampleCounting
is VK_FALSE
and there is a fragment shader which
declares the EarlyFragmentTests
execution mode, fragment shading and multisample coverage operations
should instead be performed after sample counting,
but may be performed before sample counting.
If
VkPhysicalDeviceMaintenance5Properties
::earlyFragmentSampleMaskTestBeforeSampleCounting
is VK_TRUE
and there is a fragment shader which
declares the EarlyFragmentTests
execution mode sample mask test operations must follow the order of fragment operations
from above.
Otherwise, if
VkPhysicalDeviceMaintenance5Properties
::earlyFragmentSampleMaskTestBeforeSampleCounting
is VK_FALSE
and there is a fragment shader which
declares the EarlyFragmentTests
execution mode, sample mask test operations should follow the order of fragment
operations from above but may instead be performed after
sample counting.
If there is a fragment shader which declares the
EarlyAndLateFragmentTestsAMD
execution mode, and it does not declare
the DepthReplacing
or StencilRefReplacingEXT
execution mode, fragment shading and multisample coverage operations are instead be performed after
sample counting.
For a pipeline with the following properties:
-
a fragment shader is specified
-
the fragment shader either specifies
EarlyAndLateFragmentTestsAMD
or does not write to storage resources; -
the fragment shader specifies the
StencilRefReplacingEXT
execution mode; -
either
-
the fragment shader specifies the
StencilRefUnchangedFrontAMD
execution mode; -
the fragment shader specifies the
StencilRefLessFrontAMD
execution mode and the pipeline uses a VkPipelineDepthStencilStateCreateInfo::front.compareOp
ofVK_COMPARE_OP_GREATER
orVK_COMPARE_OP_GREATER_OR_EQUAL
; or -
the fragment shader specifies the
StencilRefGreaterFrontAMD
execution mode and the pipeline uses a VkPipelineDepthStencilStateCreateInfo::front.compareOp
ofVK_COMPARE_OP_LESS
orVK_COMPARE_OP_LESS_OR_EQUAL
; and
-
-
either
-
the fragment shader specifies the
StencilRefUnchangedBackAMD
execution mode; -
the fragment shader specifies the
StencilRefLessBackAMD
execution mode and the pipeline uses a VkPipelineDepthStencilStateCreateInfo::back.compareOp
ofVK_COMPARE_OP_GREATER
orVK_COMPARE_OP_GREATER_OR_EQUAL
; or -
the fragment shader specifies the
StencilRefGreaterBackAMD
execution mode and the pipeline uses a VkPipelineDepthStencilStateCreateInfo::back.compareOp
ofVK_COMPARE_OP_LESS
orVK_COMPARE_OP_LESS_OR_EQUAL
-
an additional stencil test may be performed before
fragment shading, using the stencil reference value
specified by
VkPipelineDepthStencilStateCreateInfo::front.reference
or
VkPipelineDepthStencilStateCreateInfo::back.reference
.
For a pipeline with the following properties:
-
a fragment shader is specified
-
the fragment shader either specifies
EarlyAndLateFragmentTestsAMD
or does not write to storage resources; -
the fragment shader specifies the
DepthReplacing
execution mode; and -
either
-
the fragment shader specifies the
DepthUnchanged
execution mode; -
the fragment shader specifies the
DepthLess
execution mode and the pipeline uses a VkPipelineDepthStencilStateCreateInfo::depthCompareOp
ofVK_COMPARE_OP_GREATER
orVK_COMPARE_OP_GREATER_OR_EQUAL
; or -
the fragment shader specifies the
DepthGreater
execution mode and the pipeline uses a VkPipelineDepthStencilStateCreateInfo::depthCompareOp
ofVK_COMPARE_OP_LESS
orVK_COMPARE_OP_LESS_OR_EQUAL
-
the implementation may perform depth bounds test before fragment shading and perform an additional depth test immediately after that using the interpolated depth value generated by rasterization.
Once all fragment operations have completed, fragment shader outputs for covered color attachment samples pass through framebuffer operations.
Discard Rectangles Test
The discard rectangle test compares the framebuffer coordinates (xf,yf) of each sample covered by a fragment against a set of discard rectangles.
Each discard rectangle is defined by a VkRect2D. These values are either set by the VkPipelineDiscardRectangleStateCreateInfoEXT structure during pipeline creation, or dynamically by the vkCmdSetDiscardRectangleEXT command.
A given sample is considered inside a discard rectangle if the xf is
in the range [VkRect2D::offset.x
,
VkRect2D::offset.x
+ VkRect2D::extent.x
), and
yf is in the range [VkRect2D::offset.y
,
VkRect2D::offset.y
+ VkRect2D::extent.y
).
If the test is set to be inclusive, samples that are not inside any of the
discard rectangles will have their coverage set to 0
.
If the test is set to be exclusive, samples that are inside any of the
discard rectangles will have their coverage set to 0
.
If no discard rectangles are specified, the coverage mask is unmodified by this operation.
The VkPipelineDiscardRectangleStateCreateInfoEXT
structure is defined
as:
// 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
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
flags
is reserved for future use. -
discardRectangleMode
is a VkDiscardRectangleModeEXT value determining whether the discard rectangle test is inclusive or exclusive. -
discardRectangleCount
is the number of discard rectangles to use. -
pDiscardRectangles
is a pointer to an array of VkRect2D structures defining discard rectangles.
If the VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT
dynamic state is enabled
for a pipeline, the pDiscardRectangles
member is ignored.
If the VK_DYNAMIC_STATE_DISCARD_RECTANGLE_ENABLE_EXT
dynamic state is
not enabled for the pipeline the presence of this structure in the
VkGraphicsPipelineCreateInfo chain, and a discardRectangleCount
greater than zero, implicitly enables discard rectangles in the pipeline,
otherwise discard rectangles must enabled or disabled by
vkCmdSetDiscardRectangleEnableEXT.
If the VK_DYNAMIC_STATE_DISCARD_RECTANGLE_MODE_EXT
dynamic state is
enabled for the pipeline, the discardRectangleMode
member is ignored,
and the discard rectangle mode must be set by
vkCmdSetDiscardRectangleModeEXT.
When this structure is included in the pNext
chain of
VkGraphicsPipelineCreateInfo, it defines parameters of the discard
rectangle test.
If the VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT
dynamic state is not
enabled, and this structure is not included in the pNext
chain, it is
equivalent to specifying this structure with a discardRectangleCount
of 0
.
// Provided by VK_EXT_discard_rectangles
typedef VkFlags VkPipelineDiscardRectangleStateCreateFlagsEXT;
VkPipelineDiscardRectangleStateCreateFlagsEXT
is a bitmask type for
setting a mask, but is currently reserved for future use.
VkDiscardRectangleModeEXT
values are:
// 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
specifies that the discard rectangle test is inclusive. -
VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT
specifies that the discard rectangle test is exclusive.
To dynamically set the discard rectangles, call:
// Provided by VK_EXT_discard_rectangles
void vkCmdSetDiscardRectangleEXT(
VkCommandBuffer commandBuffer,
uint32_t firstDiscardRectangle,
uint32_t discardRectangleCount,
const VkRect2D* pDiscardRectangles);
-
commandBuffer
is the command buffer into which the command will be recorded. -
firstDiscardRectangle
is the index of the first discard rectangle whose state is updated by the command. -
discardRectangleCount
is the number of discard rectangles whose state are updated by the command. -
pDiscardRectangles
is a pointer to an array of VkRect2D structures specifying discard rectangles.
The discard rectangle taken from element i of pDiscardRectangles
replace the current state for the discard rectangle at index
firstDiscardRectangle
+ i, for i in [0,
discardRectangleCount
).
This command sets the discard rectangles for subsequent drawing commands
when drawing using shader objects, or
when the graphics pipeline is created with
VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT
set in
VkPipelineDynamicStateCreateInfo::pDynamicStates
.
Otherwise, this state is specified by the
VkPipelineDiscardRectangleStateCreateInfoEXT::pDiscardRectangles
values used to create the currently active pipeline.
To dynamically set whether discard rectangles are enabled, call:
// Provided by VK_EXT_discard_rectangles
void vkCmdSetDiscardRectangleEnableEXT(
VkCommandBuffer commandBuffer,
VkBool32 discardRectangleEnable);
-
commandBuffer
is the command buffer into which the command will be recorded. -
discardRectangleEnable
specifies whether discard rectangles are enabled or not.
This command sets the discard rectangle enable for subsequent drawing
commands
when drawing using shader objects, or
when the graphics pipeline is created with
VK_DYNAMIC_STATE_DISCARD_RECTANGLE_ENABLE_EXT
set in
VkPipelineDynamicStateCreateInfo::pDynamicStates
.
Otherwise, this state is implied by the
VkPipelineDiscardRectangleStateCreateInfoEXT::discardRectangleCount
value used to create the currently active pipeline, where a non-zero
discardRectangleCount
implicitly enables discard rectangles, otherwise
they are disabled.
To dynamically set the discard rectangle mode, call:
// Provided by VK_EXT_discard_rectangles
void vkCmdSetDiscardRectangleModeEXT(
VkCommandBuffer commandBuffer,
VkDiscardRectangleModeEXT discardRectangleMode);
-
commandBuffer
is the command buffer into which the command will be recorded. -
discardRectangleMode
specifies the discard rectangle mode for all discard rectangles, either inclusive or exclusive.
This command sets the discard rectangle mode for subsequent drawing commands
when drawing using shader objects, or
when the graphics pipeline is created with
VK_DYNAMIC_STATE_DISCARD_RECTANGLE_MODE_EXT
set in
VkPipelineDynamicStateCreateInfo::pDynamicStates
.
Otherwise, this state is specified by the
VkPipelineDiscardRectangleStateCreateInfoEXT::discardRectangleMode
value used to create the currently active pipeline.
Scissor Test
The scissor test compares the framebuffer coordinates (xf,yf) of
each sample covered by a fragment against a scissor rectangle at the index
equal to the fragment’s ViewportIndex
.
Each scissor rectangle is defined by a VkRect2D. These values are either set by the VkPipelineViewportStateCreateInfo structure during pipeline creation, or dynamically by the vkCmdSetScissor command.
A given sample is considered inside a scissor rectangle if xf is in
the range [VkRect2D::offset.x
,
VkRect2D::offset.x
+ VkRect2D::extent.x
), and
yf is in the range [VkRect2D::offset.y
,
VkRect2D::offset.y
+ VkRect2D::extent.y
).
Samples with coordinates outside the scissor rectangle at the corresponding
ViewportIndex
will have their coverage set to 0
.
If a render pass transform is enabled, the (offset.x
and
offset.y
) and (extent.width
and extent.height
) values are
transformed as described in render pass transform before participating in the scissor test.
To dynamically set the scissor rectangles, call:
// Provided by VK_VERSION_1_0
void vkCmdSetScissor(
VkCommandBuffer commandBuffer,
uint32_t firstScissor,
uint32_t scissorCount,
const VkRect2D* pScissors);
-
commandBuffer
is the command buffer into which the command will be recorded. -
firstScissor
is the index of the first scissor whose state is updated by the command. -
scissorCount
is the number of scissors whose rectangles are updated by the command. -
pScissors
is a pointer to an array of VkRect2D structures defining scissor rectangles.
The scissor rectangles taken from element i of pScissors
replace
the current state for the scissor index firstScissor
+ i,
for i in [0, scissorCount
).
This command sets the scissor rectangles for subsequent drawing commands
when drawing using shader objects, or
when the graphics pipeline is created with VK_DYNAMIC_STATE_SCISSOR
set in VkPipelineDynamicStateCreateInfo::pDynamicStates
.
Otherwise, this state is specified by the
VkPipelineViewportStateCreateInfo::pScissors
values used to
create the currently active pipeline.
Exclusive Scissor Test
The exclusive scissor test compares the framebuffer coordinates
(xf,yf) of each sample covered by a fragment against an exclusive
scissor rectangle at the index equal to the fragment’s
ViewportIndex
.
Each exclusive scissor rectangle is defined by a VkRect2D. These values are either set by the VkPipelineViewportExclusiveScissorStateCreateInfoNV structure during pipeline creation, or dynamically by the vkCmdSetExclusiveScissorNV command.
A given sample is considered inside an exclusive scissor rectangle if
xf is in the range [VkRect2D::offset.x
,
VkRect2D::offset.x
+ VkRect2D::extent.x
), and
yf is in the range [VkRect2D::offset.y
,
VkRect2D::offset.y
+ VkRect2D::extent.y
).
Samples with coordinates inside the exclusive scissor rectangle at the
corresponding ViewportIndex
will have their coverage set to 0
.
If no exclusive scissor rectangles are specified, the coverage mask is unmodified by this operation.
The VkPipelineViewportExclusiveScissorStateCreateInfoNV
structure is
defined as:
// Provided by VK_NV_scissor_exclusive
typedef struct VkPipelineViewportExclusiveScissorStateCreateInfoNV {
VkStructureType sType;
const void* pNext;
uint32_t exclusiveScissorCount;
const VkRect2D* pExclusiveScissors;
} VkPipelineViewportExclusiveScissorStateCreateInfoNV;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
exclusiveScissorCount
is the number of exclusive scissor rectangles. -
pExclusiveScissors
is a pointer to an array of VkRect2D structures defining exclusive scissor rectangles.
If the VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV
dynamic state is enabled
for a pipeline, the pExclusiveScissors
member is ignored.
When this structure is included in the pNext
chain of
VkGraphicsPipelineCreateInfo, it defines parameters of the exclusive
scissor test.
If this structure is not included in the pNext
chain, it is equivalent
to specifying this structure with an exclusiveScissorCount
of 0
.
To dynamically set the exclusive scissor rectangles, call:
// Provided by VK_NV_scissor_exclusive
void vkCmdSetExclusiveScissorNV(
VkCommandBuffer commandBuffer,
uint32_t firstExclusiveScissor,
uint32_t exclusiveScissorCount,
const VkRect2D* pExclusiveScissors);
-
commandBuffer
is the command buffer into which the command will be recorded. -
firstExclusiveScissor
is the index of the first exclusive scissor rectangle whose state is updated by the command. -
exclusiveScissorCount
is the number of exclusive scissor rectangles updated by the command. -
pExclusiveScissors
is a pointer to an array of VkRect2D structures defining exclusive scissor rectangles.
The scissor rectangles taken from element i of
pExclusiveScissors
replace the current state for the scissor index
firstExclusiveScissor
+ i, for i in [0,
exclusiveScissorCount
).
This command sets the exclusive scissor rectangles for subsequent drawing
commands
when drawing using shader objects, or
when the graphics pipeline is created with
VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV
set in
VkPipelineDynamicStateCreateInfo::pDynamicStates
.
Otherwise, this state is specified by the
VkPipelineViewportExclusiveScissorStateCreateInfoNV::pExclusiveScissors
values used to create the currently active pipeline.
To dynamically set whether an exclusive scissor is enabled or not, call:
// Provided by VK_NV_scissor_exclusive
void vkCmdSetExclusiveScissorEnableNV(
VkCommandBuffer commandBuffer,
uint32_t firstExclusiveScissor,
uint32_t exclusiveScissorCount,
const VkBool32* pExclusiveScissorEnables);
-
commandBuffer
is the command buffer into which the command will be recorded. -
firstExclusiveScissor
is the index of the first exclusive scissor rectangle whose state is updated by the command. -
exclusiveScissorCount
is the number of exclusive scissor rectangles updated by the command. -
pExclusiveScissorEnables
is a pointer to an array ofVkBool32
values defining whether the exclusive scissor is enabled.
The exclusive scissor enables taken from element i of
pExclusiveScissorEnables
replace the current state for the scissor
index firstExclusiveScissor
+ i, for i in [0,
exclusiveScissorCount
).
This command sets the exclusive scissor enable for subsequent drawing
commands
when drawing using shader objects, or
when the graphics pipeline is created with
VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_ENABLE_NV
set in
VkPipelineDynamicStateCreateInfo::pDynamicStates
.
Otherwise, this state is implied by the
VkPipelineViewportExclusiveScissorStateCreateInfoNV::exclusiveScissorCount
value used to create the currently active pipeline, where all
exclusiveScissorCount
exclusive scissors are implicitly enabled and
the remainder up to VkPhysicalDeviceLimits
::maxViewports
are
implicitly disabled.
Sample Mask Test
The sample mask test compares the coverage mask for a fragment with the sample mask defined by
VkPipelineMultisampleStateCreateInfo::pSampleMask
.
To dynamically set the sample mask, call:
// Provided by VK_EXT_extended_dynamic_state3, VK_EXT_shader_object
void vkCmdSetSampleMaskEXT(
VkCommandBuffer commandBuffer,
VkSampleCountFlagBits samples,
const VkSampleMask* pSampleMask);
-
commandBuffer
is the command buffer into which the command will be recorded. -
samples
specifies the number of sample bits in thepSampleMask
. -
pSampleMask
is a pointer to an array ofVkSampleMask
values, where the array size is based on thesamples
parameter.
This command sets the sample mask for subsequent drawing commands
when drawing using shader objects, or
when the graphics pipeline is created with
VK_DYNAMIC_STATE_SAMPLE_MASK_EXT
set in
VkPipelineDynamicStateCreateInfo::pDynamicStates
.
Otherwise, this state is specified by the
VkPipelineMultisampleStateCreateInfo::pSampleMask
value used to
create the currently active pipeline.
Each bit of the coverage mask is associated with a sample index as described
in the rasterization chapter.
If the bit in VkPipelineMultisampleStateCreateInfo::pSampleMask
which is associated with that same sample index is set to 0
, the coverage
mask bit is set to 0
.
Fragment Shading
Fragment shaders are invoked for each fragment, or as helper invocations.
Most operations in the fragment shader are not performed in rasterization order, with exceptions called out in the following sections.
For fragment shaders invoked by fragments, the following rules apply:
-
A fragment shader must not be executed if a fragment operation that executes before fragment shading discards the fragment.
-
A fragment shader may not be executed if:
-
An implementation determines that another fragment shader, invoked by a subsequent primitive in primitive order, overwrites all results computed by the shader (including writes to storage resources).
-
Any other fragment operation discards the fragment, and the shader does not write to any storage resources.
-
If a fragment shader statically computes the same values for different framebuffer locations, and does not write to any storage resources, multiple fragments may be shaded by one fragment shader invocation. This may affect
VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT
results, but must otherwise not be visible behavior to applications.
-
-
Otherwise, at least one fragment shader must be executed.
-
If sample shading is enabled and multiple invocations per fragment are required, additional invocations must be executed as specified.
-
If a shading rate image is used and multiple invocations per fragment are required, additional invocations must be executed as specified.
-
Each covered sample must be included in at least one fragment shader invocation.
-
If no fragment shader is included in the pipeline, no fragment shader is executed, and undefined values may be written to all color attachment outputs during this fragment operation.
Multiple fragment shader invocations may be executed for the same fragment for any number of implementation-dependent reasons. When there is more than one fragment shader invocation per fragment, the association of samples to invocations is implementation-dependent. Stores and atomics performed by these additional invocations have the normal effect. For example, if the subpass includes multiple views in its view mask, a fragment shader may be invoked separately for each view. Similarly, if the render pass has a fragment density map attachment, more
than one fragment shader invocation may be invoked for each covered sample.
Such additional invocations are only produced if
|
Sample Mask
Reading from the SampleMask
built-in in the Input
storage class will return the
coverage mask for the current fragment as calculated by fragment operations
that executed prior to fragment shading.
If sample shading is enabled, fragment shaders
will only see values of 1
for samples being shaded - other bits will be
0
.
Each bit of the coverage mask is associated with a sample index as described
in the rasterization chapter.
If the bit in SampleMask
which is associated with that same sample
index is set to 0
, that coverage mask bit is set to 0
.
Values written to the SampleMask
built-in in the Output
storage class will be used by
the multisample coverage operation, with the same encoding
as the input built-in.
Shader Termination and Demotion
If a fragment shader is terminated early or
demoted to a helper invocation by using
OpKill
, OpTerminateInvocation
, or OpDemoteToHelperInvocation
,
samples covered by that shader invocation have their coverage mask bits set
to 0
.
Fragment Shader Tile Image Reads
If the VK_EXT_shader_tile_image
extension is enabled,
implementations divide the framebuffer into a grid of tiles.
A tile image is a view of a framebuffer attachment
tile for fragments with locations within the tile.
Within a render pass instance initiated by vkCmdBeginRenderingKHR, fragment shader invocations can read the framebuffer color, depth, and stencil values at the fragment location via tile images.
Even though fragment shader invocation can only read from the corresponding fragment location, the abstraction of a tile image is introduced for the following reasons:
|
Enabling shaderTileImageColorReadAccess, shaderTileImageDepthReadAccess, shaderTileImageStencilReadAccess enables fragment shader invocations to read from color, depth, and stencil, respectively.
Color values are read from tile image variables with
OpColorAttachmentReadEXT
.
Tile image variables are linked to specific color attachments using
Location
decoration.
See Fragment Tile Image Interface for more
details.
Depth values are read with OpDepthAttachmentReadEXT
.
Stencil values are read with OpStencilAttachmentReadEXT
.
The sample to read is specified by a
sample index value specified as
the Sample
operand to OpColorAttachmentReadEXT
,
OpDepthAttachmentReadEXT
, or OpStencilAttachmentReadEXT
.
If sample shading is disabled, a fragment
invocation can read from all sample locations associated with the fragment
regardless of the fragment’s coverage.
This functionality is supported for
VkPipelineMultisampleStateCreateInfo::rasterizationSamples
> 1
when
VkPhysicalDeviceShaderTileImagePropertiesEXT::shaderTileImageReadSampleFromPixelRateInvocation
is VK_TRUE
.
If sample shading is enabled, and
minSampleShading
is 1.0, a fragment invocation must only read from
the coverage index sample.
Tile image access must not be used if the value of minSampleShading
is not 1.0.
If the fragment shader declares the
EarlyFragmentTests
execution mode, depth reads are allowed only if
depth writes are disabled and stencil reads are allowed only if stencil
writes are disabled.
If
VkPhysicalDeviceShaderTileImagePropertiesEXT::shaderTileImageReadFromHelperInvocation
is VK_FALSE
, values read from helper invocations are undefined
otherwise the values read are subject to the coherency guarantees described
below.
OpDepthAttachmentReadEXT
returns an undefined value if no depth
attachment is present.
OpStencilAttachmentReadEXT
returns an undefined value if no stencil
attachment is present.
Tile image reads from color, depth and stencil attachments are said to be coherent when the accesses happen in raster order and without data race with respect to accesses to the attachments from framebuffer-space pipeline stages. The samples which qualify for coherent access and the enabling conditions are described below.
-
Let Rc be the set of components being read from an attachment A in a draw call
-
Let Wc be the set of components being written to A by the draw call
The samples which qualify for coherent tile image reads from an attachment A are:
-
All samples in a pixel when Rc is disjoint with Wc.
-
The samples with coverage in a fragment when Rc is not disjoint with Wc. The samples with coverage are determined by the coverage mask for the fragment as calculated by fragment operations that executed prior to fragment shading, including early fragment tests if enabled for the draw call.
A fragment shader can declare NonCoherentColorAttachmentReadEXT
,
NonCoherentDepthAttachmentReadEXT
, or
NonCoherentStencilAttachmentReadEXT
execution modes to enable
non-coherent tile image reads which require an explicit
vkCmdPipelineBarrier2 call for the writes to an attachment to be made
visible via tile image reads.
When
VkPhysicalDeviceShaderTileImagePropertiesEXT::shaderTileImageCoherentReadAccelerated
is VK_TRUE
, the implementation prefers that coherent tile image reads
are used, otherwise the implementation prefers that non-coherent tile image
reads are used.
In practice, the most common tile image reads usage patterns fall under one of the following:
All of the above use cases are supported by coherent tile image reads, but only the latter three are supported when non-coherent reads are used as there is no mechanism to synchronize non-coherent reads with writes within a draw call. |
Depth Replacement
Writing to the FragDepth
built-in will replace the fragment’s calculated depth values for each sample
in the input SampleMask
.
Depth testing performed after the fragment shader for
this fragment will use this new value as zf.
Stencil Reference Replacement
Writing to the
FragStencilRefEXT
built-in will replace the fragment’s stencil reference value for each sample
in the input SampleMask
.
Stencil testing performed after the fragment shader for
this fragment will use this new value as sr.
Interlocked Operations
OpBeginInvocationInterlockEXT
and OpEndInvocationInterlockEXT
define a section of a fragment shader which imposes additional ordering
constraints on operations performed within them.
These operations are defined as interlocked operations.
How interlocked operations are ordered against other fragment shader
invocations depends on the specified execution modes.
If the ShadingRateInterlockOrderedEXT
execution mode is specified, any
interlocked operations in a fragment shader must happen before interlocked
operations in fragment shader invocations that execute later in
rasterization order and cover at least one sample in
the same fragment area, and must happen after interlocked operations in a
fragment shader that executes earlier in rasterization order and cover at least one sample in the same fragment area.
If the ShadingRateInterlockUnorderedEXT
execution mode is specified,
any interlocked operations in a fragment shader must happen before or after
interlocked operations in fragment shader invocations that execute earlier
or later in rasterization order and cover at least one
sample in the same fragment area.
If the PixelInterlockOrderedEXT
execution mode is specified, any
interlocked operations in a fragment shader must happen before interlocked
operations in fragment shader invocations that execute later in
rasterization order and cover at least one sample in
the same pixel, and must happen after interlocked operations in a fragment
shader that executes earlier in rasterization order and
cover at least one sample in the same pixel.
If the PixelInterlockUnorderedEXT
execution mode is specified, any
interlocked operations in a fragment shader must happen before or after
interlocked operations in fragment shader invocations that execute earlier
or later in rasterization order and cover at least one
sample in the same pixel.
If the SampleInterlockOrderedEXT
execution mode is specified, any
interlocked operations in a fragment shader must happen before interlocked
operations in fragment shader invocations that execute later in
rasterization order and cover at least one of the same
samples, and must happen after interlocked operations in a fragment shader
that executes earlier in rasterization order and cover
at least one of the same samples.
If the SampleInterlockUnorderedEXT
execution mode is specified, any
interlocked operations in a fragment shader must happen before or after
interlocked operations in fragment shader invocations that execute earlier
or later in rasterization order and cover at least one
of the same samples.
Multisample Coverage
If a fragment shader is active and its entry point’s interface includes a
built-in output variable decorated with SampleMask
,
but not OverrideCoverageNV
,
the coverage mask is ANDed
with the bits of the SampleMask
built-in to generate a new coverage mask.
If the SampleMask
built-in is also decorated with
OverrideCoverageNV
, the coverage mask is replaced with the mask bits
set in the shader.
If sample shading is enabled, bits written to
SampleMask
corresponding to samples that are not being shaded by the
fragment shader invocation are ignored.
If no fragment shader is active, or if the active fragment shader does not
include SampleMask
in its interface, the coverage mask is not modified.
Next, the fragment alpha value and coverage mask are modified based on the
line coverage factor if the lineRasterizationMode
member of the
VkPipelineRasterizationStateCreateInfo structure is
VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH
, and the
alphaToCoverageEnable
and alphaToOneEnable
members of the
VkPipelineMultisampleStateCreateInfo structure.
To dynamically set the
alphaToCoverageEnable
state, call:
// Provided by VK_EXT_extended_dynamic_state3, VK_EXT_shader_object
void vkCmdSetAlphaToCoverageEnableEXT(
VkCommandBuffer commandBuffer,
VkBool32 alphaToCoverageEnable);
-
commandBuffer
is the command buffer into which the command will be recorded. -
alphaToCoverageEnable
specifies thealphaToCoverageEnable
state.
This command sets the alphaToCoverageEnable
state for subsequent
drawing commands
when drawing using shader objects, or
when the graphics pipeline is created with
VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT
set in
VkPipelineDynamicStateCreateInfo::pDynamicStates
.
Otherwise, this state is specified by the
VkPipelineMultisampleStateCreateInfo::alphaToCoverageEnable
value used to create the currently active pipeline.
To dynamically set the alphaToOneEnable
state, call:
// Provided by VK_EXT_extended_dynamic_state3, VK_EXT_shader_object
void vkCmdSetAlphaToOneEnableEXT(
VkCommandBuffer commandBuffer,
VkBool32 alphaToOneEnable);
-
commandBuffer
is the command buffer into which the command will be recorded. -
alphaToOneEnable
specifies thealphaToOneEnable
state.
This command sets the alphaToOneEnable
state for subsequent drawing
commands
when drawing using shader objects, or
when the graphics pipeline is created with
VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT
set in
VkPipelineDynamicStateCreateInfo::pDynamicStates
.
Otherwise, this state is specified by the
VkPipelineMultisampleStateCreateInfo::alphaToOneEnable
value
used to create the currently active pipeline.
All alpha values in this section refer only to the alpha component of the
fragment shader output that has a Location
and Index
decoration of
zero (see the Fragment Output Interface
section).
If that shader output has an integer or unsigned integer type, then these
operations are skipped.
If the lineRasterizationMode
member of the
VkPipelineRasterizationStateCreateInfo structure is
VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH
and the fragment came
from a line segment, then the alpha value is replaced by multiplying it by
the coverage factor for the fragment computed during
smooth line rasterization.
If alphaToCoverageEnable
is enabled, a temporary coverage mask is
generated where each bit is determined by the fragment’s alpha value, which
is ANDed with the fragment coverage mask.
No specific algorithm is specified for converting the alpha value to a temporary coverage mask. It is intended that the number of 1’s in this value be proportional to the alpha value (clamped to [0,1]), with all 1’s corresponding to a value of 1.0 and all 0’s corresponding to 0.0. The algorithm may be different at different framebuffer coordinates.
Using different algorithms at different framebuffer coordinates may help to avoid artifacts caused by regular coverage sample locations. |
Finally, if alphaToOneEnable
is enabled, each alpha value is replaced
by the maximum representable alpha value for fixed-point color attachments,
or by 1.0 for floating-point attachments.
Otherwise, the alpha values are not changed.
Depth and Stencil Operations
Pipeline state controlling the depth bounds tests,
stencil test, and depth test is
specified through the members of the
VkPipelineDepthStencilStateCreateInfo
structure.
The VkPipelineDepthStencilStateCreateInfo
structure is defined as:
// 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
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
flags
is a bitmask of VkPipelineDepthStencilStateCreateFlagBits specifying additional depth/stencil state information. -
depthTestEnable
controls whether depth testing is enabled. -
depthWriteEnable
controls whether depth writes are enabled whendepthTestEnable
isVK_TRUE
. Depth writes are always disabled whendepthTestEnable
isVK_FALSE
. -
depthCompareOp
is a VkCompareOp value specifying the comparison operator to use in the Depth Comparison step of the depth test. -
depthBoundsTestEnable
controls whether depth bounds testing is enabled. -
stencilTestEnable
controls whether stencil testing is enabled. -
front
andback
are VkStencilOpState values controlling the corresponding parameters of the stencil test. -
minDepthBounds
is the minimum depth bound used in the depth bounds test. -
maxDepthBounds
is the maximum depth bound used in the depth bounds test.
// Provided by VK_VERSION_1_0
typedef VkFlags VkPipelineDepthStencilStateCreateFlags;
VkPipelineDepthStencilStateCreateFlags
is a bitmask type for setting a
mask of zero or more VkPipelineDepthStencilStateCreateFlagBits.
Bits which can be set in the
VkPipelineDepthStencilStateCreateInfo::flags
parameter are:
// 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
specifies that access to the depth aspects of depth/stencil and input attachments will have implicit framebuffer-local memory dependencies. -
VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_EXT
specifies that access to the stencil aspects of depth/stencil and input attachments will have implicit framebuffer-local memory dependencies.
When
VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_EXT
is included in a pipeline, it forms a framebuffer-local memory dependency
for each fragment generated by draw commands for that pipeline with the
following scopes:
-
The first synchronization scope includes
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
andVK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
pipeline stages executed by all previous fragments (as defined by primitive order) in the corresponding framebuffer regions including those generated by the same draw command. -
The second synchronization scope includes
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
stage executed by the generated fragment. -
The first access scope includes all writes to the depth aspect of depth/stencil attachments.
-
The second access scope includes all reads from the depth aspect of input attachments.
When
VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_EXT
is included in a pipeline, it forms a framebuffer-local memory dependency
for each fragment generated by draw commands for that pipeline with the
following scopes:
-
The first synchronization scope includes
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
pipeline stages executed by all previous fragments (as defined by primitive order) in the corresponding framebuffer regions including those generated by the same draw command. -
The second synchronization scope includes
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
andVK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
pipeline stages executed by the generated fragment. -
The first access scope includes all writes to the stencil aspect of depth/stencil attachments.
-
The second access scope includes all reads from the stencil aspect of input attachments.
Depth Bounds Test
The depth bounds test compares the depth value za in the depth/stencil attachment at each sample’s framebuffer coordinates (xf,yf) and sample index i against a set of depth bounds.
The depth bounds are determined by two floating-point values defining a
minimum (minDepthBounds
) and maximum (maxDepthBounds
) depth
value.
These values are either set by the
VkPipelineDepthStencilStateCreateInfo structure during pipeline
creation, or dynamically by
vkCmdSetDepthBoundsTestEnable and
vkCmdSetDepthBounds.
A given sample is considered within the depth bounds if za is in the
range [minDepthBounds
,maxDepthBounds
].
Samples with depth attachment values outside of the depth bounds will have
their coverage set to 0
.
If the depth bounds test is disabled, or if there is no depth attachment, the coverage mask is unmodified by this operation.
To dynamically enable or disable the depth bounds test, call:
// Provided by VK_VERSION_1_3
void vkCmdSetDepthBoundsTestEnable(
VkCommandBuffer commandBuffer,
VkBool32 depthBoundsTestEnable);
or the equivalent command
// Provided by VK_EXT_extended_dynamic_state, VK_EXT_shader_object
void vkCmdSetDepthBoundsTestEnableEXT(
VkCommandBuffer commandBuffer,
VkBool32 depthBoundsTestEnable);
-
commandBuffer
is the command buffer into which the command will be recorded. -
depthBoundsTestEnable
specifies if the depth bounds test is enabled.
This command sets the depth bounds enable for subsequent drawing commands
when drawing using shader objects, or
when the graphics pipeline is created with
VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE
set in
VkPipelineDynamicStateCreateInfo::pDynamicStates
.
Otherwise, this state is specified by the
VkPipelineDepthStencilStateCreateInfo::depthBoundsTestEnable
value used to create the currently active pipeline.
To dynamically set the depth bounds range, call:
// Provided by VK_VERSION_1_0
void vkCmdSetDepthBounds(
VkCommandBuffer commandBuffer,
float minDepthBounds,
float maxDepthBounds);
-
commandBuffer
is the command buffer into which the command will be recorded. -
minDepthBounds
is the minimum depth bound. -
maxDepthBounds
is the maximum depth bound.
This command sets the depth bounds range for subsequent drawing commands
when drawing using shader objects, or
when the graphics pipeline is created with
VK_DYNAMIC_STATE_DEPTH_BOUNDS
set in
VkPipelineDynamicStateCreateInfo::pDynamicStates
.
Otherwise, this state is specified by the
VkPipelineDepthStencilStateCreateInfo::minDepthBounds
and
VkPipelineDepthStencilStateCreateInfo::maxDepthBounds
values
used to create the currently active pipeline.
Stencil Test
The stencil test compares the stencil attachment value sa in the depth/stencil attachment at each sample’s framebuffer coordinates (xf,yf) and sample index i against a stencil reference value.
If the render pass has a fragment density map attachment and the fragment covers multiple pixels, there is an implementation-dependent association of coverage samples to stencil attachment samples within the fragment. However, if all samples in the fragment are covered, and the stencil attachment value is updated as a result of this test, all stencil attachment samples will be updated.
If the stencil test is not enabled, as specified by
vkCmdSetStencilTestEnable or
VkPipelineDepthStencilStateCreateInfo::stencilTestEnable
, or if
there is no stencil attachment, the coverage mask is unmodified by this
operation.
The stencil test is controlled by one of two sets of stencil-related state, the front stencil state and the back stencil state. Stencil tests and writes use the back stencil state when processing fragments generated by back-facing polygons, and the front stencil state when processing fragments generated by front-facing polygons or any other primitives.
The comparison operation performed is determined by the VkCompareOp
value set by
vkCmdSetStencilOp::compareOp
, or by
VkStencilOpState::compareOp
during pipeline creation.
The compare mask sc and stencil reference value sr of the front or the back stencil state set determine arguments of the comparison operation. sc is set by the VkPipelineDepthStencilStateCreateInfo structure during pipeline creation, or by the vkCmdSetStencilCompareMask command. sr is set by VkPipelineDepthStencilStateCreateInfo or by vkCmdSetStencilReference.
sr and sa are each independently combined with sc
using a bitwise AND
operation to create masked reference and attachment
values s'r and s'a.
s'r and s'a are used as the reference and test values,
respectively, in the operation specified by the VkCompareOp.
If the comparison evaluates to false, the coverage for the sample is set to
0
.
A new stencil value sg is generated according to a stencil operation
defined by VkStencilOp parameters set by
vkCmdSetStencilOp or
VkPipelineDepthStencilStateCreateInfo.
If the stencil test fails, failOp
defines the stencil operation used.
If the stencil test passes however, the stencil op used is based on the
depth test - if it passes,
VkPipelineDepthStencilStateCreateInfo::passOp
is used, otherwise
VkPipelineDepthStencilStateCreateInfo::depthFailOp
is used.
The stencil attachment value sa is then updated with the generated
stencil value sg according to the write mask sw defined by
writeMask
in VkPipelineDepthStencilStateCreateInfo::front
and VkPipelineDepthStencilStateCreateInfo::back
as:
-
sa = (sa ∧ ¬sw) ∨ (sg ∧ sw)
To dynamically enable or disable the stencil test, call:
// Provided by VK_VERSION_1_3
void vkCmdSetStencilTestEnable(
VkCommandBuffer commandBuffer,
VkBool32 stencilTestEnable);
or the equivalent command
// Provided by VK_EXT_extended_dynamic_state, VK_EXT_shader_object
void vkCmdSetStencilTestEnableEXT(
VkCommandBuffer commandBuffer,
VkBool32 stencilTestEnable);
-
commandBuffer
is the command buffer into which the command will be recorded. -
stencilTestEnable
specifies if the stencil test is enabled.
This command sets the stencil test enable for subsequent drawing commands
when drawing using shader objects, or
when the graphics pipeline is created with
VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE
set in
VkPipelineDynamicStateCreateInfo::pDynamicStates
.
Otherwise, this state is specified by the
VkPipelineDepthStencilStateCreateInfo::stencilTestEnable
value
used to create the currently active pipeline.
To dynamically set the stencil operation, call:
// Provided by VK_VERSION_1_3
void vkCmdSetStencilOp(
VkCommandBuffer commandBuffer,
VkStencilFaceFlags faceMask,
VkStencilOp failOp,
VkStencilOp passOp,
VkStencilOp depthFailOp,
VkCompareOp compareOp);
or the equivalent command
// 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
is the command buffer into which the command will be recorded. -
faceMask
is a bitmask of VkStencilFaceFlagBits specifying the set of stencil state for which to update the stencil operation. -
failOp
is a VkStencilOp value specifying the action performed on samples that fail the stencil test. -
passOp
is a VkStencilOp value specifying the action performed on samples that pass both the depth and stencil tests. -
depthFailOp
is a VkStencilOp value specifying the action performed on samples that pass the stencil test and fail the depth test. -
compareOp
is a VkCompareOp value specifying the comparison operator used in the stencil test.
This command sets the stencil operation for subsequent drawing commands when
when drawing using shader objects, or
when the graphics pipeline is created with VK_DYNAMIC_STATE_STENCIL_OP
set in VkPipelineDynamicStateCreateInfo::pDynamicStates
.
Otherwise, this state is specified by the corresponding
VkPipelineDepthStencilStateCreateInfo
::failOp
, passOp
,
depthFailOp
, and compareOp
values used to create the currently
active pipeline, for both front and back faces.
The VkStencilOpState
structure is defined as:
// 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
is a VkStencilOp value specifying the action performed on samples that fail the stencil test. -
passOp
is a VkStencilOp value specifying the action performed on samples that pass both the depth and stencil tests. -
depthFailOp
is a VkStencilOp value specifying the action performed on samples that pass the stencil test and fail the depth test. -
compareOp
is a VkCompareOp value specifying the comparison operator used in the stencil test. -
compareMask
selects the bits of the unsigned integer stencil values participating in the stencil test. -
writeMask
selects the bits of the unsigned integer stencil values updated by the stencil test in the stencil framebuffer attachment. -
reference
is an integer stencil reference value that is used in the unsigned stencil comparison.
To dynamically set the stencil compare mask, call:
// Provided by VK_VERSION_1_0
void vkCmdSetStencilCompareMask(
VkCommandBuffer commandBuffer,
VkStencilFaceFlags faceMask,
uint32_t compareMask);
-
commandBuffer
is the command buffer into which the command will be recorded. -
faceMask
is a bitmask of VkStencilFaceFlagBits specifying the set of stencil state for which to update the compare mask. -
compareMask
is the new value to use as the stencil compare mask.
This command sets the stencil compare mask for subsequent drawing commands
when drawing using shader objects, or
when the graphics pipeline is created with
VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK
set in
VkPipelineDynamicStateCreateInfo::pDynamicStates
.
Otherwise, this state is specified by the
VkStencilOpState::compareMask
value used to create the currently
active pipeline, for both front and back faces.
VkStencilFaceFlagBits
values are:
// 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
specifies that only the front set of stencil state is updated. -
VK_STENCIL_FACE_BACK_BIT
specifies that only the back set of stencil state is updated. -
VK_STENCIL_FACE_FRONT_AND_BACK
is the combination ofVK_STENCIL_FACE_FRONT_BIT
andVK_STENCIL_FACE_BACK_BIT
, and specifies that both sets of stencil state are updated.
// Provided by VK_VERSION_1_0
typedef VkFlags VkStencilFaceFlags;
VkStencilFaceFlags
is a bitmask type for setting a mask of zero or
more VkStencilFaceFlagBits.
To dynamically set the stencil write mask, call:
// Provided by VK_VERSION_1_0
void vkCmdSetStencilWriteMask(
VkCommandBuffer commandBuffer,
VkStencilFaceFlags faceMask,
uint32_t writeMask);
-
commandBuffer
is the command buffer into which the command will be recorded. -
faceMask
is a bitmask of VkStencilFaceFlagBits specifying the set of stencil state for which to update the write mask, as described above for vkCmdSetStencilCompareMask. -
writeMask
is the new value to use as the stencil write mask.
This command sets the stencil write mask for subsequent drawing commands
when drawing using shader objects, or
when the graphics pipeline is created with
VK_DYNAMIC_STATE_STENCIL_WRITE_MASK
set in
VkPipelineDynamicStateCreateInfo::pDynamicStates
.
Otherwise, this state is specified by the writeMask
value used to
create the currently active pipeline, for both
VkPipelineDepthStencilStateCreateInfo::front
and
VkPipelineDepthStencilStateCreateInfo::back
faces.
To dynamically set the stencil reference value, call:
// Provided by VK_VERSION_1_0
void vkCmdSetStencilReference(
VkCommandBuffer commandBuffer,
VkStencilFaceFlags faceMask,
uint32_t reference);
-
commandBuffer
is the command buffer into which the command will be recorded. -
faceMask
is a bitmask of VkStencilFaceFlagBits specifying the set of stencil state for which to update the reference value, as described above for vkCmdSetStencilCompareMask. -
reference
is the new value to use as the stencil reference value.
This command sets the stencil reference value for subsequent drawing
commands
when drawing using shader objects, or
when the graphics pipeline is created with
VK_DYNAMIC_STATE_STENCIL_REFERENCE
set in
VkPipelineDynamicStateCreateInfo::pDynamicStates
.
Otherwise, this state is specified by the
VkPipelineDepthStencilStateCreateInfo::reference
value used to
create the currently active pipeline, for both front and back faces.
Possible values of the failOp
, passOp
, and depthFailOp
members of VkStencilOpState, specifying what happens to the stored
stencil value if this or certain subsequent tests fail or pass, are:
// 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
keeps the current value. -
VK_STENCIL_OP_ZERO
sets the value to 0. -
VK_STENCIL_OP_REPLACE
sets the value toreference
. -
VK_STENCIL_OP_INCREMENT_AND_CLAMP
increments the current value and clamps to the maximum representable unsigned value. -
VK_STENCIL_OP_DECREMENT_AND_CLAMP
decrements the current value and clamps to 0. -
VK_STENCIL_OP_INVERT
bitwise-inverts the current value. -
VK_STENCIL_OP_INCREMENT_AND_WRAP
increments the current value and wraps to 0 when the maximum value would have been exceeded. -
VK_STENCIL_OP_DECREMENT_AND_WRAP
decrements the current value and wraps to the maximum possible value when the value would go below 0.
For purposes of increment and decrement, the stencil bits are considered as an unsigned integer.
Depth Test
The depth test compares the depth value za in the depth/stencil attachment at each sample’s framebuffer coordinates (xf,yf) and sample index i against the sample’s depth value zf. If there is no depth attachment then the depth test is skipped.
If the render pass has a fragment density map attachment and the fragment covers multiple pixels, there is an implementation-dependent association of rasterization samples to depth attachment samples within the fragment. However, if all samples in the fragment are covered, and the depth attachment value is updated as a result of this test, all depth attachment samples will be updated.
The depth test occurs in three stages, as detailed in the following sections.
Depth Clamping and Range Adjustment
If VkPipelineRasterizationStateCreateInfo::depthClampEnable
is
enabled, zf is clamped to [zmin, zmax], where zmin
= min(n,f), zmax = max(n,f), and n and f are the
minDepth
and maxDepth
depth range values of the viewport used by
this fragment, respectively.
If the depthClampControl
feature is
enabled and
VkPipelineViewportDepthClampControlCreateInfoEXT::depthClampMode
is VK_DEPTH_CLAMP_MODE_USER_DEFINED_RANGE_EXT
, then zmin and
zmax are equal to the minDepthClamp
and maxDepthClamp
values of the VkDepthClampRangeEXT structure pointed to by
pDepthClampRange
.
If
VkPhysicalDeviceDepthClampZeroOneFeaturesEXT::depthClampZeroOne
is enabled:
-
If the depth attachment has a floating-point format and VK_EXT_depth_range_unrestricted is enabled then zf is unchanged.
-
Otherwise, zf is clamped to the range [0, 1].
Otherwise:
-
If zf is not in the range [zmin, zmax], then zf is undefined following this step.
-
If the depth attachment has a fixed-point format and zf is not in the range [0, 1], then zf is undefined following this step.
The VkPipelineViewportDepthClampControlCreateInfoEXT
structure is
defined as:
// Provided by VK_EXT_depth_clamp_control
typedef struct VkPipelineViewportDepthClampControlCreateInfoEXT {
VkStructureType sType;
const void* pNext;
VkDepthClampModeEXT depthClampMode;
const VkDepthClampRangeEXT* pDepthClampRange;
} VkPipelineViewportDepthClampControlCreateInfoEXT;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
depthClampMode
determines how the clamp range is determined for each viewport. -
pDepthClampRange
sets the depth clamp range for all viewports ifdepthClampMode
isVK_DEPTH_CLAMP_MODE_USER_DEFINED_RANGE_EXT
.
This structure extends VkPipelineViewportStateCreateInfo
and specifies
the depth clamp range used in the pipeline.
If this structure is not provided in the next chain then
depthClampMode
defaults to
VK_DEPTH_CLAMP_MODE_VIEWPORT_RANGE_EXT
.
Possible values of
VkPipelineViewportDepthClampControlCreateInfoEXT::depthClampMode
,
specifying which range should be used for depth clamping, are:
// 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
specifies that the depth clamp range follows the viewport depth range. The depth clamp range of each viewport will implicitly be set to zmin = min(n,f) and zmax = max(n,f), where n and f are theminDepth
andmaxDepth
depth range values of the viewport. -
VK_DEPTH_CLAMP_MODE_USER_DEFINED_RANGE_EXT
specifies that a single user-defined depth clamp range will be used for all viewports. The user-defined depth clamp range is defined by theminDepthClamp
andmaxDepthClamp
members of VkDepthClampRangeEXT.
To dynamically set the viewport depth clamp range parameters, call:
// 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
is the command buffer into which the command will be recorded. -
depthClampMode
determines how the clamp range is determined for each viewport. -
pDepthClampRange
sets the depth clamp range for all viewports ifdepthClampMode
isVK_DEPTH_CLAMP_MODE_USER_DEFINED_RANGE_EXT
.
This command sets the viewport depth clamp range for subsequent drawing
commands
when drawing using shader objects, or
when the graphics pipeline is created with
VK_DYNAMIC_STATE_DEPTH_CLAMP_RANGE_EXT
set in
VkPipelineDynamicStateCreateInfo::pDynamicStates
.
Otherwise, this state is specified by the
VkPipelineViewportDepthClampControlCreateInfoEXT::depthClampMode
value used to create the currently active pipeline.
Both VkPipelineViewportDepthClampControlCreateInfoEXT and
vkCmdSetDepthClampRangeEXT use VkDepthClampRangeEXT
to set the
viewport depth clamp range parameters.
The VkDepthClampRangeEXT
structure is defined as:
// Provided by VK_EXT_depth_clamp_control
typedef struct VkDepthClampRangeEXT {
float minDepthClamp;
float maxDepthClamp;
} VkDepthClampRangeEXT;
-
minDepthClamp
sets zmin in the depth clamp range of the viewport. -
maxDepthClamp
sets zmax in the depth clamp range of the viewport.
Depth Comparison
If the depth test is not enabled, as specified by
vkCmdSetDepthTestEnable or
VkPipelineDepthStencilStateCreateInfo::depthTestEnable
, then
this step is skipped.
The comparison operation performed is determined by the VkCompareOp
value set by
vkCmdSetDepthCompareOp, or by
VkPipelineDepthStencilStateCreateInfo::depthCompareOp
during
pipeline creation.
zf and za are used as the reference and test values,
respectively, in the operation specified by the VkCompareOp.
If the comparison evaluates to false, the coverage for the sample is set to
0
.
Depth Attachment Writes
If depth writes are enabled, as specified by
vkCmdSetDepthWriteEnable or
VkPipelineDepthStencilStateCreateInfo::depthWriteEnable
, and the
comparison evaluated to true, the depth attachment value za is set
to the sample’s depth value zf.
If there is no depth attachment, no value is written.
To dynamically enable or disable the depth test, call:
// Provided by VK_VERSION_1_3
void vkCmdSetDepthTestEnable(
VkCommandBuffer commandBuffer,
VkBool32 depthTestEnable);
or the equivalent command
// Provided by VK_EXT_extended_dynamic_state, VK_EXT_shader_object
void vkCmdSetDepthTestEnableEXT(
VkCommandBuffer commandBuffer,
VkBool32 depthTestEnable);
-
commandBuffer
is the command buffer into which the command will be recorded. -
depthTestEnable
specifies if the depth test is enabled.
This command sets the depth test enable for subsequent drawing commands
when drawing using shader objects, or
when the graphics pipeline is created with
VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE
set in
VkPipelineDynamicStateCreateInfo::pDynamicStates
.
Otherwise, this state is specified by the
VkPipelineDepthStencilStateCreateInfo::depthTestEnable
value
used to create the currently active pipeline.
To dynamically set the depth compare operator, call:
// Provided by VK_VERSION_1_3
void vkCmdSetDepthCompareOp(
VkCommandBuffer commandBuffer,
VkCompareOp depthCompareOp);
or the equivalent command
// Provided by VK_EXT_extended_dynamic_state, VK_EXT_shader_object
void vkCmdSetDepthCompareOpEXT(
VkCommandBuffer commandBuffer,
VkCompareOp depthCompareOp);
-
commandBuffer
is the command buffer into which the command will be recorded. -
depthCompareOp
is a VkCompareOp value specifying the comparison operator used for the Depth Comparison step of the depth test.
This command sets the depth comparison operator for subsequent drawing
commands
when drawing using shader objects, or
when the graphics pipeline is created with
VK_DYNAMIC_STATE_DEPTH_COMPARE_OP
set in
VkPipelineDynamicStateCreateInfo::pDynamicStates
.
Otherwise, this state is specified by the
VkPipelineDepthStencilStateCreateInfo::depthCompareOp
value used
to create the currently active pipeline.
To dynamically set the depth write enable, call:
// Provided by VK_VERSION_1_3
void vkCmdSetDepthWriteEnable(
VkCommandBuffer commandBuffer,
VkBool32 depthWriteEnable);
or the equivalent command
// Provided by VK_EXT_extended_dynamic_state, VK_EXT_shader_object
void vkCmdSetDepthWriteEnableEXT(
VkCommandBuffer commandBuffer,
VkBool32 depthWriteEnable);
-
commandBuffer
is the command buffer into which the command will be recorded. -
depthWriteEnable
specifies if depth writes are enabled.
This command sets the depth write enable for subsequent drawing commands
when drawing using shader objects, or
when the graphics pipeline is created with
VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE
set in
VkPipelineDynamicStateCreateInfo::pDynamicStates
.
Otherwise, this state is specified by the
VkPipelineDepthStencilStateCreateInfo::depthWriteEnable
value
used to create the currently active pipeline.
Representative Fragment Test
The representative fragment test allows implementations to reduce the amount of rasterization and fragment processing work performed for each point, line, or triangle primitive. For any primitive that produces one or more fragments that pass all prior early fragment tests, the implementation may choose one or more “representative” fragments for processing and discard all other fragments. For draw calls rendering multiple points, lines, or triangles arranged in lists, strips, or fans, the representative fragment test is performed independently for each of those primitives. The set of fragments discarded by the representative fragment test is implementation-dependent. In some cases, the representative fragment test may not discard any fragments for a given primitive.
If the pNext
chain of VkGraphicsPipelineCreateInfo includes a
VkPipelineRepresentativeFragmentTestStateCreateInfoNV
structure, then
that structure includes parameters controlling the representative fragment
test.
The VkPipelineRepresentativeFragmentTestStateCreateInfoNV
structure is
defined as:
// Provided by VK_NV_representative_fragment_test
typedef struct VkPipelineRepresentativeFragmentTestStateCreateInfoNV {
VkStructureType sType;
const void* pNext;
VkBool32 representativeFragmentTestEnable;
} VkPipelineRepresentativeFragmentTestStateCreateInfoNV;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
representativeFragmentTestEnable
controls whether the representative fragment test is enabled.
If this structure is not included in the pNext
chain,
representativeFragmentTestEnable
is considered to be VK_FALSE
,
and the representative fragment test is disabled.
If the active fragment shader does not specify the EarlyFragmentTests
execution mode, the representative fragment shader test has no effect, even
if enabled.
To dynamically set the
representativeFragmentTestEnable
state, call:
// 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
is the command buffer into which the command will be recorded. -
representativeFragmentTestEnable
specifies therepresentativeFragmentTestEnable
state.
This command sets the representativeFragmentTestEnable
state for
subsequent drawing commands
when drawing using shader objects, or
when the graphics pipeline is created with
VK_DYNAMIC_STATE_REPRESENTATIVE_FRAGMENT_TEST_ENABLE_NV
set in
VkPipelineDynamicStateCreateInfo::pDynamicStates
.
Otherwise, this state is specified by the
VkPipelineRepresentativeFragmentTestStateCreateInfoNV::representativeFragmentTestEnable
value used to create the currently active pipeline.
Sample Counting
Occlusion queries use query pool entries to track the number of samples that pass all the per-fragment tests. The mechanism of collecting an occlusion query value is described in Occlusion Queries.
The occlusion query sample counter increments by one for each sample with a coverage value of 1 in each fragment that survives all the per-fragment tests, including scissor, exclusive scissor, sample mask, alpha to coverage, stencil, and depth tests.
Fragment Coverage to Color
The VkPipelineCoverageToColorStateCreateInfoNV
structure is defined
as:
// 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
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
flags
is reserved for future use. -
coverageToColorEnable
controls whether the fragment coverage value replaces a fragment color output. -
coverageToColorLocation
controls which fragment shader color output value is replaced.
If the pNext
chain of VkPipelineMultisampleStateCreateInfo
includes a VkPipelineCoverageToColorStateCreateInfoNV
structure, then
that structure controls whether the fragment coverage is substituted for a
fragment color output and, if so, which output is replaced.
If coverageToColorEnable
is VK_TRUE
, the
coverage mask replaces the first
component of the color value corresponding to the fragment shader output
location with Location
equal to coverageToColorLocation
and
Index
equal to zero.
If the color attachment format has fewer bits than the coverage mask, the
low bits of the sample coverage mask are taken without any clamping.
If the color attachment format has more bits than the coverage mask, the
high bits of the sample coverage mask are filled with zeros.
If coverageToColorEnable
is VK_FALSE
, these operations are
skipped.
If this structure is not included in the pNext
chain, it is as if
coverageToColorEnable
is VK_FALSE
.
// Provided by VK_NV_fragment_coverage_to_color
typedef VkFlags VkPipelineCoverageToColorStateCreateFlagsNV;
VkPipelineCoverageToColorStateCreateFlagsNV
is a bitmask type for
setting a mask, but is currently reserved for future use.
To dynamically set the
coverageToColorEnable
state, call:
// 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
is the command buffer into which the command will be recorded. -
coverageToColorEnable
specifies thecoverageToColorEnable
state.
This command sets the coverageToColorEnable
state for subsequent
drawing commands
when drawing using shader objects, or
when the graphics pipeline is created with
VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_ENABLE_NV
set in
VkPipelineDynamicStateCreateInfo::pDynamicStates
.
Otherwise, this state is specified by the
VkPipelineCoverageToColorStateCreateInfoNV::coverageToColorEnable
value used to create the currently active pipeline.
To dynamically set the
coverageToColorLocation
state, call:
// 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
is the command buffer into which the command will be recorded. -
coverageToColorLocation
specifies thecoverageToColorLocation
state.
This command sets the coverageToColorLocation
state for subsequent
drawing commands
when drawing using shader objects, or
when the graphics pipeline is created with
VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_LOCATION_NV
set in
VkPipelineDynamicStateCreateInfo::pDynamicStates
.
Otherwise, this state is specified by the
VkPipelineCoverageToColorStateCreateInfoNV::coverageToColorLocation
value used to create the currently active pipeline.
Coverage Reduction
Coverage reduction takes the coverage information for a fragment and converts that to a boolean coverage value for each color sample in each pixel covered by the fragment.
Pixel Coverage
Coverage for each pixel is first extracted from the total fragment coverage
mask.
This consists of rasterizationSamples
unique coverage samples for each
pixel in the fragment area, each with a unique
sample index.
If the fragment only contains a single pixel, coverage for the pixel is
equivalent to the fragment coverage.
If the render pass has a fragment density map attachment and the fragment covers multiple pixels, pixel coverage is generated in an implementation-dependent manner. If all samples in the fragment are covered, all samples will be covered in each pixel coverage.
If a shading rate image is used, and the fragment covers multiple pixels, each pixel’s coverage consists of the coverage samples corresponding to that pixel, and each sample retains its unique sample index i.
If the fragment shading rate is set, and the fragment covers multiple pixels, each pixel’s coverage consists of the coverage samples with a pixel index matching that pixel, and each sample retains its unique sample index i.
Color Sample Coverage
Once pixel coverage is determined, coverage for each individual color sample corresponding to that pixel is determined.
If the
number of rasterizationSamples
is identical to the number of samples
in the color
attachments, a
color sample is covered if the pixel coverage sample with the same
sample index i is covered.
Otherwise, the coverage for each color sample is computed from the pixel coverage as follows.
If the VK_AMD_mixed_attachment_samples
extension is enabled, for
color samples present in the color attachments, a color sample is covered if
the pixel coverage sample with the same
sample index i is covered;
additional pixel coverage samples are discarded.
If the pNext
chain of VkSubpassDescription2
or VkRenderingInfo
includes a VkMultisampledRenderToSingleSampledInfoEXT structure with
the multisampledRenderToSingleSampledEnable
field equal to
VK_TRUE
, sample coverage is calculated as if the attachment has
VkMultisampledRenderToSingleSampledInfoEXT::rasterizationSamples
samples.
When the VK_NV_coverage_reduction_mode
extension is enabled, the
pipeline state controlling coverage reduction is specified through the
members of the VkPipelineCoverageReductionStateCreateInfoNV
structure.
The VkPipelineCoverageReductionStateCreateInfoNV
structure is defined
as:
// Provided by VK_NV_coverage_reduction_mode
typedef struct VkPipelineCoverageReductionStateCreateInfoNV {
VkStructureType sType;
const void* pNext;
VkPipelineCoverageReductionStateCreateFlagsNV flags;
VkCoverageReductionModeNV coverageReductionMode;
} VkPipelineCoverageReductionStateCreateInfoNV;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
flags
is reserved for future use. -
coverageReductionMode
is a VkCoverageReductionModeNV value controlling how color sample coverage is generated from pixel coverage.
If this structure is not included in the pNext
chain, or if the
extension is not enabled, the default coverage reduction mode is inferred as
follows:
-
If the
VK_NV_framebuffer_mixed_samples
extension is enabled, then it is as if thecoverageReductionMode
isVK_COVERAGE_REDUCTION_MODE_MERGE_NV
. -
If the
VK_AMD_mixed_attachment_samples
extension is enabled, then it is as if thecoverageReductionMode
isVK_COVERAGE_REDUCTION_MODE_TRUNCATE_NV
. -
If both
VK_NV_framebuffer_mixed_samples
andVK_AMD_mixed_attachment_samples
are enabled, then the default coverage reduction mode is implementation-dependent.
// Provided by VK_NV_coverage_reduction_mode
typedef VkFlags VkPipelineCoverageReductionStateCreateFlagsNV;
VkPipelineCoverageReductionStateCreateFlagsNV
is a bitmask type for
setting a mask, but is currently reserved for future use.
Possible values of
VkPipelineCoverageReductionStateCreateInfoNV::coverageReductionMode
,
specifying how color sample coverage is generated from pixel coverage, are:
// 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
specifies that each color sample will be associated with an implementation-dependent subset of samples in the pixel coverage. If any of those associated samples are covered, the color sample is covered. -
VK_COVERAGE_REDUCTION_MODE_TRUNCATE_NV
specifies that for color samples present in the color attachments, a color sample is covered if the pixel coverage sample with the same sample index i is covered; other pixel coverage samples are discarded.
To dynamically set the
coverageReductionMode
state, call:
// 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
is the command buffer into which the command will be recorded. -
coverageReductionMode
specifies thecoverageReductionMode
state.
This command sets the coverageReductionMode
state for subsequent
drawing commands
when drawing using shader objects, or
when the graphics pipeline is created with
VK_DYNAMIC_STATE_COVERAGE_REDUCTION_MODE_NV
set in
VkPipelineDynamicStateCreateInfo::pDynamicStates
.
Otherwise, this state is specified by the
VkPipelineCoverageReductionStateCreateInfoNV::coverageReductionMode
value used to create the currently active pipeline.
To query the set of mixed sample combinations of coverage reduction mode, rasterization samples and color, depth, stencil attachment sample counts that are supported by a physical device, call:
// Provided by VK_NV_coverage_reduction_mode
VkResult vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV(
VkPhysicalDevice physicalDevice,
uint32_t* pCombinationCount,
VkFramebufferMixedSamplesCombinationNV* pCombinations);
-
physicalDevice
is the physical device from which to query the set of combinations. -
pCombinationCount
is a pointer to an integer related to the number of combinations available or queried, as described below. -
pCombinations
is eitherNULL
or a pointer to an array of VkFramebufferMixedSamplesCombinationNV values, indicating the supported combinations of coverage reduction mode, rasterization samples, and color, depth, stencil attachment sample counts.
If pCombinations
is NULL
, then the number of supported combinations
for the given physicalDevice
is returned in pCombinationCount
.
Otherwise, pCombinationCount
must point to a variable set by the
application to the number of elements in the pCombinations
array, and
on return the variable is overwritten with the number of values actually
written to pCombinations
.
If the value of pCombinationCount
is less than the number of
combinations supported for the given physicalDevice
, at most
pCombinationCount
values will be written to pCombinations
, and
VK_INCOMPLETE
will be returned instead of VK_SUCCESS
, to
indicate that not all the supported values were returned.
The VkFramebufferMixedSamplesCombinationNV
structure is defined as:
// Provided by VK_NV_coverage_reduction_mode
typedef struct VkFramebufferMixedSamplesCombinationNV {
VkStructureType sType;
void* pNext;
VkCoverageReductionModeNV coverageReductionMode;
VkSampleCountFlagBits rasterizationSamples;
VkSampleCountFlags depthStencilSamples;
VkSampleCountFlags colorSamples;
} VkFramebufferMixedSamplesCombinationNV;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
coverageReductionMode
is a VkCoverageReductionModeNV value specifying the coverage reduction mode. -
rasterizationSamples
is a VkSampleCountFlagBits specifying the number of rasterization samples in the supported combination. -
depthStencilSamples
specifies the number of samples in the depth stencil attachment in the supported combination. A value of 0 indicates the combination does not have a depth stencil attachment. -
colorSamples
specifies the number of color samples in a color attachment in the supported combination. A value of 0 indicates the combination does not have a color attachment.
Coverage Modulation
As part of coverage reduction, fragment color values can also be modulated (multiplied) by a value that is a function of fraction of covered rasterization samples associated with that color sample.
Pipeline state controlling coverage modulation is specified through the
members of the VkPipelineCoverageModulationStateCreateInfoNV
structure.
The VkPipelineCoverageModulationStateCreateInfoNV
structure is defined
as:
// 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
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
flags
is reserved for future use. -
coverageModulationMode
is a VkCoverageModulationModeNV value controlling which color components are modulated. -
coverageModulationTableEnable
controls whether the modulation factor is looked up from a table inpCoverageModulationTable
. -
coverageModulationTableCount
is the number of elements inpCoverageModulationTable
. -
pCoverageModulationTable
is a table of modulation factors containing a value for each number of covered samples.
If coverageModulationTableEnable
is VK_FALSE
, then for each
color sample the associated bits of the pixel coverage are counted and
divided by the number of associated bits to produce a modulation factor
R in the range (0,1] (a value of zero would have been killed due
to a color coverage of 0).
Specifically:
-
N = value of
rasterizationSamples
-
M = value of VkAttachmentDescription::
samples
for any color attachments -
R = popcount(associated coverage bits) / (N / M)
If coverageModulationTableEnable
is VK_TRUE
, the value R
is computed using a programmable lookup table.
The lookup table has N / M elements, and the element of the table is
selected by:
-
R =
pCoverageModulationTable
[popcount(associated coverage bits)-1]
Note that the table does not have an entry for popcount(associated coverage bits) = 0, because such samples would have been killed.
The values of pCoverageModulationTable
may be rounded to an
implementation-dependent precision, which is at least as fine as 1 /
N, and clamped to [0,1].
For each color attachment with a floating-point or normalized color format,
each fragment output color value is replicated to M values which can
each be modulated (multiplied) by that color sample’s associated value of
R.
Which components are modulated is controlled by
coverageModulationMode
.
If this structure is not included in the pNext
chain, it is as if
coverageModulationMode
is VK_COVERAGE_MODULATION_MODE_NONE_NV
.
If the coverage reduction mode is
VK_COVERAGE_REDUCTION_MODE_TRUNCATE_NV
, each color sample is
associated with only a single coverage sample.
In this case, it is as if coverageModulationMode
is
VK_COVERAGE_MODULATION_MODE_NONE_NV
.
// Provided by VK_NV_framebuffer_mixed_samples
typedef VkFlags VkPipelineCoverageModulationStateCreateFlagsNV;
VkPipelineCoverageModulationStateCreateFlagsNV
is a bitmask type for
setting a mask, but is currently reserved for future use.
Possible values of
VkPipelineCoverageModulationStateCreateInfoNV::coverageModulationMode
,
specifying which color components are modulated, are:
// 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
specifies that no components are multiplied by the modulation factor. -
VK_COVERAGE_MODULATION_MODE_RGB_NV
specifies that the red, green, and blue components are multiplied by the modulation factor. -
VK_COVERAGE_MODULATION_MODE_ALPHA_NV
specifies that the alpha component is multiplied by the modulation factor. -
VK_COVERAGE_MODULATION_MODE_RGBA_NV
specifies that all components are multiplied by the modulation factor.
To dynamically set the
coverageModulationMode
state, call:
// 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
is the command buffer into which the command will be recorded. -
coverageModulationMode
specifies thecoverageModulationMode
state.
This command sets the coverageModulationMode
state for subsequent
drawing commands
when drawing using shader objects, or
the graphics pipeline is created with
VK_DYNAMIC_STATE_COVERAGE_MODULATION_MODE_NV
set in
VkPipelineDynamicStateCreateInfo::pDynamicStates
.
Otherwise, this state is specified by the
VkPipelineCoverageModulationStateCreateInfoNV::coverageModulationMode
value used to create the currently active pipeline.
To dynamically set the
coverageModulationTableEnable
state, call:
// 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
is the command buffer into which the command will be recorded. -
coverageModulationTableEnable
specifies thecoverageModulationTableEnable
state.
This command sets the coverageModulationTableEnable
state for
subsequent drawing commands
when drawing using shader objects, or
when the graphics pipeline is created with
VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_ENABLE_NV
set in
VkPipelineDynamicStateCreateInfo::pDynamicStates
.
Otherwise, this state is specified by the
VkPipelineCoverageModulationStateCreateInfoNV::coverageModulationTableEnable
value used to create the currently active pipeline.
To dynamically set the
pCoverageModulationTable
state, call:
// 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
is the command buffer into which the command will be recorded. -
coverageModulationTableCount
specifies the number of elements inpCoverageModulationTable
. -
pCoverageModulationTable
specifies the table of modulation factors containing a value for each number of covered samples.
This command sets the table of modulation factors for subsequent drawing
commands
when drawing using shader objects, or
when the graphics pipeline is created with
VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_NV
set in
VkPipelineDynamicStateCreateInfo::pDynamicStates
.
Otherwise, this state is specified by the
VkPipelineCoverageModulationStateCreateInfoNV::coverageModulationTableCount
,
and
VkPipelineCoverageModulationStateCreateInfoNV::pCoverageModulationTable
values used to create the currently active pipeline.