• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (c) 2017-2020 NVIDIA Corporation
2//
3// SPDX-License-Identifier: CC-BY-4.0
4
5include::{generated}/meta/{refprefix}VK_NV_geometry_shader_passthrough.adoc[]
6
7=== Other Extension Metadata
8
9*Last Modified Date*::
10    2017-02-15
11*Interactions and External Dependencies*::
12  - This extension provides API support for
13    {GLregistry}/NV/NV_geometry_shader_passthrough.txt[`GL_NV_geometry_shader_passthrough`]
14  - This extension requires the pname:geometryShader feature.
15*Contributors*::
16  - Piers Daniell, NVIDIA
17  - Jeff Bolz, NVIDIA
18
19=== Description
20
21This extension adds support for the following SPIR-V extension in Vulkan:
22
23  * `SPV_NV_geometry_shader_passthrough`
24
25Geometry shaders provide the ability for applications to process each
26primitive sent through the graphics pipeline using a programmable shader.
27However, one common use case treats them largely as a "`passthrough`".
28In this use case, the bulk of the geometry shader code simply copies inputs
29from each vertex of the input primitive to corresponding outputs in the
30vertices of the output primitive.
31Such shaders might also compute values for additional built-in or
32user-defined per-primitive attributes (e.g., code:Layer) to be assigned to
33all the vertices of the output primitive.
34
35This extension provides access to the code:PassthroughNV decoration under
36the code:GeometryShaderPassthroughNV capability.
37Adding this to a geometry shader input variable specifies that the values of
38this input are copied to the corresponding vertex of the output primitive.
39
40When using GLSL source-based shading languages, the code:passthrough layout
41qualifier from `GL_NV_geometry_shader_passthrough` maps to the
42code:PassthroughNV decoration.
43To use the code:passthrough layout, in GLSL the
44`GL_NV_geometry_shader_passthrough` extension must be enabled.
45Behaviour is described in the `GL_NV_geometry_shader_passthrough` extension
46specification.
47
48include::{generated}/interfaces/VK_NV_geometry_shader_passthrough.adoc[]
49
50=== New Variable Decoration
51
52  * <<geometry-passthrough-passthrough,code:PassthroughNV>> in
53    <<geometry-passthrough,Geometry Shader Passthrough>>
54
55=== New SPIR-V Capabilities
56
57  * <<spirvenv-capabilities-table-GeometryShaderPassthroughNV,
58    code:GeometryShaderPassthroughNV>>
59
60=== Issues
61
621) Should we require or allow a passthrough geometry shader to specify the
63output layout qualifiers for the output primitive type and maximum vertex
64count in the SPIR-V?
65
66*RESOLVED*: Yes they should be required in the SPIR-V.
67Per GL_NV_geometry_shader_passthrough they are not permitted in the GLSL
68source shader, but SPIR-V is lower-level.
69It is straightforward for the GLSL compiler to infer them from the input
70primitive type and to explicitly emit them in the SPIR-V according to the
71following table.
72
73[options="header"]
74|====
75| Input Layout     | Implied Output Layout
76| points           | `layout(points, max_vertices=1)`
77| lines            | `layout(line_strip, max_vertices=2)`
78| triangles        | `layout(triangle_strip, max_vertices=3)`
79|====
80
812) How does interface matching work with passthrough geometry shaders?
82
83*RESOLVED*: This is described in <<geometry-passthrough-interface,
84Passthrough Interface Matching>>.
85In GL when using passthough geometry shaders in separable mode, all inputs
86must also be explicitly assigned location layout qualifiers.
87In Vulkan all SPIR-V shader inputs (except built-ins) must also have
88location decorations specified.
89Redeclarations of built-in variables that add the passthrough layout
90qualifier are exempted from the rule requiring location assignment because
91built-in variables do not have locations and are matched by code:BuiltIn
92decoration.
93
94
95=== Sample Code
96
97Consider the following simple geometry shader in unextended GLSL:
98
99[source,c]
100----
101layout(triangles) in;
102layout(triangle_strip) out;
103layout(max_vertices=3) out;
104
105in Inputs {
106    vec2 texcoord;
107    vec4 baseColor;
108} v_in[];
109out Outputs {
110    vec2 texcoord;
111    vec4 baseColor;
112};
113
114void main()
115{
116    int layer = compute_layer();
117    for (int i = 0; i < 3; i++) {
118        gl_Position = gl_in[i].gl_Position;
119        texcoord = v_in[i].texcoord;
120        baseColor = v_in[i].baseColor;
121        gl_Layer = layer;
122        EmitVertex();
123    }
124}
125----
126
127In this shader, the inputs code:gl_Position, code:Inputs.texcoord, and
128code:Inputs.baseColor are simply copied from the input vertex to the
129corresponding output vertex.
130The only "`interesting`" work done by the geometry shader is computing and
131emitting a code:gl_Layer value for the primitive.
132
133The following geometry shader, using this extension, is equivalent:
134
135[source,c]
136----
137#extension GL_NV_geometry_shader_passthrough : require
138
139layout(triangles) in;
140// No output primitive layout qualifiers required.
141
142// Redeclare gl_PerVertex to pass through "gl_Position".
143layout(passthrough) in gl_PerVertex {
144    vec4 gl_Position;
145} gl_in[];
146
147// Declare "Inputs" with "passthrough" to automatically copy members.
148layout(passthrough) in Inputs {
149    vec2 texcoord;
150    vec4 baseColor;
151} v_in[];
152
153// No output block declaration required.
154
155void main()
156{
157    // The shader simply computes and writes gl_Layer.  We do not
158    // loop over three vertices or call EmitVertex().
159    gl_Layer = compute_layer();
160}
161----
162
163
164=== Version History
165
166  * Revision 1, 2017-02-15 (Daniel Koch)
167  ** Internal revisions
168