580 lines
26 KiB
Plaintext
580 lines
26 KiB
Plaintext
// Copyright (c) 2015-2016 The Khronos Group Inc.
|
|
// Copyright notice at https://www.khronos.org/registry/speccopyright.html
|
|
|
|
[[fragops]]
|
|
= Fragment Operations
|
|
|
|
|
|
[[fragops-early]]
|
|
== Early Per-Fragment Tests
|
|
|
|
Once fragments are produced by rasterization, a number of per-fragment
|
|
operations are performed prior to fragment shader execution.
|
|
If a fragment is discarded during any of these
|
|
operations, it will not be processed by any subsequent stage, including
|
|
fragment shader execution.
|
|
|
|
Two fragment operations are performed in the following order:
|
|
|
|
* the scissor test (see <<fragops-scissor,Scissor Test>>)
|
|
* multisample fragment operations (see <<fragops-samplemask,Sample Mask>>)
|
|
|
|
If early per-fragment operations are <<shaders-fragment-earlytest,enabled by
|
|
the fragment shader>>, these tests are also performed in the following
|
|
order:
|
|
|
|
* the depth bounds tests (see <<fragops-dbt,Depth Bounds Tests>>)
|
|
* the stencil test (see <<fragops-stencil,Stencil Test>>)
|
|
* the depth test (see <<fragops-depth,Depth Test>>)
|
|
* sample counting (see <<fragops-samplecount,Sample Counting>>)
|
|
|
|
|
|
[[fragops-scissor]]
|
|
== Scissor Test
|
|
|
|
// refBegin vkCmdSetScissor Set the dynamic scissor rectangles on a command buffer.
|
|
|
|
The scissor test determines if a fragment's framebuffer coordinates
|
|
latexmath:[$(x_f,y_f)$] lie within the scissor rectangle corresponding to
|
|
the viewport index (see <<vertexpostproc-viewport,Controlling the
|
|
Viewport>>) used by the primitive that generated the fragment. If the
|
|
pipeline state object is created without ename:VK_DYNAMIC_STATE_SCISSOR
|
|
enabled then the scissor rectangles are set by the
|
|
slink:VkPipelineViewportStateCreateInfo state of the pipeline state object.
|
|
Otherwise, to dynamically set the scissor rectangles call:
|
|
|
|
include::../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 latexmath:[$i$] of pname:pScissors
|
|
replace the current state for the scissor index
|
|
latexmath:[$\mathit{firstScissor}+i$], for latexmath:[$i$] in
|
|
latexmath:[$[0, scissorCount)$].
|
|
|
|
Each scissor rectangle is described by a slink:VkRect2D structure, with the
|
|
pname:offset.x and pname:offset.y values determining the upper left corner
|
|
of the scissor rectangle, and the pname:extent.width and pname:extent.height
|
|
values determining the size in pixels.
|
|
|
|
include::../validity/protos/vkCmdSetScissor.txt[]
|
|
|
|
If latexmath:[$\mathit{offset.x} \le x_f \lt \mathit{offset.x} +
|
|
\mathit{extent.width}$] and latexmath:[$\mathit{offset.y} \le y_f \lt
|
|
\mathit{offset.y} + \mathit{extent.height}$] for the selected scissor
|
|
rectangle, then the scissor test passes. Otherwise, the test fails and the
|
|
fragment is discarded. For points, lines, and polygons, the scissor
|
|
rectangle for a primitive is selected in the same manner as the viewport
|
|
(see <<vertexpostproc-viewport,Controlling the Viewport>>). The scissor
|
|
rectangles only apply to drawing commands, not to other commands like clears
|
|
or copies.
|
|
|
|
It is legal for latexmath:[$\mathit{offset.x} + \mathit{extent.width}$] or
|
|
latexmath:[$\mathit{offset.y} + \mathit{extent.height}$] to exceed the
|
|
dimensions of the framebuffer - the scissor test still applies as defined
|
|
above. Rasterization does not produce fragments outside of the framebuffer,
|
|
so such fragments never have the scissor test performed on them.
|
|
|
|
The scissor test is always performed. Applications can: effectively disable
|
|
the scissor test by specifying a scissor rectangle that encompasses the
|
|
entire framebuffer.
|
|
|
|
|
|
[[fragops-samplemask]]
|
|
== Sample Mask
|
|
|
|
This step modifies fragment coverage values based on the values in the
|
|
pname:pSampleMask array member of
|
|
slink:VkPipelineMultisampleStateCreateInfo, as described previously in
|
|
section <<pipelines-graphics>>.
|
|
|
|
pname:pSampleMask contains a array of static coverage information that is
|
|
code:ANDed with the coverage information generated during rasterization.
|
|
Bits that are zero disable coverage for the corresponding sample. Bit B of
|
|
mask word M corresponds to sample latexmath:[$32 \times M + B$]. The array
|
|
is sized to a length of latexmath:[$\lceil{rasterizationSamples /
|
|
32}\rceil$] words. If pname:pSampleMask is `NULL`, it is treated as if the
|
|
mask has all bits enabled, i.e. no coverage is removed from fragments.
|
|
|
|
// refBegin VkSampleMask - Mask of sample coverage information
|
|
|
|
The elements of the sample mask array are of type basetype:VkSampleMask,
|
|
each representing 32 bits of coverage information:
|
|
|
|
include::../api/basetypes/VkSampleMask.txt[]
|
|
|
|
// refEnd VkSampleMask VkPipelineMultisampleStateCreateInfo
|
|
|
|
|
|
[[fragops-early-mode]]
|
|
== Early Fragment Test Mode
|
|
|
|
The depth bounds test, stencil test, depth test, and occlusion query sample
|
|
counting are performed before fragment shading if and only if early fragment
|
|
tests are enabled by the fragment shader (see
|
|
<<shaders-fragment-earlytest,Early Fragment Tests>>). When early
|
|
per-fragment operations are enabled, these operations are performed prior to
|
|
fragment shader execution, and the stencil buffer, depth buffer, and
|
|
occlusion query sample counts will be updated accordingly; these operations
|
|
will not be performed again after fragment shader execution.
|
|
|
|
If a pipeline's fragment shader has early fragment tests disabled, these
|
|
operations are performed only after fragment program execution, in the order
|
|
described below. If a pipeline does not contain a fragment shader, these
|
|
operations are performed only once.
|
|
|
|
If early fragment tests are enabled, any depth value computed by the
|
|
fragment shader has no effect. Additionally, the depth test (including depth
|
|
writes), stencil test (including stencil writes) and sample counting
|
|
operations are performed even for fragments or samples that would be
|
|
discarded after fragment shader execution due to per-fragment operations
|
|
such as alpha-to-coverage tests, or due to the fragment being discarded by
|
|
the shader itself.
|
|
|
|
|
|
[[fragops-late]]
|
|
== Late Per-Fragment Tests
|
|
|
|
After programmable fragment processing, per-fragment operations are
|
|
performed before blending and color output to the framebuffer.
|
|
|
|
A fragment is produced by rasterization with framebuffer coordinates of
|
|
latexmath:[$(x_f,y_f)$] and depth latexmath:[$z$], as described in
|
|
<<primsrast,Rasterization>>. The fragment is then modified by programmable
|
|
fragment processing, which adds associated data as described in
|
|
<<shaders,Shaders>>. The fragment is then further modified, and possibly
|
|
discarded by the late per-fragment operations described in this chapter.
|
|
Finally, if the fragment was not discarded, it is used to update the
|
|
framebuffer at the fragment's framebuffer coordinates for any samples that
|
|
remain covered.
|
|
|
|
ifdef::editing-notes[]
|
|
[NOTE]
|
|
.editing-note
|
|
==================
|
|
There used to be a sentence of form "These operations are diagrammed in
|
|
figure ((fig-fragops,Fragment Operations)), in the order in which they are
|
|
performed" following "described in this chapter." above, but the referred
|
|
figure does not yet exist.
|
|
==================
|
|
endif::editing-notes[]
|
|
|
|
The depth bounds test, stencil test, and depth test are performed for each
|
|
pixel sample, rather than just once for each fragment. Stencil and depth
|
|
operations are performed for a pixel sample only if that sample's fragment
|
|
coverage bit is a value of 1 when the fragment executes the corresponding
|
|
stage of the graphics pipeline. If the corresponding coverage bit is 0, no
|
|
operations are performed for that sample. Failure of the depth bounds,
|
|
stencil, or depth test results in termination of the processing of that
|
|
sample by means of disabling coverage for that sample, rather than
|
|
discarding of the fragment. If, at any point, a fragment's coverage becomes
|
|
zero for all samples, then the fragment is discarded. All operations are
|
|
performed on the depth and stencil values stored in the depth/stencil
|
|
attachment of the framebuffer. The contents of the color attachments are not
|
|
modified at this point.
|
|
|
|
The depth bounds test, stencil test, depth test, and occlusion query
|
|
operations described in <<fragops-dbt,Depth Bounds Test>>,
|
|
<<fragops-stencil,Stencil Test>>, <<fragops-depth,Depth Test>>,
|
|
<<fragops-samplecount,Sample Counting>> are instead performed prior to
|
|
fragment processing, as described in <<fragops-early-mode,Early Fragment
|
|
Test Mode>>, if requested by the fragment shader.
|
|
|
|
|
|
[[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, the fragment
|
|
coverage is code:ANDed with the bits
|
|
of the sample mask to generate a new fragment coverage value. If such a
|
|
fragment shader did not assign a value to code:SampleMask due to flow of
|
|
control, the value code:ANDed with the fragment coverage is undefined. If no
|
|
fragment shader is active, or if the active fragment shader does not
|
|
include code:SampleMask in its interface, the fragment coverage is not
|
|
modified.
|
|
|
|
Next, the fragment alpha and coverage values are modified based on the
|
|
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.
|
|
|
|
If pname:alphaToCoverageEnable is enabled, a temporary coverage value is
|
|
generated where each bit is determined by the fragment's alpha value. The
|
|
temporary coverage value is then ANDed with the fragment coverage value to
|
|
generate a new fragment coverage value.
|
|
|
|
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
|
|
latexmath:[$[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 pixel
|
|
locations.
|
|
|
|
[NOTE]
|
|
.Note
|
|
====
|
|
Using different algorithms at different pixel location may: help to
|
|
avoid artifacts caused by regular coverage sample locations.
|
|
====
|
|
|
|
Next, 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.
|
|
|
|
// refBegin VkPipelineDepthStencilStateCreateInfo - Structure specifying parameters of a newly created pipeline depth stencil state
|
|
|
|
The sname:VkPipelineDepthStencilStateCreateInfo structure is defined as:
|
|
|
|
include::../api/structs/VkPipelineDepthStencilStateCreateInfo.txt[]
|
|
|
|
* pname:sType is the type of this structure.
|
|
* pname:pNext is `NULL` or a pointer to an extension-specific 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.
|
|
* 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 and pname:maxDepthBounds define the range of values
|
|
used in the <<fragops-dbt,depth bounds test>>.
|
|
|
|
include::../validity/structs/VkPipelineDepthStencilStateCreateInfo.txt[]
|
|
|
|
[[fragops-dbt]]
|
|
== Depth Bounds Test
|
|
|
|
// refBegin vkCmdSetDepthBounds Set the depth bounds test values for a command buffer.
|
|
|
|
The depth bounds test conditionally disables coverage of a sample based on
|
|
the outcome of a comparison between the value latexmath:[$z_a$] in the depth
|
|
attachment at location latexmath:[$(x_f,y_f)$] (for the appropriate sample)
|
|
and a range of values. The test is enabled or disabled by the
|
|
pname:depthBoundsTestEnable member of
|
|
slink:VkPipelineDepthStencilStateCreateInfo: If the pipeline state object
|
|
is created without the ename:VK_DYNAMIC_STATE_DEPTH_BOUNDS dynamic state
|
|
enabled then the range of values used in the depth bounds test are defined
|
|
by the pname:minDepthBounds and pname:maxDepthBounds members of the
|
|
slink:VkPipelineDepthStencilStateCreateInfo structure. Otherwise, to
|
|
dynamically set the depth bounds range values call:
|
|
|
|
include::../api/protos/vkCmdSetDepthBounds.txt[]
|
|
|
|
* pname:commandBuffer is the command buffer into which the command will be
|
|
recorded.
|
|
* pname:minDepthBounds is the lower bound of the range of depth values
|
|
used in the depth bounds test.
|
|
* pname:maxDepthBounds is the upper bound of the range.
|
|
|
|
include::../validity/protos/vkCmdSetDepthBounds.txt[]
|
|
|
|
If latexmath:[$\mathit{minDepthBounds} \leq z_a \leq
|
|
\mathit{maxDepthBounds}$], then the depth bounds test passes. Otherwise, the
|
|
test fails and the sample's coverage bit is cleared in the fragment. If
|
|
there is no depth framebuffer attachment or if the depth bounds test is
|
|
disabled, it is as if the depth bounds test always passes.
|
|
|
|
|
|
[[fragops-stencil]]
|
|
== Stencil Test
|
|
|
|
The stencil test conditionally disables coverage of a sample based on the
|
|
outcome of a comparison between the stencil value in the depth/stencil
|
|
attachment at location latexmath:[$(x_f,y_f)$] (for the appropriate sample)
|
|
and a reference value. The stencil test also updates the value in the
|
|
stencil attachment, depending on the test state, the stencil value and the
|
|
stencil write masks. The test is enabled or disabled by the
|
|
pname:stencilTestEnable member of
|
|
slink:VkPipelineDepthStencilStateCreateInfo.
|
|
|
|
When disabled, the stencil test and associated modifications are not made,
|
|
and the sample's coverage is not modified.
|
|
|
|
The stencil test is controlled with the pname:front and pname:back members
|
|
of sname:VkPipelineDepthStencilStateCreateInfo which are of type
|
|
sname:VkStencilOpState.
|
|
|
|
// refBegin VkStencilOpState - Structure specifying stencil operation state
|
|
|
|
The sname:VkStencilOpState structure is defined as:
|
|
|
|
include::../api/structs/VkStencilOpState.txt[]
|
|
|
|
* pname:failOp is the action performed on samples that fail the stencil
|
|
test.
|
|
* pname:passOp is the action performed on samples that pass both the depth
|
|
and stencil tests.
|
|
* pname:depthFailOp is the action performed on samples that pass the
|
|
stencil test and fail the depth test.
|
|
* pname:compareOp is 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::../validity/structs/VkStencilOpState.txt[]
|
|
|
|
There are two sets of stencil-related state, the front stencil state set and
|
|
the back stencil state set. Stencil tests and writes use the front set of
|
|
stencil state when processing fragments rasterized from non-polygon
|
|
primitives (points and lines) and front-facing polygon primitives while the
|
|
back set of stencil state is used when processing fragments rasterized from
|
|
back-facing polygon primitives. For the purposes of stencil testing, a
|
|
primitive is still considered a polygon even if the polygon is to be
|
|
rasterized as points or lines due to the current elink:VkPolygonMode.
|
|
Whether a polygon is front- or back-facing is determined in the same manner
|
|
used for face culling (see <<primsrast-polygons-basic,Basic Polygon
|
|
Rasterization>>).
|
|
|
|
The operation of the stencil test is also affected by the
|
|
pname:compareMask, pname:writeMask, and pname:reference
|
|
members of sname:VkStencilOpState set in the pipeline state object if the
|
|
pipeline state object is created without the
|
|
ename:VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
|
|
ename:VK_DYNAMIC_STATE_STENCIL_WRITE_MASK, and
|
|
ename:VK_DYNAMIC_STATE_STENCIL_REFERENCE dynamic states enabled,
|
|
respectively.
|
|
|
|
// refBegin vkCmdSetStencilCompareMask Set the stencil compare mask dynamic state.
|
|
|
|
If the pipeline state object is created with the
|
|
ename:VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK dynamic state enabled, then to
|
|
dynamically set the stencil compare mask call:
|
|
|
|
include::../api/protos/vkCmdSetStencilCompareMask.txt[]
|
|
|
|
* pname:commandBuffer is the command buffer into which the command will be
|
|
recorded.
|
|
* pname:faceMask is a bitmask specifying the set of stencil state for
|
|
which to update the compare mask. Bits which can: be set include:
|
|
+
|
|
--
|
|
// refBegin VkStencilFaceFlagBits - Bitmask specifying sets of stencil state for which to update the compare mask
|
|
include::../api/enums/VkStencilFaceFlagBits.txt[]
|
|
--
|
|
** ename:VK_STENCIL_FACE_FRONT_BIT indicates that only the front set of
|
|
stencil state is updated.
|
|
** ename:VK_STENCIL_FACE_BACK_BIT indicates that only the back set of
|
|
stencil state is updated.
|
|
** ename:VK_STENCIL_FRONT_AND_BACK is the combination of
|
|
ename:VK_STENCIL_FACE_FRONT_BIT and ename:VK_STENCIL_FACE_BACK_BIT and
|
|
indicates that both sets of stencil state are updated.
|
|
* pname:compareMask is the new value to use as the stencil compare mask.
|
|
|
|
include::../validity/protos/vkCmdSetStencilCompareMask.txt[]
|
|
|
|
// refBegin vkCmdSetStencilWriteMask Set the stencil write mask dynamic state.
|
|
|
|
If the pipeline state object is created with the
|
|
ename:VK_DYNAMIC_STATE_STENCIL_WRITE_MASK dynamic state enabled, then to
|
|
dynamically set the stencil write mask call:
|
|
|
|
include::../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.
|
|
|
|
include::../validity/protos/vkCmdSetStencilWriteMask.txt[]
|
|
|
|
// refBegin vkCmdSetStencilReference Set the stencil reference dynamic state.
|
|
|
|
If the pipeline state object is created with the
|
|
ename:VK_DYNAMIC_STATE_STENCIL_REFERENCE dynamic state enabled, then to
|
|
dynamically set the stencil reference value call:
|
|
|
|
include::../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.
|
|
|
|
include::../validity/protos/vkCmdSetStencilReference.txt[]
|
|
|
|
pname:reference is an integer reference value that is used in the
|
|
unsigned stencil comparison. Stencil comparison clamps the reference value
|
|
to latexmath:[$[0,2^s-1\]$], where latexmath:[$s$] is the number
|
|
of bits in the stencil framebuffer attachment. The latexmath:[$s$] least
|
|
significant bits of pname:compareMask are bitwise code:ANDed with
|
|
both the reference and the stored stencil value, and the resulting masked
|
|
values are those that participate in the comparison controlled by
|
|
pname:compareOp. Let latexmath:[$R$] be the masked reference value
|
|
and latexmath:[$S$] be the masked stored stencil value.
|
|
|
|
// refBegin VkCompareOp stencil comparison function
|
|
|
|
pname:compareOp is a symbolic constant that determines the stencil
|
|
comparison function:
|
|
|
|
include::../api/enums/VkCompareOp.txt[]
|
|
|
|
* ename:VK_COMPARE_OP_NEVER: the test never passes.
|
|
* ename:VK_COMPARE_OP_LESS: the test passes when latexmath:[$R \lt S$].
|
|
* ename:VK_COMPARE_OP_EQUAL: the test passes when latexmath:[$R = S$].
|
|
* ename:VK_COMPARE_OP_LESS_OR_EQUAL: the test passes when latexmath:[$R
|
|
\leq S$].
|
|
* ename:VK_COMPARE_OP_GREATER: the test passes when latexmath:[$R \gt S$].
|
|
* ename:VK_COMPARE_OP_NOT_EQUAL: the test passes when latexmath:[$R \neq
|
|
S$].
|
|
* ename:VK_COMPARE_OP_GREATER_OR_EQUAL: the test passes when latexmath:[$R
|
|
\geq S$].
|
|
* ename:VK_COMPARE_OP_ALWAYS: the test always passes.
|
|
|
|
// refEnd VkCompareOp
|
|
|
|
// refBegin VkStencilOp stencil comparison function
|
|
|
|
As described earlier, the pname:failOp, pname:passOp, and pname:depthFailOp
|
|
members of slink:VkStencilOpState indicate what happens to the stored
|
|
stencil value if this or certain subsequent tests fail or pass. Each enum is
|
|
of type elink:VkStencilOp, which is defined as:
|
|
|
|
include::../api/enums/VkStencilOp.txt[]
|
|
|
|
The possible values are:
|
|
|
|
* 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.
|
|
|
|
If the stencil test fails, the sample's coverage bit is cleared in the
|
|
fragment. If there is no stencil framebuffer attachment, stencil
|
|
modification cannot: occur, and it is as if the stencil tests always pass.
|
|
|
|
If the stencil test passes, the pname:writeMask member of the
|
|
slink:VkStencilOpState structures controls how the updated stencil value is
|
|
written to the stencil framebuffer attachment.
|
|
|
|
The least significant latexmath:[$s$] bits of pname:writeMask, where
|
|
latexmath:[$s$] is the number of bits in the stencil framebuffer attachment,
|
|
specify an integer mask. Where a latexmath:[$1$] appears in this mask, the
|
|
corresponding bit in the stencil value in the depth/stencil attachment is
|
|
written; where a latexmath:[$0$] appears, the bit is not written. The
|
|
pname:writeMask value uses either the front-facing or back-facing state
|
|
based on the facing-ness of the fragment. Fragments generated by
|
|
front-facing primitives use the front mask and fragments generated by
|
|
back-facing primitives use the back mask.
|
|
|
|
// refEnd VkStencilOp
|
|
|
|
|
|
[[fragops-depth]]
|
|
== Depth Test
|
|
|
|
The depth test conditionally disables coverage of a sample based on the
|
|
outcome of a comparison between the fragment's depth value at the sample
|
|
location and the sample's depth value in the depth/stencil attachment at
|
|
location latexmath:[$(x_f,y_f)$]. The comparison is enabled or disabled with
|
|
the pname:depthTestEnable member of the
|
|
slink:VkPipelineDepthStencilStateCreateInfo structure. When disabled, the
|
|
depth comparison and subsequent possible updates to the value of the depth
|
|
component of the depth/stencil attachment are bypassed and the fragment is
|
|
passed to the next operation. The stencil value, however, can: be modified as
|
|
indicated above as if the depth test passed. If enabled, the comparison takes
|
|
place and the depth/stencil attachment value can: subsequently be modified.
|
|
|
|
The comparison is specified with the pname:depthCompareOp member of
|
|
slink:VkPipelineDepthStencilStateCreateInfo. Let latexmath:[$z_f$] be the
|
|
incoming fragment's depth value for a sample, and let latexmath:[$z_a$] be
|
|
the depth/stencil attachment value in memory for that sample. The depth test
|
|
passes under the following conditions:
|
|
|
|
* ename:VK_COMPARE_OP_NEVER: the test never passes.
|
|
* ename:VK_COMPARE_OP_LESS: the test passes when
|
|
latexmath:[$z_f \lt z_a$].
|
|
* ename:VK_COMPARE_OP_EQUAL: the test passes when
|
|
latexmath:[$z_f = z_a$].
|
|
* ename:VK_COMPARE_OP_LESS_OR_EQUAL: the test passes when
|
|
latexmath:[$z_f \leq z_a$].
|
|
* ename:VK_COMPARE_OP_GREATER: the test passes when
|
|
latexmath:[$z_f \gt z_a$].
|
|
* ename:VK_COMPARE_OP_NOT_EQUAL: the test passes when
|
|
latexmath:[$z_f \neq z_a$].
|
|
* ename:VK_COMPARE_OP_GREATER_OR_EQUAL: the test passes when
|
|
latexmath:[$z_f \geq z_a$].
|
|
* ename:VK_COMPARE_OP_ALWAYS: the test always passes.
|
|
|
|
If depth clamping (see <<vertexpostproc-clipping,Primitive Clipping>>) is
|
|
enabled, before the incoming fragment's latexmath:[$z_f$] is compared to
|
|
latexmath:[$z_a$], latexmath:[$z_f$] is clamped to
|
|
latexmath:[$[\min(n,f), \max(n,f)\]$], where latexmath:[$n$] and
|
|
latexmath:[$f$] are the pname:minDepth and pname:maxDepth depth range values
|
|
of the viewport used by this fragment, respectively.
|
|
|
|
If the depth test fails, the sample's coverage bit is cleared in the
|
|
fragment. The stencil value at the sample's location is updated according to
|
|
the function currently in effect for depth test failure.
|
|
|
|
[[fragops-depth-write]]
|
|
If the depth test passes, the sample's (possibly clamped) latexmath:[$z_f$]
|
|
value is conditionally written to the depth framebuffer attachment based on
|
|
the pname:depthWriteEnable member of
|
|
slink:VkPipelineDepthStencilStateCreateInfo. If pname:depthWriteEnable is
|
|
ename:VK_TRUE the value is written, and if it is ename:VK_FALSE the value is
|
|
not written. The stencil value at the sample's location is updated according
|
|
to the function currently in effect for depth test success.
|
|
|
|
If there is no depth framebuffer attachment, it is as if the depth test
|
|
always passes.
|
|
|
|
|
|
[[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, sample mask, alpha to coverage, stencil, and depth
|
|
tests.
|