24. Mesh Shading
Task and mesh shaders operate in workgroups to produce a collection of primitives that will be processed by subsequent stages of the graphics pipeline.
Work on the mesh pipeline is initiated by the application drawing a set of mesh tasks organized in global workgroups. If the optional task shader is active, each workgroup triggers the execution of task shader invocations that will create a new set of mesh workgroups upon completion. Each of these created workgroups, or each of the original workgroups if no task shader is present, triggers the execution of mesh shader invocations.
Each mesh shader workgroup emits zero or more output primitives along with the group of vertices and their associated data required for each output primitive.
24.1. Task Shader Input
For every workgroup issued via the drawing commands a group of task shader invocations is executed. There are no inputs other than the builtin workgroup identifiers.
24.2. Task Shader Output
The task shader can emit zero or more mesh workgroups to be generated using
the built-in variable TaskCountNV
.
This value must be less than or equal to
VkPhysicalDeviceMeshShaderPropertiesNV
::maxTaskOutputCount
.
It can also output user-defined data that is passed as input to all mesh
shader invocations that the task creates.
These outputs are decorated as PerTaskNV
.
24.3. Mesh Generation
If a task shader exists, the mesh assembler creates a variable amount of mesh workgroups depending on each task’s output. If there is no task shader, the drawing commands emit the mesh shader invocations directly.
24.4. Mesh Shader Input
The only inputs available to the mesh shader are variables identifying the
specific workgroup and invocation and, if applicable, any outputs written as
PerTaskNV
by the task shader that spawned the mesh shader’s workgroup.
The mesh shader can operate without a task shader as well.
24.5. Mesh Shader Output Primitives
A mesh shader generates primitives in one of three output modes: points,
lines, or triangles.
The primitive mode is specified in the shader using an OpExecutionMode
instruction with the OutputPoints
, OutputLinesNV
, or
OutputTrianglesNV
modes, respectively.
Each mesh shader must include exactly one output primitive mode.
The maximum output vertex count is specified as a literal in the shader
using an OpExecutionMode
instruction with the mode set to
OutputVertices
and must be less than or equal to
VkPhysicalDeviceMeshShaderPropertiesNV
::maxMeshOutputVertices
.
The maximum output primitive count is specified as a literal in the shader
using an OpExecutionMode
instruction with the mode set to
OutputPrimitivesNV
and must be less than or equal to
VkPhysicalDeviceMeshShaderPropertiesNV
::maxMeshOutputPrimitives
.
The number of primitives output by the mesh shader is provided via writing
to the built-in variable
PrimitiveCountNV
and must be less than or equal to the maximum output
primitive count specified in the shader.
A variable decorated with PrimitiveIndicesNV
is an output array of
local index values into the vertex output arrays from which primitives are
assembled according to the output primitive type.
These resulting primitives are then further processed as described in
Rasterization.
24.6. Mesh Shader Per-View Outputs
The mesh shader outputs decorated with the PositionPerViewNV
,
ClipDistancePerViewNV
, CullDistancePerViewNV
, LayerPerViewNV
,
and ViewportMaskPerViewNV
built-in decorations are the per-view
versions of the single-view variables with equivalent names (that is
Position
, ClipDistance
, CullDistance
, Layer
, and
ViewportMaskNV
, respectively).
If a shader statically assigns a value to any element of a per-view array it
must not statically assign a value to the equivalent single-view variable.
Each of these outputs is considered arrayed, with separate values for each view. The view number is used to index the first dimension of these arrays.
The second dimension of the ClipDistancePerViewNV
, and
CullDistancePerViewNV
arrays have the same requirements as the
ClipDistance
, and CullDistance
arrays.
If a mesh shader output is per-view, the corresponding fragment shader input is taken from the element of the per-view output array that corresponds to the view that is currently being processed by the fragment shader.
24.7. Mesh Shader Primitive Ordering
Following guarantees are provided for the relative ordering of primitives produced by a mesh shader, as they pertain to primitive order.
-
When a task shader is used, mesh workgroups spawned from lower tasks will be ordered prior those workgroups from subsequent tasks.
-
All output primitives generated from a given mesh workgroup are passed to subsequent pipeline stages before any output primitives generated from subsequent input workgroups.
-
All output primitives within a mesh workgroup, will be generated in the ordering provided by the builtin primitive indexbuffer (from low address to high address).