blob: 3d828361ce2aedcb857f9248da59a46b20d24234 [file] [log] [blame]
// Copyright 2015-2021 The Khronos Group, Inc.
//
// SPDX-License-Identifier: CC-BY-4.0
[[fragops]]
= 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 <<primsrast-order,rasterization
order>>, and are typically performed in this order:
ifdef::VK_EXT_discard_rectangles[]
. <<fragops-discard-rectangles,Discard rectangles test>>
endif::VK_EXT_discard_rectangles[]
. <<fragops-scissor,Scissor test>>
ifdef::VK_NV_scissor_exclusive[]
. <<fragops-exclusive-scissor,Exclusive scissor test>>
endif::VK_NV_scissor_exclusive[]
. <<fragops-samplemask,Sample mask test>>
. Certain <<fragops-shader,Fragment shading>> operations:
** <<fragops-shader-samplemask, Sample Mask Accesses>>
** <<fragops-shader-depthreplacement, Depth Replacement>>
ifdef::VK_EXT_shader_stencil_export[]
** <<fragops-shader-stencilrefreplacement, Stencil Reference Replacement>>
endif::VK_EXT_shader_stencil_export[]
ifdef::VK_EXT_fragment_shader_interlock[]
** <<fragops-shader-interlock, Interlocked Operations>>
endif::VK_EXT_fragment_shader_interlock[]
. <<fragops-covg, Multisample coverage>>
. <<fragops-dbt, Depth bounds test>>
. <<fragops-stencil, Stencil test>>
. <<fragops-depth, Depth test>>
ifdef::VK_NV_representative_fragment_test[]
. <<fragops-rep-frag-test, Representative fragment test>>
endif::VK_NV_representative_fragment_test[]
. <<fragops-samplecount, Sample counting>>
ifdef::VK_NV_fragment_coverage_to_color[]
. <<fragops-coverage-to-color, Coverage to color>>
endif::VK_NV_fragment_coverage_to_color[]
. <<fragops-coverage-reduction, Coverage reduction>>
ifdef::VK_NV_framebuffer_mixed_samples[]
. <<fragops-coverage-modulation, Coverage modulation>>
endif::VK_NV_framebuffer_mixed_samples[]
The <<primsrast-multisampling-coverage-mask, 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.
Fragments can also be programmatically discarded in a fragment shader by
executing one of
ifdef::VK_KHR_shader_terminate_invocation[]
* code:OpTerminateInvocation
endif::VK_KHR_shader_terminate_invocation[]
ifdef::VK_EXT_shader_demote_to_helper_invocation[]
* code:OpDemoteToHelperInvocationEXT
endif::VK_EXT_shader_demote_to_helper_invocation[]
* code:OpKill.
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.
ifdef::VK_EXT_post_depth_coverage[]
If the <<fragops-shader, fragment shader>> declares the
code:PostDepthCoverage execution mode, the <<fragops-samplemask, sample mask
test>> is instead performed after the <<fragops-depth, depth test>>.
endif::VK_EXT_post_depth_coverage[]
If the <<fragops-shader, fragment shader>> declares the
code:EarlyFragmentTests execution mode, <<fragops-shader,fragment shading>>
and <<fragops-covg, multisample coverage>> operations are instead performed
after <<fragops-samplecount, sample counting>>.
Once all fragment operations have completed, fragment shader outputs for
covered color attachment samples pass through <<framebuffer, framebuffer
operations>>.
ifdef::VK_EXT_discard_rectangles[]
[[fragops-discard-rectangles]]
== Discard Rectangles Test
The discard rectangle test compares the framebuffer coordinates
[eq]#(x~f~,y~f~)# of each sample covered by a fragment against a set of
_discard rectangles_.
Each discard rectangle is defined by a slink:VkRect2D.
These values are either set by the
slink:VkPipelineDiscardRectangleStateCreateInfoEXT structure during pipeline
creation, or dynamically by the flink:vkCmdSetDiscardRectangleEXT command.
A given sample is considered inside a discard rectangle if the [eq]#x~f~# is
in the range [eq]#[slink:VkRect2D::offset.x, slink:VkRect2D::offset.x {plus}
slink:VkRect2D::extent.x)#, and [eq]#y~f~# is in the range
[eq]#[slink:VkRect2D::offset.y, slink:VkRect2D::offset.y {plus}
slink: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.
[open,refpage='VkPipelineDiscardRectangleStateCreateInfoEXT',desc='Structure specifying discard rectangle',type='structs']
--
The sname:VkPipelineDiscardRectangleStateCreateInfoEXT structure is defined
as:
include::{generated}/api/structs/VkPipelineDiscardRectangleStateCreateInfoEXT.txt[]
* pname:sType is the type of this structure.
* pname:pNext is `NULL` or a pointer to a structure extending this
structure.
* pname:flags is reserved for future use.
* pname:discardRectangleMode is a elink:VkDiscardRectangleModeEXT value
determining whether the discard rectangle test is inclusive or
exclusive.
* pname:discardRectangleCount is the number of discard rectangles to use.
* pname:pDiscardRectangles is a pointer to an array of slink:VkRect2D
structures defining discard rectangles.
If the ename:VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT dynamic state is enabled
for a pipeline, the pname:pDiscardRectangles member is ignored.
When this structure is included in the pname:pNext chain of
slink:VkGraphicsPipelineCreateInfo, it defines parameters of the discard
rectangle test.
If this structure is not included in the pname:pNext chain, it is equivalent
to specifying this structure with a pname:discardRectangleCount of `0`.
.Valid Usage
****
* [[VUID-VkPipelineDiscardRectangleStateCreateInfoEXT-discardRectangleCount-00582]]
pname:discardRectangleCount must: be less than or equal to
sname:VkPhysicalDeviceDiscardRectanglePropertiesEXT::pname:maxDiscardRectangles
****
include::{generated}/validity/structs/VkPipelineDiscardRectangleStateCreateInfoEXT.txt[]
--
[open,refpage='VkPipelineDiscardRectangleStateCreateFlagsEXT',desc='Reserved for future use',type='flags']
--
include::{generated}/api/flags/VkPipelineDiscardRectangleStateCreateFlagsEXT.txt[]
tname:VkPipelineDiscardRectangleStateCreateFlagsEXT is a bitmask type for
setting a mask, but is currently reserved for future use.
--
[open,refpage='VkDiscardRectangleModeEXT',desc='Specify the discard rectangle mode',type='enums']
--
ename:VkDiscardRectangleModeEXT values are:
include::{generated}/api/enums/VkDiscardRectangleModeEXT.txt[]
* ename:VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT specifies that the discard
rectangle test is inclusive.
* ename:VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT specifies that the discard
rectangle test is exclusive.
--
[open,refpage='vkCmdSetDiscardRectangleEXT',desc='Set discard rectangles dynamically for a command buffer',type='protos']
--
To <<pipelines-dynamic-state, dynamically set>> the discard rectangles,
call:
include::{generated}/api/protos/vkCmdSetDiscardRectangleEXT.txt[]
* pname:commandBuffer is the command buffer into which the command will be
recorded.
* pname:firstDiscardRectangle is the index of the first discard rectangle
whose state is updated by the command.
* pname:discardRectangleCount is the number of discard rectangles whose
state are updated by the command.
* pname:pDiscardRectangles is a pointer to an array of slink:VkRect2D
structures specifying discard rectangles.
The discard rectangle taken from element [eq]#i# of pname:pDiscardRectangles
replace the current state for the discard rectangle at index
[eq]#pname:firstDiscardRectangle {plus} i#, for [eq]#i# in [eq]#[0,
pname:discardRectangleCount)#.
This command sets the discard rectangles for subsequent drawing commands
when the graphics pipeline is created with
ename:VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT set in
slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
Otherwise, this state is specified by the
slink:VkPipelineDiscardRectangleStateCreateInfoEXT::pname:pDiscardRectangles
values used to create the currently active pipeline.
.Valid Usage
****
* [[VUID-vkCmdSetDiscardRectangleEXT-firstDiscardRectangle-00585]]
The sum of pname:firstDiscardRectangle and pname:discardRectangleCount
must: be less than or equal to
slink:VkPhysicalDeviceDiscardRectanglePropertiesEXT::pname:maxDiscardRectangles
* [[VUID-vkCmdSetDiscardRectangleEXT-x-00587]]
The pname:x and pname:y member of pname:offset in each slink:VkRect2D
element of pname:pDiscardRectangles must: be greater than or equal to
`0`
* [[VUID-vkCmdSetDiscardRectangleEXT-offset-00588]]
Evaluation of [eq]#(pname:offset.x {plus} pname:extent.width)# in each
slink:VkRect2D element of pname:pDiscardRectangles must: not cause a
signed integer addition overflow
* [[VUID-vkCmdSetDiscardRectangleEXT-offset-00589]]
Evaluation of [eq]#(pname:offset.y {plus} pname:extent.height)# in each
slink:VkRect2D element of pname:pDiscardRectangles must: not cause a
signed integer addition overflow
ifdef::VK_NV_inherited_viewport_scissor[]
* [[VUID-vkCmdSetDiscardRectangleEXT-viewportScissor2D-04788]]
If this command is recorded in a secondary command buffer with
slink:VkCommandBufferInheritanceViewportScissorInfoNV::pname:viewportScissor2D
enabled, then this function must: not be called
endif::VK_NV_inherited_viewport_scissor[]
****
include::{generated}/validity/protos/vkCmdSetDiscardRectangleEXT.txt[]
--
endif::VK_EXT_discard_rectangles[]
[[fragops-scissor]]
== Scissor Test
The scissor test compares the framebuffer coordinates [eq]#(x~f~,y~f~)# of
each sample covered by a fragment against a _scissor rectangle_ at the index
equal to the fragment's <<interfaces-builtin-variables-viewportindex,
code:ViewportIndex>>.
Each scissor rectangle is defined by a slink:VkRect2D.
These values are either set by the slink:VkPipelineViewportStateCreateInfo
structure during pipeline creation, or dynamically by the
flink:vkCmdSetScissor command.
A given sample is considered inside a scissor rectangle if [eq]#x~f~# is in
the range [eq]#[slink:VkRect2D::offset.x, slink:VkRect2D::offset.x {plus}
slink:VkRect2D::extent.x)#, and [eq]#y~f~# is in the range
[eq]#[slink:VkRect2D::offset.y, slink:VkRect2D::offset.y {plus}
slink:VkRect2D::extent.y)#.
Samples with coordinates outside the scissor rectangle at the corresponding
code:ViewportIndex will have their coverage set to `0`.
ifdef::VK_QCOM_render_pass_transform[]
If a render pass transform is enabled, the (pname:offset.x and
pname:offset.y) and (pname:extent.width and pname:extent.height) values are
transformed as described in <<vertexpostproc-renderpass-transform, render
pass transform>> before participating in the scissor test.
endif::VK_QCOM_render_pass_transform[]
[open,refpage='vkCmdSetScissor',desc='Set scissor rectangles dynamically for a command buffer',type='protos']
--
To <<pipelines-dynamic-state, dynamically set>> the scissor rectangles,
call:
include::{generated}/api/protos/vkCmdSetScissor.txt[]
* pname:commandBuffer is the command buffer into which the command will be
recorded.
* pname:firstScissor is the index of the first scissor whose state is
updated by the command.
* pname:scissorCount is the number of scissors whose rectangles are
updated by the command.
* pname:pScissors is a pointer to an array of slink:VkRect2D structures
defining scissor rectangles.
The scissor rectangles taken from element [eq]#i# of pname:pScissors replace
the current state for the scissor index [eq]#pname:firstScissor {plus} i#,
for [eq]#i# in [eq]#[0, pname:scissorCount)#.
This command sets the scissor rectangles for subsequent drawing commands
when the graphics pipeline is created with ename:VK_DYNAMIC_STATE_SCISSOR
set in slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
Otherwise, this state is specified by the
slink:VkPipelineViewportStateCreateInfo::pname:pScissors values used to
create the currently active pipeline.
.Valid Usage
****
* [[VUID-vkCmdSetScissor-firstScissor-00592]]
The sum of pname:firstScissor and pname:scissorCount must: be between
`1` and sname:VkPhysicalDeviceLimits::pname:maxViewports, inclusive
* [[VUID-vkCmdSetScissor-firstScissor-00593]]
If the <<features-multiViewport,multiple viewports>> feature is not
enabled, pname:firstScissor must: be `0`
* [[VUID-vkCmdSetScissor-scissorCount-00594]]
If the <<features-multiViewport,multiple viewports>> feature is not
enabled, pname:scissorCount must: be `1`
* [[VUID-vkCmdSetScissor-x-00595]]
The pname:x and pname:y members of pname:offset member of any element of
pname:pScissors must: be greater than or equal to `0`
* [[VUID-vkCmdSetScissor-offset-00596]]
Evaluation of [eq]#(pname:offset.x {plus} pname:extent.width)# must: not
cause a signed integer addition overflow for any element of
pname:pScissors
* [[VUID-vkCmdSetScissor-offset-00597]]
Evaluation of [eq]#(pname:offset.y {plus} pname:extent.height)# must:
not cause a signed integer addition overflow for any element of
pname:pScissors
ifdef::VK_NV_inherited_viewport_scissor[]
* [[VUID-vkCmdSetScissor-viewportScissor2D-04789]]
If this command is recorded in a secondary command buffer with
slink:VkCommandBufferInheritanceViewportScissorInfoNV::pname:viewportScissor2D
enabled, then this function must: not be called
endif::VK_NV_inherited_viewport_scissor[]
****
include::{generated}/validity/protos/vkCmdSetScissor.txt[]
--
ifdef::VK_NV_scissor_exclusive[]
[[fragops-exclusive-scissor]]
== Exclusive Scissor Test
The exclusive scissor test compares the framebuffer coordinates
[eq]#(x~f~,y~f~)# of each sample covered by a fragment against an _exclusive
scissor rectangle_ at the index equal to the fragment's
<<interfaces-builtin-variables-viewportindex, code:ViewportIndex>>.
Each exclusive scissor rectangle is defined by a slink:VkRect2D.
These values are either set by the
slink:VkPipelineViewportExclusiveScissorStateCreateInfoNV structure during
pipeline creation, or dynamically by the flink:vkCmdSetExclusiveScissorNV
command.
A given sample is considered inside an exclusive scissor rectangle if
[eq]#x~f~# is in the range [eq]#[slink:VkRect2D::offset.x,
slink:VkRect2D::offset.x {plus} slink:VkRect2D::extent.x)#, and [eq]#y~f~#
is in the range [eq]#[slink:VkRect2D::offset.y, slink:VkRect2D::offset.y
{plus} slink:VkRect2D::extent.y)#.
Samples with coordinates inside the exclusive scissor rectangle at the
corresponding code:ViewportIndex will have their coverage set to `0`.
If no exclusive scissor rectangles are specified, the coverage mask is
unmodified by this operation.
[open,refpage='VkPipelineViewportExclusiveScissorStateCreateInfoNV',desc='Structure specifying parameters controlling exclusive scissor testing',type='structs']
--
The sname:VkPipelineViewportExclusiveScissorStateCreateInfoNV structure is
defined as:
include::{generated}/api/structs/VkPipelineViewportExclusiveScissorStateCreateInfoNV.txt[]
* pname:sType is the type of this structure.
* pname:pNext is `NULL` or a pointer to a structure extending this
structure.
* pname:exclusiveScissorCount is the number of exclusive scissor
rectangles.
* pname:pExclusiveScissors is a pointer to an array of slink:VkRect2D
structures defining exclusive scissor rectangles.
If the ename:VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV dynamic state is enabled
for a pipeline, the pname:pExclusiveScissors member is ignored.
When this structure is included in the pname:pNext chain of
slink:VkGraphicsPipelineCreateInfo, it defines parameters of the exclusive
scissor test.
If this structure is not included in the pname:pNext chain, it is equivalent
to specifying this structure with a pname:exclusiveScissorCount of `0`.
.Valid Usage
****
* [[VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02027]]
If the <<features-multiViewport,multiple viewports>> feature is not
enabled, pname:exclusiveScissorCount must: be `0` or `1`
* [[VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02028]]
pname:exclusiveScissorCount must: be less than or equal to
sname:VkPhysicalDeviceLimits::pname:maxViewports
* [[VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02029]]
pname:exclusiveScissorCount must: be `0` or greater than or equal to the
pname:viewportCount member of slink:VkPipelineViewportStateCreateInfo
****
include::{generated}/validity/structs/VkPipelineViewportExclusiveScissorStateCreateInfoNV.txt[]
--
[open,refpage='vkCmdSetExclusiveScissorNV',desc='Set exclusive scissor rectangles dynamically for a command buffer',type='protos']
--
To <<pipelines-dynamic-state, dynamically set>> the exclusive scissor
rectangles, call:
include::{generated}/api/protos/vkCmdSetExclusiveScissorNV.txt[]
* pname:commandBuffer is the command buffer into which the command will be
recorded.
* pname:firstExclusiveScissor is the index of the first exclusive scissor
rectangle whose state is updated by the command.
* pname:exclusiveScissorCount is the number of exclusive scissor
rectangles updated by the command.
* pname:pExclusiveScissors is a pointer to an array of slink:VkRect2D
structures defining exclusive scissor rectangles.
The scissor rectangles taken from element [eq]#i# of
pname:pExclusiveScissors replace the current state for the scissor index
[eq]#pname:firstExclusiveScissor {plus} i#, for [eq]#i# in [eq]#[0,
pname:exclusiveScissorCount)#.
This command sets the exclusive scissor rectangles for subsequent drawing
commands when the graphics pipeline is created with
ename:VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV set in
slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
Otherwise, this state is specified by the
slink:VkPipelineViewportExclusiveScissorStateCreateInfoNV::pname:pExclusiveScissors
values used to create the currently active pipeline.
.Valid Usage
****
* [[VUID-vkCmdSetExclusiveScissorNV-None-02031]]
The <<features-exclusiveScissor,exclusive scissor>> feature must: be
enabled
* [[VUID-vkCmdSetExclusiveScissorNV-firstExclusiveScissor-02034]]
The sum of pname:firstExclusiveScissor and pname:exclusiveScissorCount
must: be between `1` and
sname:VkPhysicalDeviceLimits::pname:maxViewports, inclusive
* [[VUID-vkCmdSetExclusiveScissorNV-firstExclusiveScissor-02035]]
If the <<features-multiViewport,multiple viewports>> feature is not
enabled, pname:firstExclusiveScissor must: be `0`
* [[VUID-vkCmdSetExclusiveScissorNV-exclusiveScissorCount-02036]]
If the <<features-multiViewport,multiple viewports>> feature is not
enabled, pname:exclusiveScissorCount must: be `1`
* [[VUID-vkCmdSetExclusiveScissorNV-x-02037]]
The pname:x and pname:y members of pname:offset in each member of
pname:pExclusiveScissors must: be greater than or equal to `0`
* [[VUID-vkCmdSetExclusiveScissorNV-offset-02038]]
Evaluation of [eq]#(pname:offset.x {plus} pname:extent.width)# for each
member of pname:pExclusiveScissors must: not cause a signed integer
addition overflow
* [[VUID-vkCmdSetExclusiveScissorNV-offset-02039]]
Evaluation of [eq]#(pname:offset.y {plus} pname:extent.height)# for each
member of pname:pExclusiveScissors must: not cause a signed integer
addition overflow
****
include::{generated}/validity/protos/vkCmdSetExclusiveScissorNV.txt[]
--
endif::VK_NV_scissor_exclusive[]
[[fragops-samplemask]]
== Sample Mask Test
The sample mask test compares the <<primsrast-multisampling-coverage-mask,
coverage mask>> for a fragment with the _sample mask_ defined by
slink:VkPipelineMultisampleStateCreateInfo::pname:pSampleMask.
Each bit of the coverage mask is associated with a sample index as described
in the <<primsrast-multisampling-coverage-mask, rasterization chapter>>.
If the bit in slink:VkPipelineMultisampleStateCreateInfo::pname:pSampleMask
which is associated with that same sample index is set to `0`, the coverage
mask bit is set to `0`.
[[fragops-shader]]
== Fragment Shading
<<shaders-fragment, Fragment shaders>> are invoked for each fragment, or as
<<shaders-helper-invocations, helper invocations>>.
Most operations in the fragment shader are not performed in
<<primsrast-order, 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 <<fragops, 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 <<drawing-primitive-order, primitive order>>,
overwrites all results computed by the shader (including writes to
storage resources).
** Any other <<fragops, fragment operation>> discards the fragment, and
the shader does not write to any storage resources.
* Otherwise, at least one fragment shader must: be executed.
** If <<primsrast-sampleshading,sample shading>> is enabled and multiple
invocations per fragment are required:, additional invocations must: be
executed as specified.
ifdef::VK_NV_shading_rate_image[]
** If a <<primsrast-shading-rate-image,shading rate image>> is used and
multiple invocations per fragment are required:, additional invocations
must: be executed as specified.
endif::VK_NV_shading_rate_image[]
** Each covered sample must: be included in at least one fragment shader
invocation.
[NOTE]
.Note
====
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.
ifdef::VK_VERSION_1_1,VK_KHR_multiview[]
For example, if the subpass includes multiple views in its view mask, a
fragment shader may be invoked separately for each view.
endif::VK_VERSION_1_1,VK_KHR_multiview[]
ifdef::VK_EXT_fragment_density_map[]
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
sname:VkPhysicalDeviceFragmentDensityMapPropertiesEXT::pname:fragmentDensityInvocations
is ename:VK_TRUE.
Implementations may generate these additional fragment shader invocations in
order to make transitions between fragment areas with different fragment
densities more smooth.
endif::VK_EXT_fragment_density_map[]
====
[[fragops-shader-samplemask]]
=== Sample Mask
Reading from the <<interfaces-builtin-variables-samplemask,
code:SampleMask>> built-in in the code:Input storage class will return the
coverage mask for the current fragment as calculated by fragment operations
that executed prior to fragment shading.
If <<primsrast-sampleshading, 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 <<primsrast-multisampling-coverage-mask, rasterization chapter>>.
If the bit in code: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 <<interfaces-builtin-variables-samplemask,
code:SampleMask>> built-in in the code:Output storage class will be used by
the <<fragops-covg, multisample coverage>> operation, with the same encoding
as the input built-in.
[[fragops-shader-depthreplacement]]
=== Depth Replacement
Writing to the <<interfaces-builtin-variables-fragdepth,code:FragDepth>>
built-in will replace the fragment's calculated depth values for each sample
in the input code:SampleMask.
<<fragops-depth, Depth testing>> performed after the fragment shader for
this fragment will use this new value as [eq]#z~f~#.
ifdef::VK_EXT_shader_stencil_export[]
[[fragops-shader-stencilrefreplacement]]
=== Stencil Reference Replacement
Writing to the
<<interfaces-builtin-variables-fragdepth,code:FragStencilRefEXT>> built-in
will replace the fragment's stencil reference value for each sample in the
input code:SampleMask.
<<fragops-stencil, Stencil testing>> performed after the fragment shader for
this fragment will use this new value as [eq]#s~r~#.
endif::VK_EXT_shader_stencil_export[]
ifdef::VK_EXT_fragment_shader_interlock[]
[[fragops-shader-interlock]]
=== Interlocked Operations
code:OpBeginInvocationInterlockEXT and code: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.
ifdef::VK_NV_shading_rate_image,VK_KHR_fragment_shading_rate[]
If the code: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
<<primsrast-order, 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 <<primsrast-order, rasterization
order>> and cover at least one sample in the same fragment area.
If the code: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 <<primsrast-order, rasterization order>> and cover at least one
sample in the same fragment area.
endif::VK_NV_shading_rate_image,VK_KHR_fragment_shading_rate[]
If the code: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
<<primsrast-order, 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 <<primsrast-order, rasterization order>> and
cover at least one sample in the same pixel.
If the code: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 <<primsrast-order, rasterization order>> and cover at least one
sample in the same pixel.
If the code: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
<<primsrast-order, 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 <<primsrast-order, rasterization order>> and cover
at least one of the same samples.
If the code: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 <<primsrast-order, rasterization order>> and cover at least one
of the same samples.
endif::VK_EXT_fragment_shader_interlock[]
[[fragops-covg]]
== Multisample Coverage
If a fragment shader is active and its entry point's interface includes a
built-in output variable decorated with code:SampleMask,
ifdef::VK_NV_sample_mask_override_coverage[]
but not code:OverrideCoverageNV,
endif::VK_NV_sample_mask_override_coverage[]
the coverage mask is code:ANDed with the bits of the code:SampleMask
built-in to generate a new coverage mask.
ifdef::VK_NV_sample_mask_override_coverage[]
If the code:SampleMask built-in is also decorated with
code:OverrideCoverageNV, the coverage mask is replaced with the mask bits
set in the shader.
endif::VK_NV_sample_mask_override_coverage[]
If <<primsrast-sampleshading,sample shading>> is enabled, bits written to
code: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 code:SampleMask in its interface, the coverage mask is not modified.
Next, the fragment alpha value and coverage mask are modified based on the
ifdef::VK_EXT_line_rasterization[]
line coverage factor if the pname:lineRasterizationMode member of the
slink:VkPipelineRasterizationStateCreateInfo structure is
ename:VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT, and the
endif::VK_EXT_line_rasterization[]
pname:alphaToCoverageEnable and pname:alphaToOneEnable members of the
slink:VkPipelineMultisampleStateCreateInfo structure.
All alpha values in this section refer only to the alpha component of the
fragment shader output that has a code:Location and code:Index decoration of
zero (see the <<interfaces-fragmentoutput,Fragment Output Interface>>
section).
If that shader output has an integer or unsigned integer type, then these
operations are skipped.
ifdef::VK_EXT_line_rasterization[]
If the pname:lineRasterizationMode member of the
slink:VkPipelineRasterizationStateCreateInfo structure is
ename:VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT 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
<<primsrast-lines-smooth,smooth line rasterization>>.
endif::VK_EXT_line_rasterization[]
If pname: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 [eq]#[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.
[NOTE]
.Note
====
Using different algorithms at different framebuffer coordinates may: help to
avoid artifacts caused by regular coverage sample locations.
====
Finally, if pname:alphaToOneEnable is enabled, each alpha value is replaced
by the maximum representable alpha value for fixed-point color buffers, or
by 1.0 for floating-point buffers.
Otherwise, the alpha values are not changed.
[[fragops-ds-state]]
== Depth and Stencil Operations
Pipeline state controlling the <<fragops-dbt,depth bounds tests>>,
<<fragops-stencil,stencil test>>, and <<fragops-depth,depth test>> is
specified through the members of the
sname:VkPipelineDepthStencilStateCreateInfo structure.
[open,refpage='VkPipelineDepthStencilStateCreateInfo',desc='Structure specifying parameters of a newly created pipeline depth stencil state',type='structs']
--
The sname:VkPipelineDepthStencilStateCreateInfo structure is defined as:
include::{generated}/api/structs/VkPipelineDepthStencilStateCreateInfo.txt[]
* pname:sType is the type of this structure.
* pname:pNext is `NULL` or a pointer to a structure extending this
structure.
* pname:flags is reserved for future use.
* pname:depthTestEnable controls whether <<fragops-depth,depth testing>>
is enabled.
* pname:depthWriteEnable controls whether <<fragops-depth-write,depth
writes>> are enabled when pname:depthTestEnable is ename:VK_TRUE.
Depth writes are always disabled when pname:depthTestEnable is
ename:VK_FALSE.
* pname:depthCompareOp is the comparison operator used in the
<<fragops-depth,depth test>>.
* pname:depthBoundsTestEnable controls whether <<fragops-dbt,depth bounds
testing>> is enabled.
* pname:stencilTestEnable controls whether <<fragops-stencil,stencil
testing>> is enabled.
* pname:front and pname:back control the parameters of the
<<fragops-stencil,stencil test>>.
* pname:minDepthBounds is the minimum depth bound used in the
<<fragops-dbt, depth bounds test>>.
* pname:maxDepthBounds is the maximum depth bound used in the
<<fragops-dbt, depth bounds test>>.
.Valid Usage
****
* [[VUID-VkPipelineDepthStencilStateCreateInfo-depthBoundsTestEnable-00598]]
If the <<features-depthBounds,depth bounds testing>> feature is not
enabled, pname:depthBoundsTestEnable must: be ename:VK_FALSE
ifdef::VK_KHR_portability_subset[]
* [[VUID-VkPipelineDepthStencilStateCreateInfo-separateStencilMaskRef-04453]]
If the `apiext:VK_KHR_portability_subset` extension is enabled, and
slink:VkPhysicalDevicePortabilitySubsetFeaturesKHR::pname:separateStencilMaskRef
is ename:VK_FALSE, and the value of
slink:VkPipelineDepthStencilStateCreateInfo::pname:stencilTestEnable is
ename:VK_TRUE, and the value of
slink:VkPipelineRasterizationStateCreateInfo::pname:cullMode is
ename:VK_CULL_MODE_NONE, the value of pname:reference in each of the
slink:VkStencilOpState structs in pname:front and pname:back must: be
the same
endif::VK_KHR_portability_subset[]
****
include::{generated}/validity/structs/VkPipelineDepthStencilStateCreateInfo.txt[]
--
[open,refpage='VkPipelineDepthStencilStateCreateFlags',desc='Reserved for future use',type='flags']
--
include::{generated}/api/flags/VkPipelineDepthStencilStateCreateFlags.txt[]
tname:VkPipelineDepthStencilStateCreateFlags is a bitmask type for setting a
mask, but is currently reserved for future use.
--
[[fragops-dbt]]
== Depth Bounds Test
The depth bounds test compares the depth value [eq]#z~a~# in the
depth/stencil attachment at each sample's framebuffer coordinates
[eq]#(x~f~,y~f~)# and <<primsrast-multisampling-coverage-mask, sample
index>> [eq]#i# against a set of _depth bounds_.
The depth bounds are determined by two floating point values defining a
minimum (pname:minDepthBounds) and maximum (pname:maxDepthBounds) depth
value.
These values are either set by the
slink:VkPipelineDepthStencilStateCreateInfo structure during pipeline
creation, or dynamically by
ifdef::VK_EXT_extended_dynamic_state[]
flink:vkCmdSetDepthBoundsTestEnableEXT and
endif::VK_EXT_extended_dynamic_state[]
flink:vkCmdSetDepthBounds.
A given sample is considered within the depth bounds if [eq]#z~a~# is in the
range [eq]#[pname:minDepthBounds,pname: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.
ifdef::VK_EXT_extended_dynamic_state[]
[open,refpage='vkCmdSetDepthBoundsTestEnableEXT',desc='Set depth bounds test enable dynamically for a command buffer',type='protos']
--
To <<pipelines-dynamic-state, dynamically enable or disable>> the depth
bounds test, call:
include::{generated}/api/protos/vkCmdSetDepthBoundsTestEnableEXT.txt[]
* pname:commandBuffer is the command buffer into which the command will be
recorded.
* pname:depthBoundsTestEnable specifies if the depth bounds test is
enabled.
This command sets the depth bounds enable for subsequent drawing commands
when the graphics pipeline is created with
ename:VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT set in
slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
Otherwise, this state is specified by the
slink:VkPipelineDepthStencilStateCreateInfo::pname:depthBoundsTestEnable
value used to create the currently active pipeline.
.Valid Usage
****
* [[VUID-vkCmdSetDepthBoundsTestEnableEXT-None-03349]]
The <<features-extendedDynamicState, extendedDynamicState>> feature
must: be enabled
****
include::{generated}/validity/protos/vkCmdSetDepthBoundsTestEnableEXT.txt[]
--
endif::VK_EXT_extended_dynamic_state[]
[open,refpage='vkCmdSetDepthBounds',desc='Set depth bounds range dynamically for a command buffer',type='protos']
--
To <<pipelines-dynamic-state, dynamically set>> the depth bounds range,
call:
include::{generated}/api/protos/vkCmdSetDepthBounds.txt[]
* pname:commandBuffer is the command buffer into which the command will be
recorded.
* pname:minDepthBounds is the minimum depth bound.
* pname:maxDepthBounds is the maximum depth bound.
This command sets the depth bounds range for subsequent drawing commands
when the graphics pipeline is created with
ename:VK_DYNAMIC_STATE_DEPTH_BOUNDS set in
slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
Otherwise, this state is specified by the
slink:VkPipelineDepthStencilStateCreateInfo::pname:minDepthBounds and
slink:VkPipelineDepthStencilStateCreateInfo::pname:maxDepthBounds values
used to create the currently active pipeline.
.Valid Usage
****
ifdef::VK_EXT_depth_range_unrestricted[]
* [[VUID-vkCmdSetDepthBounds-minDepthBounds-00600]]
Unless the `apiext:VK_EXT_depth_range_unrestricted` extension is enabled
pname:minDepthBounds must: be between `0.0` and `1.0`, inclusive
endif::VK_EXT_depth_range_unrestricted[]
ifndef::VK_EXT_depth_range_unrestricted[]
* [[VUID-vkCmdSetDepthBounds-minDepthBounds-02508]]
pname:minDepthBounds must: be between `0.0` and `1.0`, inclusive
endif::VK_EXT_depth_range_unrestricted[]
ifdef::VK_EXT_depth_range_unrestricted[]
* [[VUID-vkCmdSetDepthBounds-maxDepthBounds-00601]]
Unless the `apiext:VK_EXT_depth_range_unrestricted` extension is enabled
pname:maxDepthBounds must: be between `0.0` and `1.0`, inclusive
endif::VK_EXT_depth_range_unrestricted[]
ifndef::VK_EXT_depth_range_unrestricted[]
* [[VUID-vkCmdSetDepthBounds-maxDepthBounds-02509]]
pname:maxDepthBounds must: be between `0.0` and `1.0`, inclusive
endif::VK_EXT_depth_range_unrestricted[]
****
include::{generated}/validity/protos/vkCmdSetDepthBounds.txt[]
--
[[fragops-stencil]]
== Stencil Test
The stencil test compares the stencil attachment value [eq]#s~a~# in the
depth/stencil attachment at each sample's framebuffer coordinates
[eq]#(x~f~,y~f~)# and <<primsrast-multisampling-coverage-mask, sample
index>> [eq]#i# against a _stencil reference value_.
ifdef::VK_EXT_fragment_density_map[]
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.
endif::VK_EXT_fragment_density_map[]
If the stencil test is not enabled, as specified by
ifdef::VK_EXT_extended_dynamic_state[]
flink:vkCmdSetStencilTestEnableEXT or
endif::VK_EXT_extended_dynamic_state[]
slink:VkPipelineDepthStencilStateCreateInfo::pname: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 <<primsrast-polygons-basic,back-facing>>
<<primsrast-polygons,polygons>>, and the front stencil state when processing
fragments generated by <<primsrast-polygons-basic,front-facing polygons>> or
any other primitives.
The comparison performed is based on the elink:VkCompareOp, compare mask
[eq]#s~c~# , and stencil reference value [eq]#s~r~# of the relevant state
set.
The compare mask and stencil reference value are set by either the
slink:VkPipelineDepthStencilStateCreateInfo structure during pipeline
creation, or by the flink:vkCmdSetStencilCompareMask and
flink:vkCmdSetStencilReference commands respectively.
The compare operation is set by slink:VkStencilOpState::pname:compareOp
during pipeline creation.
The stencil reference and attachment values [eq]#s~r~# and [eq]#s~a~# are
each independently combined with the compare mask [eq]#s~c~# using a logical
code:AND operation to create masked reference and attachment values
[eq]#s'~r~# and [eq]#s'~a~#.
[eq]#s'~r~# and [eq]#s'~a~# are used as [eq]#A# and [eq]#B#, respectively,
in the operation specified by elink:VkCompareOp.
If the comparison evaluates to false, the coverage for the sample is set to
`0`.
A new stencil value [eq]#s~g~# is generated according to a stencil operation
defined by elink:VkStencilOp parameters set by
ifdef::VK_EXT_extended_dynamic_state[]
flink:vkCmdSetStencilOpEXT or
endif::VK_EXT_extended_dynamic_state[]
slink:VkPipelineDepthStencilStateCreateInfo.
If the stencil test fails, pname:failOp defines the stencil operation used.
If the stencil test passes however, the stencil op used is based on the
<<fragops-depth, depth test>> - if it passes,
slink:VkPipelineDepthStencilStateCreateInfo::pname:passOp is used, otherwise
slink:VkPipelineDepthStencilStateCreateInfo::pname:depthFailOp is used.
The stencil attachment value [eq]#s~a~# is then updated with the generated
stencil value [eq]#s~g~# according to the write mask [eq]#s~w~# defined by
slink:VkPipelineDepthStencilStateCreateInfo::pname:writeMask as:
{empty}:: [eq]#s~a~ = (s~a~ & ¬s~w~) | (s~g~ & s~w~)#
If there is no stencil attachment, no value is written.
ifdef::VK_EXT_extended_dynamic_state[]
[open,refpage='vkCmdSetStencilTestEnableEXT',desc='Set stencil test enable dynamically for a command buffer',type='protos']
--
To <<pipelines-dynamic-state, dynamically enable or disable>> the stencil
test, call:
include::{generated}/api/protos/vkCmdSetStencilTestEnableEXT.txt[]
* pname:commandBuffer is the command buffer into which the command will be
recorded.
* pname:stencilTestEnable specifies if the stencil test is enabled.
This command sets the stencil test enable for subsequent drawing commands
when the graphics pipeline is created with
ename:VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT set in
slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
Otherwise, this state is specified by the
slink:VkPipelineDepthStencilStateCreateInfo::pname:stencilTestEnable value
used to create the currently active pipeline.
.Valid Usage
****
* [[VUID-vkCmdSetStencilTestEnableEXT-None-03350]]
The <<features-extendedDynamicState, extendedDynamicState>> feature
must: be enabled
****
include::{generated}/validity/protos/vkCmdSetStencilTestEnableEXT.txt[]
--
[open,refpage='vkCmdSetStencilOpEXT',desc='Set stencil operation dynamically for a command buffer',type='protos']
--
To <<pipelines-dynamic-state, dynamically set>> the stencil operation, call:
include::{generated}/api/protos/vkCmdSetStencilOpEXT.txt[]
* pname:commandBuffer is the command buffer into which the command will be
recorded.
* pname:faceMask is a bitmask of elink:VkStencilFaceFlagBits specifying
the set of stencil state for which to update the stencil operation.
* pname:failOp is a elink:VkStencilOp value specifying the action
performed on samples that fail the stencil test.
* pname:passOp is a elink:VkStencilOp value specifying the action
performed on samples that pass both the depth and stencil tests.
* pname:depthFailOp is a elink:VkStencilOp value specifying the action
performed on samples that pass the stencil test and fail the depth test.
* pname:compareOp is a elink:VkCompareOp value specifying the comparison
operator used in the stencil test.
This command sets the stencil operation for subsequent drawing commands when
the graphics pipeline is created with ename:VK_DYNAMIC_STATE_STENCIL_OP_EXT
set in slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
Otherwise, this state is specified by the corresponding
sname:VkPipelineDepthStencilStateCreateInfo::pname:failOp, pname:passOp,
pname:depthFailOp, and pname:compareOp values used to create the currently
active pipeline, for both front and back faces.
.Valid Usage
****
* [[VUID-vkCmdSetStencilOpEXT-None-03351]]
The <<features-extendedDynamicState, extendedDynamicState>> feature
must: be enabled
****
include::{generated}/validity/protos/vkCmdSetStencilOpEXT.txt[]
--
endif::VK_EXT_extended_dynamic_state[]
[open,refpage='VkStencilOpState',desc='Structure specifying stencil operation state',type='structs']
--
The sname:VkStencilOpState structure is defined as:
include::{generated}/api/structs/VkStencilOpState.txt[]
* pname:failOp is a elink:VkStencilOp value specifying the action
performed on samples that fail the stencil test.
* pname:passOp is a elink:VkStencilOp value specifying the action
performed on samples that pass both the depth and stencil tests.
* pname:depthFailOp is a elink:VkStencilOp value specifying the action
performed on samples that pass the stencil test and fail the depth test.
* pname:compareOp is a elink:VkCompareOp value specifying the comparison
operator used in the stencil test.
* pname:compareMask selects the bits of the unsigned integer stencil
values participating in the stencil test.
* pname:writeMask selects the bits of the unsigned integer stencil values
updated by the stencil test in the stencil framebuffer attachment.
* pname:reference is an integer reference value that is used in the
unsigned stencil comparison.
include::{generated}/validity/structs/VkStencilOpState.txt[]
--
[open,refpage='vkCmdSetStencilCompareMask',desc='Set stencil compare mask dynamically for a command buffer',type='protos']
--
To <<pipelines-dynamic-state, dynamically set>> the stencil compare mask
call:
include::{generated}/api/protos/vkCmdSetStencilCompareMask.txt[]
* pname:commandBuffer is the command buffer into which the command will be
recorded.
* pname:faceMask is a bitmask of elink:VkStencilFaceFlagBits specifying
the set of stencil state for which to update the compare mask.
* pname:compareMask is the new value to use as the stencil compare mask.
This command sets the stencil compare mask for subsequent drawing commands
when the graphics pipeline is created with
ename:VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK set in
slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
Otherwise, this state is specified by the
slink:VkPipelineDepthStencilStateCreateInfo::pname:compareMask value used to
create the currently active pipeline, for both front and back faces.
include::{generated}/validity/protos/vkCmdSetStencilCompareMask.txt[]
--
[open,refpage='VkStencilFaceFlagBits',desc='Bitmask specifying sets of stencil state for which to update the compare mask',type='enums']
--
ename:VkStencilFaceFlagBits values are:
include::{generated}/api/enums/VkStencilFaceFlagBits.txt[]
* ename:VK_STENCIL_FACE_FRONT_BIT specifies that only the front set of
stencil state is updated.
* ename:VK_STENCIL_FACE_BACK_BIT specifies that only the back set of
stencil state is updated.
* ename:VK_STENCIL_FACE_FRONT_AND_BACK is the combination of
ename:VK_STENCIL_FACE_FRONT_BIT and ename:VK_STENCIL_FACE_BACK_BIT, and
specifies that both sets of stencil state are updated.
--
[open,refpage='VkStencilFaceFlags',desc='Bitmask of VkStencilFaceFlagBits',type='flags']
--
include::{generated}/api/flags/VkStencilFaceFlags.txt[]
tname:VkStencilFaceFlags is a bitmask type for setting a mask of zero or
more elink:VkStencilFaceFlagBits.
--
[open,refpage='vkCmdSetStencilWriteMask',desc='Set stencil write mask dynamically for a command buffer',type='protos']
--
To <<pipelines-dynamic-state, dynamically set>> the stencil write mask,
call:
include::{generated}/api/protos/vkCmdSetStencilWriteMask.txt[]
* pname:commandBuffer is the command buffer into which the command will be
recorded.
* pname:faceMask is a bitmask of elink:VkStencilFaceFlagBits specifying
the set of stencil state for which to update the write mask, as
described above for flink:vkCmdSetStencilCompareMask.
* pname:writeMask is the new value to use as the stencil write mask.
This command sets the stencil write mask for subsequent drawing commands
when the graphics pipeline is created with
ename:VK_DYNAMIC_STATE_STENCIL_WRITE_MASK set in
slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
Otherwise, this state is specified by the
slink:VkPipelineDepthStencilStateCreateInfo::pname:writeMask value used to
create the currently active pipeline, for both front and back faces.
include::{generated}/validity/protos/vkCmdSetStencilWriteMask.txt[]
--
[open,refpage='vkCmdSetStencilReference',desc='Set stencil reference value dynamically for a command buffer',type='protos']
--
To <<pipelines-dynamic-state, dynamically set>> the stencil reference value,
call:
include::{generated}/api/protos/vkCmdSetStencilReference.txt[]
* pname:commandBuffer is the command buffer into which the command will be
recorded.
* pname:faceMask is a bitmask of elink:VkStencilFaceFlagBits specifying
the set of stencil state for which to update the reference value, as
described above for flink:vkCmdSetStencilCompareMask.
* pname:reference is the new value to use as the stencil reference value.
This command sets the stencil reference value for subsequent drawing
commands when the graphics pipeline is created with
ename:VK_DYNAMIC_STATE_STENCIL_REFERENCE set in
slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
Otherwise, this state is specified by the
slink:VkPipelineDepthStencilStateCreateInfo::pname:reference value used to
create the currently active pipeline, for both front and back faces.
include::{generated}/validity/protos/vkCmdSetStencilReference.txt[]
--
[open,refpage='VkCompareOp',desc='Stencil comparison function',type='enums']
--
Possible values of slink:VkStencilOpState::pname:compareOp, specifying the
stencil comparison function, are:
include::{generated}/api/enums/VkCompareOp.txt[]
* ename:VK_COMPARE_OP_NEVER specifies that the test evaluates to false.
* ename:VK_COMPARE_OP_LESS specifies that the test evaluates [eq]#A < B#.
* ename:VK_COMPARE_OP_EQUAL specifies that the test evaluates [eq]#A = B#.
* ename:VK_COMPARE_OP_LESS_OR_EQUAL specifies that the test evaluates
[eq]#A {leq} B#.
* ename:VK_COMPARE_OP_GREATER specifies that the test evaluates [eq]#A >
B#.
* ename:VK_COMPARE_OP_NOT_EQUAL specifies that the test evaluates [eq]#A
{neq} B#.
* ename:VK_COMPARE_OP_GREATER_OR_EQUAL specifies that the test evaluates
[eq]#A {geq} B#.
* ename:VK_COMPARE_OP_ALWAYS specifies that the test evaluates to true.
--
[open,refpage='VkStencilOp',desc='Stencil comparison function',type='enums']
--
Possible values of the pname:failOp, pname:passOp, and pname:depthFailOp
members of slink:VkStencilOpState, specifying what happens to the stored
stencil value if this or certain subsequent tests fail or pass, are:
include::{generated}/api/enums/VkStencilOp.txt[]
* ename:VK_STENCIL_OP_KEEP keeps the current value.
* ename:VK_STENCIL_OP_ZERO sets the value to 0.
* ename:VK_STENCIL_OP_REPLACE sets the value to pname:reference.
* ename:VK_STENCIL_OP_INCREMENT_AND_CLAMP increments the current value and
clamps to the maximum representable unsigned value.
* ename:VK_STENCIL_OP_DECREMENT_AND_CLAMP decrements the current value and
clamps to 0.
* ename:VK_STENCIL_OP_INVERT bitwise-inverts the current value.
* ename:VK_STENCIL_OP_INCREMENT_AND_WRAP increments the current value and
wraps to 0 when the maximum value would have been exceeded.
* ename: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.
--
[[fragops-depth]]
== Depth Test
The depth test compares the depth value [eq]#z~a~# in the depth/stencil
attachment at each sample's framebuffer coordinates [eq]#(x~f~,y~f~)# and
<<primsrast-multisampling-coverage-mask, sample index>> [eq]#i# against the
sample's depth value [eq]#z~f~#.
If there is no depth attachment then the depth test is skipped.
ifdef::VK_EXT_fragment_density_map[]
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.
endif::VK_EXT_fragment_density_map[]
The depth test occurs in three stages, as detailed in the following
sections.
=== Depth Clamping and Range Adjustment
If slink:VkPipelineRasterizationStateCreateInfo::pname:depthClampEnable is
enabled, before the sample's [eq]#z~f~# is compared to [eq]#z~a~#,
[eq]#z~f~# is clamped to [eq]#[min(n,f),max(n,f)]#, where [eq]#n# and
[eq]#f# are the pname:minDepth and pname:maxDepth depth range values of the
viewport used by this fragment, respectively.
If depth clamping is not enabled and [eq]#z~f~# is not in the range [eq]#[0,
1]#
ifdef::VK_EXT_depth_range_unrestricted[]
and either apiext:VK_EXT_depth_range_unrestricted is not enabled, or the
depth attachment has a fixed-point format,
endif::VK_EXT_depth_range_unrestricted[]
then [eq]#z~f~# is undefined: following this step.
=== Depth Comparison
If the depth test is not enabled, as specified by
ifdef::VK_EXT_extended_dynamic_state[]
flink:vkCmdSetDepthTestEnableEXT or
endif::VK_EXT_extended_dynamic_state[]
slink:VkPipelineDepthStencilStateCreateInfo::pname:depthTestEnable, then
this step is skipped.
The comparison performed is based on the elink:VkCompareOp, set by
ifdef::VK_EXT_extended_dynamic_state[]
flink:vkCmdSetDepthCompareOpEXT or
endif::VK_EXT_extended_dynamic_state[]
slink:VkPipelineDepthStencilStateCreateInfo::pname:depthCompareOp during
pipeline creation.
[eq]#z~f~# and [eq]#z~a~# are used as [eq]#A# and [eq]#B#, respectively, in
the operation specified by the elink:VkCompareOp.
If the comparison evaluates to false, the coverage for the sample is set to
`0`.
[[fragops-depth-write]]
=== Depth Buffer Writes
If depth writes are enabled, as specified by
ifdef::VK_EXT_extended_dynamic_state[]
flink:vkCmdSetDepthWriteEnableEXT or
endif::VK_EXT_extended_dynamic_state[]
slink:VkPipelineDepthStencilStateCreateInfo::pname:depthWriteEnable, and the
comparison evaluated to true, the depth attachment value [eq]#z~a~# is set
to the sample's depth value [eq]#z~f~#.
If there is no depth attachment, no value is written.
ifdef::VK_EXT_extended_dynamic_state[]
[open,refpage='vkCmdSetDepthTestEnableEXT',desc='Set depth test enable dynamically for a command buffer',type='protos']
--
To <<pipelines-dynamic-state, dynamically enable or disable>> the depth
test, call:
include::{generated}/api/protos/vkCmdSetDepthTestEnableEXT.txt[]
* pname:commandBuffer is the command buffer into which the command will be
recorded.
* pname:depthTestEnable specifies if the depth test is enabled.
This command sets the depth test enable for subsequent drawing commands when
the graphics pipeline is created with
ename:VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT set in
slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
Otherwise, this state is specified by the
slink:VkPipelineDepthStencilStateCreateInfo::pname:depthTestEnable value
used to create the currently active pipeline.
.Valid Usage
****
* [[VUID-vkCmdSetDepthTestEnableEXT-None-03352]]
The <<features-extendedDynamicState, extendedDynamicState>> feature
must: be enabled
****
include::{generated}/validity/protos/vkCmdSetDepthTestEnableEXT.txt[]
--
[open,refpage='vkCmdSetDepthCompareOpEXT',desc='Set depth comparison operator dynamically for a command buffer',type='protos']
--
To <<pipelines-dynamic-state, dynamically set>> the depth compare operator,
call:
include::{generated}/api/protos/vkCmdSetDepthCompareOpEXT.txt[]
* pname:commandBuffer is the command buffer into which the command will be
recorded.
* pname:depthCompareOp specifies the depth comparison operator.
This command sets the depth comparison operator for subsequent drawing
commands when the graphics pipeline is created with
ename:VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT set in
slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
Otherwise, this state is specified by the
slink:VkPipelineDepthStencilStateCreateInfo::pname:depthCompareOp value used
to create the currently active pipeline.
.Valid Usage
****
* [[VUID-vkCmdSetDepthCompareOpEXT-None-03353]]
The <<features-extendedDynamicState, extendedDynamicState>> feature
must: be enabled
****
include::{generated}/validity/protos/vkCmdSetDepthCompareOpEXT.txt[]
--
[open,refpage='vkCmdSetDepthWriteEnableEXT',desc='Set depth write enable dynamically for a command buffer',type='protos']
--
To <<pipelines-dynamic-state, dynamically set>> the depth write enable,
call:
include::{generated}/api/protos/vkCmdSetDepthWriteEnableEXT.txt[]
* pname:commandBuffer is the command buffer into which the command will be
recorded.
* pname:depthWriteEnable specifies if depth writes are enabled.
This command sets the depth write enable for subsequent drawing commands
when the graphics pipeline is created with
ename:VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT set in
slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates.
Otherwise, this state is specified by the
slink:VkPipelineDepthStencilStateCreateInfo::pname:depthWriteEnable value
used to create the currently active pipeline.
.Valid Usage
****
* [[VUID-vkCmdSetDepthWriteEnableEXT-None-03354]]
The <<features-extendedDynamicState, extendedDynamicState>> feature
must: be enabled
****
include::{generated}/validity/protos/vkCmdSetDepthWriteEnableEXT.txt[]
--
endif::VK_EXT_extended_dynamic_state[]
ifdef::VK_NV_representative_fragment_test[]
[[fragops-rep-frag-test]]
== 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.
[open,refpage='VkPipelineRepresentativeFragmentTestStateCreateInfoNV',desc='Structure specifying representative fragment test',type='structs']
--
If the pname:pNext chain of slink:VkGraphicsPipelineCreateInfo includes a
sname:VkPipelineRepresentativeFragmentTestStateCreateInfoNV structure, then
that structure includes parameters that control the representative fragment
test.
The sname:VkPipelineRepresentativeFragmentTestStateCreateInfoNV structure is
defined as:
include::{generated}/api/structs/VkPipelineRepresentativeFragmentTestStateCreateInfoNV.txt[]
* pname:sType is the type of this structure.
* pname:pNext is `NULL` or a pointer to a structure extending this
structure.
* pname:representativeFragmentTestEnable controls whether the
representative fragment test is enabled.
If this structure is not included in the pname:pNext chain,
pname:representativeFragmentTestEnable is considered to be ename:VK_FALSE,
and the representative fragment test is disabled.
If the active fragment shader specifies the code:EarlyFragmentTests
execution mode, the representative fragment shader test has no effect, even
if enabled.
include::{generated}/validity/structs/VkPipelineRepresentativeFragmentTestStateCreateInfoNV.txt[]
--
endif::VK_NV_representative_fragment_test[]
[[fragops-samplecount]]
== 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
<<queries-occlusion,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,
ifdef::VK_NV_scissor_exclusive[]
exclusive scissor,
endif::VK_NV_scissor_exclusive[]
sample mask, alpha to coverage, stencil, and depth tests.
ifdef::VK_NV_fragment_coverage_to_color[]
[[fragops-coverage-to-color]]
== Fragment Coverage To Color
[open,refpage='VkPipelineCoverageToColorStateCreateInfoNV',desc='Structure specifying whether fragment coverage replaces a color',type='structs']
--
The sname:VkPipelineCoverageToColorStateCreateInfoNV structure is defined
as:
include::{generated}/api/structs/VkPipelineCoverageToColorStateCreateInfoNV.txt[]
* pname:sType is the type of this structure.
* pname:pNext is `NULL` or a pointer to a structure extending this
structure.
* pname:flags is reserved for future use.
* pname:coverageToColorEnable controls whether the fragment coverage value
replaces a fragment color output.
* pname:coverageToColorLocation controls which fragment shader color
output value is replaced.
If the pname:pNext chain of slink:VkPipelineMultisampleStateCreateInfo
includes a sname: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 pname:coverageToColorEnable is ename:VK_TRUE, the
<<primsrast-multisampling-coverage-mask, coverage mask>> replaces the first
component of the color value corresponding to the fragment shader output
location with code:Location equal to pname:coverageToColorLocation and
code: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 pname:coverageToColorEnable is ename:VK_FALSE, these operations are
skipped.
If this structure is not included in the pname:pNext chain, it is as if
pname:coverageToColorEnable is ename:VK_FALSE.
.Valid Usage
****
* [[VUID-VkPipelineCoverageToColorStateCreateInfoNV-coverageToColorEnable-01404]]
If pname:coverageToColorEnable is ename:VK_TRUE, then the render pass
subpass indicated by
slink:VkGraphicsPipelineCreateInfo::pname:renderPass and
slink:VkGraphicsPipelineCreateInfo::pname:subpass must: have a color
attachment at the location selected by pname:coverageToColorLocation,
with a elink:VkFormat of ename:VK_FORMAT_R8_UINT,
ename:VK_FORMAT_R8_SINT, ename:VK_FORMAT_R16_UINT,
ename:VK_FORMAT_R16_SINT, ename:VK_FORMAT_R32_UINT, or
ename:VK_FORMAT_R32_SINT
****
include::{generated}/validity/structs/VkPipelineCoverageToColorStateCreateInfoNV.txt[]
--
[open,refpage='VkPipelineCoverageToColorStateCreateFlagsNV',desc='Reserved for future use',type='flags']
--
include::{generated}/api/flags/VkPipelineCoverageToColorStateCreateFlagsNV.txt[]
tname:VkPipelineCoverageToColorStateCreateFlagsNV is a bitmask type for
setting a mask, but is currently reserved for future use.
--
endif::VK_NV_fragment_coverage_to_color[]
[[fragops-coverage-reduction]]
== 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 pname:rasterizationSamples unique coverage samples for each
pixel in the fragment area, each with a unique
<<primsrast-multisampling-coverage-mask, sample index>>.
If the fragment only contains a single pixel, coverage for the pixel is
equivalent to the fragment coverage.
ifdef::VK_EXT_fragment_density_map[]
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.
endif::VK_EXT_fragment_density_map[]
ifdef::VK_NV_shading_rate_image[]
If a <<primsrast-shading-rate-image,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 <<primsrast-multisampling-coverage-mask, sample index [eq]#i#>>.
endif::VK_NV_shading_rate_image[]
ifdef::VK_KHR_fragment_shading_rate[]
If the <<primsrast-fragment-shading-rate, fragment shading rate>> is set,
and the fragment covers multiple pixels, each pixel's coverage consists of
the coverage samples with a <<primsrast-multisampling-coverage-mask-vrfs,
pixel index>> matching that pixel, and each sample retains its unique
<<primsrast-multisampling-coverage-mask, sample index [eq]#i#>>.
endif::VK_KHR_fragment_shading_rate[]
=== Color Sample Coverage
Once pixel coverage is determined, coverage for each individual color sample
corresponding to that pixel is determined.
ifdef::VK_AMD_mixed_attachment_samples,VK_NV_framebuffer_mixed_samples,VK_NV_coverage_reduction_mode[If the]
ifndef::VK_AMD_mixed_attachment_samples,VK_NV_framebuffer_mixed_samples,VK_NV_coverage_reduction_mode[The]
number of pname: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
<<primsrast-multisampling-coverage-mask, sample index>> [eq]#i# is covered.
ifdef::VK_AMD_mixed_attachment_samples,VK_NV_framebuffer_mixed_samples,VK_NV_coverage_reduction_mode[]
Otherwise, the coverage for each color sample is computed from the pixel
coverage as follows.
endif::VK_AMD_mixed_attachment_samples,VK_NV_framebuffer_mixed_samples,VK_NV_coverage_reduction_mode[]
ifdef::VK_AMD_mixed_attachment_samples[]
If the `apiext: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
<<primsrast-multisampling-coverage-mask, sample index>> [eq]#i# is covered;
additional pixel coverage samples are discarded.
endif::VK_AMD_mixed_attachment_samples[]
ifdef::VK_NV_framebuffer_mixed_samples[]
ifndef::VK_NV_coverage_reduction_mode[]
When the `apiext:VK_NV_framebuffer_mixed_samples` extension is enabled, if
the pipeline's
slink:VkPipelineMultisampleStateCreateInfo::pname:rasterizationSamples is
greater than the slink:VkAttachmentDescription::pname:samples of the color
attachments in the subpass, 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.
endif::VK_NV_coverage_reduction_mode[]
ifdef::VK_NV_coverage_reduction_mode[]
When the `apiext:VK_NV_coverage_reduction_mode` extension is enabled, the
pipeline state controlling coverage reduction is specified through the
members of the sname:VkPipelineCoverageReductionStateCreateInfoNV structure.
[open,refpage='VkPipelineCoverageReductionStateCreateInfoNV',desc='Structure specifying parameters controlling coverage reduction',type='structs']
--
The sname:VkPipelineCoverageReductionStateCreateInfoNV structure is defined
as:
include::{generated}/api/structs/VkPipelineCoverageReductionStateCreateInfoNV.txt[]
* pname:sType is the type of this structure.
* pname:pNext is `NULL` or a pointer to a structure extending this
structure.
* pname:flags is reserved for future use.
* pname:coverageReductionMode is a elink:VkCoverageReductionModeNV value
controlling how color sample coverage is generated from pixel coverage.
If this structure is not included in the pname:pNext chain, or if the
extension is not enabled, the default coverage reduction mode is inferred as
follows:
* If the `apiext:VK_NV_framebuffer_mixed_samples` extension is enabled,
then it is as if the pname:coverageReductionMode is
ename:VK_COVERAGE_REDUCTION_MODE_MERGE_NV.
* If the `apiext:VK_AMD_mixed_attachment_samples` extension is enabled,
then it is as if the pname:coverageReductionMode is
ename:VK_COVERAGE_REDUCTION_MODE_TRUNCATE_NV.
* If both `apiext:VK_NV_framebuffer_mixed_samples` and
`apiext:VK_AMD_mixed_attachment_samples` are enabled, then the default
coverage reduction mode is implementation-dependent.
include::{generated}/validity/structs/VkPipelineCoverageReductionStateCreateInfoNV.txt[]
--
[open,refpage='VkPipelineCoverageReductionStateCreateFlagsNV',desc='Reserved for future use',type='flags']
--
include::{generated}/api/flags/VkPipelineCoverageReductionStateCreateFlagsNV.txt[]
tname:VkPipelineCoverageReductionStateCreateFlagsNV is a bitmask type for
setting a mask, but is currently reserved for future use.
--
[open,refpage='VkCoverageReductionModeNV',desc='Specify the coverage reduction mode',type='enums']
--
Possible values of
slink:VkPipelineCoverageReductionStateCreateInfoNV::pname:coverageReductionMode,
specifying how color sample coverage is generated from pixel coverage, are:
include::{generated}/api/enums/VkCoverageReductionModeNV.txt[]
* ename: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.
* ename: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
<<primsrast-multisampling-coverage-mask, sample index>> [eq]#i# is
covered; other pixel coverage samples are discarded.
--
[open,refpage='vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV',desc='Query supported sample count combinations',type='protos']
--
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:
include::{generated}/api/protos/vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV.txt[]
* pname:physicalDevice is the physical device from which to query the set
of combinations.
* pname:pCombinationCount is a pointer to an integer related to the number
of combinations available or queried, as described below.
* pname:pCombinations is either `NULL` or a pointer to an array of
slink:VkFramebufferMixedSamplesCombinationNV values, indicating the
supported combinations of coverage reduction mode, rasterization
samples, and color, depth, stencil attachment sample counts.
If pname:pCombinations is `NULL`, then the number of supported combinations
for the given pname:physicalDevice is returned in pname:pCombinationCount.
Otherwise, pname:pCombinationCount must: point to a variable set by the user
to the number of elements in the pname:pCombinations array, and on return
the variable is overwritten with the number of values actually written to
pname:pCombinations.
If the value of pname:pCombinationCount is less than the number of
combinations supported for the given pname:physicalDevice, at most
pname:pCombinationCount values will be written to pname:pCombinations, and
ename:VK_INCOMPLETE will be returned instead of ename:VK_SUCCESS, to
indicate that not all the supported values were returned.
include::{generated}/validity/protos/vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV.txt[]
--
[open,refpage='VkFramebufferMixedSamplesCombinationNV',desc='Structure specifying a supported sample count combination',type='structs']
--
The sname:VkFramebufferMixedSamplesCombinationNV structure is defined as:
include::{generated}/api/structs/VkFramebufferMixedSamplesCombinationNV.txt[]
* pname:sType is the type of this structure.
* pname:pNext is `NULL` or a pointer to a structure extending this
structure.
* pname:coverageReductionMode is a elink:VkCoverageReductionModeNV value
specifying the coverage reduction mode.
* pname:rasterizationSamples is a elink:VkSampleCountFlagBits specifying
the number of rasterization samples in the supported combination.
* pname: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.
* pname: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.
include::{generated}/validity/structs/VkFramebufferMixedSamplesCombinationNV.txt[]
--
endif::VK_NV_coverage_reduction_mode[]
[[fragops-coverage-modulation]]
=== Coverage Modulation
[open,refpage='VkPipelineCoverageModulationStateCreateInfoNV',desc='Structure specifying parameters controlling coverage modulation',type='structs']
--
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 sname:VkPipelineCoverageModulationStateCreateInfoNV
structure.
The sname:VkPipelineCoverageModulationStateCreateInfoNV structure is defined
as:
include::{generated}/api/structs/VkPipelineCoverageModulationStateCreateInfoNV.txt[]
* pname:sType is the type of this structure.
* pname:pNext is `NULL` or a pointer to a structure extending this
structure.
* pname:flags is reserved for future use.
* pname:coverageModulationMode is a elink:VkCoverageModulationModeNV value
controlling which color components are modulated.
* pname:coverageModulationTableEnable controls whether the modulation
factor is looked up from a table in pname:pCoverageModulationTable.
* pname:coverageModulationTableCount is the number of elements in
pname:pCoverageModulationTable.
* pname:pCoverageModulationTable is a table of modulation factors
containing a value for each number of covered samples.
If pname:coverageModulationTableEnable is ename: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
[eq]#R# in the range [eq]#(0,1]# (a value of zero would have been killed due
to a color coverage of 0).
Specifically:
* [eq]#N# = value of pname:rasterizationSamples
* [eq]#M# = value of slink:VkAttachmentDescription::pname:samples for any
color attachments
* [eq]#R = popcount(associated coverage bits) / (N / M)#
If pname:coverageModulationTableEnable is ename:VK_TRUE, the value [eq]#R#
is computed using a programmable lookup table.
The lookup table has [eq]#N / M# elements, and the element of the table is
selected by:
* [eq]#R = pname:pCoverageModulationTable[popcount(associated coverage
bits)-1]#
Note that the table does not have an entry for [eq]#popcount(associated
coverage bits) = 0#, because such samples would have been killed.
The values of pname:pCoverageModulationTable may: be rounded to an
implementation-dependent precision, which is at least as fine as [eq]#1 /
N#, and clamped to [eq]#[0,1]#.
For each color attachment with a floating point or normalized color format,
each fragment output color value is replicated to [eq]#M# values which can:
each be modulated (multiplied) by that color sample's associated value of
[eq]#R#.
Which components are modulated is controlled by
pname:coverageModulationMode.
If this structure is not included in the pname:pNext chain, it is as if
pname:coverageModulationMode is ename:VK_COVERAGE_MODULATION_MODE_NONE_NV.
ifdef::VK_NV_coverage_reduction_mode[]
If the <<fragops-coverage-reduction, coverage reduction mode>> is
ename:VK_COVERAGE_REDUCTION_MODE_TRUNCATE_NV, each color sample is
associated with only a single coverage sample.
In this case, it is as if pname:coverageModulationMode is
ename:VK_COVERAGE_MODULATION_MODE_NONE_NV.
endif::VK_NV_coverage_reduction_mode[]
.Valid Usage
****
* [[VUID-VkPipelineCoverageModulationStateCreateInfoNV-coverageModulationTableEnable-01405]]
If pname:coverageModulationTableEnable is ename:VK_TRUE,
pname:coverageModulationTableCount must: be equal to the number of
rasterization samples divided by the number of color samples in the
subpass
****
include::{generated}/validity/structs/VkPipelineCoverageModulationStateCreateInfoNV.txt[]
--
[open,refpage='VkPipelineCoverageModulationStateCreateFlagsNV',desc='Reserved for future use',type='flags']
--
include::{generated}/api/flags/VkPipelineCoverageModulationStateCreateFlagsNV.txt[]
tname:VkPipelineCoverageModulationStateCreateFlagsNV is a bitmask type for
setting a mask, but is currently reserved for future use.
--
[open,refpage='VkCoverageModulationModeNV',desc='Specify the coverage modulation mode',type='enums']
--
Possible values of
slink:VkPipelineCoverageModulationStateCreateInfoNV::pname:coverageModulationMode,
specifying which color components are modulated, are:
include::{generated}/api/enums/VkCoverageModulationModeNV.txt[]
* ename:VK_COVERAGE_MODULATION_MODE_NONE_NV specifies that no components
are multiplied by the modulation factor.
* ename:VK_COVERAGE_MODULATION_MODE_RGB_NV specifies that the red, green,
and blue components are multiplied by the modulation factor.
* ename:VK_COVERAGE_MODULATION_MODE_ALPHA_NV specifies that the alpha
component is multiplied by the modulation factor.
* ename:VK_COVERAGE_MODULATION_MODE_RGBA_NV specifies that all components
are multiplied by the modulation factor.
--
endif::VK_NV_framebuffer_mixed_samples[]