Vulkan Logo

26. Fragment Operations

Fragments produced by rasterization go through a number of operations to determine whether or how values produced by fragment shading are written to the framebuffer.

The following fragment operations adhere to rasterization order, and are typically performed in this order:

The coverage mask generated by rasterization describes the initial coverage of each sample covered by the fragment. Fragment operations will update the coverage mask to add or subtract coverage where appropriate. If a fragment operation results in all bits of the coverage mask being 0, the fragment is discarded, and no further operations are performed. Fragments can also be programmatically discarded in a fragment shader by executing one of

  • OpTerminateInvocation

  • OpDemoteToHelperInvocationEXT

  • 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.

If VkPhysicalDeviceMaintenance5PropertiesKHR::earlyFragmentMultisampleCoverageAfterSampleCounting is set to VK_TRUE and there is a fragment shader which declares the EarlyFragmentTests execution mode, fragment shading and multisample coverage operations must be performed after sample counting.

Otherwise, if VkPhysicalDeviceMaintenance5PropertiesKHR::earlyFragmentMultisampleCoverageAfterSampleCounting is set to VK_FALSE and there is a fragment shader which declares the EarlyFragmentTests execution mode, fragment shading and multisample coverage operations should instead be performed after sample counting, but may be performed before sample counting.

If VkPhysicalDeviceMaintenance5PropertiesKHR::earlyFragmentSampleMaskTestBeforeSampleCounting is set to VK_TRUE and there is a fragment shader which declares the EarlyFragmentTests execution mode sample mask test operations must follow the order of fragment operations from above.

Otherwise, if VkPhysicalDeviceMaintenance5PropertiesKHR::earlyFragmentSampleMaskTestBeforeSampleCounting is set to VK_FALSE and there is a fragment shader which declares the EarlyFragmentTests execution mode, sample mask test operations should follow the order of fragment operations from above but may instead be performed after sample counting.

For a pipeline with the following properties:

  • a fragment shader is specified

  • the fragment shader does not write to storage resources;

  • the fragment shader specifies the DepthReplacing execution mode; and

  • either

    • the fragment shader specifies the DepthUnchanged execution mode;

    • the fragment shader specifies the DepthLess execution mode and the pipeline uses a VkPipelineDepthStencilStateCreateInfo::depthCompareOp of VK_COMPARE_OP_GREATER or VK_COMPARE_OP_GREATER_OR_EQUAL; or

    • the fragment shader specifies the DepthGreater execution mode and the pipeline uses a VkPipelineDepthStencilStateCreateInfo::depthCompareOp of VK_COMPARE_OP_LESS or VK_COMPARE_OP_LESS_OR_EQUAL

the implementation may perform depth bounds test before fragment shading and perform an additional depth test immediately after that using the interpolated depth value generated by rasterization.

Once all fragment operations have completed, fragment shader outputs for covered color attachment samples pass through framebuffer operations.

26.1. Discard Rectangles Test

The discard rectangle test compares the framebuffer coordinates (xf,yf) of each sample covered by a fragment against a set of discard rectangles.

Each discard rectangle is defined by a VkRect2D. These values are either set by the VkPipelineDiscardRectangleStateCreateInfoEXT structure during pipeline creation, or dynamically by the vkCmdSetDiscardRectangleEXT command.

A given sample is considered inside a discard rectangle if the xf is in the range [VkRect2D::offset.x, VkRect2D::offset.x + VkRect2D::extent.x), and yf is in the range [VkRect2D::offset.y, VkRect2D::offset.y + VkRect2D::extent.y). If the test is set to be inclusive, samples that are not inside any of the discard rectangles will have their coverage set to 0. If the test is set to be exclusive, samples that are inside any of the discard rectangles will have their coverage set to 0.

If no discard rectangles are specified, the coverage mask is unmodified by this operation.

The VkPipelineDiscardRectangleStateCreateInfoEXT structure is defined as:

// Provided by VK_EXT_discard_rectangles
typedef struct VkPipelineDiscardRectangleStateCreateInfoEXT {
    VkStructureType                                  sType;
    const void*                                      pNext;
    VkPipelineDiscardRectangleStateCreateFlagsEXT    flags;
    VkDiscardRectangleModeEXT                        discardRectangleMode;
    uint32_t                                         discardRectangleCount;
    const VkRect2D*                                  pDiscardRectangles;
} VkPipelineDiscardRectangleStateCreateInfoEXT;
  • sType is a VkStructureType value identifying this structure.

  • pNext is NULL or a pointer to a structure extending this structure.

  • flags is reserved for future use.

  • discardRectangleMode is a VkDiscardRectangleModeEXT value determining whether the discard rectangle test is inclusive or exclusive.

  • discardRectangleCount is the number of discard rectangles to use.

  • pDiscardRectangles is a pointer to an array of VkRect2D structures defining discard rectangles.

If the VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT dynamic state is enabled for a pipeline, the pDiscardRectangles member is ignored. If the VK_DYNAMIC_STATE_DISCARD_RECTANGLE_ENABLE_EXT dynamic state is not enabled for the pipeline the presence of this structure in the VkGraphicsPipelineCreateInfo chain, and a discardRectangleCount greater than zero, implicitly enables discard rectangles in the pipeline, otherwise discard rectangles must enabled or disabled by vkCmdSetDiscardRectangleEnableEXT. If the VK_DYNAMIC_STATE_DISCARD_RECTANGLE_MODE_EXT dynamic state is enabled for the pipeline, the discardRectangleMode member is ignored, and the discard rectangle mode must be set by vkCmdSetDiscardRectangleModeEXT.

When this structure is included in the pNext chain of VkGraphicsPipelineCreateInfo, it defines parameters of the discard rectangle test. If the VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT dynamic state is not enabled, and this structure is not included in the pNext chain, it is equivalent to specifying this structure with a discardRectangleCount of 0.

Valid Usage
  • VUID-VkPipelineDiscardRectangleStateCreateInfoEXT-discardRectangleCount-00582
    discardRectangleCount must be less than or equal to VkPhysicalDeviceDiscardRectanglePropertiesEXT::maxDiscardRectangles

Valid Usage (Implicit)
  • VUID-VkPipelineDiscardRectangleStateCreateInfoEXT-sType-sType
    sType must be VK_STRUCTURE_TYPE_PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT

  • VUID-VkPipelineDiscardRectangleStateCreateInfoEXT-flags-zerobitmask
    flags must be 0

  • VUID-VkPipelineDiscardRectangleStateCreateInfoEXT-discardRectangleMode-parameter
    discardRectangleMode must be a valid VkDiscardRectangleModeEXT value

// Provided by VK_EXT_discard_rectangles
typedef VkFlags VkPipelineDiscardRectangleStateCreateFlagsEXT;

VkPipelineDiscardRectangleStateCreateFlagsEXT is a bitmask type for setting a mask, but is currently reserved for future use.

VkDiscardRectangleModeEXT values are:

// Provided by VK_EXT_discard_rectangles
typedef enum VkDiscardRectangleModeEXT {
    VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT = 0,
    VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT = 1,
} VkDiscardRectangleModeEXT;
  • VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT specifies that the discard rectangle test is inclusive.

  • VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT specifies that the discard rectangle test is exclusive.

To dynamically set the discard rectangles, call:

// Provided by VK_EXT_discard_rectangles
void vkCmdSetDiscardRectangleEXT(
    VkCommandBuffer                             commandBuffer,
    uint32_t                                    firstDiscardRectangle,
    uint32_t                                    discardRectangleCount,
    const VkRect2D*                             pDiscardRectangles);
  • commandBuffer is the command buffer into which the command will be recorded.

  • firstDiscardRectangle is the index of the first discard rectangle whose state is updated by the command.

  • discardRectangleCount is the number of discard rectangles whose state are updated by the command.

  • pDiscardRectangles is a pointer to an array of VkRect2D structures specifying discard rectangles.

The discard rectangle taken from element i of pDiscardRectangles replace the current state for the discard rectangle at index firstDiscardRectangle + i, for i in [0, discardRectangleCount).

This command sets the discard rectangles for subsequent drawing commands when drawing using shader objects, or when the graphics pipeline is created with VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT set in VkPipelineDynamicStateCreateInfo::pDynamicStates. Otherwise, this state is specified by the VkPipelineDiscardRectangleStateCreateInfoEXT::pDiscardRectangles values used to create the currently active pipeline.

Valid Usage
  • VUID-vkCmdSetDiscardRectangleEXT-firstDiscardRectangle-00585
    The sum of firstDiscardRectangle and discardRectangleCount must be less than or equal to VkPhysicalDeviceDiscardRectanglePropertiesEXT::maxDiscardRectangles

  • VUID-vkCmdSetDiscardRectangleEXT-x-00587
    The x and y member of offset in each VkRect2D element of pDiscardRectangles must be greater than or equal to 0

  • VUID-vkCmdSetDiscardRectangleEXT-offset-00588
    Evaluation of (offset.x + extent.width) in each VkRect2D element of pDiscardRectangles must not cause a signed integer addition overflow

  • VUID-vkCmdSetDiscardRectangleEXT-offset-00589
    Evaluation of (offset.y + extent.height) in each VkRect2D element of pDiscardRectangles must not cause a signed integer addition overflow

Valid Usage (Implicit)
  • VUID-vkCmdSetDiscardRectangleEXT-commandBuffer-parameter
    commandBuffer must be a valid VkCommandBuffer handle

  • VUID-vkCmdSetDiscardRectangleEXT-pDiscardRectangles-parameter
    pDiscardRectangles must be a valid pointer to an array of discardRectangleCount VkRect2D structures

  • VUID-vkCmdSetDiscardRectangleEXT-commandBuffer-recording
    commandBuffer must be in the recording state

  • VUID-vkCmdSetDiscardRectangleEXT-commandBuffer-cmdpool
    The VkCommandPool that commandBuffer was allocated from must support graphics operations

  • VUID-vkCmdSetDiscardRectangleEXT-videocoding
    This command must only be called outside of a video coding scope

  • VUID-vkCmdSetDiscardRectangleEXT-discardRectangleCount-arraylength
    discardRectangleCount must be greater than 0

Host Synchronization
  • Host access to commandBuffer must be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be externally synchronized

Command Properties
Command Buffer Levels Render Pass Scope Video Coding Scope Supported Queue Types Command Type

Primary
Secondary

Both

Outside

Graphics

State

To dynamically set whether discard rectangles are enabled, call:

// Provided by VK_EXT_discard_rectangles
void vkCmdSetDiscardRectangleEnableEXT(
    VkCommandBuffer                             commandBuffer,
    VkBool32                                    discardRectangleEnable);
  • commandBuffer is the command buffer into which the command will be recorded.

  • discardRectangleEnable specifies whether discard rectangles are enabled or not.

This command sets the discard rectangle enable for subsequent drawing commands when drawing using shader objects, or when the graphics pipeline is created with VK_DYNAMIC_STATE_DISCARD_RECTANGLE_ENABLE_EXT set in VkPipelineDynamicStateCreateInfo::pDynamicStates. Otherwise, this state is implied by the VkPipelineDiscardRectangleStateCreateInfoEXT::discardRectangleCount value used to create the currently active pipeline, where a non-zero discardRectangleCount implicitly enables discard rectangles, otherwise they are disabled.

Valid Usage
  • VUID-vkCmdSetDiscardRectangleEnableEXT-specVersion-07851
    The VK_EXT_discard_rectangles extension must be enabled, and the implementation must support at least specVersion 2 of this extension

Valid Usage (Implicit)
  • VUID-vkCmdSetDiscardRectangleEnableEXT-commandBuffer-parameter
    commandBuffer must be a valid VkCommandBuffer handle

  • VUID-vkCmdSetDiscardRectangleEnableEXT-commandBuffer-recording
    commandBuffer must be in the recording state

  • VUID-vkCmdSetDiscardRectangleEnableEXT-commandBuffer-cmdpool
    The VkCommandPool that commandBuffer was allocated from must support graphics operations

  • VUID-vkCmdSetDiscardRectangleEnableEXT-videocoding
    This command must only be called outside of a video coding scope

Host Synchronization
  • Host access to commandBuffer must be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be externally synchronized

Command Properties
Command Buffer Levels Render Pass Scope Video Coding Scope Supported Queue Types Command Type

Primary
Secondary

Both

Outside

Graphics

State

To dynamically set the discard rectangle mode, call:

// Provided by VK_EXT_discard_rectangles
void vkCmdSetDiscardRectangleModeEXT(
    VkCommandBuffer                             commandBuffer,
    VkDiscardRectangleModeEXT                   discardRectangleMode);
  • commandBuffer is the command buffer into which the command will be recorded.

  • discardRectangleMode specifies the discard rectangle mode for all discard rectangles, either inclusive or exclusive.

This command sets the discard rectangle mode for subsequent drawing commands when drawing using shader objects, or when the graphics pipeline is created with VK_DYNAMIC_STATE_DISCARD_RECTANGLE_MODE_EXT set in VkPipelineDynamicStateCreateInfo::pDynamicStates. Otherwise, this state is specified by the VkPipelineDiscardRectangleStateCreateInfoEXT::discardRectangleMode value used to create the currently active pipeline.

Valid Usage
  • VUID-vkCmdSetDiscardRectangleModeEXT-specVersion-07852
    The VK_EXT_discard_rectangles extension must be enabled, and the implementation must support at least specVersion 2 of this extension

Valid Usage (Implicit)
  • VUID-vkCmdSetDiscardRectangleModeEXT-commandBuffer-parameter
    commandBuffer must be a valid VkCommandBuffer handle

  • VUID-vkCmdSetDiscardRectangleModeEXT-discardRectangleMode-parameter
    discardRectangleMode must be a valid VkDiscardRectangleModeEXT value

  • VUID-vkCmdSetDiscardRectangleModeEXT-commandBuffer-recording
    commandBuffer must be in the recording state

  • VUID-vkCmdSetDiscardRectangleModeEXT-commandBuffer-cmdpool
    The VkCommandPool that commandBuffer was allocated from must support graphics operations

  • VUID-vkCmdSetDiscardRectangleModeEXT-videocoding
    This command must only be called outside of a video coding scope

Host Synchronization
  • Host access to commandBuffer must be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be externally synchronized

Command Properties
Command Buffer Levels Render Pass Scope Video Coding Scope Supported Queue Types Command Type

Primary
Secondary

Both

Outside

Graphics

State

26.2. Scissor Test

The scissor test compares the framebuffer coordinates (xf,yf) of each sample covered by a fragment against a scissor rectangle at the index equal to the fragment’s ViewportIndex.

Each scissor rectangle is defined by a VkRect2D. These values are either set by the VkPipelineViewportStateCreateInfo structure during pipeline creation, or dynamically by the vkCmdSetScissor command.

A given sample is considered inside a scissor rectangle if xf is in the range [VkRect2D::offset.x, VkRect2D::offset.x + VkRect2D::extent.x), and yf is in the range [VkRect2D::offset.y, VkRect2D::offset.y + VkRect2D::extent.y). Samples with coordinates outside the scissor rectangle at the corresponding ViewportIndex will have their coverage set to 0.

To dynamically set the scissor rectangles, call:

// Provided by VK_VERSION_1_0
void vkCmdSetScissor(
    VkCommandBuffer                             commandBuffer,
    uint32_t                                    firstScissor,
    uint32_t                                    scissorCount,
    const VkRect2D*                             pScissors);
  • commandBuffer is the command buffer into which the command will be recorded.

  • firstScissor is the index of the first scissor whose state is updated by the command.

  • scissorCount is the number of scissors whose rectangles are updated by the command.

  • pScissors is a pointer to an array of VkRect2D structures defining scissor rectangles.

The scissor rectangles taken from element i of pScissors replace the current state for the scissor index firstScissor + i, for i in [0, scissorCount).

This command sets the scissor rectangles for subsequent drawing commands when drawing using shader objects, or when the graphics pipeline is created with VK_DYNAMIC_STATE_SCISSOR set in VkPipelineDynamicStateCreateInfo::pDynamicStates. Otherwise, this state is specified by the VkPipelineViewportStateCreateInfo::pScissors values used to create the currently active pipeline.

Valid Usage
  • VUID-vkCmdSetScissor-firstScissor-00592
    The sum of firstScissor and scissorCount must be between 1 and VkPhysicalDeviceLimits::maxViewports, inclusive

  • VUID-vkCmdSetScissor-firstScissor-00593
    If the multiViewport feature is not enabled, firstScissor must be 0

  • VUID-vkCmdSetScissor-scissorCount-00594
    If the multiViewport feature is not enabled, scissorCount must be 1

  • VUID-vkCmdSetScissor-x-00595
    The x and y members of offset member of any element of pScissors must be greater than or equal to 0

  • VUID-vkCmdSetScissor-offset-00596
    Evaluation of (offset.x + extent.width) must not cause a signed integer addition overflow for any element of pScissors

  • VUID-vkCmdSetScissor-offset-00597
    Evaluation of (offset.y + extent.height) must not cause a signed integer addition overflow for any element of pScissors

Valid Usage (Implicit)
  • VUID-vkCmdSetScissor-commandBuffer-parameter
    commandBuffer must be a valid VkCommandBuffer handle

  • VUID-vkCmdSetScissor-pScissors-parameter
    pScissors must be a valid pointer to an array of scissorCount VkRect2D structures

  • VUID-vkCmdSetScissor-commandBuffer-recording
    commandBuffer must be in the recording state

  • VUID-vkCmdSetScissor-commandBuffer-cmdpool
    The VkCommandPool that commandBuffer was allocated from must support graphics operations

  • VUID-vkCmdSetScissor-videocoding
    This command must only be called outside of a video coding scope

  • VUID-vkCmdSetScissor-scissorCount-arraylength
    scissorCount must be greater than 0

Host Synchronization
  • Host access to commandBuffer must be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be externally synchronized

Command Properties
Command Buffer Levels Render Pass Scope Video Coding Scope Supported Queue Types Command Type

Primary
Secondary

Both

Outside

Graphics

State

26.3. Sample Mask Test

The sample mask test compares the coverage mask for a fragment with the sample mask defined by VkPipelineMultisampleStateCreateInfo::pSampleMask.

To dynamically set the sample mask, call:

// Provided by VK_EXT_extended_dynamic_state3, VK_EXT_shader_object
void vkCmdSetSampleMaskEXT(
    VkCommandBuffer                             commandBuffer,
    VkSampleCountFlagBits                       samples,
    const VkSampleMask*                         pSampleMask);
  • commandBuffer is the command buffer into which the command will be recorded.

  • samples specifies the number of sample bits in the pSampleMask.

  • pSampleMask is a pointer to an array of VkSampleMask values, where the array size is based on the samples parameter.

This command sets the sample mask for subsequent drawing commands when drawing using shader objects, or when the graphics pipeline is created with VK_DYNAMIC_STATE_SAMPLE_MASK_EXT set in VkPipelineDynamicStateCreateInfo::pDynamicStates. Otherwise, this state is specified by the VkPipelineMultisampleStateCreateInfo::pSampleMask value used to create the currently active pipeline.

Valid Usage
Valid Usage (Implicit)
  • VUID-vkCmdSetSampleMaskEXT-commandBuffer-parameter
    commandBuffer must be a valid VkCommandBuffer handle

  • VUID-vkCmdSetSampleMaskEXT-samples-parameter
    samples must be a valid VkSampleCountFlagBits value

  • VUID-vkCmdSetSampleMaskEXT-pSampleMask-parameter
    pSampleMask must be a valid pointer to an array of VkSampleMask values

  • VUID-vkCmdSetSampleMaskEXT-commandBuffer-recording
    commandBuffer must be in the recording state

  • VUID-vkCmdSetSampleMaskEXT-commandBuffer-cmdpool
    The VkCommandPool that commandBuffer was allocated from must support graphics operations

  • VUID-vkCmdSetSampleMaskEXT-videocoding
    This command must only be called outside of a video coding scope

Host Synchronization
  • Host access to commandBuffer must be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be externally synchronized

Command Properties
Command Buffer Levels Render Pass Scope Video Coding Scope Supported Queue Types Command Type

Primary
Secondary

Both

Outside

Graphics

State

Each bit of the coverage mask is associated with a sample index as described in the rasterization chapter. If the bit in VkPipelineMultisampleStateCreateInfo::pSampleMask which is associated with that same sample index is set to 0, the coverage mask bit is set to 0.

26.4. Fragment Shading

Fragment shaders are invoked for each fragment, or as helper invocations.

Most operations in the fragment shader are not performed in rasterization order, with exceptions called out in the following sections.

For fragment shaders invoked by fragments, the following rules apply:

  • A fragment shader must not be executed if a fragment operation that executes before fragment shading discards the fragment.

  • A fragment shader may not be executed if:

    • An implementation determines that another fragment shader, invoked by a subsequent primitive in primitive order, overwrites all results computed by the shader (including writes to storage resources).

    • Any other fragment operation discards the fragment, and the shader does not write to any storage resources.

    • If a fragment shader statically computes the same values for different framebuffer locations, and does not write to any storage resources, multiple fragments may be shaded by one fragment shader invocation. This may affect VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT results, but must otherwise not be visible behavior to applications.

  • Otherwise, at least one fragment shader must be executed.

    • If sample shading is enabled and multiple invocations per fragment are required, additional invocations must be executed as specified.

    • Each covered sample must be included in at least one fragment shader invocation.

If no fragment shader is included in the pipeline, no fragment shader is executed, and undefined values may be written to all color attachment outputs during this fragment operation.

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.

For example, if the subpass includes multiple views in its view mask, a fragment shader may be invoked separately for each view.

26.4.1. Sample Mask

Reading from the SampleMask built-in in the Input storage class will return the coverage mask for the current fragment as calculated by fragment operations that executed prior to fragment shading.

If sample shading is enabled, fragment shaders will only see values of 1 for samples being shaded - other bits will be 0.

Each bit of the coverage mask is associated with a sample index as described in the rasterization chapter. If the bit in SampleMask which is associated with that same sample index is set to 0, that coverage mask bit is set to 0.

Values written to the SampleMask built-in in the Output storage class will be used by the multisample coverage operation, with the same encoding as the input built-in.

26.4.2. Fragment Shader Tile Image Reads

If the VK_EXT_shader_tile_image extension is enabled, implementations divide the framebuffer into a grid of tiles. A tile image is a view of a framebuffer attachment tile for fragments with locations within the tile.

Within a render pass instance initiated by vkCmdBeginRenderingKHR, fragment shader invocations can read the framebuffer color, depth, and stencil values at the fragment location via tile images.

Note

Even though fragment shader invocation can only read from the corresponding fragment location, the abstraction of a tile image is introduced for the following reasons:

  • Tile dimensions will be exposed in a future extension

  • Future functionality such as executing compute dispatches within render passes via tile shaders can leverage tile images.

Enabling shaderTileImageColorReadAccess, shaderTileImageDepthReadAccess, shaderTileImageStencilReadAccess enables fragment shader invocations to read from color, depth, and stencil, respectively.

Color values are read from tile image variables with OpColorAttachmentReadEXT. Tile image variables are linked to specific color attachments using Location decoration. See Fragment Tile Image Interface for more details.

Depth values are read with OpDepthAttachmentReadEXT.

Stencil values are read with OpStencilAttachmentReadEXT.

The sample to read is specified by a sample index value specified as the Sample operand to OpColorAttachmentReadEXT, OpDepthAttachmentReadEXT, or OpStencilAttachmentReadEXT.

If sample shading is disabled, a fragment invocation can read from all sample locations associated with the fragment regardless of the fragment’s coverage. This functionality is supported for VkPipelineMultisampleStateCreateInfo::rasterizationSamples > 1 when VkPhysicalDeviceShaderTileImagePropertiesEXT::shaderTileImageReadSampleFromPixelRateInvocation is VK_TRUE.

If sample shading is enabled, and minSampleShading is 1.0, a fragment invocation must only read from the coverage index sample. Tile image access must not be used if the value of minSampleShading is not 1.0.

If the fragment shader declares the EarlyFragmentTests execution mode, depth reads are allowed only if depth writes are disabled and stencil reads are allowed only if stencil writes are disabled.

If VkPhysicalDeviceShaderTileImagePropertiesEXT::shaderTileImageReadFromHelperInvocation is VK_FALSE, values read from helper invocations are undefined otherwise the values read are subject to the coherency guarantees described below.

OpDepthAttachmentReadEXT returns an undefined value if no depth attachment is present. OpStencilAttachmentReadEXT returns an undefined value if no stencil attachment is present.

Tile image reads from color, depth and stencil attachments are said to be coherent when the accesses happen in raster order and without data race with respect to accesses to the attachments from framebuffer-space pipeline stages. The samples which qualify for coherent access and the enabling conditions are described below.

  • Let Rc be the set of components being read from an attachment A in a draw call

  • Let Wc be the set of components being written to A by the draw call

The samples which qualify for coherent tile image reads from an attachment A are:

  • All samples in a pixel when Rc is disjoint with Wc.

  • The samples with coverage in a fragment when Rc is not disjoint with Wc. The samples with coverage are determined by the coverage mask for the fragment as calculated by fragment operations that executed prior to fragment shading, including early fragment tests if enabled for the draw call.

A fragment shader can declare NonCoherentColorAttachmentReadEXT, NonCoherentDepthAttachmentReadEXT, or NonCoherentStencilAttachmentReadEXT execution modes to enable non-coherent tile image reads which require an explicit vkCmdPipelineBarrier2 call for the writes to an attachment to be made visible via tile image reads.

When VkPhysicalDeviceShaderTileImagePropertiesEXT::shaderTileImageCoherentReadAccelerated is VK_TRUE, the implementation prefers that coherent tile image reads are used, otherwise the implementation prefers that non-coherent tile image reads are used.

Note

In practice, the most common tile image reads usage patterns fall under one of the following:

  • Programmable blending - each fragment reads from a single sample (SampleID) at its location. Per-sample shading is typically enabled when multisampled rendertargets are used.

  • G-buffer generation and shading in one render pass - in the shading phase a fragment reads from a single sample at its location.

  • Programmable resolve - a fragment reads from all samples at its location (per-sample shading is disabled). This requires the use of a "full-screen triangle" instead of a rectangle composed of two triangles in order to avoid data races along the shared edge of the triangles.

  • 1:1 texturing with LOD - in use cases such a deferred screen space decals a fragment reads a single sample (SampleID) from depth buffer, but requires being able to read from helper threads to derive the texture LOD. This use case is supported as long as the attachment components being read are not overwritten by color, depth, or stencil attachment writes.

All of the above use cases are supported by coherent tile image reads, but only the latter three are supported when non-coherent reads are used as there is no mechanism to synchronize non-coherent reads with writes within a draw call.

26.4.3. Depth Replacement

Writing to the FragDepth built-in will replace the fragment’s calculated depth values for each sample in the input SampleMask. Depth testing performed after the fragment shader for this fragment will use this new value as zf.

26.5. Multisample Coverage

If a fragment shader is active and its entry point’s interface includes a built-in output variable decorated with SampleMask, the coverage mask is ANDed with the bits of the SampleMask built-in to generate a new coverage mask. If sample shading is enabled, bits written to SampleMask corresponding to samples that are not being shaded by the fragment shader invocation are ignored. If no fragment shader is active, or if the active fragment shader does not include SampleMask in its interface, the coverage mask is not modified.

Next, the fragment alpha value and coverage mask are modified based on the line coverage factor if the lineRasterizationMode member of the VkPipelineRasterizationStateCreateInfo structure is VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_KHR, and the alphaToCoverageEnable and alphaToOneEnable members of the VkPipelineMultisampleStateCreateInfo structure.

To dynamically set the alphaToCoverageEnable state, call:

// Provided by VK_EXT_extended_dynamic_state3, VK_EXT_shader_object
void vkCmdSetAlphaToCoverageEnableEXT(
    VkCommandBuffer                             commandBuffer,
    VkBool32                                    alphaToCoverageEnable);
  • commandBuffer is the command buffer into which the command will be recorded.

  • alphaToCoverageEnable specifies the alphaToCoverageEnable state.

This command sets the alphaToCoverageEnable state for subsequent drawing commands when drawing using shader objects, or when the graphics pipeline is created with VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT set in VkPipelineDynamicStateCreateInfo::pDynamicStates. Otherwise, this state is specified by the VkPipelineMultisampleStateCreateInfo::alphaToCoverageEnable value used to create the currently active pipeline.

Valid Usage
Valid Usage (Implicit)
  • VUID-vkCmdSetAlphaToCoverageEnableEXT-commandBuffer-parameter
    commandBuffer must be a valid VkCommandBuffer handle

  • VUID-vkCmdSetAlphaToCoverageEnableEXT-commandBuffer-recording
    commandBuffer must be in the recording state

  • VUID-vkCmdSetAlphaToCoverageEnableEXT-commandBuffer-cmdpool
    The VkCommandPool that commandBuffer was allocated from must support graphics operations

  • VUID-vkCmdSetAlphaToCoverageEnableEXT-videocoding
    This command must only be called outside of a video coding scope

Host Synchronization
  • Host access to commandBuffer must be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be externally synchronized

Command Properties
Command Buffer Levels Render Pass Scope Video Coding Scope Supported Queue Types Command Type

Primary
Secondary

Both

Outside

Graphics

State

To dynamically set the alphaToOneEnable state, call:

// Provided by VK_EXT_extended_dynamic_state3, VK_EXT_shader_object
void vkCmdSetAlphaToOneEnableEXT(
    VkCommandBuffer                             commandBuffer,
    VkBool32                                    alphaToOneEnable);
  • commandBuffer is the command buffer into which the command will be recorded.

  • alphaToOneEnable specifies the alphaToOneEnable state.

This command sets the alphaToOneEnable state for subsequent drawing commands when drawing using shader objects, or when the graphics pipeline is created with VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT set in VkPipelineDynamicStateCreateInfo::pDynamicStates. Otherwise, this state is specified by the VkPipelineMultisampleStateCreateInfo::alphaToOneEnable value used to create the currently active pipeline.

Valid Usage
  • VUID-vkCmdSetAlphaToOneEnableEXT-None-09423
    At least one of the following must be true:

  • VUID-vkCmdSetAlphaToOneEnableEXT-alphaToOne-07607
    If the alphaToOne feature is not enabled, alphaToOneEnable must be VK_FALSE

Valid Usage (Implicit)
  • VUID-vkCmdSetAlphaToOneEnableEXT-commandBuffer-parameter
    commandBuffer must be a valid VkCommandBuffer handle

  • VUID-vkCmdSetAlphaToOneEnableEXT-commandBuffer-recording
    commandBuffer must be in the recording state

  • VUID-vkCmdSetAlphaToOneEnableEXT-commandBuffer-cmdpool
    The VkCommandPool that commandBuffer was allocated from must support graphics operations

  • VUID-vkCmdSetAlphaToOneEnableEXT-videocoding
    This command must only be called outside of a video coding scope

Host Synchronization
  • Host access to commandBuffer must be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be externally synchronized

Command Properties
Command Buffer Levels Render Pass Scope Video Coding Scope Supported Queue Types Command Type

Primary
Secondary

Both

Outside

Graphics

State

All alpha values in this section refer only to the alpha component of the fragment shader output that has a Location and Index decoration of zero (see the Fragment Output Interface section). If that shader output has an integer or unsigned integer type, then these operations are skipped.

If the lineRasterizationMode member of the VkPipelineRasterizationStateCreateInfo structure is VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_KHR and the fragment came from a line segment, then the alpha value is replaced by multiplying it by the coverage factor for the fragment computed during smooth line rasterization.

If alphaToCoverageEnable is enabled, a temporary coverage mask is generated where each bit is determined by the fragment’s alpha value, which is ANDed with the fragment coverage mask.

No specific algorithm is specified for converting the alpha value to a temporary coverage mask. It is intended that the number of 1’s in this value be proportional to the alpha value (clamped to [0,1]), with all 1’s corresponding to a value of 1.0 and all 0’s corresponding to 0.0. The algorithm may be different at different framebuffer coordinates.

Note

Using different algorithms at different framebuffer coordinates may help to avoid artifacts caused by regular coverage sample locations.

Finally, if alphaToOneEnable is enabled, each alpha value is replaced by the maximum representable alpha value for fixed-point color attachments, or by 1.0 for floating-point attachments. Otherwise, the alpha values are not changed.

26.6. Depth and Stencil Operations

Pipeline state controlling the depth bounds tests, stencil test, and depth test is specified through the members of the VkPipelineDepthStencilStateCreateInfo structure.

The VkPipelineDepthStencilStateCreateInfo structure is defined as:

// Provided by VK_VERSION_1_0
typedef struct VkPipelineDepthStencilStateCreateInfo {
    VkStructureType                           sType;
    const void*                               pNext;
    VkPipelineDepthStencilStateCreateFlags    flags;
    VkBool32                                  depthTestEnable;
    VkBool32                                  depthWriteEnable;
    VkCompareOp                               depthCompareOp;
    VkBool32                                  depthBoundsTestEnable;
    VkBool32                                  stencilTestEnable;
    VkStencilOpState                          front;
    VkStencilOpState                          back;
    float                                     minDepthBounds;
    float                                     maxDepthBounds;
} VkPipelineDepthStencilStateCreateInfo;
  • sType is a VkStructureType value identifying this structure.

  • pNext is NULL or a pointer to a structure extending this structure.

  • flags is reserved for future use.

  • depthTestEnable controls whether depth testing is enabled.

  • depthWriteEnable controls whether depth writes are enabled when depthTestEnable is VK_TRUE. Depth writes are always disabled when depthTestEnable is VK_FALSE.

  • depthCompareOp is a VkCompareOp value specifying the comparison operator to use in the Depth Comparison step of the depth test.

  • depthBoundsTestEnable controls whether depth bounds testing is enabled.

  • stencilTestEnable controls whether stencil testing is enabled.

  • front and back are VkStencilOpState values controlling the corresponding parameters of the stencil test.

  • minDepthBounds is the minimum depth bound used in the depth bounds test.

  • maxDepthBounds is the maximum depth bound used in the depth bounds test.

Valid Usage
Valid Usage (Implicit)
  • VUID-VkPipelineDepthStencilStateCreateInfo-sType-sType
    sType must be VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO

  • VUID-VkPipelineDepthStencilStateCreateInfo-pNext-pNext
    pNext must be NULL

  • VUID-VkPipelineDepthStencilStateCreateInfo-flags-zerobitmask
    flags must be 0

  • VUID-VkPipelineDepthStencilStateCreateInfo-depthCompareOp-parameter
    depthCompareOp must be a valid VkCompareOp value

  • VUID-VkPipelineDepthStencilStateCreateInfo-front-parameter
    front must be a valid VkStencilOpState structure

  • VUID-VkPipelineDepthStencilStateCreateInfo-back-parameter
    back must be a valid VkStencilOpState structure

// Provided by VK_VERSION_1_0
typedef VkFlags VkPipelineDepthStencilStateCreateFlags;

VkPipelineDepthStencilStateCreateFlags is a bitmask type for setting a mask, but is currently reserved for future use.

26.7. Depth Bounds Test

The depth bounds test compares the depth value za in the depth/stencil attachment at each sample’s framebuffer coordinates (xf,yf) and sample index i against a set of depth bounds.

The depth bounds are determined by two floating point values defining a minimum (minDepthBounds) and maximum (maxDepthBounds) depth value. These values are either set by the VkPipelineDepthStencilStateCreateInfo structure during pipeline creation, or dynamically by vkCmdSetDepthBoundsTestEnable and vkCmdSetDepthBounds.

A given sample is considered within the depth bounds if za is in the range [minDepthBounds,maxDepthBounds]. Samples with depth attachment values outside of the depth bounds will have their coverage set to 0.

If the depth bounds test is disabled, or if there is no depth attachment, the coverage mask is unmodified by this operation.

To dynamically enable or disable the depth bounds test, call:

// Provided by VK_VERSION_1_3
void vkCmdSetDepthBoundsTestEnable(
    VkCommandBuffer                             commandBuffer,
    VkBool32                                    depthBoundsTestEnable);

or the equivalent command

// Provided by VK_EXT_shader_object
void vkCmdSetDepthBoundsTestEnableEXT(
    VkCommandBuffer                             commandBuffer,
    VkBool32                                    depthBoundsTestEnable);
  • commandBuffer is the command buffer into which the command will be recorded.

  • depthBoundsTestEnable specifies if the depth bounds test is enabled.

This command sets the depth bounds enable for subsequent drawing commands when drawing using shader objects, or when the graphics pipeline is created with VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE set in VkPipelineDynamicStateCreateInfo::pDynamicStates. Otherwise, this state is specified by the VkPipelineDepthStencilStateCreateInfo::depthBoundsTestEnable value used to create the currently active pipeline.

Valid Usage
  • VUID-vkCmdSetDepthBoundsTestEnable-None-08971
    At least one of the following must be true:

Valid Usage (Implicit)
  • VUID-vkCmdSetDepthBoundsTestEnable-commandBuffer-parameter
    commandBuffer must be a valid VkCommandBuffer handle

  • VUID-vkCmdSetDepthBoundsTestEnable-commandBuffer-recording
    commandBuffer must be in the recording state

  • VUID-vkCmdSetDepthBoundsTestEnable-commandBuffer-cmdpool
    The VkCommandPool that commandBuffer was allocated from must support graphics operations

  • VUID-vkCmdSetDepthBoundsTestEnable-videocoding
    This command must only be called outside of a video coding scope

Host Synchronization
  • Host access to commandBuffer must be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be externally synchronized

Command Properties
Command Buffer Levels Render Pass Scope Video Coding Scope Supported Queue Types Command Type

Primary
Secondary

Both

Outside

Graphics

State

To dynamically set the depth bounds range, call:

// Provided by VK_VERSION_1_0
void vkCmdSetDepthBounds(
    VkCommandBuffer                             commandBuffer,
    float                                       minDepthBounds,
    float                                       maxDepthBounds);
  • commandBuffer is the command buffer into which the command will be recorded.

  • minDepthBounds is the minimum depth bound.

  • maxDepthBounds is the maximum depth bound.

This command sets the depth bounds range for subsequent drawing commands when drawing using shader objects, or when the graphics pipeline is created with VK_DYNAMIC_STATE_DEPTH_BOUNDS set in VkPipelineDynamicStateCreateInfo::pDynamicStates. Otherwise, this state is specified by the VkPipelineDepthStencilStateCreateInfo::minDepthBounds and VkPipelineDepthStencilStateCreateInfo::maxDepthBounds values used to create the currently active pipeline.

Valid Usage
  • VUID-vkCmdSetDepthBounds-minDepthBounds-00600
    If the VK_EXT_depth_range_unrestricted extension is not enabled minDepthBounds must be between 0.0 and 1.0, inclusive

  • VUID-vkCmdSetDepthBounds-maxDepthBounds-00601
    If the VK_EXT_depth_range_unrestricted extension is not enabled maxDepthBounds must be between 0.0 and 1.0, inclusive

Valid Usage (Implicit)
  • VUID-vkCmdSetDepthBounds-commandBuffer-parameter
    commandBuffer must be a valid VkCommandBuffer handle

  • VUID-vkCmdSetDepthBounds-commandBuffer-recording
    commandBuffer must be in the recording state

  • VUID-vkCmdSetDepthBounds-commandBuffer-cmdpool
    The VkCommandPool that commandBuffer was allocated from must support graphics operations

  • VUID-vkCmdSetDepthBounds-videocoding
    This command must only be called outside of a video coding scope

Host Synchronization
  • Host access to commandBuffer must be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be externally synchronized

Command Properties
Command Buffer Levels Render Pass Scope Video Coding Scope Supported Queue Types Command Type

Primary
Secondary

Both

Outside

Graphics

State

26.8. Stencil Test

The stencil test compares the stencil attachment value sa in the depth/stencil attachment at each sample’s framebuffer coordinates (xf,yf) and sample index i against a stencil reference value.

If the stencil test is not enabled, as specified by vkCmdSetStencilTestEnable or VkPipelineDepthStencilStateCreateInfo::stencilTestEnable, or if there is no stencil attachment, the coverage mask is unmodified by this operation.

The stencil test is controlled by one of two sets of stencil-related state, the front stencil state and the back stencil state. Stencil tests and writes use the back stencil state when processing fragments generated by back-facing polygons, and the front stencil state when processing fragments generated by front-facing polygons or any other primitives.

The comparison operation performed is determined by the VkCompareOp value set by vkCmdSetStencilOp::compareOp, or by VkStencilOpState::compareOp during pipeline creation.

The compare mask sc and stencil reference value sr of the front or the back stencil state set determine arguments of the comparison operation. sc is set by the VkPipelineDepthStencilStateCreateInfo structure during pipeline creation, or by the vkCmdSetStencilCompareMask command. sr is set by VkPipelineDepthStencilStateCreateInfo or by vkCmdSetStencilReference.

sr and sa are each independently combined with sc using a bitwise AND operation to create masked reference and attachment values s'r and s'a. s'r and s'a are used as the reference and test values, respectively, in the operation specified by the VkCompareOp.

If the comparison evaluates to false, the coverage for the sample is set to 0.

A new stencil value sg is generated according to a stencil operation defined by VkStencilOp parameters set by vkCmdSetStencilOp or VkPipelineDepthStencilStateCreateInfo. If the stencil test fails, failOp defines the stencil operation used. If the stencil test passes however, the stencil op used is based on the depth test - if it passes, VkPipelineDepthStencilStateCreateInfo::passOp is used, otherwise VkPipelineDepthStencilStateCreateInfo::depthFailOp is used.

The stencil attachment value sa is then updated with the generated stencil value sg according to the write mask sw defined by writeMask in VkPipelineDepthStencilStateCreateInfo::front and VkPipelineDepthStencilStateCreateInfo::back as:

sa = (sa & ¬sw) | (sg & sw)

To dynamically enable or disable the stencil test, call:

// Provided by VK_VERSION_1_3
void vkCmdSetStencilTestEnable(
    VkCommandBuffer                             commandBuffer,
    VkBool32                                    stencilTestEnable);

or the equivalent command

// Provided by VK_EXT_shader_object
void vkCmdSetStencilTestEnableEXT(
    VkCommandBuffer                             commandBuffer,
    VkBool32                                    stencilTestEnable);
  • commandBuffer is the command buffer into which the command will be recorded.

  • stencilTestEnable specifies if the stencil test is enabled.

This command sets the stencil test enable for subsequent drawing commands when drawing using shader objects, or when the graphics pipeline is created with VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE set in VkPipelineDynamicStateCreateInfo::pDynamicStates. Otherwise, this state is specified by the VkPipelineDepthStencilStateCreateInfo::stencilTestEnable value used to create the currently active pipeline.

Valid Usage
  • VUID-vkCmdSetStencilTestEnable-None-08971
    At least one of the following must be true:

Valid Usage (Implicit)
  • VUID-vkCmdSetStencilTestEnable-commandBuffer-parameter
    commandBuffer must be a valid VkCommandBuffer handle

  • VUID-vkCmdSetStencilTestEnable-commandBuffer-recording
    commandBuffer must be in the recording state

  • VUID-vkCmdSetStencilTestEnable-commandBuffer-cmdpool
    The VkCommandPool that commandBuffer was allocated from must support graphics operations

  • VUID-vkCmdSetStencilTestEnable-videocoding
    This command must only be called outside of a video coding scope

Host Synchronization
  • Host access to commandBuffer must be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be externally synchronized

Command Properties
Command Buffer Levels Render Pass Scope Video Coding Scope Supported Queue Types Command Type

Primary
Secondary

Both

Outside

Graphics

State

To dynamically set the stencil operation, call:

// Provided by VK_VERSION_1_3
void vkCmdSetStencilOp(
    VkCommandBuffer                             commandBuffer,
    VkStencilFaceFlags                          faceMask,
    VkStencilOp                                 failOp,
    VkStencilOp                                 passOp,
    VkStencilOp                                 depthFailOp,
    VkCompareOp                                 compareOp);

or the equivalent command

// Provided by VK_EXT_shader_object
void vkCmdSetStencilOpEXT(
    VkCommandBuffer                             commandBuffer,
    VkStencilFaceFlags                          faceMask,
    VkStencilOp                                 failOp,
    VkStencilOp                                 passOp,
    VkStencilOp                                 depthFailOp,
    VkCompareOp                                 compareOp);
  • commandBuffer is the command buffer into which the command will be recorded.

  • faceMask is a bitmask of VkStencilFaceFlagBits specifying the set of stencil state for which to update the stencil operation.

  • failOp is a VkStencilOp value specifying the action performed on samples that fail the stencil test.

  • passOp is a VkStencilOp value specifying the action performed on samples that pass both the depth and stencil tests.

  • depthFailOp is a VkStencilOp value specifying the action performed on samples that pass the stencil test and fail the depth test.

  • compareOp is a VkCompareOp value specifying the comparison operator used in the stencil test.

This command sets the stencil operation for subsequent drawing commands when when drawing using shader objects, or when the graphics pipeline is created with VK_DYNAMIC_STATE_STENCIL_OP set in VkPipelineDynamicStateCreateInfo::pDynamicStates. Otherwise, this state is specified by the corresponding VkPipelineDepthStencilStateCreateInfo::failOp, passOp, depthFailOp, and compareOp values used to create the currently active pipeline, for both front and back faces.

Valid Usage
  • VUID-vkCmdSetStencilOp-None-08971
    At least one of the following must be true:

Valid Usage (Implicit)
  • VUID-vkCmdSetStencilOp-commandBuffer-parameter
    commandBuffer must be a valid VkCommandBuffer handle

  • VUID-vkCmdSetStencilOp-faceMask-parameter
    faceMask must be a valid combination of VkStencilFaceFlagBits values

  • VUID-vkCmdSetStencilOp-faceMask-requiredbitmask
    faceMask must not be 0

  • VUID-vkCmdSetStencilOp-failOp-parameter
    failOp must be a valid VkStencilOp value

  • VUID-vkCmdSetStencilOp-passOp-parameter
    passOp must be a valid VkStencilOp value

  • VUID-vkCmdSetStencilOp-depthFailOp-parameter
    depthFailOp must be a valid VkStencilOp value

  • VUID-vkCmdSetStencilOp-compareOp-parameter
    compareOp must be a valid VkCompareOp value

  • VUID-vkCmdSetStencilOp-commandBuffer-recording
    commandBuffer must be in the recording state

  • VUID-vkCmdSetStencilOp-commandBuffer-cmdpool
    The VkCommandPool that commandBuffer was allocated from must support graphics operations

  • VUID-vkCmdSetStencilOp-videocoding
    This command must only be called outside of a video coding scope

Host Synchronization
  • Host access to commandBuffer must be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be externally synchronized

Command Properties
Command Buffer Levels Render Pass Scope Video Coding Scope Supported Queue Types Command Type

Primary
Secondary

Both

Outside

Graphics

State

The VkStencilOpState structure is defined as:

// Provided by VK_VERSION_1_0
typedef struct VkStencilOpState {
    VkStencilOp    failOp;
    VkStencilOp    passOp;
    VkStencilOp    depthFailOp;
    VkCompareOp    compareOp;
    uint32_t       compareMask;
    uint32_t       writeMask;
    uint32_t       reference;
} VkStencilOpState;
  • failOp is a VkStencilOp value specifying the action performed on samples that fail the stencil test.

  • passOp is a VkStencilOp value specifying the action performed on samples that pass both the depth and stencil tests.

  • depthFailOp is a VkStencilOp value specifying the action performed on samples that pass the stencil test and fail the depth test.

  • compareOp is a VkCompareOp value specifying the comparison operator used in the stencil test.

  • compareMask selects the bits of the unsigned integer stencil values participating in the stencil test.

  • writeMask selects the bits of the unsigned integer stencil values updated by the stencil test in the stencil framebuffer attachment.

  • reference is an integer stencil reference value that is used in the unsigned stencil comparison.

Valid Usage (Implicit)
  • VUID-VkStencilOpState-failOp-parameter
    failOp must be a valid VkStencilOp value

  • VUID-VkStencilOpState-passOp-parameter
    passOp must be a valid VkStencilOp value

  • VUID-VkStencilOpState-depthFailOp-parameter
    depthFailOp must be a valid VkStencilOp value

  • VUID-VkStencilOpState-compareOp-parameter
    compareOp must be a valid VkCompareOp value

To dynamically set the stencil compare mask, call:

// Provided by VK_VERSION_1_0
void vkCmdSetStencilCompareMask(
    VkCommandBuffer                             commandBuffer,
    VkStencilFaceFlags                          faceMask,
    uint32_t                                    compareMask);
  • commandBuffer is the command buffer into which the command will be recorded.

  • faceMask is a bitmask of VkStencilFaceFlagBits specifying the set of stencil state for which to update the compare mask.

  • compareMask is the new value to use as the stencil compare mask.

This command sets the stencil compare mask for subsequent drawing commands when drawing using shader objects, or when the graphics pipeline is created with VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK set in VkPipelineDynamicStateCreateInfo::pDynamicStates. Otherwise, this state is specified by the VkStencilOpState::compareMask value used to create the currently active pipeline, for both front and back faces.

Valid Usage (Implicit)
  • VUID-vkCmdSetStencilCompareMask-commandBuffer-parameter
    commandBuffer must be a valid VkCommandBuffer handle

  • VUID-vkCmdSetStencilCompareMask-faceMask-parameter
    faceMask must be a valid combination of VkStencilFaceFlagBits values

  • VUID-vkCmdSetStencilCompareMask-faceMask-requiredbitmask
    faceMask must not be 0

  • VUID-vkCmdSetStencilCompareMask-commandBuffer-recording
    commandBuffer must be in the recording state

  • VUID-vkCmdSetStencilCompareMask-commandBuffer-cmdpool
    The VkCommandPool that commandBuffer was allocated from must support graphics operations

  • VUID-vkCmdSetStencilCompareMask-videocoding
    This command must only be called outside of a video coding scope

Host Synchronization
  • Host access to commandBuffer must be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be externally synchronized

Command Properties
Command Buffer Levels Render Pass Scope Video Coding Scope Supported Queue Types Command Type

Primary
Secondary

Both

Outside

Graphics

State

VkStencilFaceFlagBits values are:

// Provided by VK_VERSION_1_0
typedef enum VkStencilFaceFlagBits {
    VK_STENCIL_FACE_FRONT_BIT = 0x00000001,
    VK_STENCIL_FACE_BACK_BIT = 0x00000002,
    VK_STENCIL_FACE_FRONT_AND_BACK = 0x00000003,
    VK_STENCIL_FRONT_AND_BACK = VK_STENCIL_FACE_FRONT_AND_BACK,
} VkStencilFaceFlagBits;
  • VK_STENCIL_FACE_FRONT_BIT specifies that only the front set of stencil state is updated.

  • VK_STENCIL_FACE_BACK_BIT specifies that only the back set of stencil state is updated.

  • VK_STENCIL_FACE_FRONT_AND_BACK is the combination of VK_STENCIL_FACE_FRONT_BIT and VK_STENCIL_FACE_BACK_BIT, and specifies that both sets of stencil state are updated.

// Provided by VK_VERSION_1_0
typedef VkFlags VkStencilFaceFlags;

VkStencilFaceFlags is a bitmask type for setting a mask of zero or more VkStencilFaceFlagBits.

To dynamically set the stencil write mask, call:

// Provided by VK_VERSION_1_0
void vkCmdSetStencilWriteMask(
    VkCommandBuffer                             commandBuffer,
    VkStencilFaceFlags                          faceMask,
    uint32_t                                    writeMask);
  • commandBuffer is the command buffer into which the command will be recorded.

  • faceMask is a bitmask of VkStencilFaceFlagBits specifying the set of stencil state for which to update the write mask, as described above for vkCmdSetStencilCompareMask.

  • writeMask is the new value to use as the stencil write mask.

This command sets the stencil write mask for subsequent drawing commands when drawing using shader objects, or when the graphics pipeline is created with VK_DYNAMIC_STATE_STENCIL_WRITE_MASK set in VkPipelineDynamicStateCreateInfo::pDynamicStates. Otherwise, this state is specified by the writeMask value used to create the currently active pipeline, for both VkPipelineDepthStencilStateCreateInfo::front and VkPipelineDepthStencilStateCreateInfo::back faces.

Valid Usage (Implicit)
  • VUID-vkCmdSetStencilWriteMask-commandBuffer-parameter
    commandBuffer must be a valid VkCommandBuffer handle

  • VUID-vkCmdSetStencilWriteMask-faceMask-parameter
    faceMask must be a valid combination of VkStencilFaceFlagBits values

  • VUID-vkCmdSetStencilWriteMask-faceMask-requiredbitmask
    faceMask must not be 0

  • VUID-vkCmdSetStencilWriteMask-commandBuffer-recording
    commandBuffer must be in the recording state

  • VUID-vkCmdSetStencilWriteMask-commandBuffer-cmdpool
    The VkCommandPool that commandBuffer was allocated from must support graphics operations

  • VUID-vkCmdSetStencilWriteMask-videocoding
    This command must only be called outside of a video coding scope

Host Synchronization
  • Host access to commandBuffer must be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be externally synchronized

Command Properties
Command Buffer Levels Render Pass Scope Video Coding Scope Supported Queue Types Command Type

Primary
Secondary

Both

Outside

Graphics

State

To dynamically set the stencil reference value, call:

// Provided by VK_VERSION_1_0
void vkCmdSetStencilReference(
    VkCommandBuffer                             commandBuffer,
    VkStencilFaceFlags                          faceMask,
    uint32_t                                    reference);
  • commandBuffer is the command buffer into which the command will be recorded.

  • faceMask is a bitmask of VkStencilFaceFlagBits specifying the set of stencil state for which to update the reference value, as described above for vkCmdSetStencilCompareMask.

  • reference is the new value to use as the stencil reference value.

This command sets the stencil reference value for subsequent drawing commands when drawing using shader objects, or when the graphics pipeline is created with VK_DYNAMIC_STATE_STENCIL_REFERENCE set in VkPipelineDynamicStateCreateInfo::pDynamicStates. Otherwise, this state is specified by the VkPipelineDepthStencilStateCreateInfo::reference value used to create the currently active pipeline, for both front and back faces.

Valid Usage (Implicit)
  • VUID-vkCmdSetStencilReference-commandBuffer-parameter
    commandBuffer must be a valid VkCommandBuffer handle

  • VUID-vkCmdSetStencilReference-faceMask-parameter
    faceMask must be a valid combination of VkStencilFaceFlagBits values

  • VUID-vkCmdSetStencilReference-faceMask-requiredbitmask
    faceMask must not be 0

  • VUID-vkCmdSetStencilReference-commandBuffer-recording
    commandBuffer must be in the recording state

  • VUID-vkCmdSetStencilReference-commandBuffer-cmdpool
    The VkCommandPool that commandBuffer was allocated from must support graphics operations

  • VUID-vkCmdSetStencilReference-videocoding
    This command must only be called outside of a video coding scope

Host Synchronization
  • Host access to commandBuffer must be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be externally synchronized

Command Properties
Command Buffer Levels Render Pass Scope Video Coding Scope Supported Queue Types Command Type

Primary
Secondary

Both

Outside

Graphics

State

Possible values of the failOp, passOp, and depthFailOp members of VkStencilOpState, specifying what happens to the stored stencil value if this or certain subsequent tests fail or pass, are:

// Provided by VK_VERSION_1_0
typedef enum VkStencilOp {
    VK_STENCIL_OP_KEEP = 0,
    VK_STENCIL_OP_ZERO = 1,
    VK_STENCIL_OP_REPLACE = 2,
    VK_STENCIL_OP_INCREMENT_AND_CLAMP = 3,
    VK_STENCIL_OP_DECREMENT_AND_CLAMP = 4,
    VK_STENCIL_OP_INVERT = 5,
    VK_STENCIL_OP_INCREMENT_AND_WRAP = 6,
    VK_STENCIL_OP_DECREMENT_AND_WRAP = 7,
} VkStencilOp;
  • VK_STENCIL_OP_KEEP keeps the current value.

  • VK_STENCIL_OP_ZERO sets the value to 0.

  • VK_STENCIL_OP_REPLACE sets the value to reference.

  • VK_STENCIL_OP_INCREMENT_AND_CLAMP increments the current value and clamps to the maximum representable unsigned value.

  • VK_STENCIL_OP_DECREMENT_AND_CLAMP decrements the current value and clamps to 0.

  • VK_STENCIL_OP_INVERT bitwise-inverts the current value.

  • VK_STENCIL_OP_INCREMENT_AND_WRAP increments the current value and wraps to 0 when the maximum value would have been exceeded.

  • VK_STENCIL_OP_DECREMENT_AND_WRAP decrements the current value and wraps to the maximum possible value when the value would go below 0.

For purposes of increment and decrement, the stencil bits are considered as an unsigned integer.

26.9. Depth Test

The depth test compares the depth value za in the depth/stencil attachment at each sample’s framebuffer coordinates (xf,yf) and sample index i against the sample’s depth value zf. If there is no depth attachment then the depth test is skipped.

The depth test occurs in three stages, as detailed in the following sections.

26.9.1. Depth Clamping and Range Adjustment

If VkPipelineRasterizationStateCreateInfo::depthClampEnable is enabled, zf is clamped to [zmin, zmax], where zmin = min(n,f), zmax = max(n,f)], and n and f are the minDepth and maxDepth depth range values of the viewport used by this fragment, respectively.

Following depth clamping:

  • If zf is not in the range [zmin, zmax], then zf is undefined following this step.

  • If the depth attachment has a fixed-point format and zf is not in the range [0, 1], then zf is undefined following this step.

26.9.2. Depth Comparison

If the depth test is not enabled, as specified by vkCmdSetDepthTestEnable or VkPipelineDepthStencilStateCreateInfo::depthTestEnable, then this step is skipped.

The comparison operation performed is determined by the VkCompareOp value set by vkCmdSetDepthCompareOp, or by VkPipelineDepthStencilStateCreateInfo::depthCompareOp during pipeline creation. zf and za are used as the reference and test values, respectively, in the operation specified by the VkCompareOp.

If the comparison evaluates to false, the coverage for the sample is set to 0.

26.9.3. Depth Attachment Writes

If depth writes are enabled, as specified by vkCmdSetDepthWriteEnable or VkPipelineDepthStencilStateCreateInfo::depthWriteEnable, and the comparison evaluated to true, the depth attachment value za is set to the sample’s depth value zf. If there is no depth attachment, no value is written.

To dynamically enable or disable the depth test, call:

// Provided by VK_VERSION_1_3
void vkCmdSetDepthTestEnable(
    VkCommandBuffer                             commandBuffer,
    VkBool32                                    depthTestEnable);

or the equivalent command

// Provided by VK_EXT_shader_object
void vkCmdSetDepthTestEnableEXT(
    VkCommandBuffer                             commandBuffer,
    VkBool32                                    depthTestEnable);
  • commandBuffer is the command buffer into which the command will be recorded.

  • depthTestEnable specifies if the depth test is enabled.

This command sets the depth test enable for subsequent drawing commands when drawing using shader objects, or when the graphics pipeline is created with VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE set in VkPipelineDynamicStateCreateInfo::pDynamicStates. Otherwise, this state is specified by the VkPipelineDepthStencilStateCreateInfo::depthTestEnable value used to create the currently active pipeline.

Valid Usage
  • VUID-vkCmdSetDepthTestEnable-None-08971
    At least one of the following must be true:

Valid Usage (Implicit)
  • VUID-vkCmdSetDepthTestEnable-commandBuffer-parameter
    commandBuffer must be a valid VkCommandBuffer handle

  • VUID-vkCmdSetDepthTestEnable-commandBuffer-recording
    commandBuffer must be in the recording state

  • VUID-vkCmdSetDepthTestEnable-commandBuffer-cmdpool
    The VkCommandPool that commandBuffer was allocated from must support graphics operations

  • VUID-vkCmdSetDepthTestEnable-videocoding
    This command must only be called outside of a video coding scope

Host Synchronization
  • Host access to commandBuffer must be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be externally synchronized

Command Properties
Command Buffer Levels Render Pass Scope Video Coding Scope Supported Queue Types Command Type

Primary
Secondary

Both

Outside

Graphics

State

To dynamically set the depth compare operator, call:

// Provided by VK_VERSION_1_3
void vkCmdSetDepthCompareOp(
    VkCommandBuffer                             commandBuffer,
    VkCompareOp                                 depthCompareOp);

or the equivalent command

// Provided by VK_EXT_shader_object
void vkCmdSetDepthCompareOpEXT(
    VkCommandBuffer                             commandBuffer,
    VkCompareOp                                 depthCompareOp);
  • commandBuffer is the command buffer into which the command will be recorded.

  • depthCompareOp is a VkCompareOp value specifying the comparison operator used for the Depth Comparison step of the depth test.

This command sets the depth comparison operator for subsequent drawing commands when drawing using shader objects, or when the graphics pipeline is created with VK_DYNAMIC_STATE_DEPTH_COMPARE_OP set in VkPipelineDynamicStateCreateInfo::pDynamicStates. Otherwise, this state is specified by the VkPipelineDepthStencilStateCreateInfo::depthCompareOp value used to create the currently active pipeline.

Valid Usage
  • VUID-vkCmdSetDepthCompareOp-None-08971
    At least one of the following must be true:

Valid Usage (Implicit)
  • VUID-vkCmdSetDepthCompareOp-commandBuffer-parameter
    commandBuffer must be a valid VkCommandBuffer handle

  • VUID-vkCmdSetDepthCompareOp-depthCompareOp-parameter
    depthCompareOp must be a valid VkCompareOp value

  • VUID-vkCmdSetDepthCompareOp-commandBuffer-recording
    commandBuffer must be in the recording state

  • VUID-vkCmdSetDepthCompareOp-commandBuffer-cmdpool
    The VkCommandPool that commandBuffer was allocated from must support graphics operations

  • VUID-vkCmdSetDepthCompareOp-videocoding
    This command must only be called outside of a video coding scope

Host Synchronization
  • Host access to commandBuffer must be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be externally synchronized

Command Properties
Command Buffer Levels Render Pass Scope Video Coding Scope Supported Queue Types Command Type

Primary
Secondary

Both

Outside

Graphics

State

To dynamically set the depth write enable, call:

// Provided by VK_VERSION_1_3
void vkCmdSetDepthWriteEnable(
    VkCommandBuffer                             commandBuffer,
    VkBool32                                    depthWriteEnable);

or the equivalent command

// Provided by VK_EXT_shader_object
void vkCmdSetDepthWriteEnableEXT(
    VkCommandBuffer                             commandBuffer,
    VkBool32                                    depthWriteEnable);
  • commandBuffer is the command buffer into which the command will be recorded.

  • depthWriteEnable specifies if depth writes are enabled.

This command sets the depth write enable for subsequent drawing commands when drawing using shader objects, or when the graphics pipeline is created with VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE set in VkPipelineDynamicStateCreateInfo::pDynamicStates. Otherwise, this state is specified by the VkPipelineDepthStencilStateCreateInfo::depthWriteEnable value used to create the currently active pipeline.

Valid Usage
  • VUID-vkCmdSetDepthWriteEnable-None-08971
    At least one of the following must be true:

Valid Usage (Implicit)
  • VUID-vkCmdSetDepthWriteEnable-commandBuffer-parameter
    commandBuffer must be a valid VkCommandBuffer handle

  • VUID-vkCmdSetDepthWriteEnable-commandBuffer-recording
    commandBuffer must be in the recording state

  • VUID-vkCmdSetDepthWriteEnable-commandBuffer-cmdpool
    The VkCommandPool that commandBuffer was allocated from must support graphics operations

  • VUID-vkCmdSetDepthWriteEnable-videocoding
    This command must only be called outside of a video coding scope

Host Synchronization
  • Host access to commandBuffer must be externally synchronized

  • Host access to the VkCommandPool that commandBuffer was allocated from must be externally synchronized

Command Properties
Command Buffer Levels Render Pass Scope Video Coding Scope Supported Queue Types Command Type

Primary
Secondary

Both

Outside

Graphics

State

26.10. Sample Counting

Occlusion queries use query pool entries to track the number of samples that pass all the per-fragment tests. The mechanism of collecting an occlusion query value is described in Occlusion Queries.

The occlusion query sample counter increments by one for each sample with a coverage value of 1 in each fragment that survives all the per-fragment tests, including scissor, sample mask, alpha to coverage, stencil, and depth tests.

26.11. 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.

26.11.1. Pixel Coverage

Coverage for each pixel is first extracted from the total fragment coverage mask. This consists of rasterizationSamples unique coverage samples for each pixel in the fragment area, each with a unique sample index. If the fragment only contains a single pixel, coverage for the pixel is equivalent to the fragment coverage.

If the fragment shading rate is set, and the fragment covers multiple pixels, each pixel’s coverage consists of the coverage samples with a pixel index matching that pixel, and each sample retains its unique sample index i.

26.11.2. Color Sample Coverage

Once pixel coverage is determined, coverage for each individual color sample corresponding to that pixel is determined.

The number of rasterizationSamples is identical to the number of samples in the color attachments. A color sample is covered if the pixel coverage sample with the same sample index i is covered.