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