• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (c) 2018-2020 NVIDIA Corporation
2//
3// SPDX-License-Identifier: CC-BY-4.0
4
5[[mesh]]
6= Mesh Shading
7
8<<shaders-task,Task>> and <<shaders-mesh,mesh shaders>> operate in
9workgroups to produce a collection of primitives that will be processed by
10subsequent stages of the graphics pipeline.
11
12Work on the mesh pipeline is initiated by the application
13<<drawing-mesh-shading,drawing>> a set of mesh tasks organized in global
14workgroups.
15If the optional task shader is active, each workgroup triggers the execution
16of task shader invocations that will create a new set of mesh workgroups
17upon completion.
18Each of these created workgroups, or each of the original workgroups if no
19task shader is present, triggers the execution of mesh shader invocations.
20
21Each mesh shader workgroup emits zero or more output primitives along with
22the group of vertices and their associated data required for each output
23primitive.
24
25
26[[mesh-task-input]]
27== Task Shader Input
28For every workgroup issued via the drawing commands a group of task shader
29invocations is executed.
30There are no inputs other than the builtin workgroup identifiers.
31
32
33[[mesh-task-output]]
34== Task Shader Output
35The task shader can emit zero or more mesh workgroups to be generated.
36ifdef::VK_NV_mesh_shader[]
37Shaders using the code:TaskNV {ExecutionModel} can do so using the
38<<interfaces-builtin-variables,built-in variable>> code:TaskCountNV.
39This value must: be less than or equal to
40sname:VkPhysicalDeviceMeshShaderPropertiesNV::pname:maxTaskOutputCount.
41endif::VK_NV_mesh_shader[]
42ifdef::VK_EXT_mesh_shader[]
43Shaders using the code:TaskEXT {ExecutionModel} can do so using the
44code:OpEmitMeshTasksEXT instruction.
45The code:groupCountX, code:groupCountY and code:groupCountZ arguments passed
46to this instruction must: be less than or equal to the respective dimension
47within
48sname:VkPhysicalDeviceMeshShaderPropertiesEXT::pname:maxMeshWorkGroupCount.
49The product of these arguments must: be less than or equal to
50sname:VkPhysicalDeviceMeshShaderPropertiesEXT::pname:maxMeshWorkGroupTotalCount.
51endif::VK_EXT_mesh_shader[]
52
53The task shader can also pass user-defined data to all mesh shader
54invocations that it creates.
55ifdef::VK_NV_mesh_shader[]
56Shaders using the code:TaskNV {ExecutionModel} can do so by writing to
57output variables that are decorated with code:PerTaskNV.
58They are available as inputs in mesh shaders.
59endif::VK_NV_mesh_shader[]
60ifdef::VK_EXT_mesh_shader[]
61Shaders using the code:TaskEXT {ExecutionModel} can do so by writing to a
62payload variable with code:TaskPayloadWorkgroupEXT storage class that is
63passed to the code:OpEmitMeshTasksEXT instruction.
64endif::VK_EXT_mesh_shader[]
65
66
67[[mesh-generation]]
68== Mesh Generation
69If a task shader exists, the mesh assembler creates a variable amount of
70mesh workgroups depending on each task's output.
71If there is no task shader, the drawing commands emit the mesh shader
72invocations directly.
73
74
75[[mesh-input]]
76== Mesh Shader Input
77The only inputs available to the mesh shader are variables identifying the
78specific workgroup and invocation and, if applicable,
79ifdef::VK_NV_mesh_shader[]
80any outputs written as code:PerTaskNV
81endif::VK_NV_mesh_shader[]
82ifdef::VK_NV_mesh_shader+VK_EXT_mesh_shader[or]
83ifdef::VK_EXT_mesh_shader[]
84the payload variable passed to the code:OpEmitMeshTasksEXT instruction
85endif::VK_EXT_mesh_shader[]
86by the task shader that spawned the mesh shader's workgroup.
87The mesh shader can operate without a task shader as well.
88
89
90[[mesh-output]]
91== Mesh Shader Output
92
93A mesh shader generates primitives in one of three output modes: points,
94lines, or triangles.
95ifdef::VK_NV_mesh_shader[]
96For shaders using the code:MeshNV {ExecutionModel} the primitive mode is
97specified in the shader using an code:OpExecutionMode instruction with the
98code:OutputPoints, code:OutputLinesNV, or code:OutputTrianglesNV modes,
99respectively.
100endif::VK_NV_mesh_shader[]
101ifdef::VK_EXT_mesh_shader[]
102For shaders using the code:MeshEXT {ExecutionModel} the primitive mode is
103specified in the shader using an code:OpExecutionMode instruction with the
104code:OutputPoints, code:OutputLinesEXT, or code:OutputTrianglesEXT modes,
105respectively.
106endif::VK_EXT_mesh_shader[]
107Each mesh shader must: include exactly one output primitive mode.
108
109ifdef::VK_NV_mesh_shader[]
110For shaders using the code:MeshNV {ExecutionModel} the maximum output vertex
111count is specified as a literal in the shader using an code:OpExecutionMode
112instruction with the mode set to code:OutputVertices and must: be less than
113or equal to
114sname:VkPhysicalDeviceMeshShaderPropertiesNV::pname:maxMeshOutputVertices.
115endif::VK_NV_mesh_shader[]
116ifdef::VK_EXT_mesh_shader[]
117For shaders using the code:MeshEXT {ExecutionModel} the maximum output
118vertex count is specified as a literal in the shader using an
119code:OpExecutionMode instruction with the mode set to code:OutputVertices
120and must: be less than or equal to
121sname:VkPhysicalDeviceMeshShaderPropertiesEXT::pname:maxMeshOutputVertices.
122endif::VK_EXT_mesh_shader[]
123
124ifdef::VK_NV_mesh_shader[]
125For shaders using the code:MeshNV {ExecutionModel} the maximum output
126primitive count is specified as a literal in the shader using an
127code:OpExecutionMode instruction with the mode set to
128code:OutputPrimitivesNV and must: be less than or equal to
129sname:VkPhysicalDeviceMeshShaderPropertiesNV::pname:maxMeshOutputPrimitives.
130endif::VK_NV_mesh_shader[]
131ifdef::VK_EXT_mesh_shader[]
132For shaders using the code:MeshEXT {ExecutionModel} the maximum output
133primitive count is specified as a literal in the shader using an
134code:OpExecutionMode instruction with the mode set to
135code:OutputPrimitivesEXT, and must: be less than or equal to
136sname:VkPhysicalDeviceMeshShaderPropertiesEXT::pname:maxMeshOutputPrimitives.
137endif::VK_EXT_mesh_shader[]
138
139ifdef::VK_NV_mesh_shader[]
140For shaders using the code:MeshNV {ExecutionModel} the number of primitives
141output by the mesh shader is provided via writing to the
142<<interfaces-builtin-variables,built-in variable>> code:PrimitiveCountNV and
143must: be less than or equal to the maximum output primitive count specified
144in the shader.
145A variable decorated with code:PrimitiveIndicesNV is an output array of
146local index values into the vertex output arrays from which primitives are
147assembled according to the output primitive type.
148endif::VK_NV_mesh_shader[]
149ifdef::VK_EXT_mesh_shader[]
150For shaders using the code:MeshEXT {ExecutionModel} the number of vertices
151and primitives output by the mesh shader is provided via calling the
152code:OpSetMeshOutputsEXT instruction.
153The code:vertexCount argument must: be less than or equal to the maximum
154output vertex count specified in the shader.
155The code:primitiveCount argument must: be less than or equal to the maximum
156output primitive count specified in the shader.
157
158Depending on the output primitive mode an appropriately-decorated variable
159is the output array of local index values into the vertex output arrays from
160which primitives are assembled according to the output primitive type:
161
162  * code:OutputPoints uses the code:PrimitivePointIndicesEXT decoration.
163  * code:OutputLinesEXT uses the code:PrimitiveLineIndicesEXT decoration.
164  * code:OutputTrianglesEXT uses the code:PrimitiveTriangleIndicesEXT
165    decoration.
166endif::VK_EXT_mesh_shader[]
167
168These resulting primitives are then further processed as described in
169<<primsrast>>.
170
171ifdef::VK_EXT_mesh_shader[]
172With the exception of primitive indices, all output built-ins and custom
173attributes count towards the total storage size occupied by output variables
174in mesh shaders.
175This size can be calculated as follows, taking into account the fact that
176the number of effective scalar attributes is 4 times the number of effective
177locations used according to the <<interfaces-iointerfaces-locations,location
178assignment rules>>.
179Let latexmath:[v] be the number of views, latexmath:[n_v] be the number of
180effective scalar per-vertex attributes not dependent on code:ViewIndex,
181latexmath:[n_{vpv}] be the number of effective scalar per-vertex attributes
182dependent on code:ViewIndex, latexmath:[m_v] be the maximum number of
183vertices specified by the code:OutputVertices {ExecutionMode},
184latexmath:[g_v] be pname:meshOutputPerVertexGranularity, latexmath:[n_p] be
185the number of effective scalar per-primitive attributes not dependent on
186code:ViewIndex, latexmath:[n_{ppv}] be the number of effective scalar
187per-primitive attributes dependent on code:ViewIndex, latexmath:[m_p] be the
188maximum number of primitives specified by the code:OutputPrimitivesEXT
189{ExecutionMode} and latexmath:[g_p] be
190pname:meshOutputPerPrimitiveGranularity:
191
192[latexmath]
193++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
194(n_v + (n_{vpv} \times v)) \times 4 \times \mathrm{align}(m_v, g_v) +
195(n_p + (n_{ppv} \times v)) \times 4 \times \mathrm{align}(m_p, g_p)
196++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
197
198endif::VK_EXT_mesh_shader[]
199
200ifdef::VK_NV_mesh_shader[]
201[[mesh-output-perview]]
202== Mesh Shader Per-View Outputs
203
204The mesh shader outputs decorated with the code:PositionPerViewNV,
205code:ClipDistancePerViewNV, code:CullDistancePerViewNV, code:LayerPerViewNV,
206and code:ViewportMaskPerViewNV built-in decorations are the per-view
207versions of the single-view variables with equivalent names (that is
208code:Position, code:ClipDistance, code:CullDistance, code:Layer, and
209code:ViewportMaskNV, respectively).
210If a shader statically assigns a value to any element of a per-view array it
211must: not statically assign a value to the equivalent single-view variable.
212
213Each of these outputs is considered arrayed, with separate values for each
214view.
215The view number is used to index the first dimension of these arrays.
216
217The second dimension of the code:ClipDistancePerViewNV, and
218code:CullDistancePerViewNV arrays have the same requirements as the
219code:ClipDistance, and code:CullDistance arrays.
220
221If a mesh shader output is _per-view_, the corresponding fragment shader
222input is taken from the element of the per-view output array that
223corresponds to the view that is currently being processed by the fragment
224shader.
225
226ifdef::VK_EXT_mesh_shader[]
227These _per-view_ outputs are available only in shaders using the code:MeshNV
228{ExecutionModel}.
229They are not available in shaders using the code:MeshEXT {ExecutionModel}.
230endif::VK_EXT_mesh_shader[]
231
232endif::VK_NV_mesh_shader[]
233
234
235[[mesh-ordering]]
236== Mesh Shader Primitive Ordering
237
238Following guarantees are provided for the relative ordering of primitives
239produced by a mesh shader, as they pertain to <<drawing-primitive-order,
240primitive order>>.
241
242  * When a task shader is used, mesh workgroups spawned from lower tasks
243    will be ordered prior those workgroups from subsequent tasks.
244  * All output primitives generated from a given mesh workgroup are passed
245    to subsequent pipeline stages before any output primitives generated
246    from subsequent input workgroups.
247  * All output primitives within a mesh workgroup, will be generated in the
248    ordering provided by the builtin primitive indexbuffer (from low address
249    to high address).
250