| // Copyright 2015-2023 The Khronos Group Inc. |
| // |
| // SPDX-License-Identifier: CC-BY-4.0 |
| |
| [[geometry]] |
| = Geometry Shading |
| |
| The geometry shader operates on a group of vertices and their associated |
| data assembled from a single input primitive, and emits zero or more output |
| primitives and the group of vertices and their associated data required for |
| each output primitive. |
| Geometry shading is enabled when a geometry shader is included in the |
| pipeline. |
| |
| |
| [[geometry-input]] |
| == Geometry Shader Input Primitives |
| |
| Each geometry shader invocation has access to all vertices in the primitive |
| (and their associated data), which are presented to the shader as an array |
| of inputs. |
| |
| The input primitive type expected by the geometry shader is specified with |
| an code:OpExecutionMode instruction in the geometry shader, and must: match |
| the incoming primitive type specified by either the pipeline's |
| <<drawing-primitive-topologies, primitive topology>> if tessellation is |
| inactive, or the <<tessellation, tessellation mode>> if tessellation is |
| active, as follows: |
| |
| * An input primitive type of code:InputPoints must: only be used with a |
| pipeline topology of ename:VK_PRIMITIVE_TOPOLOGY_POINT_LIST, or with a |
| tessellation shader specifying code:PointMode. |
| The input arrays always contain one element, as described by the |
| <<drawing-point-lists, point list topology>> or |
| <<tessellation-point-mode, tessellation in point mode>>. |
| * An input primitive type of code:InputLines must: only be used with a |
| pipeline topology of ename:VK_PRIMITIVE_TOPOLOGY_LINE_LIST or |
| ename:VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, or with a tessellation shader |
| specifying code:IsoLines that does not specify code:PointMode. |
| The input arrays always contain two elements, as described by the |
| <<drawing-line-lists, line list topology>> or <<drawing-line-strips, |
| line strip topology>>, or by <<tessellation-isoline-tessellation, |
| isoline tessellation>>. |
| * An input primitive type of code:InputLinesAdjacency must: only be used |
| when tessellation is inactive, with a pipeline topology of |
| ename:VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY or |
| ename:VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY. |
| The input arrays always contain four elements, as described by the |
| <<drawing-line-lists-with-adjacency, line list with adjacency topology>> |
| or <<drawing-line-strips-with-adjacency, line strip with adjacency |
| topology>>. |
| * An input primitive type of code:Triangles must: only be used with a |
| pipeline topology of ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, |
| ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, or |
| ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN; or with a tessellation shader |
| specifying code:Quads or code:Triangles that does not specify |
| code:PointMode. |
| The input arrays always contain three elements, as described by the |
| <<drawing-triangle-lists, triangle list topology>>, |
| <<drawing-triangle-strips, triangle strip topology>>, or |
| <<drawing-triangle-fans, triangle fan topology>>, or by |
| <<tessellation-triangle-tessellation, triangle>> or |
| <<tessellation-quad-tessellation, quad tessellation>>. |
| Vertices may: be in a different absolute order than specified by the |
| topology, but must: adhere to the specified winding order. |
| * An input primitive type of code:InputTrianglesAdjacency must: only be |
| used when tessellation is inactive, with a pipeline topology of |
| ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY or |
| ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY. |
| The input arrays always contain six elements, as described by the |
| <<drawing-triangle-lists-with-adjacency, triangle list with adjacency |
| topology>> or <<drawing-triangle-strips-with-adjacency, triangle strip |
| with adjacency topology>>. |
| Vertices may: be in a different absolute order than specified by the |
| topology, but must: adhere to the specified winding order, and the |
| vertices making up the main primitive must: still occur at the first, |
| third, and fifth index. |
| |
| |
| [[geometry-output]] |
| == Geometry Shader Output Primitives |
| |
| A geometry shader generates primitives in one of three output modes: points, |
| line strips, or triangle strips. |
| The primitive mode is specified in the shader using an code:OpExecutionMode |
| instruction with the code:OutputPoints, code:OutputLineStrip or |
| code:OutputTriangleStrip modes, respectively. |
| Each geometry shader must: include exactly one output primitive mode. |
| |
| The vertices output by the geometry shader are assembled into points, lines, |
| or triangles based on the output primitive type and the resulting primitives |
| are then further processed as described in <<primsrast>>. |
| If the number of vertices emitted by the geometry shader is not sufficient |
| to produce a single primitive, vertices corresponding to incomplete |
| primitives are not processed by subsequent pipeline stages. |
| The number of vertices output by the geometry shader is limited to a maximum |
| count specified in the shader. |
| |
| The maximum output vertex count is specified in the shader using an |
| code:OpExecutionMode instruction with the mode set to code:OutputVertices |
| and the maximum number of vertices that will be produced by the geometry |
| shader specified as a literal. |
| Each geometry shader must: specify a maximum output vertex count. |
| |
| |
| [[geometry-invocations]] |
| == Multiple Invocations of Geometry Shaders |
| |
| Geometry shaders can: be invoked more than one time for each input |
| primitive. |
| This is known as _geometry shader instancing_ and is requested by including |
| an code:OpExecutionMode instruction with code:mode specified as |
| code:Invocations and the number of invocations specified as an integer |
| literal. |
| |
| In this mode, the geometry shader will execute at least [eq]#n# times for |
| each input primitive, where [eq]#n# is the number of invocations specified |
| in the code:OpExecutionMode instruction. |
| The instance number is available to each invocation as a built-in input |
| using code:InvocationId. |
| |
| |
| [[geometry-ordering]] |
| == Geometry Shader Primitive Ordering |
| |
| Limited guarantees are provided for the relative ordering of primitives |
| produced by a geometry shader, as they pertain to <<drawing-primitive-order, |
| primitive order>>. |
| |
| * For instanced geometry shaders, the output primitives generated from |
| each input primitive are passed to subsequent pipeline stages using the |
| invocation number to order the primitives, from least to greatest. |
| * All output primitives generated from a given input primitive are passed |
| to subsequent pipeline stages before any output primitives generated |
| from subsequent input primitives. |
| |
| |
| ifdef::VK_NV_geometry_shader_passthrough[] |
| [[geometry-passthrough]] |
| == Geometry Shader Passthrough |
| |
| A geometry shader that uses the code:PassthroughNV decoration on a variable |
| in its input interface is considered a _passthrough geometry shader_. |
| Output primitives in a passthrough geometry shader must: have the same |
| topology as the input primitive and are not produced by emitting vertices. |
| The vertices of the output primitive have two different types of attributes, |
| per-vertex and per-primitive. |
| Geometry shader input variables with code:PassthroughNV decoration are |
| considered to produce per-vertex outputs, where values for each output |
| vertex are copied from the corresponding input vertex. |
| Any built-in or user-defined geometry shader outputs are considered |
| per-primitive in a passthrough geometry shader, where a single output value |
| is copied to all output vertices. |
| |
| The remainder of this section details the usage of the code:PassthroughNV |
| decoration and modifications to the interface matching rules when using |
| passthrough geometry shaders. |
| |
| |
| [[geometry-passthrough-passthrough]] |
| === code:PassthroughNV Decoration |
| |
| Decorating a geometry shader input variable with the code:PassthroughNV |
| decoration indicates that values of this input are copied through to the |
| corresponding vertex of the output primitive. |
| Input variables and block members which do not have the code:PassthroughNV |
| decoration are consumed by the geometry shader without being passed through |
| to subsequent stages. |
| |
| The code:PassthroughNV decoration must: only be used within a geometry |
| shader. |
| |
| Any variable decorated with code:PassthroughNV must: be declared using the |
| code:Input storage class. |
| |
| The code:PassthroughNV decoration must: not be used with any of: |
| |
| * an input primitive type other than code:InputPoints, code:InputLines, or |
| code:Triangles, as specified by the mode for code:OpExecutionMode. |
| * an invocation count other than one, as specified by the code:Invocations |
| mode for code:OpExecutionMode. |
| * an code:OpEntryPoint which statically uses the code:OpEmitVertex or |
| code:OpEndPrimitive instructions. |
| * a variable decorated with the code:InvocationId built-in decoration. |
| * a variable decorated with the code:PrimitiveId built-in decoration that |
| is declared using the code:Input storage class. |
| |
| |
| [[geometry-passthrough-interface]] |
| === Passthrough Interface Matching |
| |
| When a passthrough geometry shader is in use, the |
| <<interfaces-iointerfaces-matching,Interface Matching>> rules involving the |
| geometry shader input and output interfaces operate as described in this |
| section. |
| |
| For the purposes of matching passthrough geometry shader inputs with outputs |
| of the previous pipeline stages, the code:PassthroughNV decoration is |
| ignored. |
| |
| For the purposes of matching the outputs of the geometry shader with |
| subsequent pipeline stages, each input variable with the code:PassthroughNV |
| decoration is considered to add an equivalent output variable with the same |
| type, decoration (other than code:PassthroughNV), number, and declaration |
| order on the output interface. |
| The output variable declaration corresponding to an input variable decorated |
| with code:PassthroughNV will be identical to the input declaration, except |
| that the outermost array dimension of such variables is removed. |
| The output block declaration corresponding to an input block decorated with |
| code:PassthroughNV or having members decorated with code:PassthroughNV will |
| be identical to the input declaration, except that the outermost array |
| dimension of such declaration is removed. |
| |
| If an input block is decorated with code:PassthroughNV, the equivalent |
| output block contains all the members of the input block. |
| Otherwise, the equivalent output block contains only those input block |
| members decorated with code:PassthroughNV. |
| All members of the corresponding output block are assigned code:Location and |
| code:Component decorations identical to those assigned to the corresponding |
| input block members. |
| |
| Output variables and blocks generated from inputs decorated with |
| code:PassthroughNV will only exist for the purposes of interface matching; |
| these declarations are not available to geometry shader code or listed in |
| the module interface. |
| |
| For the purposes of component counting, passthrough geometry shaders count |
| all statically used input variable components declared with the |
| code:PassthroughNV decoration as output components as well, since their |
| values will be copied to the output primitive produced by the geometry |
| shader. |
| |
| endif::VK_NV_geometry_shader_passthrough[] |
| |
| |