2337 lines
105 KiB
Plaintext
2337 lines
105 KiB
Plaintext
// Copyright (c) 2015-2019 Khronos Group. This work is licensed under a
|
|
// Creative Commons Attribution 4.0 International License; see
|
|
// http://creativecommons.org/licenses/by/4.0/
|
|
|
|
[[primsrast]]
|
|
= Rasterization
|
|
|
|
Rasterization is the process by which a primitive is converted to a
|
|
two-dimensional image.
|
|
Each point 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 the <<fragops-early,early
|
|
per-fragment tests>>, if enabled.
|
|
|
|
Several factors affect rasterization, including the members of
|
|
sname:VkPipelineRasterizationStateCreateInfo and
|
|
sname: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.txt[]
|
|
|
|
* pname:sType is the type of this structure.
|
|
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
|
|
* pname:flags is reserved for future use.
|
|
* pname: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
|
|
sname: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 sname:VkPipelineRasterizationStateCreateInfo
|
|
structure.
|
|
This structure enables selecting the rasterization order to use when
|
|
rendering with the corresponding graphics pipeline as described in
|
|
<<primrast-order, Rasterization Order>>.
|
|
endif::VK_AMD_rasterization_order[]
|
|
|
|
.Valid Usage
|
|
****
|
|
* [[VUID-VkPipelineRasterizationStateCreateInfo-depthClampEnable-00782]]
|
|
If the <<features-depthClamp,depth clamping>> feature is not enabled,
|
|
pname:depthClampEnable must: be ename:VK_FALSE
|
|
ifndef::VK_NV_fill_rectangle[]
|
|
* [[VUID-VkPipelineRasterizationStateCreateInfo-polygonMode-01413]]
|
|
If the <<features-fillModeNonSolid,non-solid fill modes>> feature is not
|
|
enabled, pname:polygonMode must: be ename:VK_POLYGON_MODE_FILL
|
|
endif::VK_NV_fill_rectangle[]
|
|
ifdef::VK_NV_fill_rectangle[]
|
|
* [[VUID-VkPipelineRasterizationStateCreateInfo-polygonMode-01507]]
|
|
If the <<features-fillModeNonSolid,non-solid fill modes>> feature is not
|
|
enabled, pname:polygonMode must: be ename:VK_POLYGON_MODE_FILL or
|
|
ename:VK_POLYGON_MODE_FILL_RECTANGLE_NV
|
|
* [[VUID-VkPipelineRasterizationStateCreateInfo-polygonMode-01414]]
|
|
If the `<<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/structs/VkPipelineRasterizationStateCreateInfo.txt[]
|
|
--
|
|
|
|
[open,refpage='VkPipelineRasterizationStateCreateFlags',desc='Reserved for future use',type='flags']
|
|
--
|
|
include::{generated}/api/flags/VkPipelineRasterizationStateCreateFlags.txt[]
|
|
|
|
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 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.txt[]
|
|
|
|
* pname:sType is the type of this structure.
|
|
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
|
|
* pname:flags is reserved for future use.
|
|
* pname:depthClipEnable controls whether depth clipping is enabled as
|
|
described in <<vertexpostproc-clipping, Primitive Clipping>>.
|
|
|
|
include::{generated}/validity/structs/VkPipelineRasterizationDepthClipStateCreateInfoEXT.txt[]
|
|
--
|
|
|
|
[open,refpage='VkPipelineRasterizationDepthClipStateCreateFlagsEXT',desc='Reserved for future use',type='flags']
|
|
--
|
|
include::{generated}/api/flags/VkPipelineRasterizationDepthClipStateCreateFlagsEXT.txt[]
|
|
|
|
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.txt[]
|
|
|
|
* pname:sType is the type of this structure.
|
|
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
|
|
* pname:flags is reserved for future use.
|
|
* pname:rasterizationSamples is a elink:VkSampleCountFlagBits specifying
|
|
the number of samples used in rasterization.
|
|
* 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 bitmask of static coverage information that is
|
|
ANDed with the coverage information generated during rasterization, as
|
|
described in <<fragops-samplemask,Sample Mask>>.
|
|
* 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>>.
|
|
|
|
.Valid Usage
|
|
****
|
|
* [[VUID-VkPipelineMultisampleStateCreateInfo-sampleShadingEnable-00784]]
|
|
If the <<features-sampleRateShading,sample rate shading>> feature is not
|
|
enabled, pname:sampleShadingEnable must: be ename:VK_FALSE
|
|
* [[VUID-VkPipelineMultisampleStateCreateInfo-alphaToOneEnable-00785]]
|
|
If the <<features-alphaToOne,alpha to one>> 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 `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.txt[]
|
|
--
|
|
|
|
[open,refpage='VkPipelineMultisampleStateCreateFlags',desc='Reserved for future use',type='flags']
|
|
--
|
|
include::{generated}/api/flags/VkPipelineMultisampleStateCreateFlags.txt[]
|
|
|
|
tname:VkPipelineMultisampleStateCreateFlags is a bitmask type for setting a
|
|
mask, but is currently reserved for future use.
|
|
--
|
|
|
|
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 early per-fragment tests described in
|
|
<<fragops-early,Early Per-Fragment Tests>>.
|
|
|
|
Surviving fragments are processed by fragment shaders.
|
|
Fragment shaders determine associated data for fragments, and can: also
|
|
modify or replace their assigned depth values.
|
|
|
|
When the `VK_AMD_mixed_attachment_samples` and
|
|
`VK_NV_framebuffer_mixed_samples` extensions are not enabled, if the subpass
|
|
for which this pipeline is being created uses color and/or depth/stencil
|
|
attachments, then pname:rasterizationSamples must: be the same as the sample
|
|
count for those subpass attachments.
|
|
|
|
ifdef::VK_AMD_mixed_attachment_samples[]
|
|
|
|
When the `VK_AMD_mixed_attachment_samples` extension is enabled, if the
|
|
subpass for which this pipeline is being created uses color and/or
|
|
depth/stencil attachments, then pname:rasterizationSamples must: be the same
|
|
as the maximum of the sample counts of those subpass attachments.
|
|
|
|
endif::VK_AMD_mixed_attachment_samples[]
|
|
|
|
ifdef::VK_NV_framebuffer_mixed_samples[]
|
|
|
|
When the `VK_NV_framebuffer_mixed_samples` extension is enabled,
|
|
pname:rasterizationSamples must: match the sample count of the depth/stencil
|
|
attachment if present, otherwise must: be greater than or equal to the
|
|
sample count of the color attachments, if present.
|
|
|
|
endif::VK_NV_framebuffer_mixed_samples[]
|
|
|
|
ifdef::VK_NV_coverage_reduction_mode[]
|
|
|
|
If the `VK_NV_coverage_reduction_mode` extension is enabled, the coverage
|
|
reduction mode specified by
|
|
slink:VkPipelineCoverageReductionStateCreateInfoNV::pname:coverageReductionMode,
|
|
the pname:rasterizationSamples member of pname:pMultisampleState and the
|
|
sample counts for the color and depth/stencil attachments (if present) must:
|
|
be a valid combination returned by
|
|
fname:vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV
|
|
|
|
endif::VK_NV_coverage_reduction_mode[]
|
|
|
|
If the subpass for which this pipeline is being created does not use color
|
|
or depth/stencil attachments, pname:rasterizationSamples must: follow the
|
|
rules for a <<renderpass-noattachments, zero-attachment subpass>>.
|
|
|
|
[[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_EXT_transform_feedback[]
|
|
|
|
[[primsrast-stream]]
|
|
== Controlling the Vertex Stream Used for Rasterization
|
|
|
|
By default vertex data output from the last vertex processing 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 vertex processing 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.txt[]
|
|
|
|
* pname:sType is the type of this structure.
|
|
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
|
|
* pname:flags is reserved for future use.
|
|
* pname: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.txt[]
|
|
--
|
|
|
|
[open,refpage='VkPipelineRasterizationStateStreamCreateFlagsEXT',desc='Reserved for future use',type='flags']
|
|
--
|
|
include::{generated}/api/flags/VkPipelineRasterizationStateStreamCreateFlagsEXT.txt[]
|
|
|
|
tname:VkPipelineRasterizationStateStreamCreateFlagsEXT is a bitmask type for
|
|
setting a mask, but is currently reserved for future use.
|
|
--
|
|
|
|
endif::VK_EXT_transform_feedback[]
|
|
|
|
[[primrast-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-scissor,Scissor test>>
|
|
ifdef::VK_NV_scissor_exclusive[]
|
|
. <<fragops-exclusive-scissor,Exclusive scissor test>>
|
|
endif::VK_NV_scissor_exclusive[]
|
|
. <<fragops-samplemask,Sample mask generation>>
|
|
. <<fragops-dbt,Depth bounds test>>
|
|
. <<fragops-stencil, Stencil test, stencil op and stencil write>>
|
|
. <<fragops-depth, Depth test and depth write>>
|
|
. <<fragops-samplecount,Sample counting>> for
|
|
<<queries-occlusion,occlusion queries>>
|
|
ifdef::VK_NV_fragment_coverage_to_color[]
|
|
. <<fragops-coverage-to-color,Fragment Coverage To Color>>
|
|
endif::VK_NV_fragment_coverage_to_color[]
|
|
. <<fragops-coverage-reduction,coverage reduction>>
|
|
. <<framebuffer-blending, Blending>>, <<framebuffer-logicop, logic
|
|
operations>>, and color writes
|
|
|
|
Each of these operations is atomically executed for each primitive and
|
|
sample location.
|
|
|
|
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.txt[]
|
|
|
|
* pname:sType is the type of this structure.
|
|
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
|
|
* pname:rasterizationOrder is a elink:VkRasterizationOrderAMD value
|
|
specifying the primitive rasterization order to use.
|
|
|
|
include::{generated}/validity/structs/VkPipelineRasterizationStateRasterizationOrderAMD.txt[]
|
|
|
|
If the `<<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.txt[]
|
|
|
|
* 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 coverage value with pname:rasterizationSamples bits
|
|
(see <<fragops-samplemask,Sample Mask>>).
|
|
Each fragment includes pname:rasterizationSamples depth values and sets of
|
|
associated data.
|
|
An implementation may: choose to assign the same associated data to more
|
|
than one sample.
|
|
The location for evaluating such associated data may: be anywhere within the
|
|
fragment area including the fragment's center location [eq]#(x~f~,y~f~)# or
|
|
any of the sample locations.
|
|
When pname:rasterizationSamples is ename:VK_SAMPLE_COUNT_1_BIT, the
|
|
fragment's center location must: be used.
|
|
The different associated data values need not all be evaluated at the same
|
|
location.
|
|
Each fragment thus consists of integer x and y grid coordinates,
|
|
pname:rasterizationSamples depth values and sets of associated data, and a
|
|
coverage value with pname:rasterizationSamples bits.
|
|
|
|
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.
|
|
|
|
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 bit [eq]#i# in the sample masks.
|
|
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
|
|
[align="center"]
|
|
|====
|
|
|ename:VK_SAMPLE_COUNT_1_BIT|ename:VK_SAMPLE_COUNT_2_BIT|ename:VK_SAMPLE_COUNT_4_BIT|ename:VK_SAMPLE_COUNT_8_BIT|ename:VK_SAMPLE_COUNT_16_BIT
|
|
|
|
|
[eq]#(0.5,0.5)#
|
|
|
|
|
[eq]#(0.75,0.75)# +
|
|
[eq]#(0.25,0.25)#
|
|
|
|
|
[eq]#(0.375, 0.125)# +
|
|
[eq]#(0.875, 0.375)# +
|
|
[eq]#(0.125, 0.625)# +
|
|
[eq]#(0.625, 0.875)#
|
|
|
|
|
[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)#
|
|
|
|
|
[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_1.svg[align="center",opts="{imageopts}"]
|
|
|image:{images}/sample_count_2.svg[align="center",opts="{imageopts}"]
|
|
|image:{images}/sample_count_4.svg[align="center",opts="{imageopts}"]
|
|
|image:{images}/sample_count_8.svg[align="center",opts="{imageopts}"]
|
|
|image:{images}/sample_count_16.svg[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 `<<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[]
|
|
|
|
[[primrast-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 an instance of the
|
|
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.txt[]
|
|
|
|
* pname:sType is the type of this structure.
|
|
* pname:pNext is `NULL` or a pointer to an extension-specific 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.txt[]
|
|
--
|
|
|
|
[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.txt[]
|
|
|
|
* pname:sType is the type of this structure.
|
|
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
|
|
* pname:sampleLocationsPerPixel is a elink:VkSampleCountFlagBits
|
|
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 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 + y *
|
|
pname:sampleLocationGridSize.width) * pname:sampleLocationsPerPixel + 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.txt[]
|
|
--
|
|
|
|
[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.txt[]
|
|
|
|
* 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 by chaining the
|
|
slink:VkPhysicalDeviceSampleLocationsPropertiesEXT structure to the
|
|
pname:pNext chain of slink:VkPhysicalDeviceProperties2.
|
|
|
|
include::{generated}/validity/structs/VkSampleLocationEXT.txt[]
|
|
--
|
|
|
|
[open,refpage='vkCmdSetSampleLocationsEXT',desc='Set the dynamic sample locations state',type='protos']
|
|
--
|
|
The custom sample locations used for rasterization when
|
|
sname:VkPipelineSampleLocationsStateCreateInfoEXT::pname:sampleLocationsEnable
|
|
is ename:VK_TRUE are specified by the
|
|
sname:VkPipelineSampleLocationsStateCreateInfoEXT::pname:sampleLocationsInfo
|
|
property of the bound graphics pipeline, if the pipeline was not created
|
|
with ename:VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT enabled.
|
|
|
|
Otherwise, the sample locations used for rasterization are set by calling
|
|
fname:vkCmdSetSampleLocationsEXT:
|
|
|
|
include::{generated}/api/protos/vkCmdSetSampleLocationsEXT.txt[]
|
|
|
|
* pname:commandBuffer is the command buffer into which the command will be
|
|
recorded.
|
|
* pname:pSampleLocationsInfo is the sample locations state to set.
|
|
|
|
.Valid Usage
|
|
****
|
|
* [[VUID-vkCmdSetSampleLocationsEXT-None-01528]]
|
|
The bound graphics pipeline must: have been created with the
|
|
ename:VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT dynamic state enabled
|
|
* [[VUID-vkCmdSetSampleLocationsEXT-sampleLocationsPerPixel-01529]]
|
|
The pname:sampleLocationsPerPixel member of pname:pSampleLocationsInfo
|
|
must: equal the pname:rasterizationSamples member of the
|
|
slink:VkPipelineMultisampleStateCreateInfo structure the bound graphics
|
|
pipeline has been created with
|
|
* [[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.txt[]
|
|
--
|
|
|
|
endif::VK_EXT_sample_locations[]
|
|
|
|
ifdef::VK_NV_shading_rate_image[]
|
|
|
|
[[primsrast-shading-rate-image]]
|
|
== Shading Rate Image
|
|
|
|
The <<features-shadingRateImage, shading rate image>> 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,
|
|
which 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 that control the shading rate.
|
|
|
|
The sname:VkPipelineViewportShadingRateImageStateCreateInfoNV structure is
|
|
defined as:
|
|
|
|
include::{generated}/api/structs/VkPipelineViewportShadingRateImageStateCreateInfoNV.txt[]
|
|
|
|
* pname:sType is the type of this structure.
|
|
* pname:pNext is `NULL` or a pointer to an extension-specific 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,multiple viewports>> 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 equal to the pname:viewportCount member of
|
|
sname:VkPipelineViewportStateCreateInfo
|
|
* [[VUID-VkPipelineViewportShadingRateImageStateCreateInfoNV-pDynamicStates-02057]]
|
|
If no element of the pname:pDynamicStates member of pname:pDynamicState
|
|
is ename:VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV,
|
|
pname:pShadingRatePalettes must: be a valid pointer to an array of
|
|
pname:viewportCount sname:VkShadingRatePaletteNV structures
|
|
****
|
|
include::{generated}/validity/structs/VkPipelineViewportShadingRateImageStateCreateInfoNV.txt[]
|
|
--
|
|
|
|
[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.txt[]
|
|
|
|
* pname:commandBuffer is the command buffer into which the command will be
|
|
recorded.
|
|
* pname:imageView is an image view handle that specifies 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,shading rate image>> 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.txt[]
|
|
--
|
|
|
|
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 = \lfloor
|
|
\frac{x}{twidth} \rfloor], latexmath:[v = \lfloor \frac{y}{theight}
|
|
\rfloor], and latexmath:[twidth] and latexmath:[theight] are the width and
|
|
height of the implementation-dependent <<limits-shading-rate-texel-size,
|
|
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-shading-rate-palette-size, shading rate
|
|
image palette size>>.
|
|
|
|
[open,refpage='vkCmdSetViewportShadingRatePaletteNV',desc='Set shading rate image palettes on a command buffer',type='protos']
|
|
--
|
|
|
|
If a pipeline state object is created with
|
|
ename:VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV enabled, the
|
|
per-viewport shading rate image palettes are set by the command:
|
|
|
|
include::{generated}/api/protos/vkCmdSetViewportShadingRatePaletteNV.txt[]
|
|
|
|
* 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.
|
|
|
|
.Valid Usage
|
|
****
|
|
* [[VUID-vkCmdSetViewportShadingRatePaletteNV-None-02064]]
|
|
The <<features-shadingRateImage,shading rate image>> feature must: be
|
|
enabled.
|
|
* [[VUID-vkCmdSetViewportShadingRatePaletteNV-None-02065]]
|
|
The bound graphics pipeline must: have been created with the
|
|
ename:VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV dynamic state
|
|
enabled
|
|
* [[VUID-vkCmdSetViewportShadingRatePaletteNV-firstViewport-02066]]
|
|
pname:firstViewport must: be less than
|
|
sname:VkPhysicalDeviceLimits::pname:maxViewports
|
|
* [[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,multiple viewports>> feature is not
|
|
enabled, pname:firstViewport must: be `0`
|
|
* [[VUID-vkCmdSetViewportShadingRatePaletteNV-viewportCount-02069]]
|
|
If the <<features-multiViewport,multiple viewports>> feature is not
|
|
enabled, pname:viewportCount must: be `1`
|
|
****
|
|
|
|
include::{generated}/validity/protos/vkCmdSetViewportShadingRatePaletteNV.txt[]
|
|
--
|
|
|
|
[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.txt[]
|
|
|
|
* 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.txt[]
|
|
--
|
|
|
|
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.txt[]
|
|
|
|
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-shading-rate-max-coarse-samples, 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
|
|
code:totalSamples 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 the value of code:totalSamples used for
|
|
<<primsrast-sampleshading, sample shading>>.
|
|
|
|
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}
|
|
\lfloor \frac{x}{fw} \rfloor == \lfloor \frac{x'}{fw} \rfloor
|
|
\end{aligned}
|
|
+++++++++++++++++++
|
|
[latexmath]
|
|
+++++++++++++++++++
|
|
\begin{aligned}
|
|
\lfloor \frac{y}{fh} \rfloor == \lfloor \frac{y'}{fh} \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 <<primrast-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 sample number in the range [0,_samples_-1].
|
|
If the
|
|
<<features-shadingRateCoarseSampleOrder,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 that control the order of coverage
|
|
samples in fragments larger than one pixel.
|
|
|
|
The sname:VkPipelineViewportCoarseSampleOrderStateCreateInfoNV structure is
|
|
defined as:
|
|
|
|
include::{generated}/api/structs/VkPipelineViewportCoarseSampleOrderStateCreateInfoNV.txt[]
|
|
|
|
* pname:sType is the type of this structure.
|
|
* pname:pNext is `NULL` or a pointer to an extension-specific 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
|
|
slink:VkCoarseSampleOrderCustomNV structures, each of which specifies
|
|
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.txt[]
|
|
--
|
|
|
|
[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.txt[]
|
|
|
|
* 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 coverage sample number.
|
|
* ename:VK_COARSE_SAMPLE_ORDER_TYPE_SAMPLE_MAJOR_NV specifies that
|
|
coverage samples will be ordered sequentially, sorted first by coverage
|
|
sample number 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] coverage samples per pixel, sample
|
|
latexmath:[cs] of the fragment will be assigned to sample latexmath:[fs] of
|
|
pixel latexmath:[(px,py)] will be assigned as follows:
|
|
|
|
[latexmath]
|
|
+++++++++++++++++++
|
|
\begin{aligned}
|
|
px = & fx + (\lfloor {cs \over fsc} \rfloor \text{ \% } fw) \\
|
|
py = & fy + \lfloor {cs \over {fsc \times fw}} \rfloor \\
|
|
fs = & cs \text{ \% } fsc
|
|
\end{aligned}
|
|
+++++++++++++++++++
|
|
|
|
When using a coarse sample order of
|
|
ename:VK_COARSE_SAMPLE_ORDER_TYPE_SAMPLE_MAJOR_NV, sample latexmath:[cs]
|
|
will be assigned as follows:
|
|
|
|
[latexmath]
|
|
+++++++++++++++++++
|
|
\begin{aligned}
|
|
px = & fx + cs \text{ \% } fw \\
|
|
py = & (fy + \lfloor {cs \over fw} \rfloor \text{ \% } fh) \\
|
|
fs = & \lfloor {cs \over {fw \times fh}} \rfloor
|
|
\end{aligned}
|
|
+++++++++++++++++++
|
|
|
|
[open,refpage='VkCoarseSampleOrderCustomNV',desc='Structure specifying parameters controlling shading rate image usage',type='structs']
|
|
--
|
|
|
|
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.
|
|
The structure is defined as:
|
|
|
|
include::{generated}/api/structs/VkCoarseSampleOrderCustomNV.txt[]
|
|
|
|
* 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:VkCoarseSampleOrderCustomNV structures that specifies the location
|
|
of each sample in the custom ordering.
|
|
|
|
When using a custom sample ordering, element _i_ in pname:pSampleLocations
|
|
specifies a specific pixel and per-pixel coverage sample number that
|
|
corresponds to the coverage sample numbered _i_ 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.txt[]
|
|
--
|
|
|
|
[open,refpage='VkCoarseSampleLocationNV',desc='Structure specifying parameters controlling shading rate image usage',type='structs']
|
|
--
|
|
|
|
The sname:VkCoarseSampleLocationNV structure identifies a specific pixel and
|
|
sample number 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.txt[]
|
|
|
|
* 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.txt[]
|
|
--
|
|
|
|
[open,refpage='vkCmdSetCoarseSampleOrderNV',desc='Set sample order for coarse fragments on a command buffer',type='protos']
|
|
--
|
|
|
|
If a pipeline state object is created with
|
|
ename:VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV enabled, the order of
|
|
coverage samples in fragments larger than one pixel is set by the command:
|
|
|
|
include::{generated}/api/protos/vkCmdSetCoarseSampleOrderNV.txt[]
|
|
|
|
* 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 of which specifies
|
|
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.
|
|
|
|
.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.txt[]
|
|
--
|
|
|
|
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: provide a minimum of
|
|
[eq]#max({lceil} pname:minSampleShadingFactor {times} pname:totalSamples
|
|
{rceil}, 1)# unique associated data for each fragment, where
|
|
pname:minSampleShadingFactor is the minimum fraction of sample shading.
|
|
ifdef::VK_AMD_mixed_attachment_samples[]
|
|
If the `VK_AMD_mixed_attachment_samples` extension is enabled and the
|
|
subpass uses color attachments, pname:totalSamples is the number of samples
|
|
of the color attachments.
|
|
Otherwise,
|
|
endif::VK_AMD_mixed_attachment_samples[]
|
|
pname:totalSamples is the value of
|
|
slink:VkPipelineMultisampleStateCreateInfo::pname:rasterizationSamples
|
|
specified at pipeline creation time.
|
|
These are associated with the samples in an implementation-dependent manner.
|
|
When pname:minSampleShadingFactor is `1.0`, a separate set of associated
|
|
data are evaluated for each sample, and each set of values is evaluated at
|
|
the sample location.
|
|
|
|
Sample shading is enabled for a graphics pipeline:
|
|
|
|
* If the interface of the fragment shader entry point of the graphics
|
|
pipeline includes an input variable decorated with code:SampleId or
|
|
code:SamplePosition.
|
|
In this case pname:minSampleShadingFactor takes the value `1.0`.
|
|
* Else if the pname:sampleShadingEnable member of the
|
|
slink:VkPipelineMultisampleStateCreateInfo structure specified when
|
|
creating the graphics pipeline is set to ename:VK_TRUE.
|
|
In this case pname:minSampleShadingFactor takes the value of
|
|
slink:VkPipelineMultisampleStateCreateInfo::pname:minSampleShading.
|
|
|
|
Otherwise, sample shading is considered disabled.
|
|
|
|
|
|
ifdef::VK_NV_fragment_shader_barycentric[]
|
|
|
|
[[primsrast-barycentric]]
|
|
== Barycentric Interpolation
|
|
|
|
When the pname:fragmentShaderBarycentric feature is enabled, the
|
|
code:PerVertexNV <<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.
|
|
|
|
ifndef::VK_NV_mesh_shader[]
|
|
When <<tessellation, tessellation>> and <<geometry, geometry shading>>
|
|
endif::VK_NV_mesh_shader[]
|
|
ifdef::VK_NV_mesh_shader[]
|
|
When <<tessellation, tessellation>>, <<geometry, geometry shading>>, and
|
|
<<mesh,mesh shading>>
|
|
endif::VK_NV_mesh_shader[]
|
|
are not active, fragment shader inputs decorated with code:PerVertexNV 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 for index values of 0, 1, and 2.
|
|
If an input decorated with code:PerVertexNV is accessed with any other
|
|
vertex index value, the value obtained is undefined.
|
|
|
|
[[primsrast-barycentric-order-table]]
|
|
[options="header"]
|
|
|======
|
|
| Primitive Topology | Vertex 0 | Vertex 1 | Vertex 2
|
|
| ename:VK_PRIMITIVE_TOPOLOGY_POINT_LIST | i | - | -
|
|
| ename:VK_PRIMITIVE_TOPOLOGY_LINE_LIST | 2i | 2i+1 | -
|
|
| ename:VK_PRIMITIVE_TOPOLOGY_LINE_STRIP | i | 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 | -
|
|
| ename:VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY | i+1 | 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
|
|
|======
|
|
|
|
When geometry
|
|
ifdef::VK_NV_mesh_shader[]
|
|
or mesh
|
|
endif::VK_NV_mesh_shader[]
|
|
shading is active, primitives processed by fragment shaders are assembled
|
|
from the vertices emitted by the geometry
|
|
ifdef::VK_NV_mesh_shader[]
|
|
or mesh
|
|
endif::VK_NV_mesh_shader[]
|
|
shader.
|
|
In this case, the vertices used for fragment shader inputs decorated with
|
|
code:PerVertexNV 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:PerVertexNV, the vertex ordering used in this case will be consistent
|
|
with the ordering used to derive the values of inputs decorated with
|
|
code::BaryCoordNV or code::BaryCoordNoPerspNV.
|
|
|
|
Fragment shader inputs decorated with code:BaryCoordNV or
|
|
code:BaryCoordNoPerspNV 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 (1,0,0).
|
|
For <<primsrast-line-basic, line>> primitives, the built-ins are obtained by
|
|
interpolating an attribute whose values for the vertices numbered 0 and 1
|
|
are (1,0,0) and (0,1,0), respectively.
|
|
For <<primsrast-polygon-basic, polygon>> primitives, the built-ins are
|
|
obtained by interpolating an attribute whose values for the vertices
|
|
numbered 0, 1, and 2 are (1,0,0), (0,1,0), and (0,0,1), respectively.
|
|
For code:BaryCoordNV, the values are obtained using perspective
|
|
interpolation.
|
|
For code:BaryCoordNoPerspNV, the values are obtained using linear
|
|
interpolation.
|
|
|
|
endif::VK_NV_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 that controls 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.
|
|
|
|
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 size 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 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
|
|
|
|
A line is drawn by generating a set of fragments overlapping a rectangle
|
|
centered on the line segment.
|
|
Each line segment has an associated width that controls the width of that
|
|
rectangle.
|
|
|
|
[open,refpage='vkCmdSetLineWidth',desc='Set the dynamic line width state',type='protos']
|
|
--
|
|
|
|
The line width is specified by the
|
|
slink:VkPipelineRasterizationStateCreateInfo::pname:lineWidth property of
|
|
the currently active pipeline, if the pipeline was not created with
|
|
ename:VK_DYNAMIC_STATE_LINE_WIDTH enabled.
|
|
|
|
Otherwise, the line width is set by calling fname:vkCmdSetLineWidth:
|
|
|
|
include::{generated}/api/protos/vkCmdSetLineWidth.txt[]
|
|
|
|
* pname:commandBuffer is the command buffer into which the command will be
|
|
recorded.
|
|
* pname:lineWidth is the width of rasterized line segments.
|
|
|
|
.Valid Usage
|
|
****
|
|
* [[VUID-vkCmdSetLineWidth-None-00787]]
|
|
The bound graphics pipeline must: have been created with the
|
|
ename:VK_DYNAMIC_STATE_LINE_WIDTH dynamic state enabled
|
|
* [[VUID-vkCmdSetLineWidth-lineWidth-00788]]
|
|
If the <<features-wideLines,wide lines>> feature is not enabled,
|
|
pname:lineWidth must: be `1.0`
|
|
****
|
|
|
|
include::{generated}/validity/protos/vkCmdSetLineWidth.txt[]
|
|
--
|
|
|
|
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 size 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
|
|
|
|
Rasterized 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.)
|
|
|
|
[[line_perspective_interpolation]]
|
|
The value of an associated datum [eq]#f# for the fragment, whether it be a
|
|
shader output or the clip [eq]#w# coordinate, must: be determined using
|
|
_perspective interpolation_:
|
|
|
|
[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
|
|
segments, respectively.
|
|
|
|
[[line_linear_interpolation]]
|
|
Depth values for lines must: be determined using _linear interpolation_:
|
|
|
|
:: [eq]#z = (1 - t) z~a~ {plus} t z~b~#
|
|
|
|
where [eq]#z~a~# and [eq]#z~b~# are the depth values of the starting and
|
|
ending endpoints of the segment, respectively.
|
|
|
|
The code:NoPerspective and code:Flat
|
|
<<shaders-interpolation-decorations,interpolation decorations>> can: be used
|
|
with fragment shader inputs to declare how they are interpolated.
|
|
When neither decoration is applied, <<line_perspective_interpolation,
|
|
perspective interpolation>> is performed as described above.
|
|
When the code:NoPerspective decoration is used, <<line_linear_interpolation,
|
|
linear interpolation>> is performed in the same fashion as for depth values,
|
|
as described above.
|
|
When the code:Flat decoration is used, no interpolation is performed, and
|
|
outputs are taken from the corresponding input value of the
|
|
<<vertexpostproc-flatshading,provoking vertex>> corresponding to that
|
|
primitive.
|
|
|
|
ifdef::VK_NV_fragment_shader_barycentric[]
|
|
When the pname:fragmentShaderBarycentric feature is enabled, the
|
|
code:PerVertexNV <<shaders-interpolation-decorations, interpolation
|
|
decoration>> can: also be used with fragment shader inputs which indicate
|
|
that the decorated inputs are not interpolated and can: only be accessed
|
|
using an extra array dimension, where the extra index identifies one of the
|
|
vertices of the primitive that produced the fragment.
|
|
endif::VK_NV_fragment_shader_barycentric[]
|
|
|
|
The above description documents the preferred method of line rasterization,
|
|
and must: be used when the implementation advertises the pname:strictLines
|
|
limit in slink:VkPhysicalDeviceLimits as ename:VK_TRUE.
|
|
|
|
When pname:strictLines is ename:VK_FALSE, 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}"]
|
|
|
|
|
|
[[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.txt[]
|
|
|
|
* 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.
|
|
|
|
--
|
|
|
|
[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.txt[]
|
|
|
|
* 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.txt[]
|
|
|
|
tname:VkCullModeFlags is a bitmask type for setting a mask of zero or more
|
|
elink:VkCullModeFlagBits.
|
|
--
|
|
|
|
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.
|
|
Define _barycentric coordinates_ for a triangle.
|
|
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
|
|
|
|
:: [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]]
|
|
The value of an associated datum [eq]#f# for a fragment produced by
|
|
rasterizing a triangle, whether it be a shader output or the clip [eq]#w#
|
|
coordinate, must: be determined using perspective interpolation:
|
|
|
|
[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 - this must: be the location of the
|
|
fragment center or the location of a sample.
|
|
When pname:rasterizationSamples is ename:VK_SAMPLE_COUNT_1_BIT, the fragment
|
|
center must: be used.
|
|
|
|
[[triangle_linear_interpolation]]
|
|
Depth values for triangles must: be determined using linear interpolation:
|
|
|
|
:: [eq]#z = a z~a~ {plus} b z~b~ {plus} c z~c~#
|
|
|
|
where [eq]#z~a~#, [eq]#z~b~#, and [eq]#z~c~# are the depth values of
|
|
[eq]#p~a~#, [eq]#p~b~#, and [eq]#p~c~#, respectively.
|
|
|
|
The code:NoPerspective and code:Flat
|
|
<<shaders-interpolation-decorations,interpolation decorations>> can: be used
|
|
with fragment shader inputs to declare how they are interpolated.
|
|
When neither decoration is applied, <<triangle_perspective_interpolation,
|
|
perspective interpolation>> is performed as described above.
|
|
When the code:NoPerspective decoration is used,
|
|
<<triangle_linear_interpolation, linear interpolation>> is performed in the
|
|
same fashion as for depth values, as described above.
|
|
When the code:Flat decoration is used, no interpolation is performed, and
|
|
outputs are taken from the corresponding input value of the
|
|
<<vertexpostproc-flatshading,provoking vertex>> corresponding to that
|
|
primitive.
|
|
|
|
ifdef::VK_AMD_shader_explicit_vertex_parameter[]
|
|
When the `<<VK_AMD_shader_explicit_vertex_parameter>>` device extension is
|
|
enabled the code:CustomInterpAMD <<shaders-interpolation-decorations,
|
|
interpolation decoration>> can: also be used with fragment shader inputs
|
|
which indicate that the decorated inputs can: only be accessed by the
|
|
extended instruction code:InterpolateAtVertexAMD and allows accessing the
|
|
value of the inputs for individual vertices of the primitive.
|
|
endif::VK_AMD_shader_explicit_vertex_parameter[]
|
|
|
|
ifdef::VK_NV_fragment_shader_barycentric[]
|
|
When the pname:fragmentShaderBarycentric feature is enabled, the
|
|
code:PerVertexNV <<shaders-interpolation-decorations, interpolation
|
|
decoration>> can: also be used with fragment shader inputs which indicate
|
|
that the decorated inputs are not interpolated and can: only be accessed
|
|
using an extra array dimension, where the extra index identifies one of the
|
|
vertices of the primitive that produced the fragment.
|
|
endif::VK_NV_fragment_shader_barycentric[]
|
|
|
|
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 equation <<triangle_perspective_interpolation>> are iterated
|
|
independently and a division 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.txt[]
|
|
|
|
* 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.
|
|
|
|
--
|
|
|
|
|
|
[[primsrast-depthbias]]
|
|
=== Depth Bias
|
|
|
|
[open,refpage='vkCmdSetDepthBias',desc='Set the depth bias dynamic state',type='protos']
|
|
--
|
|
|
|
The depth values of all fragments generated by the rasterization of a
|
|
polygon can: be offset by a single value that is computed for that polygon.
|
|
This behavior is controlled by the pname:depthBiasEnable,
|
|
pname:depthBiasConstantFactor, pname:depthBiasClamp, and
|
|
pname:depthBiasSlopeFactor members of
|
|
slink:VkPipelineRasterizationStateCreateInfo, or by the corresponding
|
|
parameters to the fname:vkCmdSetDepthBias command if depth bias state is
|
|
dynamic.
|
|
|
|
include::{generated}/api/protos/vkCmdSetDepthBias.txt[]
|
|
|
|
* 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.
|
|
|
|
If pname:depthBiasEnable is ename:VK_FALSE, no depth bias is applied and the
|
|
fragment's depth values are unchanged.
|
|
|
|
pname:depthBiasSlopeFactor scales the maximum depth slope of the polygon,
|
|
and pname:depthBiasConstantFactor scales an implementation-dependent
|
|
constant that relates to the usable resolution of the depth buffer.
|
|
The resulting values are summed to produce the depth bias 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.
|
|
|
|
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).
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
The minimum resolvable difference [eq]#r# is an implementation-dependent
|
|
parameter that depends on the depth buffer representation.
|
|
It is the smallest difference in framebuffer coordinate [eq]#z# values that
|
|
is guaranteed to remain distinct throughout polygon rasterization and in the
|
|
depth buffer.
|
|
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 buffer representations, [eq]#r# is constant throughout
|
|
the range of the entire depth buffer.
|
|
For floating-point depth buffers, 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
|
|
|
|
:: [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 buffer 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 buffer 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.
|
|
|
|
For fixed-point depth buffers, fragment depth values are always limited to
|
|
the range [eq]#[0,1]# by clamping after depth bias addition is performed.
|
|
ifdef::VK_EXT_depth_range_unrestricted[]
|
|
Unless the `<<VK_EXT_depth_range_unrestricted>>` extension is enabled,
|
|
fragment depth values are clamped even when the depth buffer uses a
|
|
floating-point representation.
|
|
endif::VK_EXT_depth_range_unrestricted[]
|
|
ifndef::VK_EXT_depth_range_unrestricted[]
|
|
Fragment depth values are clamped even when the depth buffer uses a
|
|
floating-point representation.
|
|
endif::VK_EXT_depth_range_unrestricted[]
|
|
|
|
.Valid Usage
|
|
****
|
|
* [[VUID-vkCmdSetDepthBias-None-00789]]
|
|
The bound graphics pipeline must: have been created with the
|
|
ename:VK_DYNAMIC_STATE_DEPTH_BIAS dynamic state enabled
|
|
* [[VUID-vkCmdSetDepthBias-depthBiasClamp-00790]]
|
|
If the <<features-depthBiasClamp,depth bias clamping>> feature is not
|
|
enabled, pname:depthBiasClamp must: be `0.0`
|
|
****
|
|
|
|
include::{generated}/validity/protos/vkCmdSetDepthBias.txt[]
|
|
--
|
|
|
|
ifdef::VK_EXT_conservative_rasterization[]
|
|
[[primsrast-conservativeraster]]
|
|
=== Conservative Rasterization
|
|
|
|
[open,refpage='VkPipelineRasterizationConservativeStateCreateInfoEXT',desc='Structure specifying conservative raster state',type='structs']
|
|
--
|
|
|
|
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.
|
|
The sname:VkPipelineRasterizationConservativeStateCreateInfoEXT state is set
|
|
by adding an instance of this structure to the pname:pNext chain of an
|
|
instance of the sname:VkPipelineRasterizationStateCreateInfo structure when
|
|
creating the graphics pipeline.
|
|
Enabling these modes also affects line and point rasterization if the
|
|
implementation sets
|
|
sname:VkPhysicalDeviceConservativeRasterizationPropertiesEXT::pname:conservativePointAndLineRasterization
|
|
to ename:VK_TRUE.
|
|
|
|
sname:VkPipelineRasterizationConservativeStateCreateInfoEXT is defined as:
|
|
|
|
include::{generated}/api/structs/VkPipelineRasterizationConservativeStateCreateInfoEXT.txt[]
|
|
|
|
* pname:sType is the type of this structure.
|
|
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
|
|
* pname:flags is reserved for future use.
|
|
* pname: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.
|
|
|
|
.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.txt[]
|
|
--
|
|
|
|
[open,refpage='VkPipelineRasterizationConservativeStateCreateFlagsEXT',desc='Reserved for future use',type='flags']
|
|
--
|
|
include::{generated}/api/flags/VkPipelineRasterizationConservativeStateCreateFlagsEXT.txt[]
|
|
|
|
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.txt[]
|
|
|
|
* 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.
|
|
|
|
--
|
|
|
|
When overestimate conservative rasterization is enabled, rather than
|
|
evaluating coverage at individual sample locations, a determination is made
|
|
of 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 coverage sample
|
|
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
|
|
coverage sample mask for the fragment is enabled, then all bits of the
|
|
coverage sample mask for the fragment are enabled.
|
|
endif::VK_EXT_fragment_density_map[]
|
|
|
|
ifdef::VK_EXT_post_depth_coverage[]
|
|
If the implementation supports
|
|
sname:VkPhysicalDeviceConservativeRasterizationPropertiesEXT::pname:conservativeRasterizationPostDepthCoverage
|
|
and the
|
|
<<shaders-fragment-earlytest-postdepthcoverage,code:PostDepthCoverage>>
|
|
execution mode is specified the code:SampleMask built-in input variable will
|
|
reflect the coverage after the early per-fragment depth and stencil tests
|
|
are applied.
|
|
endif::VK_EXT_post_depth_coverage[]
|
|
|
|
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 will: 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 that contain 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
|
|
of 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 coverage sample 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[]
|
|
|
|
ifdef::VK_EXT_post_depth_coverage[]
|
|
If the implementation supports
|
|
sname:VkPhysicalDeviceConservativeRasterizationPropertiesEXT::pname:conservativeRasterizationPostDepthCoverage
|
|
and the
|
|
<<shaders-fragment-earlytest-postdepthcoverage,code:PostDepthCoverage>>
|
|
execution mode is specified the code:SampleMask built-in input variable will
|
|
reflect the coverage after the early per-fragment depth and stencil tests
|
|
are applied.
|
|
endif::VK_EXT_post_depth_coverage[]
|
|
|
|
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[]
|
|
|
|
When the use of a <<primsrast-shading-rate-image, shading rate image>>
|
|
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[]
|
|
|
|
endif::VK_EXT_conservative_rasterization[]
|