| // Copyright 2015-2023 The Khronos Group Inc. |
| // |
| // SPDX-License-Identifier: CC-BY-4.0 |
| |
| [[primsrast]] |
| = Rasterization |
| |
| Rasterization is the process by which a primitive is converted to a |
| two-dimensional image. |
| Each discrete location of this image contains associated data such as depth, |
| color, or other attributes. |
| |
| Rasterizing a primitive begins by determining which squares of an integer |
| grid in framebuffer coordinates are occupied by the primitive, and assigning |
| one or more depth values to each such square. |
| This process is described below for points, lines, and polygons. |
| |
| A grid square, including its [eq]#(x,y)# framebuffer coordinates, [eq]#z# |
| (depth), and associated data added by fragment shaders, is called a |
| fragment. |
| A fragment is located by its upper left corner, which lies on integer grid |
| coordinates. |
| |
| Rasterization operations also refer to a fragment's sample locations, which |
| are offset by fractional values from its upper left corner. |
| The rasterization rules for points, lines, and triangles involve testing |
| whether each sample location is inside the primitive. |
| Fragments need not actually be square, and rasterization rules are not |
| affected by the aspect ratio of fragments. |
| Display of non-square grids, however, will cause rasterized points and line |
| segments to appear fatter in one direction than the other. |
| |
| We assume that fragments are square, since it simplifies antialiasing and |
| texturing. |
| After rasterization, fragments are processed by <<fragops, fragment |
| operations>>. |
| |
| Several factors affect rasterization, including the members of |
| slink:VkPipelineRasterizationStateCreateInfo and |
| slink:VkPipelineMultisampleStateCreateInfo. |
| |
| [open,refpage='VkPipelineRasterizationStateCreateInfo',desc='Structure specifying parameters of a newly created pipeline rasterization state',type='structs'] |
| -- |
| The sname:VkPipelineRasterizationStateCreateInfo structure is defined as: |
| |
| include::{generated}/api/structs/VkPipelineRasterizationStateCreateInfo.adoc[] |
| |
| * pname:sType is a elink:VkStructureType value identifying this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:flags is reserved for future use. |
| * pname:depthClampEnable controls whether to clamp the fragment's depth |
| values as described in <<fragops-depth,Depth Test>>. |
| ifdef::VK_EXT_depth_clip_enable[] |
| If the pipeline is not created with |
| slink:VkPipelineRasterizationDepthClipStateCreateInfoEXT present then |
| enabling depth clamp will also disable clipping primitives to the z |
| planes of the frustrum as described in <<vertexpostproc-clipping, |
| Primitive Clipping>>. |
| Otherwise depth clipping is controlled by the state set in |
| slink:VkPipelineRasterizationDepthClipStateCreateInfoEXT. |
| endif::VK_EXT_depth_clip_enable[] |
| ifndef::VK_EXT_depth_clip_enable[] |
| Enabling depth clamp will also disable clipping primitives to the z |
| planes of the frustrum as described in <<vertexpostproc-clipping, |
| Primitive Clipping>>. |
| endif::VK_EXT_depth_clip_enable[] |
| * pname:rasterizerDiscardEnable controls whether primitives are discarded |
| immediately before the rasterization stage. |
| * pname:polygonMode is the triangle rendering mode. |
| See elink:VkPolygonMode. |
| * pname:cullMode is the triangle facing direction used for primitive |
| culling. |
| See elink:VkCullModeFlagBits. |
| * pname:frontFace is a elink:VkFrontFace value specifying the front-facing |
| triangle orientation to be used for culling. |
| * pname:depthBiasEnable controls whether to bias fragment depth values. |
| * pname:depthBiasConstantFactor is a scalar factor controlling the |
| constant depth value added to each fragment. |
| * pname:depthBiasClamp is the maximum (or minimum) depth bias of a |
| fragment. |
| * pname:depthBiasSlopeFactor is a scalar factor applied to a fragment's |
| slope in depth bias calculations. |
| * pname:lineWidth is the width of rasterized line segments. |
| |
| ifdef::VK_AMD_rasterization_order[] |
| The application can: also add a |
| sname:VkPipelineRasterizationStateRasterizationOrderAMD structure to the |
| pname:pNext chain of a slink:VkPipelineRasterizationStateCreateInfo |
| structure. |
| This structure enables selecting the rasterization order to use when |
| rendering with the corresponding graphics pipeline as described in |
| <<primsrast-order, Rasterization Order>>. |
| endif::VK_AMD_rasterization_order[] |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkPipelineRasterizationStateCreateInfo-depthClampEnable-00782]] |
| If the <<features-depthClamp, pname:depthClamp>> feature is not enabled, |
| pname:depthClampEnable must: be ename:VK_FALSE |
| * [[VUID-VkPipelineRasterizationStateCreateInfo-polygonMode-01507]] |
| If the <<features-fillModeNonSolid, pname:fillModeNonSolid>> feature is |
| not enabled, pname:polygonMode must: be ename:VK_POLYGON_MODE_FILL |
| ifdef::VK_NV_fill_rectangle[or ename:VK_POLYGON_MODE_FILL_RECTANGLE_NV] |
| ifdef::VK_NV_fill_rectangle[] |
| * [[VUID-VkPipelineRasterizationStateCreateInfo-polygonMode-01414]] |
| If the `apiext:VK_NV_fill_rectangle` extension is not enabled, |
| pname:polygonMode must: not be ename:VK_POLYGON_MODE_FILL_RECTANGLE_NV |
| endif::VK_NV_fill_rectangle[] |
| ifdef::VK_KHR_portability_subset[] |
| * [[VUID-VkPipelineRasterizationStateCreateInfo-pointPolygons-04458]] |
| If the `apiext:VK_KHR_portability_subset` extension is enabled, and |
| slink:VkPhysicalDevicePortabilitySubsetFeaturesKHR::pname:pointPolygons |
| is ename:VK_FALSE, and pname:rasterizerDiscardEnable is ename:VK_FALSE, |
| pname:polygonMode must: not be ename:VK_POLYGON_MODE_POINT |
| endif::VK_KHR_portability_subset[] |
| **** |
| |
| include::{generated}/validity/structs/VkPipelineRasterizationStateCreateInfo.adoc[] |
| -- |
| |
| [open,refpage='VkPipelineRasterizationStateCreateFlags',desc='Reserved for future use',type='flags'] |
| -- |
| include::{generated}/api/flags/VkPipelineRasterizationStateCreateFlags.adoc[] |
| |
| tname:VkPipelineRasterizationStateCreateFlags is a bitmask type for setting |
| a mask, but is currently reserved for future use. |
| -- |
| |
| ifdef::VK_EXT_depth_clip_enable[] |
| [open,refpage='VkPipelineRasterizationDepthClipStateCreateInfoEXT',desc='Structure specifying depth clipping state',type='structs'] |
| -- |
| If the pname:pNext chain of slink:VkPipelineRasterizationStateCreateInfo |
| includes a sname:VkPipelineRasterizationDepthClipStateCreateInfoEXT |
| structure, then that structure controls whether depth clipping is enabled or |
| disabled. |
| |
| The sname:VkPipelineRasterizationDepthClipStateCreateInfoEXT structure is |
| defined as: |
| |
| include::{generated}/api/structs/VkPipelineRasterizationDepthClipStateCreateInfoEXT.adoc[] |
| |
| * pname:sType is a elink:VkStructureType value identifying this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:flags is reserved for future use. |
| * pname:depthClipEnable controls whether depth clipping is enabled as |
| described in <<vertexpostproc-clipping, Primitive Clipping>>. |
| |
| include::{generated}/validity/structs/VkPipelineRasterizationDepthClipStateCreateInfoEXT.adoc[] |
| -- |
| |
| [open,refpage='VkPipelineRasterizationDepthClipStateCreateFlagsEXT',desc='Reserved for future use',type='flags'] |
| -- |
| include::{generated}/api/flags/VkPipelineRasterizationDepthClipStateCreateFlagsEXT.adoc[] |
| |
| tname:VkPipelineRasterizationDepthClipStateCreateFlagsEXT is a bitmask type |
| for setting a mask, but is currently reserved for future use. |
| -- |
| endif::VK_EXT_depth_clip_enable[] |
| |
| [open,refpage='VkPipelineMultisampleStateCreateInfo',desc='Structure specifying parameters of a newly created pipeline multisample state',type='structs'] |
| -- |
| The sname:VkPipelineMultisampleStateCreateInfo structure is defined as: |
| |
| include::{generated}/api/structs/VkPipelineMultisampleStateCreateInfo.adoc[] |
| |
| * pname:sType is a elink:VkStructureType value identifying this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:flags is reserved for future use. |
| * pname:rasterizationSamples is a elink:VkSampleCountFlagBits value |
| specifying the number of samples used in rasterization. |
| ifdef::VK_EXT_extended_dynamic_state3[] |
| This value is ignored for the purposes of setting the number of samples |
| used in rasterization if the pipeline is created with the |
| ename:VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT dynamic state set, but |
| if ename:VK_DYNAMIC_STATE_SAMPLE_MASK_EXT dynamic state is not set, it |
| is still used to define the size of the pname:pSampleMask array as |
| described below. |
| endif::VK_EXT_extended_dynamic_state3[] |
| * pname:sampleShadingEnable can: be used to enable |
| <<primsrast-sampleshading,Sample Shading>>. |
| * pname:minSampleShading specifies a minimum fraction of sample shading if |
| pname:sampleShadingEnable is set to ename:VK_TRUE. |
| * pname:pSampleMask is a pointer to an array of basetype:VkSampleMask |
| values used in the <<fragops-samplemask,sample mask test>>. |
| * pname:alphaToCoverageEnable controls whether a temporary coverage value |
| is generated based on the alpha component of the fragment's first color |
| output as specified in the <<fragops-covg,Multisample Coverage>> |
| section. |
| * pname:alphaToOneEnable controls whether the alpha component of the |
| fragment's first color output is replaced with one as described in |
| <<fragops-covg,Multisample Coverage>>. |
| |
| Each bit in the sample mask is associated with a unique |
| <<primsrast-multisampling-coverage-mask, sample index>> as defined for the |
| <<primsrast-multisampling-coverage-mask, coverage mask>>. |
| Each bit [eq]#b# for mask word [eq]#w# in the sample mask corresponds to |
| sample index [eq]#i#, where [eq]#i = 32 {times} w {plus} b#. |
| pname:pSampleMask has a length equal to [eq]#{lceil} |
| pname:rasterizationSamples / 32 {rceil}# words. |
| |
| If pname:pSampleMask is `NULL`, it is treated as if the mask has all bits |
| set to `1`. |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkPipelineMultisampleStateCreateInfo-sampleShadingEnable-00784]] |
| If the <<features-sampleRateShading, pname:sampleRateShading>> feature |
| is not enabled, pname:sampleShadingEnable must: be ename:VK_FALSE |
| * [[VUID-VkPipelineMultisampleStateCreateInfo-alphaToOneEnable-00785]] |
| If the <<features-alphaToOne, pname:alphaToOne>> feature is not enabled, |
| pname:alphaToOneEnable must: be ename:VK_FALSE |
| * [[VUID-VkPipelineMultisampleStateCreateInfo-minSampleShading-00786]] |
| pname:minSampleShading must: be in the range [eq]#[0,1]# |
| ifdef::VK_NV_framebuffer_mixed_samples[] |
| * [[VUID-VkPipelineMultisampleStateCreateInfo-rasterizationSamples-01415]] |
| If the `apiext:VK_NV_framebuffer_mixed_samples` extension is enabled, |
| and if the subpass has any color attachments and |
| pname:rasterizationSamples is greater than the number of color samples, |
| then pname:sampleShadingEnable must: be ename:VK_FALSE |
| endif::VK_NV_framebuffer_mixed_samples[] |
| **** |
| |
| include::{generated}/validity/structs/VkPipelineMultisampleStateCreateInfo.adoc[] |
| -- |
| |
| [open,refpage='VkPipelineMultisampleStateCreateFlags',desc='Reserved for future use',type='flags'] |
| -- |
| include::{generated}/api/flags/VkPipelineMultisampleStateCreateFlags.adoc[] |
| |
| tname:VkPipelineMultisampleStateCreateFlags is a bitmask type for setting a |
| mask, but is currently reserved for future use. |
| -- |
| |
| [open,refpage='VkSampleMask',desc='Mask of sample coverage information',type='basetypes',xrefs='VkPipelineMultisampleStateCreateInfo'] |
| -- |
| The elements of the sample mask array are of type basetype:VkSampleMask, |
| each representing 32 bits of coverage information: |
| |
| include::{generated}/api/basetypes/VkSampleMask.adoc[] |
| -- |
| |
| Rasterization only generates fragments which cover one or more pixels inside |
| the framebuffer. |
| Pixels outside the framebuffer are never considered covered in the fragment. |
| Fragments which would be produced by application of any of the primitive |
| rasterization rules described below but which lie outside the framebuffer |
| are not produced, nor are they processed by any later stage of the pipeline, |
| including any of the <<fragops, fragment operations>>. |
| |
| Surviving fragments are processed by fragment shaders. |
| Fragment shaders determine associated data for fragments, and can: also |
| modify or replace their assigned depth values. |
| |
| |
| [[primsrast-discard]] |
| == Discarding Primitives Before Rasterization |
| |
| Primitives are discarded before rasterization if the |
| pname:rasterizerDiscardEnable member of |
| slink:VkPipelineRasterizationStateCreateInfo is enabled. |
| When enabled, primitives are discarded after they are processed by the last |
| active shader stage in the pipeline before rasterization. |
| |
| ifdef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state2,VK_EXT_shader_object[] |
| [open,refpage='vkCmdSetRasterizerDiscardEnable',desc='Control whether primitives are discarded before the rasterization stage dynamically for a command buffer',type='protos',alias='vkCmdSetRasterizerDiscardEnableEXT'] |
| -- |
| To <<pipelines-dynamic-state, dynamically enable>> whether primitives are |
| discarded before the rasterization stage, call: |
| |
| ifdef::VK_VERSION_1_3[] |
| include::{generated}/api/protos/vkCmdSetRasterizerDiscardEnable.adoc[] |
| |
| ifdef::VK_EXT_extended_dynamic_state2,VK_EXT_shader_object[or the equivalent command] |
| endif::VK_VERSION_1_3[] |
| |
| ifdef::VK_EXT_extended_dynamic_state2,VK_EXT_shader_object[] |
| include::{generated}/api/protos/vkCmdSetRasterizerDiscardEnableEXT.adoc[] |
| endif::VK_EXT_extended_dynamic_state2,VK_EXT_shader_object[] |
| |
| * pname:commandBuffer is the command buffer into which the command will be |
| recorded. |
| * pname:rasterizerDiscardEnable controls whether primitives are discarded |
| immediately before the rasterization stage. |
| |
| This command sets the discard enable for subsequent drawing commands |
| ifdef::VK_EXT_shader_object[] |
| ifdef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state2[when drawing using <<shaders-objects, shader objects>>, or] |
| ifndef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state2[when drawing using <<shaders-objects, shader objects>>.] |
| endif::VK_EXT_shader_object[] |
| ifdef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state2[] |
| when the graphics pipeline is created with |
| ename:VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE set in |
| slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates. |
| endif::VK_VERSION_1_3,VK_EXT_extended_dynamic_state2[] |
| Otherwise, this state is specified by the |
| slink:VkPipelineRasterizationStateCreateInfo::pname:rasterizerDiscardEnable |
| value used to create the currently active pipeline. |
| |
| :refpage: vkCmdSetRasterizerDiscardEnable |
| |
| .Valid Usage |
| **** |
| include::{chapters}/commonvalidity/dynamic_state2_feature_common.adoc[] |
| **** |
| |
| include::{generated}/validity/protos/vkCmdSetRasterizerDiscardEnable.adoc[] |
| -- |
| endif::VK_VERSION_1_3,VK_EXT_extended_dynamic_state2,VK_EXT_shader_object[] |
| |
| |
| ifdef::VK_EXT_transform_feedback[] |
| [[primsrast-stream]] |
| == Controlling the Vertex Stream Used for Rasterization |
| |
| By default vertex data output from the last |
| <<pipelines-graphics-subsets-pre-rasterization,pre-rasterization shader |
| stage>> are directed to vertex stream zero. |
| Geometry shaders can: emit primitives to multiple independent vertex |
| streams. |
| Each vertex emitted by the geometry shader is directed at one of the vertex |
| streams. |
| As vertices are received on each vertex stream, they are arranged into |
| primitives of the type specified by the geometry shader output primitive |
| type. |
| The shading language instructions code:OpEndPrimitive and |
| code:OpEndStreamPrimitive can: be used to end the primitive being assembled |
| on a given vertex stream and start a new empty primitive of the same type. |
| An implementation supports up to |
| sname:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:maxTransformFeedbackStreams |
| streams, which is at least 1. |
| The individual streams are numbered 0 through |
| pname:maxTransformFeedbackStreams minus 1. |
| There is no requirement on the order of the streams to which vertices are |
| emitted, and the number of vertices emitted to each vertex stream can: be |
| completely independent, subject only to the |
| sname:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:maxTransformFeedbackStreamDataSize |
| and |
| sname:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:maxTransformFeedbackBufferDataSize |
| limits. |
| The primitives output from all vertex streams are passed to the transform |
| feedback stage to be captured to transform feedback buffers in the manner |
| specified by the last |
| <<pipelines-graphics-subsets-pre-rasterization,pre-rasterization shader |
| stage>> shader's code:XfbBuffer, code:XfbStride, and code:Offsets |
| decorations on the output interface variables in the graphics pipeline. |
| To use a vertex stream other than zero, or to use multiple streams, the |
| code:GeometryStreams capability must: be specified. |
| |
| By default, the primitives output from vertex stream zero are rasterized. |
| If the implementation supports the |
| slink:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:transformFeedbackRasterizationStreamSelect |
| property it is possible to rasterize a vertex stream other than zero. |
| |
| By default, geometry shaders that emit vertices to multiple vertex streams |
| are limited to using only the code:OutputPoints output primitive type. |
| If the implementation supports the |
| slink:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:transformFeedbackStreamsLinesTriangles |
| property it is possible to emit code:OutputLineStrip or |
| code:OutputTriangleStrip in addition to code:OutputPoints. |
| |
| [open,refpage='VkPipelineRasterizationStateStreamCreateInfoEXT',desc='Structure defining the geometry stream used for rasterization',type='structs'] |
| -- |
| The vertex stream used for rasterization is specified by adding a |
| sname:VkPipelineRasterizationStateStreamCreateInfoEXT structure to the |
| pname:pNext chain of a slink:VkPipelineRasterizationStateCreateInfo |
| structure. |
| |
| The sname:VkPipelineRasterizationStateStreamCreateInfoEXT structure is |
| defined as: |
| |
| include::{generated}/api/structs/VkPipelineRasterizationStateStreamCreateInfoEXT.adoc[] |
| |
| * pname:sType is a elink:VkStructureType value identifying this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:flags is reserved for future use. |
| * pname:rasterizationStream is the vertex stream selected for |
| rasterization. |
| |
| If this structure is not present, pname:rasterizationStream is assumed to be |
| zero. |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkPipelineRasterizationStateStreamCreateInfoEXT-geometryStreams-02324]] |
| sname:VkPhysicalDeviceTransformFeedbackFeaturesEXT::pname:geometryStreams |
| must: be enabled |
| * [[VUID-VkPipelineRasterizationStateStreamCreateInfoEXT-rasterizationStream-02325]] |
| pname:rasterizationStream must: be less than |
| slink:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:maxTransformFeedbackStreams |
| * [[VUID-VkPipelineRasterizationStateStreamCreateInfoEXT-rasterizationStream-02326]] |
| pname:rasterizationStream must: be zero if |
| sname:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:transformFeedbackRasterizationStreamSelect |
| is ename:VK_FALSE |
| **** |
| |
| include::{generated}/validity/structs/VkPipelineRasterizationStateStreamCreateInfoEXT.adoc[] |
| -- |
| |
| [open,refpage='VkPipelineRasterizationStateStreamCreateFlagsEXT',desc='Reserved for future use',type='flags'] |
| -- |
| include::{generated}/api/flags/VkPipelineRasterizationStateStreamCreateFlagsEXT.adoc[] |
| |
| tname:VkPipelineRasterizationStateStreamCreateFlagsEXT is a bitmask type for |
| setting a mask, but is currently reserved for future use. |
| -- |
| |
| ifdef::VK_EXT_extended_dynamic_state3,VK_EXT_shader_object[] |
| [open,refpage='vkCmdSetRasterizationStreamEXT',desc='Specify the rasterization stream dynamically for a command buffer',type='protos'] |
| -- |
| To <<pipelines-dynamic-state, dynamically set>> the |
| pname:rasterizationStream state, call: |
| |
| include::{generated}/api/protos/vkCmdSetRasterizationStreamEXT.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command will be |
| recorded. |
| * pname:rasterizationStream specifies the pname:rasterizationStream state. |
| |
| This command sets the pname:rasterizationStream state for subsequent drawing |
| commands |
| ifdef::VK_EXT_shader_object[] |
| ifdef::VK_EXT_extended_dynamic_state3[when drawing using <<shaders-objects, shader objects>>, or] |
| ifndef::VK_EXT_extended_dynamic_state3[when drawing using <<shaders-objects, shader objects>>.] |
| endif::VK_EXT_shader_object[] |
| ifdef::VK_EXT_extended_dynamic_state3[] |
| when the graphics pipeline is created with |
| ename:VK_DYNAMIC_STATE_RASTERIZATION_STREAM_EXT set in |
| slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates. |
| endif::VK_EXT_extended_dynamic_state3[] |
| Otherwise, this state is specified by the |
| slink:VkPipelineRasterizationStateStreamCreateInfoEXT::pname:rasterizationStream |
| value used to create the currently active pipeline. |
| |
| :refpage: vkCmdSetRasterizationStreamEXT |
| :requiredfeature: extendedDynamicState3RasterizationStream |
| |
| .Valid Usage |
| **** |
| include::{chapters}/commonvalidity/dynamic_state3_feature_common.adoc[] |
| * [[VUID-vkCmdSetRasterizationStreamEXT-transformFeedback-07411]] |
| The <<features-transformFeedback, pname:transformFeedback>> feature |
| must: be enabled |
| * [[VUID-vkCmdSetRasterizationStreamEXT-rasterizationStream-07412]] |
| pname:rasterizationStream must: be less than |
| slink:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:maxTransformFeedbackStreams |
| * [[VUID-vkCmdSetRasterizationStreamEXT-rasterizationStream-07413]] |
| pname:rasterizationStream must: be zero if |
| sname:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:transformFeedbackRasterizationStreamSelect |
| is ename:VK_FALSE |
| **** |
| |
| include::{generated}/validity/protos/vkCmdSetRasterizationStreamEXT.adoc[] |
| -- |
| endif::VK_EXT_extended_dynamic_state3,VK_EXT_shader_object[] |
| endif::VK_EXT_transform_feedback[] |
| |
| |
| [[primsrast-order]] |
| == Rasterization Order |
| |
| Within a subpass of a <<renderpass,render pass instance>>, for a given |
| (x,y,layer,sample) sample location, the following operations are guaranteed |
| to execute in _rasterization order_, for each separate primitive that |
| includes that sample location: |
| |
| . <<fragops, Fragment operations>>, in the order defined |
| . <<framebuffer-blending, Blending>>, <<framebuffer-logicop, logic |
| operations>>, and color writes |
| |
| Execution of these operations for each primitive in a subpass occurs in |
| ifndef::VK_AMD_rasterization_order[] |
| <<drawing-primitive-order, primitive order>>. |
| endif::VK_AMD_rasterization_order[] |
| ifdef::VK_AMD_rasterization_order[] |
| an order determined by the application. |
| |
| [open,refpage='VkPipelineRasterizationStateRasterizationOrderAMD',desc='Structure defining rasterization order for a graphics pipeline',type='structs'] |
| -- |
| The rasterization order to use for a graphics pipeline is specified by |
| adding a sname:VkPipelineRasterizationStateRasterizationOrderAMD structure |
| to the pname:pNext chain of a slink:VkPipelineRasterizationStateCreateInfo |
| structure. |
| |
| The sname:VkPipelineRasterizationStateRasterizationOrderAMD structure is |
| defined as: |
| |
| include::{generated}/api/structs/VkPipelineRasterizationStateRasterizationOrderAMD.adoc[] |
| |
| * pname:sType is a elink:VkStructureType value identifying this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:rasterizationOrder is a elink:VkRasterizationOrderAMD value |
| specifying the primitive rasterization order to use. |
| |
| include::{generated}/validity/structs/VkPipelineRasterizationStateRasterizationOrderAMD.adoc[] |
| |
| If the `apiext:VK_AMD_rasterization_order` device extension is not enabled |
| or the application does not request a particular rasterization order through |
| specifying a sname:VkPipelineRasterizationStateRasterizationOrderAMD |
| structure then the rasterization order used by the graphics pipeline |
| defaults to ename:VK_RASTERIZATION_ORDER_STRICT_AMD. |
| -- |
| |
| [open,refpage='VkRasterizationOrderAMD',desc='Specify rasterization order for a graphics pipeline',type='enums'] |
| -- |
| Possible values of |
| slink:VkPipelineRasterizationStateRasterizationOrderAMD::pname:rasterizationOrder, |
| specifying the primitive rasterization order, are: |
| |
| include::{generated}/api/enums/VkRasterizationOrderAMD.adoc[] |
| |
| * ename:VK_RASTERIZATION_ORDER_STRICT_AMD specifies that operations for |
| each primitive in a subpass must: occur in <<drawing-primitive-order, |
| primitive order>>. |
| * ename:VK_RASTERIZATION_ORDER_RELAXED_AMD specifies that operations for |
| each primitive in a subpass may: not occur in <<drawing-primitive-order, |
| primitive order>>. |
| -- |
| endif::VK_AMD_rasterization_order[] |
| |
| |
| [[primsrast-multisampling]] |
| == Multisampling |
| |
| Multisampling is a mechanism to antialias all Vulkan primitives: points, |
| lines, and polygons. |
| The technique is to sample all primitives multiple times at each pixel. |
| Each sample in each framebuffer attachment has storage for a color, depth, |
| and/or stencil value, such that per-fragment operations apply to each sample |
| independently. |
| The color sample values can: be later _resolved_ to a single color (see |
| <<copies-resolve,Resolving Multisample Images>> and the <<renderpass,Render |
| Pass>> chapter for more details on how to resolve multisample images to |
| non-multisample images). |
| |
| Vulkan defines rasterization rules for single-sample modes in a way that is |
| equivalent to a multisample mode with a single sample in the center of each |
| fragment. |
| |
| Each fragment includes a <<primsrast-multisampling-coverage-mask, coverage |
| mask>> with a single bit for each sample in the fragment, and a number of |
| depth values and associated data for each sample. |
| |
| It is understood that each pixel has pname:rasterizationSamples locations |
| associated with it. |
| These locations are exact positions, rather than regions or areas, and each |
| is referred to as a sample point. |
| The sample points associated with a pixel must: be located inside or on the |
| boundary of the unit square that is considered to bound the pixel. |
| Furthermore, the relative locations of sample points may: be identical for |
| each pixel in the framebuffer, or they may: differ. |
| |
| ifdef::VK_EXT_fragment_density_map[] |
| If the render pass has a fragment density map attachment, each fragment only |
| has pname:rasterizationSamples locations associated with it regardless of |
| how many pixels are covered in the fragment area. |
| Fragment sample locations are defined as if the fragment had an area of |
| [eq]#(1,1)# and its sample points must: be located within these bounds. |
| Their actual location in the framebuffer is calculated by scaling the sample |
| location by the fragment area. |
| Attachments with storage for multiple samples per pixel are located at the |
| pixel sample locations. |
| Otherwise, the fragment's sample locations are generally used for evaluation |
| of associated data and fragment operations. |
| endif::VK_EXT_fragment_density_map[] |
| |
| If the current pipeline includes a fragment shader with one or more |
| variables in its interface decorated with code:Sample and code:Input, the |
| data associated with those variables will be assigned independently for each |
| sample. |
| The values for each sample must: be evaluated at the location of the sample. |
| The data associated with any other variables not decorated with code:Sample |
| and code:Input need not be evaluated independently for each sample. |
| |
| [[primsrast-multisampling-coverage-mask]] |
| A _coverage mask_ is generated for each fragment, based on which samples |
| within that fragment are determined to be within the area of the primitive |
| that generated the fragment. |
| |
| Single pixel fragments |
| ifdef::VK_EXT_fragment_density_map[] |
| and multi-pixel fragments defined by a |
| <<renderpass-fragmentdensitymapattachment, fragment density map>> |
| endif::VK_EXT_fragment_density_map[] |
| have one set of samples. |
| ifdef::VK_NV_shading_rate_image[] |
| Multi-pixel fragments defined by a <<primsrast-shading-rate-image, shading |
| rate image>> have one set of samples per pixel. |
| endif::VK_NV_shading_rate_image[] |
| ifdef::VK_KHR_fragment_shading_rate[] |
| Multi-pixel fragments defined by setting the |
| <<primsrast-fragment-shading-rate, fragment shading rate>> have one set of |
| samples per pixel. |
| endif::VK_KHR_fragment_shading_rate[] |
| Each set of samples has a number of samples determined by |
| slink:VkPipelineMultisampleStateCreateInfo::pname:rasterizationSamples. |
| Each sample in a set is assigned a unique _sample index_ [eq]#i# in the |
| range [eq]#[0, pname:rasterizationSamples)#. |
| |
| ifdef::VK_EXT_extended_dynamic_state3,VK_EXT_shader_object[] |
| [open,refpage='vkCmdSetRasterizationSamplesEXT',desc='Specify the rasterization samples dynamically for a command buffer',type='protos'] |
| -- |
| To <<pipelines-dynamic-state, dynamically set>> the |
| pname:rasterizationSamples, call: |
| |
| include::{generated}/api/protos/vkCmdSetRasterizationSamplesEXT.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command will be |
| recorded. |
| * pname:rasterizationSamples specifies pname:rasterizationSamples. |
| |
| This command sets the pname:rasterizationSamples for subsequent drawing |
| commands |
| ifdef::VK_EXT_shader_object[] |
| ifdef::VK_EXT_extended_dynamic_state3[when drawing using <<shaders-objects, shader objects>>, or] |
| ifndef::VK_EXT_extended_dynamic_state3[when drawing using <<shaders-objects, shader objects>>.] |
| endif::VK_EXT_shader_object[] |
| ifdef::VK_EXT_extended_dynamic_state3[] |
| when the graphics pipeline is created with |
| ename:VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT set in |
| slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates. |
| endif::VK_EXT_extended_dynamic_state3[] |
| Otherwise, this state is specified by the |
| slink:VkPipelineMultisampleStateCreateInfo::pname:rasterizationSamples value |
| used to create the currently active pipeline. |
| |
| :refpage: vkCmdSetRasterizationSamplesEXT |
| :requiredfeature: extendedDynamicState3RasterizationSamples |
| |
| .Valid Usage |
| **** |
| include::{chapters}/commonvalidity/dynamic_state3_feature_common.adoc[] |
| **** |
| |
| include::{generated}/validity/protos/vkCmdSetRasterizationSamplesEXT.adoc[] |
| -- |
| endif::VK_EXT_extended_dynamic_state3,VK_EXT_shader_object[] |
| |
| [[primsrast-multisampling-coverageindex]] |
| Each sample in a fragment is also assigned a unique _coverage index_ [eq]#j# |
| in the range [eq]#[0, n {times} pname:rasterizationSamples)#, where [eq]#n# |
| is the number of sets in the fragment. |
| If the fragment contains a single set of samples, the _coverage index_ is |
| always equal to the _sample index_. |
| ifdef::VK_NV_shading_rate_image[] |
| If a <<primsrast-shading-rate-image,shading rate image>> is used and a |
| fragment covers multiple pixels, the coverage index is determined as defined |
| by slink:VkPipelineViewportCoarseSampleOrderStateCreateInfoNV or |
| flink:vkCmdSetCoarseSampleOrderNV. |
| endif::VK_NV_shading_rate_image[] |
| |
| ifdef::VK_KHR_fragment_shading_rate[] |
| [[primsrast-multisampling-coverage-mask-vrfs]] |
| If the <<primsrast-fragment-shading-rate, fragment shading rate>> is set, |
| the coverage index [eq]#j# is determined as a function of the _pixel index_ |
| [eq]#p#, the _sample index_ [eq]#i#, and the number of rasterization samples |
| [eq]#r# as: |
| |
| {empty}:: [eq]#j = i + r {times} ((f~w~ {times} f~h~) - 1 - p)# |
| |
| where the pixel index [eq]#p# is determined as a function of the pixel's |
| framebuffer location [eq]#(x,y)# and the fragment size [eq]#(f~w~,f~h~)#: |
| |
| {empty}:: [eq]#p~x~ = x % f~w~# |
| {empty}:: [eq]#p~y~ = y % f~h~# |
| {empty}:: [eq]#p = p~x~ + (p~y~ {times} f~w~)# |
| |
| The table below illustrates the pixel index for multi-pixel fragments: |
| |
| .Pixel indices - 1 wide |
| [align="center"] |
| |==== |
| | 1x1 | 1x2 | 1x4 |
| |
| .>| image:{images}/pixel_index_1x1.svg[pdfwidth=90pt,opts="{imageopts}"] |
| .>| image:{images}/pixel_index_1x2.svg[pdfwidth=90pt,align="center",opts="{imageopts}"] |
| .>| image:{images}/pixel_index_1x4.svg[pdfwidth=90pt,align="center",opts="{imageopts}"] |
| |==== |
| |
| .Pixel indices - 2 wide |
| [align="center"] |
| |==== |
| | 2x1 | 2x2 | 2x4 |
| |
| .>| image:{images}/pixel_index_2x1.svg[pdfwidth=90pt,align="center",opts="{imageopts}"] |
| .>| image:{images}/pixel_index_2x2.svg[pdfwidth=90pt,align="center",opts="{imageopts}"] |
| .>| image:{images}/pixel_index_2x4.svg[pdfwidth=90pt,align="center",opts="{imageopts}"] |
| |==== |
| |
| .Pixel indices - 4 wide |
| [align="center"] |
| |==== |
| | 4x1 | 4x2 | 4x4 |
| |
| .>| image:{images}/pixel_index_4x1.svg[pdfwidth=90pt,align="center",opts="{imageopts}"] |
| .>| image:{images}/pixel_index_4x2.svg[pdfwidth=90pt,align="center",opts="{imageopts}"] |
| .>| image:{images}/pixel_index_4x4.svg[pdfwidth=90pt,align="center",opts="{imageopts}"] |
| |==== |
| endif::VK_KHR_fragment_shading_rate[] |
| |
| The coverage mask includes [eq]#B# bits packed into [eq]#W# words, defined |
| as: |
| |
| {empty}:: [eq]#B = n {times} pname:rasterizationSamples# |
| {empty}:: [eq]#W = {lceil}B/32{rceil}# |
| |
| Bit [eq]#b# in coverage mask word [eq]#w# is `1` if the sample with coverage |
| index [eq]#j = 32{times}w + b# is covered, and `0` otherwise. |
| |
| If the pname:standardSampleLocations member of slink:VkPhysicalDeviceLimits |
| is ename:VK_TRUE, then the sample counts ename:VK_SAMPLE_COUNT_1_BIT, |
| ename:VK_SAMPLE_COUNT_2_BIT, ename:VK_SAMPLE_COUNT_4_BIT, |
| ename:VK_SAMPLE_COUNT_8_BIT, and ename:VK_SAMPLE_COUNT_16_BIT have sample |
| locations as listed in the following table, with the [eq]##i##th entry in |
| the table corresponding to sample index [eq]#i#. |
| ename:VK_SAMPLE_COUNT_32_BIT and ename:VK_SAMPLE_COUNT_64_BIT do not have |
| standard sample locations. |
| Locations are defined relative to an origin in the upper left corner of the |
| fragment. |
| |
| <<< |
| |
| .Standard sample locations |
| [options="header",align="center"] |
| |==== |
| | Sample count 2+| Sample Locations |
| |ename:VK_SAMPLE_COUNT_1_BIT |
| | [eq]#(0.5,0.5)# |
| | image:{images}/sample_count_1.svg[pdfwidth=90pt,align="center",opts="{imageopts}"] |
| |ename:VK_SAMPLE_COUNT_2_BIT |
| | [eq]#(0.75,0.75)# + |
| [eq]#(0.25,0.25)# |
| | image:{images}/sample_count_2.svg[pdfwidth=90pt,align="center",opts="{imageopts}"] |
| |ename:VK_SAMPLE_COUNT_4_BIT |
| | [eq]#(0.375, 0.125)# + |
| [eq]#(0.875, 0.375)# + |
| [eq]#(0.125, 0.625)# + |
| [eq]#(0.625, 0.875)# |
| | image:{images}/sample_count_4.svg[pdfwidth=90pt,align="center",opts="{imageopts}"] |
| |ename:VK_SAMPLE_COUNT_8_BIT |
| | [eq]#(0.5625, 0.3125)# + |
| [eq]#(0.4375, 0.6875)# + |
| [eq]#(0.8125, 0.5625)# + |
| [eq]#(0.3125, 0.1875)# + |
| [eq]#(0.1875, 0.8125)# + |
| [eq]#(0.0625, 0.4375)# + |
| [eq]#(0.6875, 0.9375)# + |
| [eq]#(0.9375, 0.0625)# |
| | image:{images}/sample_count_8.svg[pdfwidth=90pt,align="center",opts="{imageopts}"] |
| |ename:VK_SAMPLE_COUNT_16_BIT |
| | [eq]#(0.5625, 0.5625)# + |
| [eq]#(0.4375, 0.3125)# + |
| [eq]#(0.3125, 0.625)# + |
| [eq]#(0.75, 0.4375)# + |
| [eq]#(0.1875, 0.375)# + |
| [eq]#(0.625, 0.8125)# + |
| [eq]#(0.8125, 0.6875)# + |
| [eq]#(0.6875, 0.1875)# + |
| [eq]#(0.375, 0.875)# + |
| [eq]#(0.5, 0.0625)# + |
| [eq]#(0.25, 0.125)# + |
| [eq]#(0.125, 0.75)# + |
| [eq]#(0.0, 0.5)# + |
| [eq]#(0.9375, 0.25)# + |
| [eq]#(0.875, 0.9375)# + |
| [eq]#(0.0625, 0.0)# |
| | image:{images}/sample_count_16.svg[pdfwidth=90pt,align="center",opts="{imageopts}"] |
| |==== |
| |
| ifdef::VK_AMD_shader_fragment_mask[] |
| Color images created with multiple samples per pixel use a compression |
| technique where there are two arrays of data associated with each pixel. |
| The first array contains one element per sample where each element stores an |
| index to the second array defining the _fragment mask_ of the pixel. |
| The second array contains one element per _color fragment_ and each element |
| stores a unique color value in the format of the image. |
| With this compression technique it is not always necessary to actually use |
| unique storage locations for each color sample: when multiple samples share |
| the same color value the fragment mask may: have two samples referring to |
| the same color fragment. |
| The number of color fragments is determined by the pname:samples member of |
| the slink:VkImageCreateInfo structure used to create the image. |
| The `apiext:VK_AMD_shader_fragment_mask` device extension provides shader |
| instructions enabling the application to get direct access to the fragment |
| mask and the individual color fragment values. |
| |
| [[vk-amd-shader-fragment-mask-diagram]] |
| image::{images}/fragment_mask.svg[align="center",title="Fragment Mask",align="center",opts="{imageopts}"] |
| |
| endif::VK_AMD_shader_fragment_mask[] |
| |
| |
| ifdef::VK_EXT_sample_locations[] |
| [[primsrast-samplelocations]] |
| == Custom Sample Locations |
| |
| [open,refpage='VkPipelineSampleLocationsStateCreateInfoEXT',desc='Structure specifying sample locations for a pipeline',type='structs'] |
| -- |
| Applications can: also control the sample locations used for rasterization. |
| |
| If the pname:pNext chain of the slink:VkPipelineMultisampleStateCreateInfo |
| structure specified at pipeline creation time includes a |
| sname:VkPipelineSampleLocationsStateCreateInfoEXT structure, then that |
| structure controls the sample locations used when rasterizing primitives |
| with the pipeline. |
| |
| The sname:VkPipelineSampleLocationsStateCreateInfoEXT structure is defined |
| as: |
| |
| include::{generated}/api/structs/VkPipelineSampleLocationsStateCreateInfoEXT.adoc[] |
| |
| * pname:sType is a elink:VkStructureType value identifying this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:sampleLocationsEnable controls whether custom sample locations are |
| used. |
| If pname:sampleLocationsEnable is ename:VK_FALSE, the default sample |
| locations are used and the values specified in pname:sampleLocationsInfo |
| are ignored. |
| * pname:sampleLocationsInfo is the sample locations to use during |
| rasterization if pname:sampleLocationsEnable is ename:VK_TRUE and the |
| graphics pipeline is not created with |
| ename:VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT. |
| |
| include::{generated}/validity/structs/VkPipelineSampleLocationsStateCreateInfoEXT.adoc[] |
| -- |
| |
| [open,refpage='VkSampleLocationsInfoEXT',desc='Structure specifying a set of sample locations',type='structs'] |
| -- |
| The sname:VkSampleLocationsInfoEXT structure is defined as: |
| |
| include::{generated}/api/structs/VkSampleLocationsInfoEXT.adoc[] |
| |
| * pname:sType is a elink:VkStructureType value identifying this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:sampleLocationsPerPixel is a elink:VkSampleCountFlagBits value |
| specifying the number of sample locations per pixel. |
| * pname:sampleLocationGridSize is the size of the sample location grid to |
| select custom sample locations for. |
| * pname:sampleLocationsCount is the number of sample locations in |
| pname:pSampleLocations. |
| * pname:pSampleLocations is a pointer to an array of |
| pname:sampleLocationsCount slink:VkSampleLocationEXT structures. |
| |
| This structure can: be used either to specify the sample locations to be |
| used for rendering or to specify the set of sample locations an image |
| subresource has been last rendered with for the purposes of layout |
| transitions of depth/stencil images created with |
| ename:VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT. |
| |
| The sample locations in pname:pSampleLocations specify |
| pname:sampleLocationsPerPixel number of sample locations for each pixel in |
| the grid of the size specified in pname:sampleLocationGridSize. |
| The sample location for sample [eq]#i# at the pixel grid location |
| [eq]#(x,y)# is taken from [eq]#pname:pSampleLocations[(x {plus} y {times} |
| pname:sampleLocationGridSize.width) {times} pname:sampleLocationsPerPixel |
| {plus} i]#. |
| |
| ifdef::VK_EXT_fragment_density_map[] |
| If the render pass has a fragment density map, the implementation will |
| choose the sample locations for the fragment and the contents of |
| pname:pSampleLocations may: be ignored. |
| endif::VK_EXT_fragment_density_map[] |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkSampleLocationsInfoEXT-sampleLocationsPerPixel-01526]] |
| pname:sampleLocationsPerPixel must: be a bit value that is set in |
| slink:VkPhysicalDeviceSampleLocationsPropertiesEXT::pname:sampleLocationSampleCounts |
| * [[VUID-VkSampleLocationsInfoEXT-sampleLocationsCount-01527]] |
| pname:sampleLocationsCount must: equal |
| [eq]#pname:sampleLocationsPerPixel {times} |
| pname:sampleLocationGridSize.width {times} |
| pname:sampleLocationGridSize.height# |
| **** |
| |
| include::{generated}/validity/structs/VkSampleLocationsInfoEXT.adoc[] |
| -- |
| |
| [open,refpage='VkSampleLocationEXT',desc='Structure specifying the coordinates of a sample location',type='structs'] |
| -- |
| The sname:VkSampleLocationEXT structure is defined as: |
| |
| include::{generated}/api/structs/VkSampleLocationEXT.adoc[] |
| |
| * pname:x is the horizontal coordinate of the sample's location. |
| * pname:y is the vertical coordinate of the sample's location. |
| |
| The domain space of the sample location coordinates has an upper-left origin |
| within the pixel in framebuffer space. |
| |
| The values specified in a sname:VkSampleLocationEXT structure are always |
| clamped to the implementation-dependent sample location coordinate range |
| [eq]#[pname:sampleLocationCoordinateRange[0],pname:sampleLocationCoordinateRange[1]]# |
| that can: be queried using |
| slink:VkPhysicalDeviceSampleLocationsPropertiesEXT. |
| |
| include::{generated}/validity/structs/VkSampleLocationEXT.adoc[] |
| -- |
| |
| ifdef::VK_EXT_extended_dynamic_state3,VK_EXT_shader_object[] |
| |
| [open,refpage='vkCmdSetSampleLocationsEnableEXT',desc='Specify the samples locations enable state dynamically for a command buffer',type='protos'] |
| -- |
| To <<pipelines-dynamic-state, dynamically set>> the |
| pname:sampleLocationsEnable state, call: |
| |
| include::{generated}/api/protos/vkCmdSetSampleLocationsEnableEXT.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command will be |
| recorded. |
| * pname:sampleLocationsEnable specifies the pname:sampleLocationsEnable |
| state. |
| |
| This command sets the pname:sampleLocationsEnable state for subsequent |
| drawing commands |
| ifdef::VK_EXT_shader_object[] |
| ifdef::VK_EXT_extended_dynamic_state3[when drawing using <<shaders-objects, shader objects>>, or] |
| ifndef::VK_EXT_extended_dynamic_state3[when drawing using <<shaders-objects, shader objects>>.] |
| endif::VK_EXT_shader_object[] |
| ifdef::VK_EXT_extended_dynamic_state3[] |
| when the graphics pipeline is created with |
| ename:VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_ENABLE_EXT set in |
| slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates. |
| endif::VK_EXT_extended_dynamic_state3[] |
| Otherwise, this state is specified by the |
| slink:VkPipelineSampleLocationsStateCreateInfoEXT::pname:sampleLocationsEnable |
| value used to create the currently active pipeline. |
| |
| :refpage: vkCmdSetSampleLocationsEnableEXT |
| :requiredfeature: extendedDynamicState3SampleLocationsEnable |
| |
| .Valid Usage |
| **** |
| include::{chapters}/commonvalidity/dynamic_state3_feature_common.adoc[] |
| **** |
| |
| include::{generated}/validity/protos/vkCmdSetSampleLocationsEnableEXT.adoc[] |
| -- |
| |
| endif::VK_EXT_extended_dynamic_state3,VK_EXT_shader_object[] |
| |
| [open,refpage='vkCmdSetSampleLocationsEXT',desc='Set sample locations dynamically for a command buffer',type='protos'] |
| -- |
| To <<pipelines-dynamic-state, dynamically set>> the sample locations used |
| for rasterization, call: |
| |
| include::{generated}/api/protos/vkCmdSetSampleLocationsEXT.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command will be |
| recorded. |
| * pname:pSampleLocationsInfo is the sample locations state to set. |
| |
| This command sets the custom sample locations for subsequent drawing |
| commands |
| ifdef::VK_EXT_shader_object[when drawing using <<shaders-objects, shader objects>>, or] |
| when the graphics pipeline is created with |
| ename:VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT set in |
| slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates, and when the |
| slink:VkPipelineSampleLocationsStateCreateInfoEXT::pname:sampleLocationsEnable |
| property of the bound graphics pipeline is ename:VK_TRUE. |
| Otherwise, this state is specified by the |
| slink:VkPipelineSampleLocationsStateCreateInfoEXT::pname:sampleLocationsInfo |
| values used to create the currently active pipeline. |
| |
| .Valid Usage |
| **** |
| * [[VUID-vkCmdSetSampleLocationsEXT-variableSampleLocations-01530]] |
| If |
| slink:VkPhysicalDeviceSampleLocationsPropertiesEXT::pname:variableSampleLocations |
| is ename:VK_FALSE then the current render pass must: have been begun by |
| specifying a slink:VkRenderPassSampleLocationsBeginInfoEXT structure |
| whose pname:pPostSubpassSampleLocations member contains an element with |
| a pname:subpassIndex matching the current subpass index and the |
| pname:sampleLocationsInfo member of that element must: match the sample |
| locations state pointed to by pname:pSampleLocationsInfo |
| **** |
| |
| include::{generated}/validity/protos/vkCmdSetSampleLocationsEXT.adoc[] |
| -- |
| endif::VK_EXT_sample_locations[] |
| |
| |
| ifdef::VK_KHR_fragment_shading_rate[] |
| [[primsrast-fragment-shading-rate]] |
| == Fragment Shading Rates |
| |
| The features advertised by |
| slink:VkPhysicalDeviceFragmentShadingRateFeaturesKHR allow an application to |
| control the <<glossary-shading-rate, shading rate>> of a given fragment |
| shader invocation. |
| |
| The fragment shading rate strongly interacts with <<primsrast-multisampling, |
| Multisampling>>, and the set of available rates for an implementation may: |
| be restricted by sample rate. |
| |
| [open,refpage='vkGetPhysicalDeviceFragmentShadingRatesKHR',desc='Get available shading rates for a physical device',type='protos'] |
| -- |
| :refpage: vkGetPhysicalDeviceFragmentShadingRatesKHR |
| |
| To query available shading rates, call: |
| |
| include::{generated}/api/protos/vkGetPhysicalDeviceFragmentShadingRatesKHR.adoc[] |
| |
| * pname:physicalDevice is the handle to the physical device whose |
| properties will be queried. |
| * pname:pFragmentShadingRateCount is a pointer to an integer related to |
| the number of fragment shading rates available or queried, as described |
| below. |
| * pname:pFragmentShadingRates is either `NULL` or a pointer to an array of |
| slink:VkPhysicalDeviceFragmentShadingRateKHR structures. |
| |
| If pname:pFragmentShadingRates is `NULL`, then the number of fragment |
| shading rates available is returned in pname:pFragmentShadingRateCount. |
| Otherwise, pname:pFragmentShadingRateCount must: point to a variable set by |
| the user to the number of elements in the pname:pFragmentShadingRates array, |
| and on return the variable is overwritten with the number of structures |
| actually written to pname:pFragmentShadingRates. |
| If pname:pFragmentShadingRateCount is less than the number of fragment |
| shading rates available, at most pname:pFragmentShadingRateCount structures |
| will be written, and ename:VK_INCOMPLETE will be returned instead of |
| ename:VK_SUCCESS, to indicate that not all the available fragment shading |
| rates were returned. |
| |
| The returned array of fragment shading rates must: be ordered from largest |
| pname:fragmentSize.width value to smallest, and each set of fragment shading |
| rates with the same pname:fragmentSize.width value must: be ordered from |
| largest pname:fragmentSize.height to smallest. |
| Any two entries in the array must: not have the same pname:fragmentSize |
| values. |
| |
| For any entry in the array, the following rules also apply: |
| |
| * The value of pname:fragmentSize.width must: be less than or equal to |
| <<limits-maxFragmentSize, pname:maxFragmentSize.width>>. |
| * The value of pname:fragmentSize.width must: be greater than or equal to |
| `1`. |
| * The value of pname:fragmentSize.width must: be a power-of-two. |
| * The value of pname:fragmentSize.height must: be less than or equal to |
| <<limits-maxFragmentSize, pname:maxFragmentSize.height>>. |
| * The value of pname:fragmentSize.height must: be greater than or equal to |
| `1`. |
| * The value of pname:fragmentSize.height must: be a power-of-two. |
| * The highest sample count in pname:sampleCounts must: be less than or |
| equal to <<limits-maxFragmentShadingRateRasterizationSamples, |
| pname:maxFragmentShadingRateRasterizationSamples>>. |
| * The product of pname:fragmentSize.width, pname:fragmentSize.height, and |
| the highest sample count in pname:sampleCounts must: be less than or |
| equal to <<limits-maxFragmentShadingRateCoverageSamples, |
| pname:maxFragmentShadingRateCoverageSamples>>. |
| |
| Implementations must: support at least the following shading rates: |
| |
| [options="autowidth"] |
| |=== |
| | pname:sampleCounts | pname:fragmentSize |
| |
| | ename:VK_SAMPLE_COUNT_1_BIT \| ename:VK_SAMPLE_COUNT_4_BIT | {2,2} |
| | ename:VK_SAMPLE_COUNT_1_BIT \| ename:VK_SAMPLE_COUNT_4_BIT | {2,1} |
| | ~0 | {1,1} |
| |=== |
| |
| If <<limits-framebufferColorSampleCounts, |
| pname:framebufferColorSampleCounts>>, includes ename:VK_SAMPLE_COUNT_2_BIT, |
| the required rates must: also include ename:VK_SAMPLE_COUNT_2_BIT. |
| |
| [NOTE] |
| .Note |
| ==== |
| Including the {1,1} fragment size is done for completeness; it has no actual |
| effect on the support of rendering without setting the fragment size. |
| All sample counts |
| ifdef::VK_QCOM_render_pass_transform[] |
| and render pass transforms |
| endif::VK_QCOM_render_pass_transform[] |
| are supported for this rate. |
| ==== |
| |
| ifdef::VK_QCOM_render_pass_transform[] |
| The returned set of fragment shading rates must: be returned in the native |
| (rotated) coordinate system. |
| For rasterization using render pass pname:transform not equal to |
| ename:VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR, the application must: transform |
| the returned fragment shading rates into the current (unrotated) coordinate |
| system to get the supported rates for that transform. |
| |
| [NOTE] |
| .Note |
| ==== |
| For example, consider an implementation returning support for 4x2, but not |
| 2x4 in the set of supported fragment shading rates. |
| This means that for transforms ename:VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR |
| and ename:VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR, 2x4 is a supported rate, |
| but 4x2 is an unsupported rate. |
| ==== |
| endif::VK_QCOM_render_pass_transform[] |
| |
| include::{chapters}/commonvalidity/no_dynamic_allocations_common.adoc[] |
| |
| include::{generated}/validity/protos/vkGetPhysicalDeviceFragmentShadingRatesKHR.adoc[] |
| -- |
| |
| [open,refpage='VkPhysicalDeviceFragmentShadingRateKHR',desc='Structure returning information about sample count specific additional multisampling capabilities',type='structs'] |
| -- |
| The sname:VkPhysicalDeviceFragmentShadingRateKHR structure is defined as |
| |
| include::{generated}/api/structs/VkPhysicalDeviceFragmentShadingRateKHR.adoc[] |
| |
| * pname:sType is a elink:VkStructureType value identifying this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:sampleCounts is a bitmask of sample counts for which the shading |
| rate described by pname:fragmentSize is supported. |
| * pname:fragmentSize is a slink:VkExtent2D describing the width and height |
| of a supported shading rate. |
| |
| include::{generated}/validity/structs/VkPhysicalDeviceFragmentShadingRateKHR.adoc[] |
| -- |
| |
| Fragment shading rates can: be set at three points, with the three rates |
| combined to determine the final shading rate. |
| |
| |
| [[primsrast-fragment-shading-rate-pipeline]] |
| === Pipeline Fragment Shading Rate |
| |
| The _pipeline fragment shading rate_ can: be set on a per-draw basis by |
| either setting the rate in a graphics pipeline, or dynamically via |
| flink:vkCmdSetFragmentShadingRateKHR. |
| |
| [open,refpage='VkPipelineFragmentShadingRateStateCreateInfoKHR',desc='Structure specifying parameters controlling the fragment shading rate',type='structs'] |
| -- |
| The sname:VkPipelineFragmentShadingRateStateCreateInfoKHR structure is |
| defined as: |
| |
| include::{generated}/api/structs/VkPipelineFragmentShadingRateStateCreateInfoKHR.adoc[] |
| |
| * pname:sType is a elink:VkStructureType value identifying this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:fragmentSize specifies a slink:VkExtent2D structure containing the |
| fragment size used to define the pipeline fragment shading rate for |
| drawing commands using this pipeline. |
| * pname:combinerOps specifies a elink:VkFragmentShadingRateCombinerOpKHR |
| value determining how the |
| <<primsrast-fragment-shading-rate-pipeline,pipeline>>, |
| <<primsrast-fragment-shading-rate-primitive,primitive>>, and |
| <<primsrast-fragment-shading-rate-attachment,attachment shading rates>> |
| are <<primsrast-fragment-shading-rate-combining,combined>> for fragments |
| generated by drawing commands using the created pipeline. |
| |
| If the pname:pNext chain of slink:VkGraphicsPipelineCreateInfo includes a |
| sname:VkPipelineFragmentShadingRateStateCreateInfoKHR structure, then that |
| structure includes parameters controlling the pipeline fragment shading |
| rate. |
| |
| If this structure is not present, pname:fragmentSize is considered to be |
| equal to [eq]#(1,1)#, and both elements of pname:combinerOps are considered |
| to be equal to ename:VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR. |
| |
| include::{generated}/validity/structs/VkPipelineFragmentShadingRateStateCreateInfoKHR.adoc[] |
| -- |
| |
| [open,refpage='vkCmdSetFragmentShadingRateKHR',desc='Set pipeline fragment shading rate and combiner operation dynamically for a command buffer',type='protos'] |
| -- |
| To <<pipelines-dynamic-state, dynamically set>> the pipeline fragment |
| shading rate and combiner operation, call: |
| |
| include::{generated}/api/protos/vkCmdSetFragmentShadingRateKHR.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command will be |
| recorded. |
| * pname:pFragmentSize specifies the pipeline fragment shading rate for |
| subsequent drawing commands. |
| * pname:combinerOps specifies a elink:VkFragmentShadingRateCombinerOpKHR |
| determining how the |
| <<primsrast-fragment-shading-rate-pipeline,pipeline>>, |
| <<primsrast-fragment-shading-rate-primitive,primitive>>, and |
| <<primsrast-fragment-shading-rate-attachment,attachment shading rates>> |
| are <<primsrast-fragment-shading-rate-combining,combined>> for fragments |
| generated by subsequent drawing commands. |
| |
| This command sets the pipeline fragment shading rate and combiner operation |
| for subsequent drawing commands |
| ifdef::VK_EXT_shader_object[when drawing using <<shaders-objects, shader objects>>, or] |
| when the graphics pipeline is created with |
| ename:VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR set in |
| slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates. |
| Otherwise, this state is specified by the |
| slink:VkPipelineFragmentShadingRateStateCreateInfoKHR values used to create |
| the currently active pipeline. |
| |
| .Valid Usage |
| **** |
| * [[VUID-vkCmdSetFragmentShadingRateKHR-pipelineFragmentShadingRate-04507]] |
| If <<features-pipelineFragmentShadingRate, |
| pname:pipelineFragmentShadingRate>> is not enabled, |
| pname:pFragmentSize->width must: be `1` |
| * [[VUID-vkCmdSetFragmentShadingRateKHR-pipelineFragmentShadingRate-04508]] |
| If <<features-pipelineFragmentShadingRate, |
| pname:pipelineFragmentShadingRate>> is not enabled, |
| pname:pFragmentSize->height must: be `1` |
| * [[VUID-vkCmdSetFragmentShadingRateKHR-pipelineFragmentShadingRate-04509]] |
| One of <<features-pipelineFragmentShadingRate, |
| pname:pipelineFragmentShadingRate>>, |
| <<features-primitiveFragmentShadingRate, |
| pname:primitiveFragmentShadingRate>>, or |
| <<features-attachmentFragmentShadingRate, |
| pname:attachmentFragmentShadingRate>> must: be enabled |
| * [[VUID-vkCmdSetFragmentShadingRateKHR-primitiveFragmentShadingRate-04510]] |
| If the <<features-primitiveFragmentShadingRate, |
| pname:primitiveFragmentShadingRate>> feature is not enabled, |
| pname:combinerOps[0] must: be |
| ename:VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR |
| * [[VUID-vkCmdSetFragmentShadingRateKHR-attachmentFragmentShadingRate-04511]] |
| If the <<features-attachmentFragmentShadingRate, |
| pname:attachmentFragmentShadingRate>> feature is not enabled, |
| pname:combinerOps[1] must: be |
| ename:VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR |
| * [[VUID-vkCmdSetFragmentShadingRateKHR-fragmentSizeNonTrivialCombinerOps-04512]] |
| If the <<limits-fragmentShadingRateNonTrivialCombinerOps, |
| pname:fragmentSizeNonTrivialCombinerOps>> limit is not supported, |
| elements of pname:combinerOps must: be either |
| ename:VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR or |
| ename:VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR |
| * [[VUID-vkCmdSetFragmentShadingRateKHR-pFragmentSize-04513]] |
| pname:pFragmentSize->width must: be greater than or equal to `1` |
| * [[VUID-vkCmdSetFragmentShadingRateKHR-pFragmentSize-04514]] |
| pname:pFragmentSize->height must: be greater than or equal to `1` |
| * [[VUID-vkCmdSetFragmentShadingRateKHR-pFragmentSize-04515]] |
| pname:pFragmentSize->width must: be a power-of-two value |
| * [[VUID-vkCmdSetFragmentShadingRateKHR-pFragmentSize-04516]] |
| pname:pFragmentSize->height must: be a power-of-two value |
| * [[VUID-vkCmdSetFragmentShadingRateKHR-pFragmentSize-04517]] |
| pname:pFragmentSize->width must: be less than or equal to `4` |
| * [[VUID-vkCmdSetFragmentShadingRateKHR-pFragmentSize-04518]] |
| pname:pFragmentSize->height must: be less than or equal to `4` |
| **** |
| |
| include::{generated}/validity/protos/vkCmdSetFragmentShadingRateKHR.adoc[] |
| -- |
| |
| |
| [[primsrast-fragment-shading-rate-primitive]] |
| === Primitive Fragment Shading Rate |
| |
| The _primitive fragment shading rate_ can: be set via the |
| <<interfaces-builtin-variables-primitiveshadingrate, |
| code:PrimitiveShadingRateKHR>> built-in in the last active |
| <<pipelines-graphics-subsets-pre-rasterization,pre-rasterization shader |
| stage>>. |
| ifdef::VK_EXT_mesh_shader[] |
| If the last <<pipelines-graphics-subsets-pre-rasterization,pre-rasterization |
| shader stage>> is using the code:MeshEXT {ExecutionModel}, the rate |
| associated with a given primitive is sourced from the value written to the |
| per-primitive code:PrimitiveShadingRateKHR. |
| Otherwise the |
| endif::VK_EXT_mesh_shader[] |
| ifndef::VK_EXT_mesh_shader[The] |
| rate associated with a given primitive is sourced from the value written to |
| code:PrimitiveShadingRateKHR by that primitive's |
| <<vertexpostproc-flatshading,provoking vertex>>. |
| |
| |
| [[primsrast-fragment-shading-rate-attachment]] |
| === Attachment Fragment Shading Rate |
| |
| The _attachment shading rate_ can: be set by including |
| slink:VkFragmentShadingRateAttachmentInfoKHR in a subpass to define a |
| _fragment shading rate attachment_. |
| Each pixel in the framebuffer is assigned an attachment fragment shading |
| rate by the corresponding texel in the fragment shading rate attachment, |
| according to: |
| |
| {empty}:: [eq]#x' = floor(x / region~x~)# |
| {empty}:: [eq]#y' = floor(y / region~y~)# |
| |
| where [eq]#x'# and [eq]#y'# are the coordinates of a texel in the fragment |
| shading rate attachment, [eq]#x# and [eq]#y# are the coordinates of the |
| pixel in the framebuffer, and [eq]#region~x~# and [eq]#region~y~# are the |
| size of the region each texel corresponds to, as defined by the |
| pname:shadingRateAttachmentTexelSize member of |
| slink:VkFragmentShadingRateAttachmentInfoKHR. |
| |
| If <<VkRenderPassMultiviewCreateInfo, multiview is enabled>> and the shading |
| rate attachment has multiple layers, the shading rate attachment texel is |
| selected from the layer determined by the |
| <<interfaces-builtin-variables-viewindex,code:ViewIndex>> built-in. |
| If <<VkRenderPassMultiviewCreateInfo, multiview is disabled>>, and both the |
| shading rate attachment and the framebuffer have multiple layers, the |
| shading rate attachment texel is selected from the layer determined by the |
| <<interfaces-builtin-variables-layer,code:Layer>> built-in. |
| Otherwise, the texel is unconditionally selected from the first layer of the |
| attachment. |
| |
| The fragment size is encoded into the first component of the identified |
| texel as follows: |
| |
| {empty}:: [eq]#size~w~ = 2^((texel / 4) & 3)^# |
| {empty}:: [eq]#size~h~ = 2^(texel & 3)^# |
| |
| where [eq]#texel# is the value in the first component of the identified |
| texel, and [eq]#size~w~# and [eq]#size~h~# are the width and height of the |
| fragment size, decoded from the texel. |
| |
| If no fragment shading rate attachment is specified, this size is calculated |
| as [eq]#size~w~ = size~h~ = 1#. |
| Applications must: not specify a width or height greater than 4 by this |
| method. |
| |
| The _Fragment Shading Rate_ enumeration in SPIR-V adheres to the above |
| encoding. |
| |
| |
| [[primsrast-fragment-shading-rate-combining]] |
| === Combining the Fragment Shading Rates |
| |
| The final rate ([eq]#C~xy~'#) used for fragment shading must: be one of the |
| rates returned by flink:vkGetPhysicalDeviceFragmentShadingRatesKHR for the |
| sample count |
| ifdef::VK_QCOM_render_pass_transform[] |
| and render pass transform |
| endif::VK_QCOM_render_pass_transform[] |
| used by rasterization. |
| |
| If any of the following conditions are met, [eq]#C~xy~'# must: be set to |
| [eq]#{1,1}#: |
| |
| * If <<primsrast-sampleshading,Sample Shading>> is enabled. |
| * The <<limits-fragmentShadingRateWithSampleMask, |
| pname:fragmentShadingRateWithSampleMask>> limit is not supported, and |
| slink:VkPipelineMultisampleStateCreateInfo::pname:pSampleMask contains a |
| zero value in any bit used by fragment operations. |
| * The <<limits-fragmentShadingRateWithShaderSampleMask, |
| pname:fragmentShadingRateWithShaderSampleMask>> is not supported, and |
| the fragment shader has code:SampleMask in the input or output |
| interface. |
| * The <<limits-fragmentShadingRateWithShaderDepthStencilWrites, |
| pname:fragmentShadingRateWithShaderDepthStencilWrites>> limit is not |
| supported, and the fragment shader declares the code:FragDepth |
| ifdef::VK_EXT_shader_stencil_export[] |
| or code:FragStencilRefEXT |
| endif::VK_EXT_shader_stencil_export[] |
| built-in. |
| ifdef::VK_EXT_conservative_rasterization[] |
| * The <<limits-fragmentShadingRateWithConservativeRasterization, |
| pname:fragmentShadingRateWithConservativeRasterization>> limit is not |
| supported, and |
| slink:VkPipelineRasterizationConservativeStateCreateInfoEXT::pname:conservativeRasterizationMode |
| is not ename:VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT. |
| endif::VK_EXT_conservative_rasterization[] |
| ifdef::VK_EXT_fragment_shader_interlock[] |
| * The <<limits-fragmentShadingRateWithFragmentShaderInterlock, |
| pname:fragmentShadingRateWithFragmentShaderInterlock>> limit is not |
| supported, and the fragment shader declares any of the |
| <<fragops-shader-interlock, fragment shader interlock>> execution modes. |
| endif::VK_EXT_fragment_shader_interlock[] |
| ifdef::VK_EXT_sample_locations[] |
| * The <<limits-fragmentShadingRateWithCustomSampleLocations, |
| pname:fragmentShadingRateWithCustomSampleLocations>> limit is not |
| supported, and |
| slink:VkPipelineSampleLocationsStateCreateInfoEXT::pname:sampleLocationsEnable |
| is ename:VK_TRUE. |
| endif::VK_EXT_sample_locations[] |
| ifdef::VK_EXT_shader_tile_image[] |
| * The fragment shader declares any of the |
| code:TileImageColorReadAccessEXT, code:TileImageDepthReadAccessEXT, or |
| code:TileImageStencilReadAccessEXT capabilities. |
| endif::VK_EXT_shader_tile_image[] |
| |
| Otherwise, each of the specified shading rates are combined and then used to |
| derive the value of [eq]#C~xy~'#. |
| As there are three ways to specify shading rates, two combiner operations |
| are specified - between the |
| <<primsrast-fragment-shading-rate-pipeline,pipeline>> and |
| <<primsrast-fragment-shading-rate-primitive,primitive>> shading rates, and |
| between the result of that and the |
| <<primsrast-fragment-shading-rate-attachment,attachment shading rate>>. |
| |
| [open,refpage='VkFragmentShadingRateCombinerOpKHR',desc='Control how fragment shading rates are combined',type='enums'] |
| -- |
| The equation used for each combiner operation is defined by |
| ename:VkFragmentShadingRateCombinerOpKHR: |
| |
| include::{generated}/api/enums/VkFragmentShadingRateCombinerOpKHR.adoc[] |
| |
| * ename:VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR specifies a combiner |
| operation of [eq]#combine(A~xy~,B~xy~) = A~xy~#. |
| * ename:VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR specifies a |
| combiner operation of [eq]#combine(A~xy~,B~xy~) = B~xy~#. |
| * ename:VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MIN_KHR specifies a combiner |
| operation of [eq]#combine(A~xy~,B~xy~) = min(A~xy~,B~xy~)#. |
| * ename:VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_KHR specifies a combiner |
| operation of [eq]#combine(A~xy~,B~xy~) = max(A~xy~,B~xy~)#. |
| * ename:VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_KHR specifies a combiner |
| operation of [eq]#combine(A~xy~,B~xy~) = A~xy~*B~xy~#. |
| |
| where [eq]#combine(A~xy~,B~xy~)# is the combine operation, and [eq]#A~xy~# |
| and [eq]#B~xy~# are the inputs to the operation. |
| |
| If <<limits-fragmentShadingRateStrictMultiplyCombiner, |
| pname:fragmentShadingRateStrictMultiplyCombiner>> is ename:VK_FALSE, using |
| ename:VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_KHR with values of 1 for both |
| A and B in the same dimension results in the value 2 being produced for that |
| dimension. |
| See the definition of <<limits-fragmentShadingRateStrictMultiplyCombiner, |
| pname:fragmentShadingRateStrictMultiplyCombiner>> for more information. |
| |
| These operations are performed in a component-wise fashion. |
| -- |
| |
| This is used to generate a combined fragment area using the equation: |
| |
| {empty}:: [eq]#C~xy~ = combine(A~xy~,B~xy~)# |
| |
| where [eq]#C~xy~# is the combined fragment area result, and [eq]#A~xy~# and |
| [eq]#B~xy~# are the fragment areas of the fragment shading rates being |
| combined. |
| |
| Two combine operations are performed, first with [eq]#A~xy~# equal to the |
| <<primsrast-fragment-shading-rate-pipeline,pipeline fragment shading rate>> |
| and [eq]#B~xy~# equal to the <<primsrast-fragment-shading-rate-primitive, |
| primitive fragment shading rate>>, with the [eq]#combine()# operation |
| selected by combinerOps[0]. |
| A second combination is then performed, with [eq]#A~xy~# equal to the result |
| of the first combination and [eq]#B~xy~# equal to the |
| <<primsrast-fragment-shading-rate-attachment, attachment fragment shading |
| rate>>, with the [eq]#combine()# operation selected by combinerOps[1]. |
| The result of the second combination is used as the final fragment shading |
| rate, reported via the <<interfaces-builtin-variables-primitiveshadingrate, |
| code:ShadingRateKHR built-in>>. |
| |
| Implementations should: clamp the inputs to the combiner operations |
| [eq]#A~xy~# and [eq]#B~xy~#, and must: clamp the result of the second |
| combiner operation. |
| |
| A fragment shading rate [eq]#R~xy~# representing any of [eq]#A~xy~#, |
| [eq]#B~xy~# or [eq]#C~xy~# is clamped as follows. |
| If [eq]#R~xy~# is one of the rates returned by |
| flink:vkGetPhysicalDeviceFragmentShadingRatesKHR for the sample count |
| ifdef::VK_QCOM_render_pass_transform[] |
| and render pass transform |
| endif::VK_QCOM_render_pass_transform[] |
| used by rasterization, the clamped shading rate [eq]#R~xy~'# is [eq]#R~xy~#. |
| Otherwise, the clamped shading rate is selected from the rates returned by |
| flink:vkGetPhysicalDeviceFragmentShadingRatesKHR for the sample count |
| ifdef::VK_QCOM_render_pass_transform[] |
| and render pass transform |
| endif::VK_QCOM_render_pass_transform[] |
| used by rasterization. |
| From this list of supported rates, the following steps are applied in order, |
| to select a single value: |
| |
| . Keep only rates where [eq]#R~x~' {leq} R~x~# and [eq]#R~y~' {leq} R~y~#. |
| ** Implementations may: also keep rates where [eq]#R~x~' {leq} R~y~# and |
| [eq]#R~y~' {leq} R~x~#. |
| . Keep only rates with the highest area ([eq]#R~x~' {times} R~y~'#). |
| . Keep only rates with the lowest aspect ratio ([eq]#R~x~' {plus} R~y~'#). |
| . In cases where a wide (e.g. 4x1) and tall (e.g. 1x4) rate remain, the |
| implementation may: choose either rate. |
| However, it must: choose this rate consistently for the same shading |
| rates, |
| ifdef::VK_QCOM_render_pass_transform[] |
| render pass transform, |
| endif::VK_QCOM_render_pass_transform[] |
| and combiner operations for the lifetime of the slink:VkDevice. |
| endif::VK_KHR_fragment_shading_rate[] |
| |
| |
| ifdef::VK_NV_fragment_shading_rate_enums[] |
| === Extended Fragment Shading Rates |
| |
| The features advertised by |
| slink:VkPhysicalDeviceFragmentShadingRateEnumsFeaturesNV provide support for |
| additional fragment shading rates beyond those specifying one fragment |
| shader invocation covering all pixels in a fragment whose size is indicated |
| by the fragment shading rate. |
| |
| [open,refpage='VkFragmentShadingRateNV',desc='Enumeration with fragment shading rates',type='enums'] |
| -- |
| If the pname:fragmentShadingRateEnums feature is enabled, fragment shading |
| rates may be specified using the elink:VkFragmentShadingRateNV enumerated |
| type defined as: |
| |
| include::{generated}/api/enums/VkFragmentShadingRateNV.adoc[] |
| |
| * ename:VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_PIXEL_NV specifies a |
| fragment size of 1x1 pixels. |
| * ename:VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_1X2_PIXELS_NV specifies |
| a fragment size of 1x2 pixels. |
| * ename:VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_2X1_PIXELS_NV specifies |
| a fragment size of 2x1 pixels. |
| * ename:VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_2X2_PIXELS_NV specifies |
| a fragment size of 2x2 pixels. |
| * ename:VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_2X4_PIXELS_NV specifies |
| a fragment size of 2x4 pixels. |
| * ename:VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_4X2_PIXELS_NV specifies |
| a fragment size of 4x2 pixels. |
| * ename:VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_4X4_PIXELS_NV specifies |
| a fragment size of 4x4 pixels. |
| * ename:VK_FRAGMENT_SHADING_RATE_2_INVOCATIONS_PER_PIXEL_NV specifies a |
| fragment size of 1x1 pixels, with two fragment shader invocations per |
| fragment. |
| * ename:VK_FRAGMENT_SHADING_RATE_4_INVOCATIONS_PER_PIXEL_NV specifies a |
| fragment size of 1x1 pixels, with four fragment shader invocations per |
| fragment. |
| * ename:VK_FRAGMENT_SHADING_RATE_8_INVOCATIONS_PER_PIXEL_NV specifies a |
| fragment size of 1x1 pixels, with eight fragment shader invocations per |
| fragment. |
| * ename:VK_FRAGMENT_SHADING_RATE_16_INVOCATIONS_PER_PIXEL_NV specifies a |
| fragment size of 1x1 pixels, with sixteen fragment shader invocations |
| per fragment. |
| * ename:VK_FRAGMENT_SHADING_RATE_NO_INVOCATIONS_NV specifies that any |
| portions of a primitive that use that shading rate should be discarded |
| without invoking any fragment shader. |
| |
| To use the shading rates |
| ename:VK_FRAGMENT_SHADING_RATE_2_INVOCATIONS_PER_PIXEL_NV, |
| ename:VK_FRAGMENT_SHADING_RATE_4_INVOCATIONS_PER_PIXEL_NV, |
| ename:VK_FRAGMENT_SHADING_RATE_8_INVOCATIONS_PER_PIXEL_NV, and |
| ename:VK_FRAGMENT_SHADING_RATE_16_INVOCATIONS_PER_PIXEL_NV as a pipeline, |
| primitive, or attachment shading rate, the |
| pname:supersampleFragmentShadingRates feature must: be enabled. |
| To use the shading rate ename:VK_FRAGMENT_SHADING_RATE_NO_INVOCATIONS_NV as |
| a pipeline, primitive, or attachment shading rate, the |
| pname:noInvocationFragmentShadingRates feature must: be enabled. |
| -- |
| |
| When using fragment shading rate enums, the pipeline fragment shading rate |
| can: be set on a per-draw basis by either setting the rate in a graphics |
| pipeline, or dynamically via flink:vkCmdSetFragmentShadingRateEnumNV. |
| |
| [open,refpage='VkPipelineFragmentShadingRateEnumStateCreateInfoNV',desc='Structure specifying parameters controlling the fragment shading rate using rate enums',type='structs'] |
| -- |
| The sname:VkPipelineFragmentShadingRateEnumStateCreateInfoNV structure is |
| defined as: |
| |
| include::{generated}/api/structs/VkPipelineFragmentShadingRateEnumStateCreateInfoNV.adoc[] |
| |
| * pname:sType is a elink:VkStructureType value identifying this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:shadingRateType specifies a elink:VkFragmentShadingRateTypeNV |
| value indicating whether fragment shading rates are specified using |
| fragment sizes or elink:VkFragmentShadingRateNV enums. |
| * pname:shadingRate specifies a elink:VkFragmentShadingRateNV value |
| indicating the pipeline fragment shading rate. |
| * pname:combinerOps specifies elink:VkFragmentShadingRateCombinerOpKHR |
| values determining how the |
| <<primsrast-fragment-shading-rate-pipeline,pipeline>>, |
| <<primsrast-fragment-shading-rate-primitive,primitive>>, and |
| <<primsrast-fragment-shading-rate-attachment,attachment shading rates>> |
| are <<primsrast-fragment-shading-rate-combining,combined>> for fragments |
| generated by drawing commands using the created pipeline. |
| |
| If the pname:pNext chain of slink:VkGraphicsPipelineCreateInfo includes a |
| sname:VkPipelineFragmentShadingRateEnumStateCreateInfoNV structure, then |
| that structure includes parameters controlling the pipeline fragment shading |
| rate. |
| |
| If this structure is not present, pname:shadingRateType is considered to be |
| equal to ename:VK_FRAGMENT_SHADING_RATE_TYPE_FRAGMENT_SIZE_NV, |
| pname:shadingRate is considered to be equal to |
| ename:VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_PIXEL_NV, and both elements |
| of pname:combinerOps are considered to be equal to |
| ename:VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR. |
| |
| include::{generated}/validity/structs/VkPipelineFragmentShadingRateEnumStateCreateInfoNV.adoc[] |
| -- |
| |
| [open,refpage='VkFragmentShadingRateTypeNV',desc='Enumeration with fragment shading rate types',type='enums'] |
| -- |
| The elink:VkFragmentShadingRateTypeNV enumerated type specifies whether a |
| graphics pipeline gets its pipeline fragment shading rates and combiners |
| from the slink:VkPipelineFragmentShadingRateEnumStateCreateInfoNV structure |
| or the slink:VkPipelineFragmentShadingRateStateCreateInfoKHR structure. |
| |
| include::{generated}/api/enums/VkFragmentShadingRateTypeNV.adoc[] |
| |
| * ename:VK_FRAGMENT_SHADING_RATE_TYPE_FRAGMENT_SIZE_NV specifies that a |
| graphics pipeline should obtain its pipeline fragment shading rate and |
| shading rate combiner state from the |
| slink:VkPipelineFragmentShadingRateStateCreateInfoKHR structure and that |
| any state specified by the |
| slink:VkPipelineFragmentShadingRateEnumStateCreateInfoNV structure |
| should be ignored. |
| * ename:VK_FRAGMENT_SHADING_RATE_TYPE_ENUMS_NV specifies that a graphics |
| pipeline should obtain its pipeline fragment shading rate and shading |
| rate combiner state from the |
| slink:VkPipelineFragmentShadingRateEnumStateCreateInfoNV structure and |
| that any state specified by the |
| slink:VkPipelineFragmentShadingRateStateCreateInfoKHR structure should |
| be ignored. |
| -- |
| |
| [open,refpage='vkCmdSetFragmentShadingRateEnumNV',desc='Set pipeline fragment shading rate dynamically for a command buffer using enums',type='protos'] |
| -- |
| To <<pipelines-dynamic-state, dynamically set>> the pipeline fragment |
| shading rate and combiner operation, call: |
| |
| include::{generated}/api/protos/vkCmdSetFragmentShadingRateEnumNV.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command will be |
| recorded. |
| * pname:shadingRate specifies a elink:VkFragmentShadingRateNV enum |
| indicating the pipeline fragment shading rate for subsequent drawing |
| commands. |
| * pname:combinerOps specifies a elink:VkFragmentShadingRateCombinerOpKHR |
| determining how the |
| <<primsrast-fragment-shading-rate-pipeline,pipeline>>, |
| <<primsrast-fragment-shading-rate-primitive,primitive>>, and |
| <<primsrast-fragment-shading-rate-attachment,attachment shading rates>> |
| are <<primsrast-fragment-shading-rate-combining,combined>> for fragments |
| generated by subsequent drawing commands. |
| |
| This command sets the pipeline fragment shading rate and combiner operation |
| for subsequent drawing commands |
| ifdef::VK_EXT_shader_object[when drawing using <<shaders-objects, shader objects>>, or] |
| when the graphics pipeline is created with |
| ename:VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR set in |
| slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates. |
| Otherwise, this state is specified by the |
| slink:VkPipelineFragmentShadingRateEnumStateCreateInfoNV values used to |
| create the currently active pipeline. |
| |
| [NOTE] |
| .Note |
| ==== |
| This command allows specifying additional shading rates beyond those |
| supported by flink:vkCmdSetFragmentShadingRateKHR. |
| For more information, refer to the |
| `apiext:VK_NV_fragment_shading_rate_enums` appendix. |
| ==== |
| |
| .Valid Usage |
| **** |
| * [[VUID-vkCmdSetFragmentShadingRateEnumNV-pipelineFragmentShadingRate-04576]] |
| If <<features-pipelineFragmentShadingRate, |
| pname:pipelineFragmentShadingRate>> is not enabled, pname:shadingRate |
| must: be ename:VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_PIXEL_NV |
| * [[VUID-vkCmdSetFragmentShadingRateEnumNV-supersampleFragmentShadingRates-04577]] |
| If <<features-supersampleFragmentShadingRates, |
| pname:supersampleFragmentShadingRates>> is not enabled, |
| pname:shadingRate must: not be |
| ename:VK_FRAGMENT_SHADING_RATE_2_INVOCATIONS_PER_PIXEL_NV, |
| ename:VK_FRAGMENT_SHADING_RATE_4_INVOCATIONS_PER_PIXEL_NV, |
| ename:VK_FRAGMENT_SHADING_RATE_8_INVOCATIONS_PER_PIXEL_NV, or |
| ename:VK_FRAGMENT_SHADING_RATE_16_INVOCATIONS_PER_PIXEL_NV |
| * [[VUID-vkCmdSetFragmentShadingRateEnumNV-noInvocationFragmentShadingRates-04578]] |
| If <<features-noInvocationFragmentShadingRates, |
| pname:noInvocationFragmentShadingRates>> is not enabled, |
| pname:shadingRate must: not be |
| ename:VK_FRAGMENT_SHADING_RATE_NO_INVOCATIONS_NV |
| * [[VUID-vkCmdSetFragmentShadingRateEnumNV-fragmentShadingRateEnums-04579]] |
| The <<features-fragmentShadingRateEnums, |
| pname:fragmentShadingRateEnums>> feature must: be enabled |
| * [[VUID-vkCmdSetFragmentShadingRateEnumNV-pipelineFragmentShadingRate-04580]] |
| One of the <<features-pipelineFragmentShadingRate, |
| pname:pipelineFragmentShadingRate>>, |
| <<features-primitiveFragmentShadingRate, |
| pname:primitiveFragmentShadingRate>>, or |
| <<features-attachmentFragmentShadingRate, |
| pname:attachmentFragmentShadingRate>> features must: be enabled |
| * [[VUID-vkCmdSetFragmentShadingRateEnumNV-primitiveFragmentShadingRate-04581]] |
| If the <<features-primitiveFragmentShadingRate, |
| pname:primitiveFragmentShadingRate>> feature is not enabled, |
| pname:combinerOps[0] must: be |
| ename:VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR |
| * [[VUID-vkCmdSetFragmentShadingRateEnumNV-attachmentFragmentShadingRate-04582]] |
| If the <<features-attachmentFragmentShadingRate, |
| pname:attachmentFragmentShadingRate>> feature is not enabled, |
| pname:combinerOps[1] must: be |
| ename:VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR |
| * [[VUID-vkCmdSetFragmentShadingRateEnumNV-fragmentSizeNonTrivialCombinerOps-04583]] |
| If the <<limits-fragmentShadingRateNonTrivialCombinerOps, |
| pname:fragmentSizeNonTrivialCombinerOps>> limit is not supported, |
| elements of pname:combinerOps must: be either |
| ename:VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR or |
| ename:VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR |
| **** |
| |
| include::{generated}/validity/protos/vkCmdSetFragmentShadingRateEnumNV.adoc[] |
| -- |
| |
| When the <<features-supersampleFragmentShadingRates, |
| pname:supersampleFragmentShadingRates>> or |
| <<features-noInvocationFragmentShadingRates, |
| pname:noInvocationFragmentShadingRates>> features are enabled, the behavior |
| of the <<primsrast-fragment-shading-rate-combining,shading rate combiner |
| operations>> is extended to support the shading rates enabled by those |
| features. |
| Primitive and attachment shading rate values are interpreted as |
| elink:VkFragmentShadingRateNV values and the behavior of the combiners is |
| modified as follows: |
| |
| * For ename:VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MIN_KHR, |
| ename:VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_KHR, and |
| ename:VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_KHR, if either |
| [eq]#A~xy~# or [eq]#B~xy~# is |
| ename:VK_FRAGMENT_SHADING_RATE_NO_INVOCATIONS_NV, |
| [eq]#combine(A~xy~,B~xy~)# produces a shading rate of |
| ename:VK_FRAGMENT_SHADING_RATE_NO_INVOCATIONS_NV, regardless of the |
| other input shading rate. |
| * For ename:VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MIN_KHR, |
| [eq]#combine(A~xy~,B~xy~)# produces a shading rate whose fragment size |
| is the smaller of the fragment sizes of [eq]#A~xy~# and [eq]#B~xy~# and |
| whose invocation count is the larger of the invocation counts of |
| [eq]#A~xy~# and [eq]#B~xy~#. |
| * For ename:VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_KHR, |
| [eq]#combine(A~xy~,B~xy~)# produces a shading rate whose fragment size |
| is the larger of the fragment sizes of [eq]#A~xy~# and [eq]#B~xy~# and |
| whose invocation count is the smaller of the invocation counts of |
| [eq]#A~xy~# and [eq]#B~xy~#. |
| * For ename:VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_KHR, |
| [eq]#combine(A~xy~,B~xy~)# produces a shading rate whose fragment size |
| and invocation count is the product of the fragment sizes and invocation |
| counts, respectively, of [eq]#A~xy~# and [eq]#B~xy~#. |
| If the resulting shading rate has both multiple pixels and multiple |
| invocations per fragment, an implementation may: adjust the shading rate |
| by reducing both the pixel and invocation counts. |
| |
| If the final shading rate from the combiners is |
| ename:VK_FRAGMENT_SHADING_RATE_NO_INVOCATIONS_NV, no fragments will be |
| generated for any portion of a primitive using that shading rate. |
| |
| If the final shading rate from the combiners specifies multiple fragment |
| shader invocations per fragment, the fragment will be processed with |
| multiple unique samples as in <<primsrast-sampleshading, sample shading>>, |
| where the total number the total number of invocations is taken from the |
| shading rate and then clamped to pname:rasterizationSamples and |
| <<limits-maxFragmentShadingRateInvocationCount, |
| pname:maxFragmentShadingRateInvocationCount>>. |
| |
| endif::VK_NV_fragment_shading_rate_enums[] |
| |
| |
| ifdef::VK_NV_shading_rate_image[] |
| [[primsrast-shading-rate-image]] |
| == Shading Rate Image |
| |
| The <<features-shadingRateImage, pname:shadingRateImage>> feature allows |
| pipelines to use a <<glossary-shading-rate-image,shading rate image>> to |
| control the <<glossary-fragment-area, fragment area>> and the minimum number |
| of fragment shader invocations launched for each fragment. |
| When the shading rate image is enabled, the rasterizer determines a base |
| <<glossary-shading-rate,shading rate>> for each region of the framebuffer |
| covered by a primitive by fetching a value from the shading rate image and |
| translating it to a shading rate using a per-viewport shading rate palette. |
| This base shading rate is then adjusted to derive a final shading rate. |
| The final shading rate specifies the fragment area and fragment shader |
| invocation count to use for fragments generated in the region. |
| |
| [open,refpage='VkPipelineViewportShadingRateImageStateCreateInfoNV',desc='Structure specifying parameters controlling shading rate image usage',type='structs'] |
| -- |
| If the pname:pNext chain of slink:VkPipelineViewportStateCreateInfo includes |
| a sname:VkPipelineViewportShadingRateImageStateCreateInfoNV structure, then |
| that structure includes parameters controlling the shading rate. |
| |
| The sname:VkPipelineViewportShadingRateImageStateCreateInfoNV structure is |
| defined as: |
| |
| include::{generated}/api/structs/VkPipelineViewportShadingRateImageStateCreateInfoNV.adoc[] |
| |
| * pname:sType is a elink:VkStructureType value identifying this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:shadingRateImageEnable specifies whether shading rate image and |
| palettes are used during rasterization. |
| * pname:viewportCount specifies the number of per-viewport palettes used |
| to translate values stored in shading rate images. |
| * pname:pShadingRatePalettes is a pointer to an array of |
| slink:VkShadingRatePaletteNV structures defining the palette for each |
| viewport. |
| If the shading rate palette state is dynamic, this member is ignored. |
| |
| If this structure is not present, pname:shadingRateImageEnable is considered |
| to be ename:VK_FALSE, and the shading rate image and palettes are not used. |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkPipelineViewportShadingRateImageStateCreateInfoNV-viewportCount-02054]] |
| If the <<features-multiViewport, pname:multiViewport>> feature is not |
| enabled, pname:viewportCount must: be `0` or `1` |
| * [[VUID-VkPipelineViewportShadingRateImageStateCreateInfoNV-viewportCount-02055]] |
| pname:viewportCount must: be less than or equal to |
| sname:VkPhysicalDeviceLimits::pname:maxViewports |
| * [[VUID-VkPipelineViewportShadingRateImageStateCreateInfoNV-shadingRateImageEnable-02056]] |
| If pname:shadingRateImageEnable is ename:VK_TRUE, pname:viewportCount |
| must: be greater or equal to the pname:viewportCount member of |
| slink:VkPipelineViewportStateCreateInfo |
| **** |
| include::{generated}/validity/structs/VkPipelineViewportShadingRateImageStateCreateInfoNV.adoc[] |
| -- |
| |
| [open,refpage='vkCmdBindShadingRateImageNV',desc='Bind a shading rate image on a command buffer',type='protos'] |
| -- |
| When shading rate image usage is enabled in the bound pipeline, the pipeline |
| uses a shading rate image specified by the command: |
| |
| include::{generated}/api/protos/vkCmdBindShadingRateImageNV.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command will be |
| recorded. |
| * pname:imageView is an image view handle specifying the shading rate |
| image. |
| pname:imageView may: be set to dlink:VK_NULL_HANDLE, which is equivalent |
| to specifying a view of an image filled with zero values. |
| * pname:imageLayout is the layout that the image subresources accessible |
| from pname:imageView will be in when the shading rate image is accessed. |
| |
| .Valid Usage |
| **** |
| * [[VUID-vkCmdBindShadingRateImageNV-None-02058]] |
| The <<features-shadingRateImage, pname:shadingRateImage>> feature must: |
| be enabled |
| * [[VUID-vkCmdBindShadingRateImageNV-imageView-02059]] |
| If pname:imageView is not dlink:VK_NULL_HANDLE, it must: be a valid |
| slink:VkImageView handle of type ename:VK_IMAGE_VIEW_TYPE_2D or |
| ename:VK_IMAGE_VIEW_TYPE_2D_ARRAY |
| * [[VUID-vkCmdBindShadingRateImageNV-imageView-02060]] |
| If pname:imageView is not dlink:VK_NULL_HANDLE, it must: have a format |
| of ename:VK_FORMAT_R8_UINT |
| * [[VUID-vkCmdBindShadingRateImageNV-imageView-02061]] |
| If pname:imageView is not dlink:VK_NULL_HANDLE, it must: have been |
| created with a pname:usage value including |
| ename:VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV |
| * [[VUID-vkCmdBindShadingRateImageNV-imageView-02062]] |
| If pname:imageView is not dlink:VK_NULL_HANDLE, pname:imageLayout must: |
| match the actual elink:VkImageLayout of each subresource accessible from |
| pname:imageView at the time the subresource is accessed |
| * [[VUID-vkCmdBindShadingRateImageNV-imageLayout-02063]] |
| If pname:imageView is not dlink:VK_NULL_HANDLE, pname:imageLayout must: |
| be ename:VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV or |
| ename:VK_IMAGE_LAYOUT_GENERAL |
| **** |
| |
| include::{generated}/validity/protos/vkCmdBindShadingRateImageNV.adoc[] |
| -- |
| |
| When the shading rate image is enabled in the current pipeline, rasterizing |
| a primitive covering the pixel with coordinates (_x_,_y_) will fetch a |
| shading rate index value from the shading rate image bound by |
| fname:vkCmdBindShadingRateImageNV. |
| If the shading rate image view has a type of ename:VK_IMAGE_VIEW_TYPE_2D, |
| the lookup will use texel coordinates (_u_,_v_) where latexmath:[u = |
| \left\lfloor \frac{x}{twidth} \right\rfloor], latexmath:[v = \left\lfloor |
| \frac{y}{theight} \right\rfloor], and latexmath:[twidth] and |
| latexmath:[theight] are the width and height of the implementation-dependent |
| <<limits-shadingRateTexelSize, shading rate texel size>>. |
| If the shading rate image view has a type of |
| ename:VK_IMAGE_VIEW_TYPE_2D_ARRAY, the lookup will use texel coordinates |
| (_u_,_v_) to extract a texel from the layer _l_, where _l_ is the layer of |
| the framebuffer being rendered to. |
| If _l_ is greater than or equal to the number of layers in the image view, |
| layer zero will be used. |
| |
| If the bound shading rate image view is not dlink:VK_NULL_HANDLE and |
| contains a texel with coordinates (_u_,_v_) in layer _l_ (if applicable), |
| the single unsigned integer component for that texel will be used as the |
| shading rate index. |
| If the (_u_,_v_) coordinate is outside the extents of the subresource used |
| by the shading rate image view, or if the image view is |
| dlink:VK_NULL_HANDLE, the shading rate index is zero. |
| If the shading rate image view has multiple mipmap levels, the base level |
| identified by sname:VkImageSubresourceRange::pname:baseMipLevel will be |
| used. |
| |
| A shading rate index is mapped to a base shading rate using a lookup table |
| called the shading rate image palette. |
| There is a separate palette for each viewport. |
| The number of entries in each palette is given by the |
| implementation-dependent <<limits-shadingRatePaletteSize, shading rate image |
| palette size>>. |
| |
| ifdef::VK_EXT_extended_dynamic_state3,VK_EXT_shader_object[] |
| [open,refpage='vkCmdSetShadingRateImageEnableNV',desc='Specify the shading rate image enable state dynamically for a command buffer',type='protos'] |
| -- |
| To <<pipelines-dynamic-state, dynamically set>> the |
| pname:shadingRateImageEnable state, call: |
| |
| include::{generated}/api/protos/vkCmdSetShadingRateImageEnableNV.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command will be |
| recorded. |
| * pname:shadingRateImageEnable specifies the pname:shadingRateImageEnable |
| state. |
| |
| This command sets the pname:shadingRateImageEnable state for subsequent |
| drawing commands |
| ifdef::VK_EXT_shader_object[] |
| ifdef::VK_EXT_extended_dynamic_state3[when drawing using <<shaders-objects, shader objects>>, or] |
| ifndef::VK_EXT_extended_dynamic_state3[when drawing using <<shaders-objects, shader objects>>.] |
| endif::VK_EXT_shader_object[] |
| ifdef::VK_EXT_extended_dynamic_state3[] |
| when the graphics pipeline is created with |
| ename:VK_DYNAMIC_STATE_SHADING_RATE_IMAGE_ENABLE_NV set in |
| slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates. |
| endif::VK_EXT_extended_dynamic_state3[] |
| Otherwise, this state is specified by the |
| slink:VkPipelineViewportShadingRateImageStateCreateInfoNV::pname:shadingRateImageEnable |
| value used to create the currently active pipeline. |
| |
| :refpage: vkCmdSetShadingRateImageEnableNV |
| :requiredfeature: extendedDynamicState3ShadingRateImageEnable |
| |
| .Valid Usage |
| **** |
| include::{chapters}/commonvalidity/dynamic_state3_feature_common.adoc[] |
| **** |
| |
| include::{generated}/validity/protos/vkCmdSetShadingRateImageEnableNV.adoc[] |
| -- |
| endif::VK_EXT_extended_dynamic_state3,VK_EXT_shader_object[] |
| |
| [open,refpage='vkCmdSetViewportShadingRatePaletteNV',desc='Set shading rate image palettes dynamically for a command buffer',type='protos'] |
| -- |
| To <<pipelines-dynamic-state, dynamically set>> the per-viewport shading |
| rate image palettes, call: |
| |
| include::{generated}/api/protos/vkCmdSetViewportShadingRatePaletteNV.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command will be |
| recorded. |
| * pname:firstViewport is the index of the first viewport whose shading |
| rate palette is updated by the command. |
| * pname:viewportCount is the number of viewports whose shading rate |
| palettes are updated by the command. |
| * pname:pShadingRatePalettes is a pointer to an array of |
| slink:VkShadingRatePaletteNV structures defining the palette for each |
| viewport. |
| |
| This command sets the per-viewport shading rate image palettes for |
| subsequent drawing commands |
| ifdef::VK_EXT_shader_object[when drawing using <<shaders-objects, shader objects>>, or] |
| when the graphics pipeline is created with |
| ename:VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV set in |
| slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates. |
| Otherwise, this state is specified by the |
| slink:VkPipelineViewportShadingRateImageStateCreateInfoNV::pname:pShadingRatePalettes |
| values used to create the currently active pipeline. |
| |
| .Valid Usage |
| **** |
| * [[VUID-vkCmdSetViewportShadingRatePaletteNV-None-02064]] |
| The <<features-shadingRateImage, pname:shadingRateImage>> feature must: |
| be enabled |
| * [[VUID-vkCmdSetViewportShadingRatePaletteNV-firstViewport-02067]] |
| The sum of pname:firstViewport and pname:viewportCount must: be between |
| `1` and sname:VkPhysicalDeviceLimits::pname:maxViewports, inclusive |
| * [[VUID-vkCmdSetViewportShadingRatePaletteNV-firstViewport-02068]] |
| If the <<features-multiViewport, pname:multiViewport>> feature is not |
| enabled, pname:firstViewport must: be `0` |
| * [[VUID-vkCmdSetViewportShadingRatePaletteNV-viewportCount-02069]] |
| If the <<features-multiViewport, pname:multiViewport>> feature is not |
| enabled, pname:viewportCount must: be `1` |
| **** |
| |
| include::{generated}/validity/protos/vkCmdSetViewportShadingRatePaletteNV.adoc[] |
| -- |
| |
| [open,refpage='VkShadingRatePaletteNV',desc='Structure specifying a single shading rate palette',type='structs'] |
| -- |
| The sname:VkShadingRatePaletteNV structure specifies to contents of a single |
| shading rate image palette and is defined as: |
| |
| include::{generated}/api/structs/VkShadingRatePaletteNV.adoc[] |
| |
| * pname:shadingRatePaletteEntryCount specifies the number of entries in |
| the shading rate image palette. |
| * pname:pShadingRatePaletteEntries is a pointer to an array of |
| elink:VkShadingRatePaletteEntryNV enums defining the shading rate for |
| each palette entry. |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkShadingRatePaletteNV-shadingRatePaletteEntryCount-02071]] |
| pname:shadingRatePaletteEntryCount must: be between `1` and |
| sname:VkPhysicalDeviceShadingRateImagePropertiesNV::pname:shadingRatePaletteSize, |
| inclusive |
| |
| **** |
| include::{generated}/validity/structs/VkShadingRatePaletteNV.adoc[] |
| -- |
| |
| To determine the base shading rate image, a shading rate index _i_ is mapped |
| to array element _i_ in the array pname:pShadingRatePaletteEntries for the |
| palette corresponding to the viewport used for the fragment. |
| If _i_ is greater than or equal to the palette size |
| pname:shadingRatePaletteEntryCount, the base shading rate is undefined:. |
| |
| [open,refpage='VkShadingRatePaletteEntryNV',desc='Shading rate image palette entry types',type='enums'] |
| -- |
| The supported shading rate image palette entries are defined by |
| elink:VkShadingRatePaletteEntryNV: |
| |
| include::{generated}/api/enums/VkShadingRatePaletteEntryNV.adoc[] |
| |
| The following table indicates the width and height (in pixels) of each |
| fragment generated using the indicated shading rate, as well as the maximum |
| number of fragment shader invocations launched for each fragment. |
| When processing regions of a primitive that have a shading rate of |
| ename:VK_SHADING_RATE_PALETTE_ENTRY_NO_INVOCATIONS_NV, no fragments will be |
| generated in that region. |
| |
| [options="header"] |
| |==== |
| | Shading Rate | Width | Height | Invocations |
| | ename:VK_SHADING_RATE_PALETTE_ENTRY_NO_INVOCATIONS_NV | 0 | 0 | 0 |
| | ename:VK_SHADING_RATE_PALETTE_ENTRY_16_INVOCATIONS_PER_PIXEL_NV | 1 | 1 | 16 |
| | ename:VK_SHADING_RATE_PALETTE_ENTRY_8_INVOCATIONS_PER_PIXEL_NV | 1 | 1 | 8 |
| | ename:VK_SHADING_RATE_PALETTE_ENTRY_4_INVOCATIONS_PER_PIXEL_NV | 1 | 1 | 4 |
| | ename:VK_SHADING_RATE_PALETTE_ENTRY_2_INVOCATIONS_PER_PIXEL_NV | 1 | 1 | 2 |
| | ename:VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_PIXEL_NV | 1 | 1 | 1 |
| | ename:VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X1_PIXELS_NV | 2 | 1 | 1 |
| | ename:VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_1X2_PIXELS_NV | 1 | 2 | 1 |
| | ename:VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X2_PIXELS_NV | 2 | 2 | 1 |
| | ename:VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X2_PIXELS_NV | 4 | 2 | 1 |
| | ename:VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X4_PIXELS_NV | 2 | 4 | 1 |
| | ename:VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X4_PIXELS_NV | 4 | 4 | 1 |
| |==== |
| -- |
| |
| When the shading rate image is disabled, a shading rate of |
| ename:VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_PIXEL_NV will be used |
| as the base shading rate. |
| |
| Once a base shading rate has been established, it is adjusted to produce a |
| final shading rate. |
| First, if the base shading rate uses multiple pixels for each fragment, the |
| implementation may: reduce the fragment area to ensure that the total number |
| of coverage samples for all pixels in a fragment does not exceed |
| <<limits-shadingRateMaxCoarseSamples, an implementation-dependent maximum>>. |
| |
| If <<primsrast-sampleshading, sample shading>> is active in the current |
| pipeline and would result in processing _n_ (_n_ > 1) unique samples per |
| fragment when the shading rate image is disabled, the shading rate is |
| adjusted in an implementation-dependent manner to increase the number of |
| fragment shader invocations spawned by the primitive. |
| If the shading rate indicates _fs_ pixels per fragment and _fs_ is greater |
| than _n_, the fragment area is adjusted so each fragment has approximately |
| latexmath:[fs \over n] pixels. |
| Otherwise, if the shading rate indicates _ipf_ invocations per fragment, the |
| fragment area will be adjusted to a single pixel with approximately |
| latexmath:[ipf \times n \over fs] invocations per fragment. |
| |
| If sample shading occurs due to the use of a fragment shader input variable |
| decorated with code:SampleId or code:SamplePosition, the shading rate is |
| ignored. |
| Each fragment will have a single pixel and will spawn up to |
| pname:rasterizationSamples fragment shader invocations, as when using |
| <<primsrast-sampleshading, sample shading>> without a shading rate image. |
| |
| Finally, if the shading rate specifies multiple fragment shader invocations |
| per fragment, the total number of invocations in the shading rate is clamped |
| to be no larger than pname:rasterizationSamples. |
| |
| When the final shading rate for a primitive covering pixel (_x_,_y_) has a |
| fragment area of latexmath:[fw \times fh], the fragment for that pixel will |
| cover all pixels with coordinates (_x_',_y_') that satisfy the equations: |
| |
| [latexmath] |
| +++++++++++++++++++ |
| \begin{aligned} |
| \left\lfloor \frac{x}{fw} \right\rfloor = \left\lfloor \frac{x'}{fw} \right\rfloor |
| \end{aligned} |
| +++++++++++++++++++ |
| [latexmath] |
| +++++++++++++++++++ |
| \begin{aligned} |
| \left\lfloor \frac{y}{fh} \right\rfloor = \left\lfloor \frac{y'}{fh} \right\rfloor |
| \end{aligned} |
| +++++++++++++++++++ |
| |
| This combined fragment is considered to have multiple coverage samples; the |
| total number of samples in this fragment is given by latexmath:[samples = fw |
| \times fh \times rs] where _rs_ indicates the value of |
| sname:VkPipelineMultisampleStateCreateInfo::pname:rasterizationSamples |
| specified at pipeline creation time. |
| The set of coverage samples in the fragment is the union of the per-pixel |
| coverage samples in each of the fragment's pixels The location and order of |
| coverage samples within each pixel in the combined fragment are assigned as |
| described in |
| ifndef::VK_EXT_sample_locations[] |
| <<primsrast-multisampling, Multisampling>>. |
| endif::VK_EXT_sample_locations[] |
| ifdef::VK_EXT_sample_locations[] |
| <<primsrast-multisampling, Multisampling>> and <<primsrast-samplelocations, |
| Custom Sample Locations>>. |
| endif::VK_EXT_sample_locations[] |
| Each coverage sample in the set of pixels belonging to the combined fragment |
| is assigned a unique <<primsrast-multisampling-coverage-mask, coverage |
| index>> in the range [0,_samples_-1]. |
| If the <<features-shadingRateCoarseSampleOrder, |
| pname:shadingRateCoarseSampleOrder>> feature is supported, the order of |
| coverage samples can: be specified for each combination of fragment area and |
| coverage sample count. |
| If this feature is not supported, the sample order is |
| implementation-dependent. |
| |
| [open,refpage='VkPipelineViewportCoarseSampleOrderStateCreateInfoNV',desc='Structure specifying parameters controlling sample order in coarse fragments',type='structs'] |
| -- |
| If the pname:pNext chain of slink:VkPipelineViewportStateCreateInfo includes |
| a sname:VkPipelineViewportCoarseSampleOrderStateCreateInfoNV structure, then |
| that structure includes parameters controlling the order of coverage samples |
| in fragments larger than one pixel. |
| |
| The sname:VkPipelineViewportCoarseSampleOrderStateCreateInfoNV structure is |
| defined as: |
| |
| include::{generated}/api/structs/VkPipelineViewportCoarseSampleOrderStateCreateInfoNV.adoc[] |
| |
| * pname:sType is a elink:VkStructureType value identifying this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:sampleOrderType specifies the mechanism used to order coverage |
| samples in fragments larger than one pixel. |
| * pname:customSampleOrderCount specifies the number of custom sample |
| orderings to use when ordering coverage samples. |
| * pname:pCustomSampleOrders is a pointer to an array of |
| pname:customSampleOrderCount slink:VkCoarseSampleOrderCustomNV |
| structures, each structure specifying the coverage sample order for a |
| single combination of fragment area and coverage sample count. |
| |
| If this structure is not present, pname:sampleOrderType is considered to be |
| ename:VK_COARSE_SAMPLE_ORDER_TYPE_DEFAULT_NV. |
| |
| If pname:sampleOrderType is ename:VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV, the |
| coverage sample order used for any combination of fragment area and coverage |
| sample count not enumerated in pname:pCustomSampleOrders will be identical |
| to that used for ename:VK_COARSE_SAMPLE_ORDER_TYPE_DEFAULT_NV. |
| |
| If the pipeline was created with |
| ename:VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV, the contents of this |
| structure (if present) are ignored, and the coverage sample order is instead |
| specified by flink:vkCmdSetCoarseSampleOrderNV. |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkPipelineViewportCoarseSampleOrderStateCreateInfoNV-sampleOrderType-02072]] |
| If pname:sampleOrderType is not |
| ename:VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV, |
| pname:customSamplerOrderCount must: be `0` |
| * [[VUID-VkPipelineViewportCoarseSampleOrderStateCreateInfoNV-pCustomSampleOrders-02234]] |
| The array pname:pCustomSampleOrders must: not contain two structures |
| with matching values for both the pname:shadingRate and |
| pname:sampleCount members |
| **** |
| include::{generated}/validity/structs/VkPipelineViewportCoarseSampleOrderStateCreateInfoNV.adoc[] |
| -- |
| |
| [open,refpage='VkCoarseSampleOrderTypeNV',desc='Shading rate image sample ordering types',type='enums'] |
| -- |
| The type elink:VkCoarseSampleOrderTypeNV specifies the technique used to |
| order coverage samples in fragments larger than one pixel, and is defined |
| as: |
| |
| include::{generated}/api/enums/VkCoarseSampleOrderTypeNV.adoc[] |
| |
| * ename:VK_COARSE_SAMPLE_ORDER_TYPE_DEFAULT_NV specifies that coverage |
| samples will be ordered in an implementation-dependent manner. |
| * ename:VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV specifies that coverage |
| samples will be ordered according to the array of custom orderings |
| provided in either the pname:pCustomSampleOrders member of |
| sname:VkPipelineViewportCoarseSampleOrderStateCreateInfoNV or the |
| pname:pCustomSampleOrders member of flink:vkCmdSetCoarseSampleOrderNV. |
| * ename:VK_COARSE_SAMPLE_ORDER_TYPE_PIXEL_MAJOR_NV specifies that coverage |
| samples will be ordered sequentially, sorted first by pixel coordinate |
| (in row-major order) and then by |
| <<primsrast-multisampling-coverage-mask, sample index>>. |
| * ename:VK_COARSE_SAMPLE_ORDER_TYPE_SAMPLE_MAJOR_NV specifies that |
| coverage samples will be ordered sequentially, sorted first by |
| <<primsrast-multisampling-coverage-mask, sample index>> and then by |
| pixel coordinate (in row-major order). |
| -- |
| |
| When using a coarse sample order of |
| ename:VK_COARSE_SAMPLE_ORDER_TYPE_PIXEL_MAJOR_NV for a fragment with an |
| upper-left corner of latexmath:[(fx,fy)] with a width of latexmath:[fw |
| \times fh] and latexmath:[fsc] samples per pixel, |
| <<primsrast-multisampling-coverage-mask, coverage index>> latexmath:[cs] of |
| the fragment will be assigned to <<primsrast-multisampling-coverage-mask, |
| sample index>> latexmath:[fs] of pixel latexmath:[(px,py)] as follows: |
| |
| [latexmath] |
| +++++++++++++++++++ |
| \begin{aligned} |
| px = & fx + (\left\lfloor {cs \over fsc} \right\rfloor \text{ \% } fw) \\ |
| py = & fy + \left\lfloor {cs \over {fsc \times fw}} \right\rfloor \\ |
| fs = & cs \text{ \% } fsc |
| \end{aligned} |
| +++++++++++++++++++ |
| |
| When using a coarse sample order of |
| ename:VK_COARSE_SAMPLE_ORDER_TYPE_SAMPLE_MAJOR_NV, |
| <<primsrast-multisampling-coverage-mask, coverage index>> latexmath:[cs] |
| will be assigned as follows: |
| |
| [latexmath] |
| +++++++++++++++++++ |
| \begin{aligned} |
| px = & fx + cs \text{ \% } fw \\ |
| py = & (fy + \left\lfloor {cs \over fw} \right\rfloor \text{ \% } fh) \\ |
| fs = & \left\lfloor {cs \over {fw \times fh}} \right\rfloor |
| \end{aligned} |
| +++++++++++++++++++ |
| |
| [open,refpage='VkCoarseSampleOrderCustomNV',desc='Structure specifying parameters controlling shading rate image usage',type='structs'] |
| -- |
| The sname:VkCoarseSampleOrderCustomNV structure is defined as: |
| |
| include::{generated}/api/structs/VkCoarseSampleOrderCustomNV.adoc[] |
| |
| * pname:shadingRate is a shading rate palette entry that identifies the |
| fragment width and height for the combination of fragment area and |
| per-pixel coverage sample count to control. |
| * pname:sampleCount identifies the per-pixel coverage sample count for the |
| combination of fragment area and coverage sample count to control. |
| * pname:sampleLocationCount specifies the number of sample locations in |
| the custom ordering. |
| * pname:pSampleLocations is a pointer to an array of |
| slink:VkCoarseSampleLocationNV structures specifying the location of |
| each sample in the custom ordering. |
| |
| The sname:VkCoarseSampleOrderCustomNV structure is used with a coverage |
| sample ordering type of ename:VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV to |
| specify the order of coverage samples for one combination of fragment width, |
| fragment height, and coverage sample count. |
| |
| When using a custom sample ordering, element _j_ in pname:pSampleLocations |
| specifies a specific pixel location and |
| <<primsrast-multisampling-coverage-mask, sample index>> that corresponds to |
| <<primsrast-multisampling-coverage-mask, coverage index>> _j_ in the |
| multi-pixel fragment. |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkCoarseSampleOrderCustomNV-shadingRate-02073]] |
| pname:shadingRate must: be a shading rate that generates fragments with |
| more than one pixel |
| * [[VUID-VkCoarseSampleOrderCustomNV-sampleCount-02074]] |
| pname:sampleCount must: correspond to a sample count enumerated in |
| tlink:VkSampleCountFlags whose corresponding bit is set in |
| slink:VkPhysicalDeviceLimits::pname:framebufferNoAttachmentsSampleCounts |
| * [[VUID-VkCoarseSampleOrderCustomNV-sampleLocationCount-02075]] |
| pname:sampleLocationCount must: be equal to the product of |
| pname:sampleCount, the fragment width for pname:shadingRate, and the |
| fragment height for pname:shadingRate |
| * [[VUID-VkCoarseSampleOrderCustomNV-sampleLocationCount-02076]] |
| pname:sampleLocationCount must: be less than or equal to the value of |
| sname:VkPhysicalDeviceShadingRateImagePropertiesNV::pname:shadingRateMaxCoarseSamples |
| * [[VUID-VkCoarseSampleOrderCustomNV-pSampleLocations-02077]] |
| The array pname:pSampleLocations must: contain exactly one entry for |
| every combination of valid values for pname:pixelX, pname:pixelY, and |
| pname:sample in the structure slink:VkCoarseSampleOrderCustomNV |
| **** |
| include::{generated}/validity/structs/VkCoarseSampleOrderCustomNV.adoc[] |
| -- |
| |
| [open,refpage='VkCoarseSampleLocationNV',desc='Structure specifying parameters controlling shading rate image usage',type='structs'] |
| -- |
| The sname:VkCoarseSampleLocationNV structure identifies a specific pixel and |
| <<primsrast-multisampling-coverage-mask, sample index>> for one of the |
| coverage samples in a fragment that is larger than one pixel. |
| This structure is defined as: |
| |
| include::{generated}/api/structs/VkCoarseSampleLocationNV.adoc[] |
| |
| * pname:pixelX is added to the x coordinate of the upper-leftmost pixel of |
| each fragment to identify the pixel containing the coverage sample. |
| * pname:pixelY is added to the y coordinate of the upper-leftmost pixel of |
| each fragment to identify the pixel containing the coverage sample. |
| * pname:sample is the number of the coverage sample in the pixel |
| identified by pname:pixelX and pname:pixelY. |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkCoarseSampleLocationNV-pixelX-02078]] |
| pname:pixelX must: be less than the width (in pixels) of the fragment |
| * [[VUID-VkCoarseSampleLocationNV-pixelY-02079]] |
| pname:pixelY must: be less than the height (in pixels) of the fragment |
| * [[VUID-VkCoarseSampleLocationNV-sample-02080]] |
| pname:sample must: be less than the number of coverage samples in each |
| pixel belonging to the fragment |
| **** |
| |
| include::{generated}/validity/structs/VkCoarseSampleLocationNV.adoc[] |
| -- |
| |
| [open,refpage='vkCmdSetCoarseSampleOrderNV',desc='Set order of coverage samples for coarse fragments dynamically for a command buffer',type='protos'] |
| -- |
| To <<pipelines-dynamic-state, dynamically set>> the order of coverage |
| samples in fragments larger than one pixel, call: |
| |
| include::{generated}/api/protos/vkCmdSetCoarseSampleOrderNV.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command will be |
| recorded. |
| * pname:sampleOrderType specifies the mechanism used to order coverage |
| samples in fragments larger than one pixel. |
| * pname:customSampleOrderCount specifies the number of custom sample |
| orderings to use when ordering coverage samples. |
| * pname:pCustomSampleOrders is a pointer to an array of |
| slink:VkCoarseSampleOrderCustomNV structures, each structure specifying |
| the coverage sample order for a single combination of fragment area and |
| coverage sample count. |
| |
| If pname:sampleOrderType is ename:VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV, the |
| coverage sample order used for any combination of fragment area and coverage |
| sample count not enumerated in pname:pCustomSampleOrders will be identical |
| to that used for ename:VK_COARSE_SAMPLE_ORDER_TYPE_DEFAULT_NV. |
| |
| This command sets the order of coverage samples for subsequent drawing |
| commands |
| ifdef::VK_EXT_shader_object[when drawing using <<shaders-objects, shader objects>>, or] |
| when the graphics pipeline is created with |
| ename:VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV set in |
| slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates. |
| Otherwise, this state is specified by the |
| slink:VkPipelineViewportCoarseSampleOrderStateCreateInfoNV values used to |
| create the currently active pipeline. |
| |
| .Valid Usage |
| **** |
| * [[VUID-vkCmdSetCoarseSampleOrderNV-sampleOrderType-02081]] |
| If pname:sampleOrderType is not |
| ename:VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV, |
| pname:customSamplerOrderCount must: be `0` |
| * [[VUID-vkCmdSetCoarseSampleOrderNV-pCustomSampleOrders-02235]] |
| The array pname:pCustomSampleOrders must: not contain two structures |
| with matching values for both the pname:shadingRate and |
| pname:sampleCount members |
| **** |
| |
| include::{generated}/validity/protos/vkCmdSetCoarseSampleOrderNV.adoc[] |
| -- |
| |
| If the final shading rate for a primitive covering pixel (_x_,_y_) results |
| in _n_ invocations per pixel (_n_ > 1), _n_ separate fragment shader |
| invocations will be generated for the fragment. |
| Each coverage sample in the fragment will be assigned to one of the _n_ |
| fragment shader invocations in an implementation-dependent manner. |
| The outputs from the <<interfaces-fragmentoutput, fragment output |
| interface>> of each shader invocation will be broadcast to all of the |
| framebuffer samples associated with the invocation. |
| If none of the coverage samples associated with a fragment shader invocation |
| is covered by a primitive, the implementation may: discard the fragment |
| shader invocation for those samples. |
| |
| If the final shading rate for a primitive covering pixel (_x_,_y_) results |
| in a fragment containing multiple pixels, a single set of fragment shader |
| invocations will be generated for all pixels in the combined fragment. |
| Outputs from the <<interfaces-fragmentoutput, fragment output interface>> |
| will be broadcast to all covered framebuffer samples belonging to the |
| fragment. |
| If the fragment shader executes code discarding the fragment, none of the |
| samples of the fragment will be updated. |
| |
| endif::VK_NV_shading_rate_image[] |
| |
| |
| [[primsrast-sampleshading]] |
| == Sample Shading |
| |
| Sample shading can: be used to specify a minimum number of unique samples to |
| process for each fragment. |
| If sample shading is enabled, an implementation must: invoke the fragment |
| shader at least [eq]#max({lceil} |
| slink:VkPipelineMultisampleStateCreateInfo::pname:minSampleShading {times} |
| slink:VkPipelineMultisampleStateCreateInfo::pname:rasterizationSamples |
| {rceil}, 1)# times per fragment. |
| If slink:VkPipelineMultisampleStateCreateInfo::pname:sampleShadingEnable is |
| set to ename:VK_TRUE, sample shading is enabled. |
| |
| If a fragment shader entry point <<shaders-staticuse, statically uses>> an |
| input variable decorated with a code:BuiltIn of code:SampleId or |
| code:SamplePosition, sample shading is enabled and a value of `1.0` is used |
| instead of pname:minSampleShading. |
| If a fragment shader entry point <<shaders-staticuse, statically uses>> an |
| input variable decorated with code:Sample, sample shading may: be enabled |
| and a value of `1.0` will be used instead of pname:minSampleShading if it |
| is. |
| ifdef::VK_AMD_mixed_attachment_samples[] |
| If the `apiext:VK_AMD_mixed_attachment_samples` extension is enabled and the |
| subpass uses color attachments, the pname:samples value used to create each |
| color attachment is used instead of pname:rasterizationSamples. |
| endif::VK_AMD_mixed_attachment_samples[] |
| |
| [NOTE] |
| .Note |
| ==== |
| If a shader decorates an input variable with code:Sample and that value |
| meaningfully impacts the output of a shader, sample shading will be enabled |
| to ensure that the input is in fact interpolated per-sample. |
| This is inherent to the specification and not spelled out here - if an |
| application simply declares such a variable it is implementation-defined |
| whether sample shading is enabled or not. |
| It is possible to see the effects of this by using atomics in the shader or |
| using a pipeline statistics query to query the number of fragment |
| invocations, even if the shader itself does not use any per-sample |
| variables. |
| ==== |
| |
| If there are fewer fragment invocations than <<fragops,covered samples>>, |
| implementations may: include those samples in fragment shader invocations in |
| any manner as long as covered samples are all shaded at least once, and each |
| invocation that is not a <<shaders-helper-invocations, helper invocation>> |
| covers at least one sample. |
| |
| ifdef::VK_NV_fragment_shader_barycentric,VK_KHR_fragment_shader_barycentric[] |
| [[primsrast-barycentric]] |
| == Barycentric Interpolation |
| |
| When the pname:fragmentShaderBarycentric feature is enabled, the |
| code:PerVertexKHR <<shaders-interpolation-decorations, interpolation |
| decoration>> can: be used with fragment shader inputs to indicate that the |
| decorated inputs do not have associated data in the fragment. |
| Such inputs can: only be accessed in a fragment shader using an array index |
| whose value (0, 1, or 2) identifies one of the vertices of the primitive |
| that produced the fragment. |
| Reads of per-vertex values for missing vertices, such as the third vertex of |
| a line primitive, will return values from the valid vertex with the highest |
| index. |
| This means that the per-vertex values of indices 1 and 2 for point |
| primitives will be equal to those of index 0, and the per-vertex values of |
| index 2 for line primitives will be equal to those of index 1. |
| |
| ifndef::VK_NV_mesh_shader,VK_EXT_mesh_shader[] |
| When <<tessellation, tessellation>> and <<geometry, geometry shading>> |
| endif::VK_NV_mesh_shader,VK_EXT_mesh_shader[] |
| ifdef::VK_NV_mesh_shader,VK_EXT_mesh_shader[] |
| When <<tessellation, tessellation>>, <<geometry, geometry shading>>, and |
| <<mesh,mesh shading>> |
| endif::VK_NV_mesh_shader,VK_EXT_mesh_shader[] |
| are not active, fragment shader inputs decorated with code:PerVertexKHR will |
| take values from one of the vertices of the primitive that produced the |
| fragment, identified by the extra index provided in SPIR-V code accessing |
| the input. |
| If the _n_ vertices passed to a draw call are numbered 0 through _n_-1, and |
| the point, line, and triangle primitives produced by the draw call are |
| numbered with consecutive integers beginning with zero, the following table |
| indicates the original vertex numbers used |
| ifdef::VK_EXT_provoking_vertex[] |
| when the <<vertexpostproc-flatshading,provoking vertex mode>> is |
| ename:VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT |
| endif::VK_EXT_provoking_vertex[] |
| for index values of 0, 1, and 2. |
| If an input decorated with code:PerVertexKHR is accessed with any other |
| vertex index value, or is accessed while rasterizing a polygon when the |
| slink:VkPipelineRasterizationStateCreateInfo::pname:polygonMode property of |
| the currently active pipeline is not ename:VK_POLYGON_MODE_FILL, an |
| undefined: value is returned. |
| |
| [[primsrast-barycentric-order-table]] |
| [options="header"] |
| |==== |
| | Primitive Topology | Vertex 0 | Vertex 1 | Vertex 2 |
| | ename:VK_PRIMITIVE_TOPOLOGY_POINT_LIST | i | i | i |
| | ename:VK_PRIMITIVE_TOPOLOGY_LINE_LIST | 2i | 2i+1 | 2i+1 |
| | ename:VK_PRIMITIVE_TOPOLOGY_LINE_STRIP | i | i+1 | i+1 |
| | ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST | 3i | 3i+1 | 3i+2 |
| | ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP (even) | i | i+1 | i+2 |
| | ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP (odd) | i | i+2 | i+1 |
| | ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN | i+1 | i+2 | 0 |
| | ename:VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY | 4i+1 | 4i+2 | 4i+2 |
| | ename:VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY | i+1 | i+2 | i+2 |
| | ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY | 6i | 6i+2 | 6i+4 |
| | ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY (even) | 2i | 2i+2 | 2i+4 |
| | ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY (odd) | 2i | 2i+4 | 2i+2 |
| |==== |
| |
| ifdef::VK_EXT_provoking_vertex[] |
| When the provoking vertex mode is |
| ename:VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT, the original vertex numbers |
| used are the same as above except as indicated in the table below. |
| |
| [[primsrast-barycentric-order-table-last-vertex]] |
| [options="header"] |
| |==== |
| | Primitive Topology | Vertex 0 | Vertex 1 | Vertex 2 |
| ifdef::VK_KHR_fragment_shader_barycentric[] |
| | ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP (odd, and |
| pname:triStripVertexOrderIndependentOfProvokingVertex of |
| slink:VkPhysicalDeviceFragmentShaderBarycentricPropertiesKHR is ename:VK_FALSE) | i+1 | i | i+2 |
| endif::VK_KHR_fragment_shader_barycentric[] |
| ifndef::VK_KHR_fragment_shader_barycentric[] |
| | ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP (odd) | i+1 | i | i+2 |
| endif::VK_KHR_fragment_shader_barycentric[] |
| | ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN | 0 | i+1 | i+2 |
| | ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY (odd) | 2i+2 | 2i | 2i+4 |
| |==== |
| endif::VK_EXT_provoking_vertex[] |
| |
| When geometry |
| ifdef::VK_NV_mesh_shader,VK_EXT_mesh_shader[or mesh] |
| shading is active, primitives processed by fragment shaders are assembled |
| from the vertices emitted by the geometry |
| ifdef::VK_NV_mesh_shader,VK_EXT_mesh_shader[or mesh] |
| shader. |
| In this case, the vertices used for fragment shader inputs decorated with |
| code:PerVertexKHR are derived by treating the primitives produced by the |
| shader as though they were specified by a draw call and consulting |
| <<primsrast-barycentric-order-table, the table above>>. |
| |
| When using tessellation without geometry shading, the tessellator produces |
| primitives in an implementation-dependent manner. |
| While there is no defined vertex ordering for inputs decorated with |
| code:PerVertexKHR, the vertex ordering used in this case will be consistent |
| with the ordering used to derive the values of inputs decorated with |
| code:BaryCoordKHR or code:BaryCoordNoPerspKHR. |
| |
| Fragment shader inputs decorated with code:BaryCoordKHR or |
| code:BaryCoordNoPerspKHR hold three-component vectors with barycentric |
| weights that indicate the location of the fragment relative to the |
| screen-space locations of vertices of its primitive. |
| For point primitives, such variables are always assigned the value |
| [eq]#(1,0,0)#. |
| For <<primsrast-lines-basic, line>> primitives, the built-ins are obtained |
| by interpolating an attribute whose values for the vertices numbered 0 and 1 |
| are [eq]#(1,0,0)# and [eq]#(0,1,0)#, respectively. |
| For <<primsrast-polygons-basic, polygon>> primitives, the built-ins are |
| obtained by interpolating an attribute whose values for the vertices |
| numbered 0, 1, and 2 are [eq]#(1,0,0)#, [eq]#(0,1,0)#, and [eq]#(0,0,1)#, |
| respectively. |
| For code:BaryCoordKHR, the values are obtained using perspective |
| interpolation. |
| For code:BaryCoordNoPerspKHR, the values are obtained using linear |
| interpolation. |
| The values of code:BaryCoordKHR and code:BaryCoordNoPerspKHR are undefined: |
| while rasterizing a polygon when the |
| slink:VkPipelineRasterizationStateCreateInfo::pname:polygonMode property of |
| the currently active pipeline is not ename:VK_POLYGON_MODE_FILL. |
| |
| endif::VK_NV_fragment_shader_barycentric,VK_KHR_fragment_shader_barycentric[] |
| |
| |
| [[primsrast-points]] |
| == Points |
| |
| A point is drawn by generating a set of fragments in the shape of a square |
| centered around the vertex of the point. |
| Each vertex has an associated point size controlling the width/height of |
| that square. |
| The point size is taken from the (potentially clipped) shader built-in |
| code:PointSize written by: |
| |
| * the geometry shader, if active; |
| * the tessellation evaluation shader, if active and no geometry shader is |
| active; |
| * the vertex shader, otherwise |
| |
| and clamped to the implementation-dependent point size range |
| [eq]#[pname:pointSizeRange[0],pname:pointSizeRange[1]]#. |
| The value written to code:PointSize must: be greater than zero. |
| ifdef::VK_KHR_maintenance5[] |
| If <<features-maintenance5, pname:maintenance5>> is enabled, and a value is |
| not written to code:PointSize, the point size takes a default value of 1.0. |
| endif::VK_KHR_maintenance5[] |
| |
| Not all point sizes need be supported, but the size 1.0 must: be supported. |
| The range of supported sizes and the size of evenly-spaced gradations within |
| that range are implementation-dependent. |
| The range and gradations are obtained from the pname:pointSizeRange and |
| pname:pointSizeGranularity members of slink:VkPhysicalDeviceLimits. |
| If, for instance, the size range is from 0.1 to 2.0 and the gradation size |
| is 0.1, then the sizes 0.1, 0.2, ..., 1.9, 2.0 are supported. |
| Additional point sizes may: also be supported. |
| There is no requirement that these sizes be equally spaced. |
| If an unsupported size is requested, the nearest supported size is used |
| instead. |
| |
| ifdef::VK_EXT_fragment_density_map[] |
| Further, if the render pass has a fragment density map attachment, point |
| size may: be rounded by the implementation to a multiple of the fragment's |
| width or height. |
| endif::VK_EXT_fragment_density_map[] |
| |
| |
| [[primsrast-points-basic]] |
| === Basic Point Rasterization |
| |
| Point rasterization produces a fragment for each fragment area group of |
| framebuffer pixels with one or more sample points that intersect a region |
| centered at the point's [eq]#(x~f~,y~f~)#. |
| This region is a square with side equal to the current point size. |
| Coverage bits that correspond to sample points that intersect the region are |
| 1, other coverage bits are 0. |
| All fragments produced in rasterizing a point are assigned the same |
| associated data, which are those of the vertex corresponding to the point. |
| However, the fragment shader built-in code:PointCoord contains point sprite |
| texture coordinates. |
| The [eq]#s# and [eq]#t# point sprite texture coordinates vary from zero to |
| one across the point horizontally left-to-right and vertically |
| top-to-bottom, respectively. |
| The following formulas are used to evaluate [eq]#s# and [eq]#t#: |
| |
| [latexmath] |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| s = {1 \over 2} + { \left( x_p - x_f \right) \over \text{size} } |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| |
| [latexmath] |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| t = {1 \over 2} + { \left( y_p - y_f \right) \over \text{size} } |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| |
| where size is the point's size; [eq]#(x~p~,y~p~)# is the location at which |
| the point sprite coordinates are evaluated - this may: be the framebuffer |
| coordinates of the fragment center, or the location of a sample; and |
| [eq]#(x~f~,y~f~)# is the exact, unrounded framebuffer coordinate of the |
| vertex for the point. |
| |
| |
| [[primsrast-lines]] |
| == Line Segments |
| |
| ifdef::VK_EXT_line_rasterization[] |
| [open,refpage='VkPipelineRasterizationLineStateCreateInfoEXT',desc='Structure specifying parameters of a newly created pipeline line rasterization state',type='structs'] |
| -- |
| Line segment rasterization options are controlled by the |
| slink:VkPipelineRasterizationLineStateCreateInfoEXT structure. |
| |
| The sname:VkPipelineRasterizationLineStateCreateInfoEXT structure is defined |
| as: |
| |
| include::{generated}/api/structs/VkPipelineRasterizationLineStateCreateInfoEXT.adoc[] |
| |
| * pname:sType is a elink:VkStructureType value identifying this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:lineRasterizationMode is a elink:VkLineRasterizationModeEXT value |
| selecting the style of line rasterization. |
| * pname:stippledLineEnable enables <<primsrast-lines-stipple, stippled |
| line rasterization>>. |
| * pname:lineStippleFactor is the repeat factor used in stippled line |
| rasterization. |
| * pname:lineStipplePattern is the bit pattern used in stippled line |
| rasterization. |
| |
| If pname:stippledLineEnable is ename:VK_FALSE, the values of |
| pname:lineStippleFactor and pname:lineStipplePattern are ignored. |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkPipelineRasterizationLineStateCreateInfoEXT-lineRasterizationMode-02768]] |
| If pname:lineRasterizationMode is |
| ename:VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT, then the |
| <<features-rectangularLines, pname:rectangularLines>> feature must: be |
| enabled |
| * [[VUID-VkPipelineRasterizationLineStateCreateInfoEXT-lineRasterizationMode-02769]] |
| If pname:lineRasterizationMode is |
| ename:VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT, then the |
| <<features-bresenhamLines, pname:bresenhamLines>> feature must: be |
| enabled |
| * [[VUID-VkPipelineRasterizationLineStateCreateInfoEXT-lineRasterizationMode-02770]] |
| If pname:lineRasterizationMode is |
| ename:VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT, then the |
| <<features-smoothLines, pname:smoothLines>> feature must: be enabled |
| * [[VUID-VkPipelineRasterizationLineStateCreateInfoEXT-stippledLineEnable-02771]] |
| If pname:stippledLineEnable is ename:VK_TRUE and |
| pname:lineRasterizationMode is |
| ename:VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT, then the |
| <<features-stippledRectangularLines, pname:stippledRectangularLines>> |
| feature must: be enabled |
| * [[VUID-VkPipelineRasterizationLineStateCreateInfoEXT-stippledLineEnable-02772]] |
| If pname:stippledLineEnable is ename:VK_TRUE and |
| pname:lineRasterizationMode is |
| ename:VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT, then the |
| <<features-stippledBresenhamLines, pname:stippledBresenhamLines>> |
| feature must: be enabled |
| * [[VUID-VkPipelineRasterizationLineStateCreateInfoEXT-stippledLineEnable-02773]] |
| If pname:stippledLineEnable is ename:VK_TRUE and |
| pname:lineRasterizationMode is |
| ename:VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT, then the |
| <<features-stippledSmoothLines, pname:stippledSmoothLines>> feature |
| must: be enabled |
| * [[VUID-VkPipelineRasterizationLineStateCreateInfoEXT-stippledLineEnable-02774]] |
| If pname:stippledLineEnable is ename:VK_TRUE and |
| pname:lineRasterizationMode is |
| ename:VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT, then the |
| <<features-stippledRectangularLines, pname:stippledRectangularLines>> |
| feature must: be enabled and |
| slink:VkPhysicalDeviceLimits::pname:strictLines must: be ename:VK_TRUE |
| **** |
| |
| include::{generated}/validity/structs/VkPipelineRasterizationLineStateCreateInfoEXT.adoc[] |
| -- |
| |
| [open,refpage='VkLineRasterizationModeEXT',desc='Line rasterization modes',type='enums'] |
| -- |
| Possible values of |
| slink:VkPipelineRasterizationLineStateCreateInfoEXT::pname:lineRasterizationMode |
| are: |
| |
| include::{generated}/api/enums/VkLineRasterizationModeEXT.adoc[] |
| |
| * ename:VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT is equivalent to |
| ename:VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT if |
| slink:VkPhysicalDeviceLimits::pname:strictLines is ename:VK_TRUE, |
| otherwise lines are drawn as non-pname:strictLines parallelograms. |
| Both of these modes are defined in <<primsrast-lines-basic,Basic Line |
| Segment Rasterization>>. |
| * ename:VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT specifies lines drawn |
| as if they were rectangles extruded from the line |
| * ename:VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT specifies lines drawn by |
| determining which pixel diamonds the line intersects and exits, as |
| defined in <<primsrast-lines-bresenham,Bresenham Line Segment |
| Rasterization>>. |
| * ename:VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT specifies lines |
| drawn if they were rectangles extruded from the line, with alpha |
| falloff, as defined in <<primsrast-lines-smooth,Smooth Lines>>. |
| -- |
| |
| ifdef::VK_EXT_extended_dynamic_state3,VK_EXT_shader_object[] |
| |
| [open,refpage='vkCmdSetLineRasterizationModeEXT',desc='Specify the line rasterization mode dynamically for a command buffer',type='protos'] |
| -- |
| To <<pipelines-dynamic-state, dynamically set>> the |
| pname:lineRasterizationMode state, call: |
| |
| include::{generated}/api/protos/vkCmdSetLineRasterizationModeEXT.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command will be |
| recorded. |
| * pname:lineRasterizationMode specifies the pname:lineRasterizationMode |
| state. |
| |
| This command sets the pname:lineRasterizationMode state for subsequent |
| drawing commands |
| ifdef::VK_EXT_shader_object[] |
| ifdef::VK_EXT_extended_dynamic_state3[when drawing using <<shaders-objects, shader objects>>, or] |
| ifndef::VK_EXT_extended_dynamic_state3[when drawing using <<shaders-objects, shader objects>>.] |
| endif::VK_EXT_shader_object[] |
| ifdef::VK_EXT_extended_dynamic_state3[] |
| when the graphics pipeline is created with |
| ename:VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT set in |
| slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates. |
| endif::VK_EXT_extended_dynamic_state3[] |
| Otherwise, this state is specified by the |
| slink:VkPipelineRasterizationLineStateCreateInfoEXT::pname:lineRasterizationMode |
| value used to create the currently active pipeline. |
| |
| :refpage: vkCmdSetLineRasterizationModeEXT |
| :requiredfeature: extendedDynamicState3LineRasterizationMode |
| |
| .Valid Usage |
| **** |
| include::{chapters}/commonvalidity/dynamic_state3_feature_common.adoc[] |
| * [[VUID-vkCmdSetLineRasterizationModeEXT-lineRasterizationMode-07418]] |
| If pname:lineRasterizationMode is |
| ename:VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT, then the |
| <<features-rectangularLines, pname:rectangularLines>> feature must: be |
| enabled |
| * [[VUID-vkCmdSetLineRasterizationModeEXT-lineRasterizationMode-07419]] |
| If pname:lineRasterizationMode is |
| ename:VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT, then the |
| <<features-bresenhamLines, pname:bresenhamLines>> feature must: be |
| enabled |
| * [[VUID-vkCmdSetLineRasterizationModeEXT-lineRasterizationMode-07420]] |
| If pname:lineRasterizationMode is |
| ename:VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT, then the |
| <<features-smoothLines, pname:smoothLines>> feature must: be enabled |
| **** |
| |
| include::{generated}/validity/protos/vkCmdSetLineRasterizationModeEXT.adoc[] |
| -- |
| |
| [open,refpage='vkCmdSetLineStippleEnableEXT',desc='Specify the line stipple enable dynamically for a command buffer',type='protos'] |
| -- |
| To <<pipelines-dynamic-state, dynamically set>> the pname:stippledLineEnable |
| state, call: |
| |
| include::{generated}/api/protos/vkCmdSetLineStippleEnableEXT.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command will be |
| recorded. |
| * pname:stippledLineEnable specifies the pname:stippledLineEnable state. |
| |
| This command sets the pname:stippledLineEnable state for subsequent drawing |
| commands |
| ifdef::VK_EXT_shader_object[] |
| ifdef::VK_EXT_extended_dynamic_state3[when drawing using <<shaders-objects, shader objects>>, or] |
| ifndef::VK_EXT_extended_dynamic_state3[when drawing using <<shaders-objects, shader objects>>.] |
| endif::VK_EXT_shader_object[] |
| ifdef::VK_EXT_extended_dynamic_state3[] |
| when the graphics pipeline is created with |
| ename:VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT set in |
| slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates. |
| endif::VK_EXT_extended_dynamic_state3[] |
| Otherwise, this state is specified by the |
| slink:VkPipelineRasterizationLineStateCreateInfoEXT::pname:stippledLineEnable |
| value used to create the currently active pipeline. |
| |
| :refpage: vkCmdSetLineStippleEnableEXT |
| :requiredfeature: extendedDynamicState3LineStippleEnable |
| |
| .Valid Usage |
| **** |
| include::{chapters}/commonvalidity/dynamic_state3_feature_common.adoc[] |
| **** |
| |
| include::{generated}/validity/protos/vkCmdSetLineStippleEnableEXT.adoc[] |
| -- |
| |
| endif::VK_EXT_extended_dynamic_state3,VK_EXT_shader_object[] |
| |
| endif::VK_EXT_line_rasterization[] |
| |
| [open,refpage='vkCmdSetLineWidth',desc='Set line width dynamically for a command buffer',type='protos'] |
| -- |
| To <<pipelines-dynamic-state, dynamically set>> the line width, call: |
| |
| include::{generated}/api/protos/vkCmdSetLineWidth.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command will be |
| recorded. |
| * pname:lineWidth is the width of rasterized line segments. |
| |
| This command sets the line width for subsequent drawing commands |
| ifdef::VK_EXT_shader_object[when drawing using <<shaders-objects, shader objects>>, or] |
| when the graphics pipeline is created with ename:VK_DYNAMIC_STATE_LINE_WIDTH |
| set in slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates. |
| Otherwise, this state is specified by the |
| slink:VkPipelineRasterizationStateCreateInfo::pname:lineWidth value used to |
| create the currently active pipeline. |
| |
| .Valid Usage |
| **** |
| * [[VUID-vkCmdSetLineWidth-lineWidth-00788]] |
| If the <<features-wideLines, pname:wideLines>> feature is not enabled, |
| pname:lineWidth must: be `1.0` |
| **** |
| |
| include::{generated}/validity/protos/vkCmdSetLineWidth.adoc[] |
| -- |
| |
| Not all line widths need be supported for line segment rasterization, but |
| width 1.0 antialiased segments must: be provided. |
| The range and gradations are obtained from the pname:lineWidthRange and |
| pname:lineWidthGranularity members of slink:VkPhysicalDeviceLimits. |
| If, for instance, the size range is from 0.1 to 2.0 and the gradation size |
| is 0.1, then the sizes 0.1, 0.2, ..., 1.9, 2.0 are supported. |
| Additional line widths may: also be supported. |
| There is no requirement that these widths be equally spaced. |
| If an unsupported width is requested, the nearest supported width is used |
| instead. |
| |
| ifdef::VK_EXT_fragment_density_map[] |
| Further, if the render pass has a fragment density map attachment, line |
| width may: be rounded by the implementation to a multiple of the fragment's |
| width or height. |
| endif::VK_EXT_fragment_density_map[] |
| |
| |
| [[primsrast-lines-basic]] |
| === Basic Line Segment Rasterization |
| |
| ifdef::VK_EXT_line_rasterization[] |
| If the pname:lineRasterizationMode member of |
| slink:VkPipelineRasterizationLineStateCreateInfoEXT is |
| ename:VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT, rasterized |
| endif::VK_EXT_line_rasterization[] |
| ifndef::VK_EXT_line_rasterization[] |
| Rasterized |
| endif::VK_EXT_line_rasterization[] |
| line segments produce fragments which intersect a rectangle centered on the |
| line segment. |
| Two of the edges are parallel to the specified line segment; each is at a |
| distance of one-half the current width from that segment in directions |
| perpendicular to the direction of the line. |
| The other two edges pass through the line endpoints and are perpendicular to |
| the direction of the specified line segment. |
| Coverage bits that correspond to sample points that intersect the rectangle |
| are 1, other coverage bits are 0. |
| |
| Next we specify how the data associated with each rasterized fragment are |
| obtained. |
| Let [eq]#**p**~r~ = (x~d~, y~d~)# be the framebuffer coordinates at which |
| associated data are evaluated. |
| This may: be the center of a fragment or the location of a sample within the |
| fragment. |
| When pname:rasterizationSamples is ename:VK_SAMPLE_COUNT_1_BIT, the fragment |
| center must: be used. |
| Let [eq]#**p**~a~ = (x~a~, y~a~)# and [eq]#**p**~b~ = (x~b~,y~b~)# be |
| initial and final endpoints of the line segment, respectively. |
| Set |
| |
| // Equation {linet:eq} |
| [latexmath] |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| t = {{( \mathbf{p}_r - \mathbf{p}_a ) \cdot ( \mathbf{p}_b - \mathbf{p}_a )} |
| \over {\| \mathbf{p}_b - \mathbf{p}_a \|^2 }} |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| |
| (Note that [eq]#t = 0# at [eq]#**p**~a~# and [eq]#t = 1# at [eq]#**p**~b~#. |
| Also note that this calculation projects the vector from [eq]#**p**~a~# to |
| [eq]#**p**~r~# onto the line, and thus computes the normalized distance of |
| the fragment along the line.) |
| |
| If <<limits-strictLines, pname:strictLines>> is ename:VK_TRUE, line segments |
| are rasterized using perspective or linear interpolation. |
| |
| [[line_perspective_interpolation]] |
| _Perspective interpolation_ for a line segment interpolates two values in a |
| manner that is correct when taking the perspective of the viewport into |
| consideration, by way of the line segment's clip coordinates. |
| An interpolated value [eq]#f# can be determined by |
| |
| [latexmath] |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| f = {{ (1-t) {f_a / w_a} + t { f_b / w_b} } \over |
| {(1-t) / w_a + t / w_b }} |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| |
| where [eq]#f~a~# and [eq]#f~b~# are the data associated with the starting |
| and ending endpoints of the segment, respectively; [eq]#w~a~# and [eq]#w~b~# |
| are the clip [eq]#w# coordinates of the starting and ending endpoints of the |
| segment, respectively. |
| |
| [[line_linear_interpolation]] |
| _Linear interpolation_ for a line segment directly interpolates two values, |
| and an interpolated value [eq]#f# can be determined by |
| |
| {empty}:: [eq]#f = (1 - t) f~a~ {plus} t f~b~# |
| |
| where [eq]#f~a~# and [eq]#f~b~# are the data associated with the starting |
| and ending endpoints of the segment, respectively. |
| |
| The clip coordinate [eq]#w# for a sample is determined using perspective |
| interpolation. |
| The depth value [eq]#z# for a sample is determined using linear |
| interpolation. |
| Interpolation of fragment shader input values are determined by |
| <<shaders-interpolation-decorations,Interpolation decorations>>. |
| |
| The above description documents the preferred method of line rasterization, |
| and must: be used when |
| ifdef::VK_EXT_line_rasterization[] |
| pname:lineRasterizationMode is |
| ename:VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT. |
| endif::VK_EXT_line_rasterization[] |
| ifndef::VK_EXT_line_rasterization[] |
| the implementation advertises the pname:strictLines limit in |
| slink:VkPhysicalDeviceLimits as ename:VK_TRUE. |
| endif::VK_EXT_line_rasterization[] |
| |
| ifndef::VK_KHR_maintenance5[] |
| When |
| endif::VK_KHR_maintenance5[] |
| ifdef::VK_KHR_maintenance5[] |
| By default, when |
| endif::VK_KHR_maintenance5[] |
| pname:strictLines is ename:VK_FALSE, |
| ifdef::VK_EXT_line_rasterization[] |
| and when the pname:lineRasterizationMode is |
| ename:VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT, |
| endif::VK_EXT_line_rasterization[] |
| the edges of the lines are generated as a parallelogram surrounding the |
| original line. |
| The major axis is chosen by noting the axis in which there is the greatest |
| distance between the line start and end points. |
| If the difference is equal in both directions then the X axis is chosen as |
| the major axis. |
| Edges 2 and 3 are aligned to the minor axis and are centered on the |
| endpoints of the line as in <<fig-non-strict-lines>>, and each is |
| pname:lineWidth long. |
| Edges 0 and 1 are parallel to the line and connect the endpoints of edges 2 |
| and 3. |
| Coverage bits that correspond to sample points that intersect the |
| parallelogram are 1, other coverage bits are 0. |
| |
| Samples that fall exactly on the edge of the parallelogram follow the |
| polygon rasterization rules. |
| |
| Interpolation occurs as if the parallelogram was decomposed into two |
| triangles where each pair of vertices at each end of the line has identical |
| attributes. |
| |
| [[fig-non-strict-lines]] |
| image::{images}/non_strict_lines.svg[align="center",title="Non strict lines",opts="{imageopts}"] |
| |
| Only when pname:strictLines is ename:VK_FALSE implementations may: deviate |
| from the non-strict line algorithm described above in the following ways: |
| |
| * Implementations may: instead interpolate each fragment according to the |
| formula in <<primsrast-lines-basic, Basic Line Segment Rasterization>> |
| using the original line segment endpoints. |
| |
| * Rasterization of non-antialiased non-strict line segments may: be |
| performed using the rules defined in |
| <<primsrast-lines-bresenham,Bresenham Line Segment Rasterization>>. |
| |
| ifdef::VK_KHR_maintenance5[] |
| If |
| sname:VkPhysicalDeviceMaintenance5PropertiesKHR::pname:nonStrictSinglePixelWideLinesUseParallelogram |
| is ename:VK_TRUE, |
| ifdef::VK_EXT_line_rasterization[] |
| the pname:lineRasterizationMode is |
| ename:VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT, |
| endif::VK_EXT_line_rasterization[] |
| and pname:strictLines is ename:VK_FALSE, non-strict lines of width 1.0 are |
| rasterized as parallelograms, otherwise they are rasterized using |
| Bresenham's algorithm. |
| |
| If |
| sname:VkPhysicalDeviceMaintenance5PropertiesKHR::pname:nonStrictWideLinesUseParallelogram |
| is ename:VK_TRUE, |
| ifdef::VK_EXT_line_rasterization[] |
| the pname:lineRasterizationMode is |
| ename:VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT, |
| endif::VK_EXT_line_rasterization[] |
| and pname:strictLines is ename:VK_FALSE, non-strict lines of width greater |
| than 1.0 are rasterized as parallelograms, otherwise they are rasterized |
| using Bresenham's algorithm. |
| endif::VK_KHR_maintenance5[] |
| |
| [[primsrast-lines-bresenham]] |
| === Bresenham Line Segment Rasterization |
| |
| ifdef::VK_EXT_line_rasterization[] |
| If pname:lineRasterizationMode is |
| ename:VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT, then the following rules |
| replace the line rasterization rules defined in <<primsrast-lines-basic, |
| Basic Line Segment Rasterization>>. |
| endif::VK_EXT_line_rasterization[] |
| |
| Non-strict lines may: also follow these rasterization rules for |
| non-antialiased lines. |
| |
| Line segment rasterization begins by characterizing the segment as either |
| _x-major_ or _y-major_. |
| x-major line segments have slope in the closed interval [eq]#[-1,1]#; all |
| other line segments are y-major (slope is determined by the segment's |
| endpoints). |
| We specify rasterization only for x-major segments except in cases where the |
| modifications for y-major segments are not self-evident. |
| |
| Ideally, Vulkan uses a _diamond-exit_ rule to determine those fragments that |
| are produced by rasterizing a line segment. |
| For each fragment [eq]#f# with center at framebuffer coordinates [eq]#x~f~# |
| and [eq]#y~f~#, define a diamond-shaped region that is the intersection of |
| four half planes: |
| |
| [latexmath] |
| +++++++++++++++++++ |
| R_f = \{ (x,y) \mid | x - x_f | + | y - y_f | < \frac{1}{2} \} |
| +++++++++++++++++++ |
| |
| Essentially, a line segment starting at [eq]#p~a~# and ending at [eq]#p~b~# |
| produces those fragments [eq]#f# for which the segment intersects |
| [eq]#R~f~#, except if [eq]#p~b~# is contained in [eq]#R~f~#. |
| |
| image::{images}/bresenham.svg[title="Visualization of Bresenham's algorithm",align="center",opts="{imageopts}"] |
| |
| To avoid difficulties when an endpoint lies on a boundary of [eq]#R~f~# we |
| (in principle) perturb the supplied endpoints by a tiny amount. |
| Let [eq]#p~a~# and [eq]#p~b~# have framebuffer coordinates [eq]#(x~a~, |
| y~a~)# and [eq]#(x~b~, y~b~)#, respectively. |
| Obtain the perturbed endpoints [eq]#p~a~'# given by [eq]#(x~a~, y~a~) - |
| ({epsilon}, {epsilon}^2^)# and [eq]#p~b~'# given by [eq]#(x~b~, y~b~) - |
| ({epsilon}, {epsilon}^2^)#. |
| Rasterizing the line segment starting at [eq]#p~a~# and ending at [eq]#p~b~# |
| produces those fragments [eq]#f# for which the segment starting at |
| [eq]#p~a~'# and ending on [eq]#p~b~'# intersects [eq]#R~f~#, except if |
| [eq]#p~b~'# is contained in [eq]#R~f~#. |
| [eq]#{epsilon}# is chosen to be so small that rasterizing the line segment |
| produces the same fragments when [eq]#{delta}# is substituted for |
| [eq]#{epsilon}# for any [eq]#0 < {delta} {leq} {epsilon}#. |
| |
| When [eq]#p~a~# and [eq]#p~b~# lie on fragment centers, this |
| characterization of fragments reduces to Bresenham's algorithm with one |
| modification: lines produced in this description are "`half-open`", meaning |
| that the final fragment (corresponding to [eq]#p~b~#) is not drawn. |
| This means that when rasterizing a series of connected line segments, shared |
| endpoints will be produced only once rather than twice (as would occur with |
| Bresenham's algorithm). |
| |
| Implementations may: use other line segment rasterization algorithms, |
| subject to the following rules: |
| |
| * The coordinates of a fragment produced by the algorithm must: not |
| deviate by more than one unit in either x or y framebuffer coordinates |
| from a corresponding fragment produced by the diamond-exit rule. |
| * The total number of fragments produced by the algorithm must: not differ |
| from that produced by the diamond-exit rule by no more than one. |
| * For an x-major line, two fragments that lie in the same |
| framebuffer-coordinate column must: not be produced (for a y-major line, |
| two fragments that lie in the same framebuffer-coordinate row must: not |
| be produced). |
| * If two line segments share a common endpoint, and both segments are |
| either x-major (both left-to-right or both right-to-left) or y-major |
| (both bottom-to-top or both top-to-bottom), then rasterizing both |
| segments must: not produce duplicate fragments. |
| Fragments also must: not be omitted so as to interrupt continuity of the |
| connected segments. |
| |
| The actual width [eq]#w# of Bresenham lines is determined by rounding the |
| line width to the nearest integer, clamping it to the |
| implementation-dependent pname:lineWidthRange (with both values rounded to |
| the nearest integer), then clamping it to be no less than 1. |
| |
| Bresenham line segments of width other than one are rasterized by offsetting |
| them in the minor direction (for an x-major line, the minor direction is y, |
| and for a y-major line, the minor direction is x) and producing a row or |
| column of fragments in the minor direction. |
| If the line segment has endpoints given by [eq]#(x~0~, y~0~)# and |
| [eq]#(x~1~, y~1~)# in framebuffer coordinates, the segment with endpoints |
| latexmath:[(x_0, y_0 - \frac{w-1}{2})] and latexmath:[(x_1, y_1 - |
| \frac{w-1}{2})] is rasterized, but instead of a single fragment, a column of |
| fragments of height w (a row of fragments of length w for a y-major segment) |
| is produced at each x (y for y-major) location. |
| The lowest fragment of this column is the fragment that would be produced by |
| rasterizing the segment of width 1 with the modified coordinates. |
| |
| The preferred method of attribute interpolation for a wide line is to |
| generate the same attribute values for all fragments in the row or column |
| described above, as if the adjusted line was used for interpolation and |
| those values replicated to the other fragments, except for code:FragCoord |
| which is interpolated as usual. |
| Implementations may: instead interpolate each fragment according to the |
| formula in <<primsrast-lines-basic,Basic Line Segment Rasterization>>, using |
| the original line segment endpoints. |
| |
| When Bresenham lines are being rasterized, sample locations may: all be |
| treated as being at the pixel center (this may: affect attribute and depth |
| interpolation). |
| |
| [NOTE] |
| .Note |
| ==== |
| The sample locations described above are *not* used for determining |
| coverage, they are only used for things like attribute interpolation. |
| The rasterization rules that determine coverage are defined in terms of |
| whether the line intersects *pixels*, as opposed to the point sampling rules |
| used for other primitive types. |
| So these rules are independent of the sample locations. |
| One consequence of this is that Bresenham lines cover the same pixels |
| regardless of the number of rasterization samples, and cover all samples in |
| those pixels (unless masked out or killed). |
| ==== |
| |
| |
| ifdef::VK_EXT_line_rasterization[] |
| [[primsrast-lines-stipple]] |
| === Line Stipple |
| |
| If the pname:stippledLineEnable member of |
| slink:VkPipelineRasterizationLineStateCreateInfoEXT is ename:VK_TRUE, then |
| lines are rasterized with a _line stipple_ determined by |
| pname:lineStippleFactor and pname:lineStipplePattern. |
| pname:lineStipplePattern is an unsigned 16-bit integer that determines which |
| fragments are to be drawn or discarded when the line is rasterized. |
| pname:lineStippleFactor is a count that is used to modify the effective line |
| stipple by causing each bit in pname:lineStipplePattern to be used |
| pname:lineStippleFactor times. |
| |
| Line stippling discards certain fragments that are produced by |
| rasterization. |
| The masking is achieved using three parameters: the 16-bit line stipple |
| pattern _p_, the line stipple factor _r_, and an integer stipple counter |
| _s_. |
| Let |
| |
| [latexmath] |
| +++++++++++++++++++ |
| b = \left\lfloor \frac{s}{r} \right\rfloor \bmod 16 |
| +++++++++++++++++++ |
| |
| Then a fragment is produced if the _b_'th bit of _p_ is 1, and discarded |
| otherwise. |
| The bits of _p_ are numbered with 0 being the least significant and 15 being |
| the most significant. |
| |
| The initial value of _s_ is zero. |
| For ename:VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT lines, _s_ is incremented |
| after production of each fragment of a line segment (fragments are produced |
| in order, beginning at the starting point and working towards the ending |
| point). |
| For ename:VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT and |
| ename:VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT lines, the |
| rectangular region is subdivided into adjacent unit-length rectangles, and s |
| is incremented once for each rectangle. |
| Rectangles with a value of _s_ such that the _b_'th bit of _p_ is zero are |
| discarded. |
| If the last rectangle in a line segment is shorter than unit-length, then |
| the remainder may: carry over to the next line segment in the line strip |
| using the same value of _s_ (this is the preferred behavior, for the stipple |
| pattern to appear more consistent through the strip). |
| |
| _s_ is reset to 0 at the start of each strip (for line strips), and before |
| every line segment in a group of independent segments. |
| |
| If the line segment has been clipped, then the value of _s_ at the beginning |
| of the line segment is implementation-dependent. |
| |
| [open,refpage='vkCmdSetLineStippleEXT',desc='Set line stipple dynamically for a command buffer',type='protos'] |
| -- |
| To <<pipelines-dynamic-state, dynamically set>> the line stipple state, |
| call: |
| |
| include::{generated}/api/protos/vkCmdSetLineStippleEXT.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command will be |
| recorded. |
| * pname:lineStippleFactor is the repeat factor used in stippled line |
| rasterization. |
| * pname:lineStipplePattern is the bit pattern used in stippled line |
| rasterization. |
| |
| This command sets the line stipple state for subsequent drawing commands |
| ifdef::VK_EXT_shader_object[when drawing using <<shaders-objects, shader objects>>, or] |
| when the graphics pipeline is created with |
| ename:VK_DYNAMIC_STATE_LINE_STIPPLE_EXT set in |
| slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates. |
| Otherwise, this state is specified by the |
| slink:VkPipelineRasterizationLineStateCreateInfoEXT::pname:lineStippleFactor |
| and |
| slink:VkPipelineRasterizationLineStateCreateInfoEXT::pname:lineStipplePattern |
| values used to create the currently active pipeline. |
| |
| .Valid Usage |
| **** |
| * [[VUID-vkCmdSetLineStippleEXT-lineStippleFactor-02776]] |
| pname:lineStippleFactor must: be in the range [eq]#[1,256]# |
| **** |
| |
| include::{generated}/validity/protos/vkCmdSetLineStippleEXT.adoc[] |
| -- |
| |
| |
| [[primsrast-lines-smooth]] |
| === Smooth Lines |
| |
| If the pname:lineRasterizationMode member of |
| slink:VkPipelineRasterizationLineStateCreateInfoEXT is |
| ename:VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT, then lines are |
| considered to be rectangles using the same geometry as for |
| ename:VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT lines. |
| The rules for determining which pixels are covered are |
| implementation-dependent, and may: include nearby pixels where no sample |
| locations are covered or where the rectangle does not intersect the pixel at |
| all. |
| For each pixel that is considered covered, the fragment computes a coverage |
| value that approximates the area of the intersection of the rectangle with |
| the pixel square, and this coverage value is multiplied into the color |
| location 0's alpha value after fragment shading, as described in |
| <<fragops-covg,Multisample Coverage>>. |
| |
| [NOTE] |
| .Note |
| ==== |
| The details of the rasterization rules and area calculation are left |
| intentionally vague, to allow implementations to generate coverage and |
| values that are aesthetically pleasing. |
| ==== |
| endif::VK_EXT_line_rasterization[] |
| |
| |
| [[primsrast-polygons]] |
| == Polygons |
| |
| A polygon results from the decomposition of a triangle strip, triangle fan |
| or a series of independent triangles. |
| Like points and line segments, polygon rasterization is controlled by |
| several variables in the slink:VkPipelineRasterizationStateCreateInfo |
| structure. |
| |
| |
| [[primsrast-polygons-basic]] |
| === Basic Polygon Rasterization |
| |
| [open,refpage='VkFrontFace',desc='Interpret polygon front-facing orientation',type='enums'] |
| -- |
| The first step of polygon rasterization is to determine whether the triangle |
| is _back-facing_ or _front-facing_. |
| This determination is made based on the sign of the (clipped or unclipped) |
| polygon's area computed in framebuffer coordinates. |
| One way to compute this area is: |
| |
| [latexmath] |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| a = -{1 \over 2}\sum_{i=0}^{n-1} |
| x_f^i y_f^{i \oplus 1} - |
| x_f^{i \oplus 1} y_f^i |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| |
| where latexmath:[x_f^i] and latexmath:[y_f^i] are the [eq]#x# and [eq]#y# |
| framebuffer coordinates of the [eq]##i##th vertex of the [eq]#n#-vertex |
| polygon (vertices are numbered starting at zero for the purposes of this |
| computation) and [eq]#i {oplus} 1# is [eq]#(i {plus} 1) mod n#. |
| |
| The interpretation of the sign of [eq]#a# is determined by the |
| slink:VkPipelineRasterizationStateCreateInfo::pname:frontFace property of |
| the currently active pipeline. |
| Possible values are: |
| |
| include::{generated}/api/enums/VkFrontFace.adoc[] |
| |
| * ename:VK_FRONT_FACE_COUNTER_CLOCKWISE specifies that a triangle with |
| positive area is considered front-facing. |
| * ename:VK_FRONT_FACE_CLOCKWISE specifies that a triangle with negative |
| area is considered front-facing. |
| |
| Any triangle which is not front-facing is back-facing, including zero-area |
| triangles. |
| -- |
| |
| ifdef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state,VK_EXT_shader_object[] |
| [open,refpage='vkCmdSetFrontFace',desc='Set front face orientation dynamically for a command buffer',type='protos',alias='vkCmdSetFrontFaceEXT'] |
| -- |
| To <<pipelines-dynamic-state, dynamically set>> the front face orientation, |
| call: |
| |
| ifdef::VK_VERSION_1_3[] |
| include::{generated}/api/protos/vkCmdSetFrontFace.adoc[] |
| |
| ifdef::VK_EXT_extended_dynamic_state,VK_EXT_shader_object[or the equivalent command] |
| endif::VK_VERSION_1_3[] |
| |
| ifdef::VK_EXT_extended_dynamic_state,VK_EXT_shader_object[] |
| include::{generated}/api/protos/vkCmdSetFrontFaceEXT.adoc[] |
| endif::VK_EXT_extended_dynamic_state,VK_EXT_shader_object[] |
| |
| * pname:commandBuffer is the command buffer into which the command will be |
| recorded. |
| * pname:frontFace is a elink:VkFrontFace value specifying the front-facing |
| triangle orientation to be used for culling. |
| |
| This command sets the front face orientation for subsequent drawing commands |
| ifdef::VK_EXT_shader_object[] |
| ifdef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[when drawing using <<shaders-objects, shader objects>>, or] |
| ifndef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[when drawing using <<shaders-objects, shader objects>>.] |
| endif::VK_EXT_shader_object[] |
| ifdef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[] |
| when the graphics pipeline is created with ename:VK_DYNAMIC_STATE_FRONT_FACE |
| set in slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates. |
| endif::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[] |
| Otherwise, this state is specified by the |
| slink:VkPipelineRasterizationStateCreateInfo::pname:frontFace value used to |
| create the currently active pipeline. |
| |
| :refpage: vkCmdSetFrontFace |
| |
| .Valid Usage |
| **** |
| include::{chapters}/commonvalidity/dynamic_state_feature_common.adoc[] |
| **** |
| |
| include::{generated}/validity/protos/vkCmdSetFrontFace.adoc[] |
| -- |
| endif::VK_VERSION_1_3,VK_EXT_extended_dynamic_state,VK_EXT_shader_object[] |
| |
| |
| [open,refpage='VkCullModeFlagBits',desc='Bitmask controlling triangle culling',type='enums'] |
| -- |
| Once the orientation of triangles is determined, they are culled according |
| to the slink:VkPipelineRasterizationStateCreateInfo::pname:cullMode property |
| of the currently active pipeline. |
| Possible values are: |
| |
| include::{generated}/api/enums/VkCullModeFlagBits.adoc[] |
| |
| * ename:VK_CULL_MODE_NONE specifies that no triangles are discarded |
| * ename:VK_CULL_MODE_FRONT_BIT specifies that front-facing triangles are |
| discarded |
| * ename:VK_CULL_MODE_BACK_BIT specifies that back-facing triangles are |
| discarded |
| * ename:VK_CULL_MODE_FRONT_AND_BACK specifies that all triangles are |
| discarded. |
| |
| Following culling, fragments are produced for any triangles which have not |
| been discarded. |
| -- |
| |
| [open,refpage='VkCullModeFlags',desc='Bitmask of VkCullModeFlagBits',type='flags'] |
| -- |
| include::{generated}/api/flags/VkCullModeFlags.adoc[] |
| |
| tname:VkCullModeFlags is a bitmask type for setting a mask of zero or more |
| elink:VkCullModeFlagBits. |
| -- |
| |
| ifdef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state,VK_EXT_shader_object[] |
| [open,refpage='vkCmdSetCullMode',desc='Set cull mode dynamically for a command buffer',type='protos',alias='vkCmdSetCullModeEXT'] |
| -- |
| To <<pipelines-dynamic-state, dynamically set>> the cull mode, call: |
| |
| ifdef::VK_VERSION_1_3[] |
| include::{generated}/api/protos/vkCmdSetCullMode.adoc[] |
| |
| ifdef::VK_EXT_extended_dynamic_state,VK_EXT_shader_object[or the equivalent command] |
| endif::VK_VERSION_1_3[] |
| |
| ifdef::VK_EXT_extended_dynamic_state,VK_EXT_shader_object[] |
| include::{generated}/api/protos/vkCmdSetCullModeEXT.adoc[] |
| endif::VK_EXT_extended_dynamic_state,VK_EXT_shader_object[] |
| |
| * pname:commandBuffer is the command buffer into which the command will be |
| recorded. |
| * pname:cullMode specifies the cull mode property to use for drawing. |
| |
| This command sets the cull mode for subsequent drawing commands |
| ifdef::VK_EXT_shader_object[] |
| ifdef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[when drawing using <<shaders-objects, shader objects>>, or] |
| ifndef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[when drawing using <<shaders-objects, shader objects>>.] |
| endif::VK_EXT_shader_object[] |
| ifdef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[] |
| when the graphics pipeline is created with ename:VK_DYNAMIC_STATE_CULL_MODE |
| set in slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates. |
| endif::VK_VERSION_1_3,VK_EXT_extended_dynamic_state[] |
| Otherwise, this state is specified by the |
| slink:VkPipelineRasterizationStateCreateInfo::pname:cullMode value used to |
| create the currently active pipeline. |
| |
| :refpage: vkCmdSetCullMode |
| |
| .Valid Usage |
| **** |
| include::{chapters}/commonvalidity/dynamic_state_feature_common.adoc[] |
| **** |
| |
| include::{generated}/validity/protos/vkCmdSetCullMode.adoc[] |
| -- |
| endif::VK_VERSION_1_3,VK_EXT_extended_dynamic_state,VK_EXT_shader_object[] |
| |
| The rule for determining which fragments are produced by polygon |
| rasterization is called _point sampling_. |
| The two-dimensional projection obtained by taking the x and y framebuffer |
| coordinates of the polygon's vertices is formed. |
| Fragments are produced for any fragment area groups of pixels for which any |
| sample points lie inside of this polygon. |
| Coverage bits that correspond to sample points that satisfy the point |
| sampling criteria are 1, other coverage bits are 0. |
| Special treatment is given to a sample whose sample location lies on a |
| polygon edge. |
| In such a case, if two polygons lie on either side of a common edge (with |
| identical endpoints) on which a sample point lies, then exactly one of the |
| polygons must: result in a covered sample for that fragment during |
| rasterization. |
| As for the data associated with each fragment produced by rasterizing a |
| polygon, we begin by specifying how these values are produced for fragments |
| in a triangle. |
| |
| [[primsrast-polygon-barycentrics]] |
| _Barycentric coordinates_ are a set of three numbers, [eq]#a#, [eq]#b#, and |
| [eq]#c#, each in the range [eq]#[0,1]#, with [eq]#a {plus} b {plus} c = 1#. |
| These coordinates uniquely specify any point [eq]#p# within the triangle or |
| on the triangle's boundary as |
| |
| {empty}:: [eq]#p = a p~a~ {plus} b p~b~ {plus} c p~c~# |
| |
| where [eq]#p~a~#, [eq]#p~b~#, and [eq]#p~c~# are the vertices of the |
| triangle. |
| [eq]#a#, [eq]#b#, and [eq]#c# are determined by: |
| |
| [latexmath] |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| a = {{\mathrm{A}(p p_b p_c)} \over {\mathrm{A}(p_a p_b p_c)}}, \quad |
| b = {{\mathrm{A}(p p_a p_c)} \over {\mathrm{A}(p_a p_b p_c)}}, \quad |
| c = {{\mathrm{A}(p p_a p_b)} \over {\mathrm{A}(p_a p_b p_c)}}, |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| |
| where [eq]#A(lmn)# denotes the area in framebuffer coordinates of the |
| triangle with vertices [eq]#l#, [eq]#m#, and [eq]#n#. |
| |
| Denote an associated datum at [eq]#p~a~#, [eq]#p~b~#, or [eq]#p~c~# as |
| [eq]#f~a~#, [eq]#f~b~#, or [eq]#f~c~#, respectively. |
| |
| [[triangle_perspective_interpolation]] |
| _Perspective interpolation_ for a triangle interpolates three values in a |
| manner that is correct when taking the perspective of the viewport into |
| consideration, by way of the triangle's clip coordinates. |
| An interpolated value [eq]#f# can be determined by |
| |
| [latexmath] |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| f = {{ a {f_a / w_a} + b {f_b / w_b} + c {f_c / w_c} } \over |
| { {a / w_a} + {b / w_b} + {c / w_c} }} |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| |
| where [eq]#w~a~#, [eq]#w~b~#, and [eq]#w~c~# are the clip [eq]#w# |
| coordinates of [eq]#p~a~#, [eq]#p~b~#, and [eq]#p~c~#, respectively. |
| [eq]#a#, [eq]#b#, and [eq]#c# are the barycentric coordinates of the |
| location at which the data are produced. |
| |
| [[triangle_linear_interpolation]] |
| _Linear interpolation_ for a triangle directly interpolates three values, |
| and an interpolated value [eq]#f# can be determined by |
| |
| {empty}:: [eq]#f = a f~a~ {plus} b f~b~ {plus} c f~c~# |
| |
| where [eq]#f~a~#, [eq]#f~b~#, and [eq]#f~c~# are the data associated with |
| [eq]#p~a~#, [eq]#p~b~#, and [eq]#p~c~#, respectively. |
| |
| The clip coordinate [eq]#w# for a sample is determined using perspective |
| interpolation. |
| The depth value [eq]#z# for a sample is determined using linear |
| interpolation. |
| Interpolation of fragment shader input values are determined by |
| <<shaders-interpolation-decorations,Interpolation decorations>>. |
| |
| For a polygon with more than three edges, such as are produced by clipping a |
| triangle, a convex combination of the values of the datum at the polygon's |
| vertices must: be used to obtain the value assigned to each fragment |
| produced by the rasterization algorithm. |
| That is, it must: be the case that at every fragment |
| |
| [latexmath] |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| f = \sum_{i=1}^{n} a_i f_i |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| |
| where [eq]#n# is the number of vertices in the polygon and [eq]#f~i~# is the |
| value of [eq]#f# at vertex [eq]#i#. |
| For each [eq]#i#, [eq]#0 {leq} a~i~ {leq} 1# and |
| latexmath:[\sum_{i=1}^{n}a_i = 1]. |
| The values of [eq]#a~i~# may: differ from fragment to fragment, but at |
| vertex [eq]#i#, [eq]#a~i~ = 1# and [eq]#a~j~ = 0# for [eq]#j {neq} i#. |
| |
| [NOTE] |
| .Note |
| ==== |
| One algorithm that achieves the required behavior is to triangulate a |
| polygon (without adding any vertices) and then treat each triangle |
| individually as already discussed. |
| A scan-line rasterizer that linearly interpolates data along each edge and |
| then linearly interpolates data across each horizontal span from edge to |
| edge also satisfies the restrictions (in this case the numerator and |
| denominator of <<triangle_perspective_interpolation, perspective |
| interpolation>> are iterated independently, and a division is performed for |
| each fragment). |
| ==== |
| |
| |
| [[primsrast-polygonmode]] |
| === Polygon Mode |
| |
| [open,refpage='VkPolygonMode',desc='Control polygon rasterization mode',type='enums'] |
| -- |
| Possible values of the |
| slink:VkPipelineRasterizationStateCreateInfo::pname:polygonMode property of |
| the currently active pipeline, specifying the method of rasterization for |
| polygons, are: |
| |
| include::{generated}/api/enums/VkPolygonMode.adoc[] |
| |
| * ename:VK_POLYGON_MODE_POINT specifies that polygon vertices are drawn as |
| points. |
| * ename:VK_POLYGON_MODE_LINE specifies that polygon edges are drawn as |
| line segments. |
| * ename:VK_POLYGON_MODE_FILL specifies that polygons are rendered using |
| the polygon rasterization rules in this section. |
| ifdef::VK_NV_fill_rectangle[] |
| * ename:VK_POLYGON_MODE_FILL_RECTANGLE_NV specifies that polygons are |
| rendered using polygon rasterization rules, modified to consider a |
| sample within the primitive if the sample location is inside the |
| axis-aligned bounding box of the triangle after projection. |
| Note that the barycentric weights used in attribute interpolation can: |
| extend outside the range [eq]#[0,1]# when these primitives are shaded. |
| Special treatment is given to a sample position on the boundary edge of |
| the bounding box. |
| In such a case, if two rectangles lie on either side of a common edge |
| (with identical endpoints) on which a sample position lies, then exactly |
| one of the triangles must: produce a fragment that covers that sample |
| during rasterization. |
| + |
| Polygons rendered in ename:VK_POLYGON_MODE_FILL_RECTANGLE_NV mode may: be |
| clipped by the frustum or by user clip planes. |
| If clipping is applied, the triangle is culled rather than clipped. |
| + |
| Area calculation and facingness are determined for |
| ename:VK_POLYGON_MODE_FILL_RECTANGLE_NV mode using the triangle's vertices. |
| endif::VK_NV_fill_rectangle[] |
| |
| These modes affect only the final rasterization of polygons: in particular, |
| a polygon's vertices are shaded and the polygon is clipped and possibly |
| culled before these modes are applied. |
| |
| ifndef::VK_KHR_maintenance5[] |
| The point size of the final rasterization of polygons when |
| <<primsrast-polygonmode, polygon mode>> is ename:VK_POLYGON_MODE_POINT is |
| implementation-dependent, and the point size may: either be code:PointSize |
| or 1.0. |
| endif::VK_KHR_maintenance5[] |
| ifdef::VK_KHR_maintenance5[] |
| If |
| sname:VkPhysicalDeviceMaintenance5PropertiesKHR::pname:polygonModePointSize |
| is set to ename:VK_TRUE, the point size of the final rasterization of |
| polygons is taken from code:PointSize when <<primsrast-polygonmode, polygon |
| mode>> is ename:VK_POLYGON_MODE_POINT. |
| |
| Otherwise, if |
| sname:VkPhysicalDeviceMaintenance5PropertiesKHR::pname:polygonModePointSize |
| is set to ename:VK_FALSE, the point size of the final rasterization of |
| polygons is 1.0 when <<primsrast-polygonmode, polygon mode>> is |
| ename:VK_POLYGON_MODE_POINT. |
| endif::VK_KHR_maintenance5[] |
| -- |
| |
| ifdef::VK_EXT_extended_dynamic_state3,VK_EXT_shader_object[] |
| |
| [open,refpage='vkCmdSetPolygonModeEXT',desc='Specify polygon mode dynamically for a command buffer',type='protos'] |
| -- |
| To <<pipelines-dynamic-state, dynamically set>> the polygon mode, call: |
| |
| include::{generated}/api/protos/vkCmdSetPolygonModeEXT.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command will be |
| recorded. |
| * pname:polygonMode specifies polygon mode. |
| |
| This command sets the polygon mode for subsequent drawing commands |
| ifdef::VK_EXT_shader_object[] |
| ifdef::VK_EXT_extended_dynamic_state3[when drawing using <<shaders-objects, shader objects>>, or] |
| ifndef::VK_EXT_extended_dynamic_state3[when drawing using <<shaders-objects, shader objects>>.] |
| endif::VK_EXT_shader_object[] |
| ifdef::VK_EXT_extended_dynamic_state3[] |
| when the graphics pipeline is created with |
| ename:VK_DYNAMIC_STATE_POLYGON_MODE_EXT set in |
| slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates. |
| endif::VK_EXT_extended_dynamic_state3[] |
| Otherwise, this state is specified by the |
| slink:VkPipelineRasterizationStateCreateInfo::pname:polygonMode value used |
| to create the currently active pipeline. |
| |
| :refpage: vkCmdSetPolygonModeEXT |
| :requiredfeature: extendedDynamicState3PolygonMode |
| |
| .Valid Usage |
| **** |
| include::{chapters}/commonvalidity/dynamic_state3_feature_common.adoc[] |
| * [[VUID-vkCmdSetPolygonModeEXT-fillModeNonSolid-07424]] |
| If the <<features-fillModeNonSolid, pname:fillModeNonSolid>> feature is |
| not enabled, pname:polygonMode must: be ename:VK_POLYGON_MODE_FILL |
| ifdef::VK_NV_fill_rectangle[or ename:VK_POLYGON_MODE_FILL_RECTANGLE_NV] |
| ifdef::VK_NV_fill_rectangle[] |
| * [[VUID-vkCmdSetPolygonModeEXT-polygonMode-07425]] |
| If the `apiext:VK_NV_fill_rectangle` extension is not enabled, |
| pname:polygonMode must: not be ename:VK_POLYGON_MODE_FILL_RECTANGLE_NV |
| endif::VK_NV_fill_rectangle[] |
| **** |
| |
| include::{generated}/validity/protos/vkCmdSetPolygonModeEXT.adoc[] |
| -- |
| |
| endif::VK_EXT_extended_dynamic_state3,VK_EXT_shader_object[] |
| |
| |
| [[primsrast-depthbias]] |
| === Depth Bias |
| |
| The depth values of all fragments generated by the rasterization of a |
| polygon can: be biased (offset) by a single depth bias value latexmath:[o] |
| that is computed for that polygon. |
| |
| |
| [[primsrast-depthbias-enable]] |
| ==== Depth Bias Enable |
| |
| The depth bias computation is enabled by the |
| ifdef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state2[] |
| pname:depthBiasEnable set with flink:vkCmdSetDepthBiasEnable |
| ifdef::VK_EXT_extended_dynamic_state2[] |
| and fname:vkCmdSetDepthBiasEnableEXT, |
| endif::VK_EXT_extended_dynamic_state2[] |
| or the corresponding |
| endif::VK_VERSION_1_3,VK_EXT_extended_dynamic_state2[] |
| slink:VkPipelineRasterizationStateCreateInfo::pname:depthBiasEnable value |
| used to create the currently active pipeline. |
| If the depth bias enable is ename:VK_FALSE, no bias is applied and the |
| fragment's depth values are unchanged. |
| |
| ifdef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state2,VK_EXT_shader_object[] |
| [open,refpage='vkCmdSetDepthBiasEnable',desc='Control whether to bias fragment depth values dynamically for a command buffer',type='protos',alias='vkCmdSetDepthBiasEnableEXT'] |
| -- |
| To <<pipelines-dynamic-state, dynamically enable>> whether to bias fragment |
| depth values, call: |
| |
| ifdef::VK_VERSION_1_3[] |
| include::{generated}/api/protos/vkCmdSetDepthBiasEnable.adoc[] |
| |
| ifdef::VK_EXT_extended_dynamic_state2,VK_EXT_shader_object[or the equivalent command] |
| endif::VK_VERSION_1_3[] |
| |
| ifdef::VK_EXT_extended_dynamic_state2,VK_EXT_shader_object[] |
| include::{generated}/api/protos/vkCmdSetDepthBiasEnableEXT.adoc[] |
| endif::VK_EXT_extended_dynamic_state2,VK_EXT_shader_object[] |
| |
| * pname:commandBuffer is the command buffer into which the command will be |
| recorded. |
| * pname:depthBiasEnable controls whether to bias fragment depth values. |
| |
| This command sets the depth bias enable for subsequent drawing commands |
| ifdef::VK_EXT_shader_object[] |
| ifdef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state2[when drawing using <<shaders-objects, shader objects>>, or] |
| ifndef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state2[when drawing using <<shaders-objects, shader objects>>.] |
| endif::VK_EXT_shader_object[] |
| ifdef::VK_VERSION_1_3,VK_EXT_extended_dynamic_state2[] |
| when the graphics pipeline is created with |
| ename:VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE set in |
| slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates. |
| endif::VK_VERSION_1_3,VK_EXT_extended_dynamic_state2[] |
| Otherwise, this state is specified by the |
| slink:VkPipelineRasterizationStateCreateInfo::pname:depthBiasEnable value |
| used to create the currently active pipeline. |
| |
| :refpage: vkCmdSetDepthBiasEnable |
| |
| .Valid Usage |
| **** |
| include::{chapters}/commonvalidity/dynamic_state2_feature_common.adoc[] |
| **** |
| |
| include::{generated}/validity/protos/vkCmdSetDepthBiasEnable.adoc[] |
| -- |
| endif::VK_VERSION_1_3,VK_EXT_extended_dynamic_state2,VK_EXT_shader_object[] |
| |
| |
| [[primsrast-depthbias-computation]] |
| ==== Depth Bias Computation |
| |
| The depth bias depends on three parameters: |
| |
| * pname:depthBiasSlopeFactor scales the maximum depth slope [eq]#m# of the |
| polygon |
| * pname:depthBiasConstantFactor scales the parameter [eq]#r# of the depth |
| attachment |
| * the scaled terms are summed to produce a value which is then clamped to |
| a minimum or maximum value specified by pname:depthBiasClamp |
| |
| pname:depthBiasSlopeFactor, pname:depthBiasConstantFactor, and |
| pname:depthBiasClamp can: each be positive, negative, or zero. |
| These parameters are set as described for flink:vkCmdSetDepthBias |
| ifdef::VK_EXT_depth_bias_control[] |
| and flink:vkCmdSetDepthBias2EXT |
| endif::VK_EXT_depth_bias_control[] |
| below. |
| |
| The maximum depth slope [eq]#m# of a triangle is |
| |
| [latexmath] |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| m = \sqrt{ \left({{\partial z_f} \over {\partial x_f}}\right)^2 |
| + \left({{\partial z_f} \over {\partial y_f}}\right)^2} |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| |
| where [eq]#(x~f~, y~f~, z~f~)# is a point on the triangle. |
| [eq]#m# may: be approximated as |
| |
| [latexmath] |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| m = \max\left( \left| { {\partial z_f} \over {\partial x_f} } \right|, |
| \left| { {\partial z_f} \over {\partial y_f} } \right| |
| \right). |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| |
| ifdef::VK_EXT_depth_bias_control[] |
| In a pipeline with a depth bias representation of |
| ename:VK_DEPTH_BIAS_REPRESENTATION_FLOAT_EXT, [eq]#r#, for the given |
| primitive is defined as |
| |
| {empty}:: [eq]#r = 1# |
| |
| |
| Otherwise |
| endif::VK_EXT_depth_bias_control[] |
| [eq]#r# is the minimum resolvable difference that depends on the depth |
| attachment representation. |
| ifdef::VK_EXT_depth_bias_control[] |
| If sname:VkDepthBiasRepresentationInfoEXT::pname:depthBiasExact is |
| ename:VK_FALSE it |
| endif::VK_EXT_depth_bias_control[] |
| ifndef::VK_EXT_depth_bias_control[It] |
| is the smallest difference in framebuffer coordinate [eq]#z# values that is |
| guaranteed to remain distinct throughout polygon rasterization and in the |
| depth attachment. |
| All pairs of fragments generated by the rasterization of two polygons with |
| otherwise identical vertices, but [eq]#pname:z~f~# values that differ by |
| [eq]#r#, will have distinct depth values. |
| |
| For fixed-point depth attachment representations, |
| ifdef::VK_EXT_depth_bias_control[] |
| or in a pipeline with a depth bias representation of |
| ename:VK_DEPTH_BIAS_REPRESENTATION_LEAST_REPRESENTABLE_VALUE_FORCE_UNORM_EXT, |
| endif::VK_EXT_depth_bias_control[] |
| [eq]#r# is constant throughout the range of the entire depth attachment. |
| ifdef::VK_EXT_depth_bias_control[] |
| If sname:VkDepthBiasRepresentationInfoEXT::pname:depthBiasExact is |
| ename:VK_TRUE, then its value must: be |
| |
| {empty}:: [eq]#r = 2^-n^# |
| |
| Otherwise its value is implementation-dependent but must: be at most |
| endif::VK_EXT_depth_bias_control[] |
| ifndef::VK_EXT_depth_bias_control[] |
| Its value is implementation-dependent but must: be at most |
| endif::VK_EXT_depth_bias_control[] |
| |
| {empty}:: [eq]#r = 2 {times} 2^-n^# |
| |
| where [eq]#n# is the number of bits used for the depth |
| ifndef::VK_EXT_depth_bias_control[aspect.] |
| ifdef::VK_EXT_depth_bias_control[] |
| aspect when using a fixed-point attachment, or the number of mantissa bits |
| plus one when using a floating-point attachment. |
| endif::VK_EXT_depth_bias_control[] |
| |
| |
| ifdef::VK_EXT_depth_bias_control[Otherwise for] |
| ifndef::VK_EXT_depth_bias_control[For] |
| floating-point depth attachment, there is no single minimum resolvable |
| difference. |
| In this case, the minimum resolvable difference for a given polygon is |
| dependent on the maximum exponent, [eq]#e#, in the range of [eq]#z# values |
| spanned by the primitive. |
| If [eq]#n# is the number of bits in the floating-point mantissa, the minimum |
| resolvable difference, [eq]#r#, for the given primitive is defined as |
| |
| {empty}:: [eq]#r = 2^e-n^# |
| |
| ifdef::VK_NV_fill_rectangle[] |
| If a triangle is rasterized using the |
| ename:VK_POLYGON_MODE_FILL_RECTANGLE_NV polygon mode, then this minimum |
| resolvable difference may: not be resolvable for samples outside of the |
| triangle, where the depth is extrapolated. |
| endif::VK_NV_fill_rectangle[] |
| |
| If no depth attachment is present, [eq]#r# is undefined:. |
| |
| The bias value [eq]#o# for a polygon is |
| |
| [latexmath] |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| \begin{aligned} |
| o &= \mathrm{dbclamp}( m \times \mathtt{depthBiasSlopeFactor} + r \times \mathtt{depthBiasConstantFactor} ) \\ |
| \text{where} &\quad \mathrm{dbclamp}(x) = |
| \begin{cases} |
| x & \mathtt{depthBiasClamp} = 0 \ \text{or}\ \texttt{NaN} \\ |
| \min(x, \mathtt{depthBiasClamp}) & \mathtt{depthBiasClamp} > 0 \\ |
| \max(x, \mathtt{depthBiasClamp}) & \mathtt{depthBiasClamp} < 0 \\ |
| \end{cases} |
| \end{aligned} |
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| |
| [eq]#m# is computed as described above. |
| If the depth attachment uses a fixed-point representation, [eq]#m# is a |
| function of depth values in the range [eq]#[0,1]#, and [eq]#o# is applied to |
| depth values in the same range. |
| |
| Depth bias is applied to triangle topology primitives received by the |
| rasterizer regardless of <<primsrast-polygonmode, polygon mode>>. |
| Depth bias may: also be applied to line and point topology primitives |
| received by the rasterizer. |
| |
| [open,refpage='vkCmdSetDepthBias',desc='Set depth bias factors and clamp dynamically for a command buffer',type='protos'] |
| -- |
| To <<pipelines-dynamic-state, dynamically set>> the depth bias parameters, |
| call: |
| |
| include::{generated}/api/protos/vkCmdSetDepthBias.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command will be |
| recorded. |
| * pname:depthBiasConstantFactor is a scalar factor controlling the |
| constant depth value added to each fragment. |
| * pname:depthBiasClamp is the maximum (or minimum) depth bias of a |
| fragment. |
| * pname:depthBiasSlopeFactor is a scalar factor applied to a fragment's |
| slope in depth bias calculations. |
| |
| This command sets the depth bias parameters for subsequent drawing commands |
| ifdef::VK_EXT_shader_object[when drawing using <<shaders-objects, shader objects>>, or] |
| when the graphics pipeline is created with ename:VK_DYNAMIC_STATE_DEPTH_BIAS |
| set in slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates. |
| Otherwise, this state is specified by the corresponding |
| slink:VkPipelineRasterizationStateCreateInfo::pname:depthBiasConstantFactor, |
| pname:depthBiasClamp, and pname:depthBiasSlopeFactor values used to create |
| the currently active pipeline. |
| |
| ifdef::VK_EXT_depth_bias_control[] |
| Calling this function is equivalent to calling fname:vkCmdSetDepthBias2EXT |
| without a sname:VkDepthBiasRepresentationInfoEXT in the pNext chain of |
| sname:VkDepthBiasInfoEXT. |
| endif::VK_EXT_depth_bias_control[] |
| |
| .Valid Usage |
| **** |
| * [[VUID-vkCmdSetDepthBias-depthBiasClamp-00790]] |
| If the <<features-depthBiasClamp, pname:depthBiasClamp>> feature is not |
| enabled, pname:depthBiasClamp must: be `0.0` |
| **** |
| |
| include::{generated}/validity/protos/vkCmdSetDepthBias.adoc[] |
| -- |
| |
| ifdef::VK_EXT_depth_bias_control[] |
| [open,refpage='VkDepthBiasRepresentationInfoEXT',desc='Structure specifying depth bias parameters',type='structs'] |
| -- |
| :refpage: VkDepthBiasRepresentationInfoEXT |
| |
| The sname:VkDepthBiasRepresentationInfoEXT structure is defined as: |
| |
| include::{generated}/api/structs/VkDepthBiasRepresentationInfoEXT.adoc[] |
| |
| * pname:sType is a elink:VkStructureType value identifying this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:depthBiasRepresentation is a elink:VkDepthBiasRepresentationEXT |
| value specifying the depth bias representation. |
| * pname:depthBiasExact specifies that the implementation is not allowed to |
| scale the depth bias value to ensure a minimum resolvable distance. |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkDepthBiasRepresentationInfoEXT-leastRepresentableValueForceUnormRepresentation-08947]] |
| If the <<features-leastRepresentableValueForceUnormRepresentation, |
| pname:leastRepresentableValueForceUnormRepresentation>> feature is not |
| enabled, pname:depthBiasRepresentation must: not be |
| `VK_DEPTH_BIAS_REPRESENTATION_LEAST_REPRESENTABLE_VALUE_FORCE_UNORM_EXT` |
| * [[VUID-VkDepthBiasRepresentationInfoEXT-floatRepresentation-08948]] |
| If the <<features-floatRepresentation, pname:floatRepresentation>> |
| feature is not enabled, pname:depthBiasRepresentation must: not be |
| `VK_DEPTH_BIAS_REPRESENTATION_FLOAT_EXT` |
| * [[VUID-VkDepthBiasRepresentationInfoEXT-depthBiasExact-08949]] |
| If the <<features-depthBiasExact, pname:depthBiasExact>> feature is not |
| enabled, pname:depthBiasExact must: be `VK_FALSE` |
| **** |
| |
| include::{generated}/validity/structs/VkDepthBiasRepresentationInfoEXT.adoc[] |
| -- |
| |
| [open,refpage='VkDepthBiasRepresentationEXT',desc='Specify the depth bias representation',type='enums'] |
| -- |
| Possible values of |
| slink:VkDepthBiasRepresentationInfoEXT::pname:depthBiasRepresentation, |
| specifying the depth bias representation are: |
| |
| include::{generated}/api/enums/VkDepthBiasRepresentationEXT.adoc[] |
| |
| * ename:VK_DEPTH_BIAS_REPRESENTATION_LEAST_REPRESENTABLE_VALUE_FORMAT_EXT |
| specifies that the depth bias representation is a factor of the format's |
| [eq]#r# as described in <<primsrast-depthbias-computation>>. |
| * ename:VK_DEPTH_BIAS_REPRESENTATION_LEAST_REPRESENTABLE_VALUE_FORCE_UNORM_EXT |
| specifies that the depth bias representation is a factor of a constant |
| [eq]#r# defined by the bit-size or mantissa of the format as described |
| in <<primsrast-depthbias-computation>>. |
| * ename:VK_DEPTH_BIAS_REPRESENTATION_FLOAT_EXT specifies that the depth |
| bias representation is a factor of constant [eq]#r# equal to 1. |
| -- |
| |
| [open,refpage='VkDepthBiasInfoEXT',desc='Structure specifying depth bias parameters',type='structs'] |
| -- |
| :refpage: VkDepthBiasInfoEXT |
| |
| The sname:VkDepthBiasInfoEXT structure is defined as: |
| |
| include::{generated}/api/structs/VkDepthBiasInfoEXT.adoc[] |
| |
| * pname:sType is a elink:VkStructureType value identifying this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:depthBiasConstantFactor is a scalar factor controlling the |
| constant depth value added to each fragment. |
| * pname:depthBiasClamp is the maximum (or minimum) depth bias of a |
| fragment. |
| * pname:depthBiasSlopeFactor is a scalar factor applied to a fragment's |
| slope in depth bias calculations. |
| |
| If pname:pNext does not contain a slink:VkDepthBiasRepresentationInfoEXT |
| structure, then this command is equivalent to including a |
| slink:VkDepthBiasRepresentationInfoEXT with pname:depthBiasExact set to |
| ename:VK_FALSE and pname:depthBiasRepresentation set to |
| ename:VK_DEPTH_BIAS_REPRESENTATION_LEAST_REPRESENTABLE_VALUE_FORMAT_EXT. |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkDepthBiasInfoEXT-depthBiasClamp-08950]] |
| If the <<features-depthBiasClamp, pname:depthBiasClamp>> feature is not |
| enabled, pname:depthBiasClamp must: be `0.0` |
| **** |
| |
| include::{generated}/validity/structs/VkDepthBiasInfoEXT.adoc[] |
| -- |
| |
| [open,refpage='vkCmdSetDepthBias2EXT',desc='Set depth bias factors and clamp dynamically for a command buffer',type='protos'] |
| -- |
| To <<pipelines-dynamic-state, dynamically set>> the depth bias parameters, |
| call: |
| |
| include::{generated}/api/protos/vkCmdSetDepthBias2EXT.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command will be |
| recorded. |
| * pname:pDepthBiasInfo is a pointer to a slink:VkDepthBiasInfoEXT |
| structure specifying depth bias parameters. |
| |
| This command is functionally identical to flink:vkCmdSetDepthBias, but |
| includes extensible sub-structures that include pname:sType and pname:pNext |
| parameters, allowing them to be more easily extended. |
| |
| include::{generated}/validity/protos/vkCmdSetDepthBias2EXT.adoc[] |
| -- |
| endif::VK_EXT_depth_bias_control[] |
| |
| ifdef::VK_EXT_conservative_rasterization[] |
| [[primsrast-conservativeraster]] |
| === Conservative Rasterization |
| |
| [open,refpage='VkPipelineRasterizationConservativeStateCreateInfoEXT',desc='Structure specifying conservative raster state',type='structs'] |
| -- |
| If the pname:pNext chain of slink:VkPipelineRasterizationStateCreateInfo |
| includes a sname:VkPipelineRasterizationConservativeStateCreateInfoEXT |
| structure, then that structure includes parameters controlling conservative |
| rasterization. |
| |
| sname:VkPipelineRasterizationConservativeStateCreateInfoEXT is defined as: |
| |
| include::{generated}/api/structs/VkPipelineRasterizationConservativeStateCreateInfoEXT.adoc[] |
| |
| * pname:sType is a elink:VkStructureType value identifying this structure. |
| * pname:pNext is `NULL` or a pointer to a structure extending this |
| structure. |
| * pname:flags is reserved for future use. |
| * pname:conservativeRasterizationMode is the conservative rasterization |
| mode to use. |
| * pname:extraPrimitiveOverestimationSize is the extra size in pixels to |
| increase the generating primitive during conservative rasterization at |
| each of its edges in `X` and `Y` equally in screen space beyond the base |
| overestimation specified in |
| sname:VkPhysicalDeviceConservativeRasterizationPropertiesEXT::pname:primitiveOverestimationSize. |
| If pname:conservativeRasterizationMode is not |
| ename:VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT, this value is |
| ignored. |
| |
| If this structure is not included in the pname:pNext chain, |
| pname:conservativeRasterizationMode is considered to be |
| ename:VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT, and and conservative |
| rasterization is disabled. |
| |
| Polygon rasterization can: be made conservative by setting |
| pname:conservativeRasterizationMode to |
| ename:VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT or |
| ename:VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT in |
| sname:VkPipelineRasterizationConservativeStateCreateInfoEXT. |
| |
| [NOTE] |
| .Note |
| ==== |
| If <<limits-conservativePointAndLineRasterization, |
| pname:conservativePointAndLineRasterization>> is supported, conservative |
| rasterization can be applied to line and point primitives, otherwise it must |
| be disabled. |
| ==== |
| |
| .Valid Usage |
| **** |
| * [[VUID-VkPipelineRasterizationConservativeStateCreateInfoEXT-extraPrimitiveOverestimationSize-01769]] |
| pname:extraPrimitiveOverestimationSize must: be in the range of `0.0` to |
| sname:VkPhysicalDeviceConservativeRasterizationPropertiesEXT::pname:maxExtraPrimitiveOverestimationSize |
| inclusive |
| **** |
| |
| include::{generated}/validity/structs/VkPipelineRasterizationConservativeStateCreateInfoEXT.adoc[] |
| -- |
| |
| [open,refpage='VkPipelineRasterizationConservativeStateCreateFlagsEXT',desc='Reserved for future use',type='flags'] |
| -- |
| include::{generated}/api/flags/VkPipelineRasterizationConservativeStateCreateFlagsEXT.adoc[] |
| |
| tname:VkPipelineRasterizationConservativeStateCreateFlagsEXT is a bitmask |
| type for setting a mask, but is currently reserved for future use. |
| -- |
| |
| [open,refpage='VkConservativeRasterizationModeEXT',desc='Specify the conservative rasterization mode',type='enums'] |
| -- |
| Possible values of |
| slink:VkPipelineRasterizationConservativeStateCreateInfoEXT::pname:conservativeRasterizationMode, |
| specifying the conservative rasterization mode are: |
| |
| include::{generated}/api/enums/VkConservativeRasterizationModeEXT.adoc[] |
| |
| * ename:VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT specifies that |
| conservative rasterization is disabled and rasterization proceeds as |
| normal. |
| * ename:VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT specifies that |
| conservative rasterization is enabled in overestimation mode. |
| * ename:VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT specifies |
| that conservative rasterization is enabled in underestimation mode. |
| -- |
| |
| ifdef::VK_EXT_extended_dynamic_state3,VK_EXT_shader_object[] |
| |
| [open,refpage='vkCmdSetConservativeRasterizationModeEXT',desc='Specify the conservative rasterization mode dynamically for a command buffer',type='protos'] |
| -- |
| To <<pipelines-dynamic-state, dynamically set>> the |
| pname:conservativeRasterizationMode, call: |
| |
| include::{generated}/api/protos/vkCmdSetConservativeRasterizationModeEXT.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command will be |
| recorded. |
| * pname:conservativeRasterizationMode specifies the |
| pname:conservativeRasterizationMode state. |
| |
| This command sets the pname:conservativeRasterizationMode state for |
| subsequent drawing commands |
| ifdef::VK_EXT_shader_object[] |
| ifdef::VK_EXT_extended_dynamic_state3[when drawing using <<shaders-objects, shader objects>>, or] |
| ifndef::VK_EXT_extended_dynamic_state3[when drawing using <<shaders-objects, shader objects>>.] |
| endif::VK_EXT_shader_object[] |
| ifdef::VK_EXT_extended_dynamic_state3[] |
| when the graphics pipeline is created with |
| ename:VK_DYNAMIC_STATE_CONSERVATIVE_RASTERIZATION_MODE_EXT set in |
| slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates. |
| endif::VK_EXT_extended_dynamic_state3[] |
| Otherwise, this state is specified by the |
| slink:VkPipelineRasterizationConservativeStateCreateInfoEXT::pname:conservativeRasterizationMode |
| value used to create the currently active pipeline. |
| |
| :refpage: vkCmdSetConservativeRasterizationModeEXT |
| :requiredfeature: extendedDynamicState3ConservativeRasterizationMode |
| |
| .Valid Usage |
| **** |
| include::{chapters}/commonvalidity/dynamic_state3_feature_common.adoc[] |
| **** |
| |
| include::{generated}/validity/protos/vkCmdSetConservativeRasterizationModeEXT.adoc[] |
| -- |
| |
| [open,refpage='vkCmdSetExtraPrimitiveOverestimationSizeEXT',desc='Specify the conservative rasterization extra primitive overestimation size dynamically for a command buffer',type='protos'] |
| -- |
| To <<pipelines-dynamic-state, dynamically set>> the |
| pname:extraPrimitiveOverestimationSize, call: |
| |
| include::{generated}/api/protos/vkCmdSetExtraPrimitiveOverestimationSizeEXT.adoc[] |
| |
| * pname:commandBuffer is the command buffer into which the command will be |
| recorded. |
| * pname:extraPrimitiveOverestimationSize specifies the |
| pname:extraPrimitiveOverestimationSize. |
| |
| This command sets the pname:extraPrimitiveOverestimationSize for subsequent |
| drawing commands |
| ifdef::VK_EXT_shader_object[] |
| ifdef::VK_EXT_extended_dynamic_state3[when drawing using <<shaders-objects, shader objects>>, or] |
| ifndef::VK_EXT_extended_dynamic_state3[when drawing using <<shaders-objects, shader objects>>.] |
| endif::VK_EXT_shader_object[] |
| ifdef::VK_EXT_extended_dynamic_state3[] |
| when the graphics pipeline is created with |
| ename:VK_DYNAMIC_STATE_EXTRA_PRIMITIVE_OVERESTIMATION_SIZE_EXT set in |
| slink:VkPipelineDynamicStateCreateInfo::pname:pDynamicStates. |
| endif::VK_EXT_extended_dynamic_state3[] |
| Otherwise, this state is specified by the |
| slink:VkPipelineRasterizationConservativeStateCreateInfoEXT::pname:extraPrimitiveOverestimationSize |
| value used to create the currently active pipeline. |
| |
| :refpage: vkCmdSetExtraPrimitiveOverestimationSizeEXT |
| :requiredfeature: extendedDynamicState3ExtraPrimitiveOverestimationSize |
| |
| .Valid Usage |
| **** |
| include::{chapters}/commonvalidity/dynamic_state3_feature_common.adoc[] |
| * [[VUID-vkCmdSetExtraPrimitiveOverestimationSizeEXT-extraPrimitiveOverestimationSize-07428]] |
| pname:extraPrimitiveOverestimationSize must: be in the range of `0.0` to |
| sname:VkPhysicalDeviceConservativeRasterizationPropertiesEXT::pname:maxExtraPrimitiveOverestimationSize |
| inclusive |
| **** |
| |
| include::{generated}/validity/protos/vkCmdSetExtraPrimitiveOverestimationSizeEXT.adoc[] |
| -- |
| |
| endif::VK_EXT_extended_dynamic_state3,VK_EXT_shader_object[] |
| |
| When overestimate conservative rasterization is enabled, rather than |
| evaluating coverage at individual sample locations, a determination is made |
| whether any portion of the pixel (including its edges and corners) is |
| covered by the primitive. |
| If any portion of the pixel is covered, then all bits of the |
| <<primsrast-multisampling-coverage-mask, coverage mask>> for the fragment |
| corresponding to that pixel are enabled. |
| ifdef::VK_EXT_fragment_density_map[] |
| If the render pass has a fragment density map attachment and any bit of the |
| <<primsrast-multisampling-coverage-mask, coverage mask>> for the fragment is |
| enabled, then all bits of the <<primsrast-multisampling-coverage-mask, |
| coverage mask>> for the fragment are enabled. |
| endif::VK_EXT_fragment_density_map[] |
| |
| For the purposes of evaluating which pixels are covered by the primitive, |
| implementations can: increase the size of the primitive by up to |
| sname:VkPhysicalDeviceConservativeRasterizationPropertiesEXT::pname:primitiveOverestimationSize |
| pixels at each of the primitive edges. |
| This may: increase the number of fragments generated by this primitive and |
| represents an overestimation of the pixel coverage. |
| |
| This overestimation size can be increased further by setting the |
| pname:extraPrimitiveOverestimationSize value above `0.0` in steps of |
| sname:VkPhysicalDeviceConservativeRasterizationPropertiesEXT::pname:extraPrimitiveOverestimationSizeGranularity |
| up to and including |
| sname:VkPhysicalDeviceConservativeRasterizationPropertiesEXT::pname:extraPrimitiveOverestimationSize. |
| This may: further increase the number of fragments generated by this |
| primitive. |
| |
| The actual precision of the overestimation size used for conservative |
| rasterization may: vary between implementations and produce results that |
| only approximate the pname:primitiveOverestimationSize and |
| pname:extraPrimitiveOverestimationSizeGranularity properties. |
| ifdef::VK_EXT_fragment_density_map[] |
| Implementations may: especially vary these approximations when the render |
| pass has a fragment density map and the fragment area covers multiple |
| pixels. |
| endif::VK_EXT_fragment_density_map[] |
| |
| For triangles if ename:VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT |
| is enabled, fragments will be generated if the primitive area covers any |
| portion of any pixel inside the fragment area, including their edges or |
| corners. |
| The tie-breaking rule described in <<primsrast-polygons-basic, Basic Polygon |
| Rasterization>> does not apply during conservative rasterization and |
| coverage is set for all fragments generated from shared edges of polygons. |
| Degenerate triangles that evaluate to zero area after rasterization, even |
| for pixels containing a vertex or edge of the zero-area polygon, will be |
| culled if |
| sname:VkPhysicalDeviceConservativeRasterizationPropertiesEXT::pname:degenerateTrianglesRasterized |
| is ename:VK_FALSE or will generate fragments if |
| pname:degenerateTrianglesRasterized is ename:VK_TRUE. |
| The fragment input values for these degenerate triangles take their |
| attribute and depth values from the provoking vertex. |
| Degenerate triangles are considered backfacing and the application can: |
| enable backface culling if desired. |
| Triangles that are zero area before rasterization may: be culled regardless. |
| |
| For lines if ename:VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT is |
| enabled, and the implementation sets |
| sname:VkPhysicalDeviceConservativeRasterizationPropertiesEXT::pname:conservativePointAndLineRasterization |
| to ename:VK_TRUE, fragments will be generated if the line covers any portion |
| of any pixel inside the fragment area, including their edges or corners. |
| Degenerate lines that evaluate to zero length after rasterization will be |
| culled if |
| sname:VkPhysicalDeviceConservativeRasterizationPropertiesEXT::pname:degenerateLinesRasterized |
| is ename:VK_FALSE or will generate fragments if |
| pname:degenerateLinesRasterized is ename:VK_TRUE. |
| The fragments input values for these degenerate lines take their attribute |
| and depth values from the provoking vertex. |
| Lines that are zero length before rasterization may: be culled regardless. |
| |
| For points if ename:VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT is |
| enabled, and the implementation sets |
| sname:VkPhysicalDeviceConservativeRasterizationPropertiesEXT::pname:conservativePointAndLineRasterization |
| to ename:VK_TRUE, fragments will be generated if the point square covers any |
| portion of any pixel inside the fragment area, including their edges or |
| corners. |
| |
| When underestimate conservative rasterization is enabled, rather than |
| evaluating coverage at individual sample locations, a determination is made |
| whether all of the pixel (including its edges and corners) is covered by the |
| primitive. |
| If the entire pixel is covered, then a fragment is generated with all bits |
| of its <<primsrast-multisampling-coverage-mask, coverage mask>> |
| corresponding to the pixel enabled, otherwise the pixel is not considered |
| covered even if some portion of the pixel is covered. |
| The fragment is discarded if no pixels inside the fragment area are |
| considered covered. |
| ifdef::VK_EXT_fragment_density_map[] |
| If the render pass has a fragment density map attachment and any pixel |
| inside the fragment area is not considered covered, then the fragment is |
| discarded even if some pixels are considered covered. |
| endif::VK_EXT_fragment_density_map[] |
| |
| For triangles, if ename:VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT |
| is enabled, fragments will only be generated if any pixel inside the |
| fragment area is fully covered by the generating primitive, including its |
| edges and corners. |
| |
| For lines, if ename:VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT is |
| enabled, fragments will be generated if any pixel inside the fragment area, |
| including its edges and corners, are entirely covered by the line. |
| |
| For points, if ename:VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT is |
| enabled, fragments will only be generated if the point square covers the |
| entirety of any pixel square inside the fragment area, including its edges |
| or corners. |
| |
| ifdef::VK_EXT_fragment_density_map[] |
| If the render pass has a fragment density map and |
| ename:VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT is enabled, |
| fragments will only be generated if the entirety of all pixels inside the |
| fragment area are covered by the generating primitive, line, or point. |
| endif::VK_EXT_fragment_density_map[] |
| |
| For both overestimate and underestimate conservative rasterization modes a |
| fragment has all of its pixel squares fully covered by the generating |
| primitive must: set code:FullyCoveredEXT to ename:VK_TRUE if the |
| implementation enables the |
| sname:VkPhysicalDeviceConservativeRasterizationPropertiesEXT::pname:fullyCoveredFragmentShaderInputVariable |
| feature. |
| |
| ifdef::VK_NV_shading_rate_image,VK_KHR_fragment_shading_rate[] |
| When |
| ifdef::VK_NV_shading_rate_image[] |
| the use of a <<primsrast-shading-rate-image, shading rate image>> |
| endif::VK_NV_shading_rate_image[] |
| ifdef::VK_NV_shading_rate_image+VK_KHR_fragment_shading_rate[or] |
| ifdef::VK_KHR_fragment_shading_rate[] |
| setting the <<primsrast-fragment-shading-rate, fragment shading rate>> |
| endif::VK_KHR_fragment_shading_rate[] |
| results in fragments covering multiple pixels, coverage for conservative |
| rasterization is still evaluated on a per-pixel basis and may result in |
| fragments with partial coverage. |
| For fragment shader inputs decorated with code:FullyCoveredEXT, a fragment |
| is considered fully covered if and only if all pixels in the fragment are |
| fully covered by the generating primitive. |
| endif::VK_NV_shading_rate_image,VK_KHR_fragment_shading_rate[] |
| |
| endif::VK_EXT_conservative_rasterization[] |