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