602 lines
26 KiB
Plaintext
602 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 an 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.
|