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