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