• 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 requires
13    {spirv}/NV/SPV_NV_geometry_shader_passthrough.html[`SPV_NV_geometry_shader_passthrough`]
14  - This extension provides API support for
15    {GLregistry}/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.adoc[]
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,
60    code:GeometryShaderPassthroughNV>>
61
62=== Issues
63
641) Should we require or allow a passthrough geometry shader to specify the
65output layout qualifiers for the output primitive type and maximum vertex
66count in the SPIR-V?
67
68*RESOLVED*: Yes they should be required in the SPIR-V.
69Per GL_NV_geometry_shader_passthrough they are not permitted in the GLSL
70source shader, but SPIR-V is lower-level.
71It is straightforward for the GLSL compiler to infer them from the input
72primitive type and to explicitly emit them in the SPIR-V according to the
73following table.
74
75[options="header"]
76|====
77| Input Layout     | Implied Output Layout
78| points           | `layout(points, max_vertices=1)`
79| lines            | `layout(line_strip, max_vertices=2)`
80| triangles        | `layout(triangle_strip, max_vertices=3)`
81|====
82
832) How does interface matching work with passthrough geometry shaders?
84
85*RESOLVED*: This is described in <<geometry-passthrough-interface,
86Passthrough Interface Matching>>.
87In GL when using passthough geometry shaders in separable mode, all inputs
88must also be explicitly assigned location layout qualifiers.
89In Vulkan all SPIR-V shader inputs (except built-ins) must also have
90location decorations specified.
91Redeclarations of built-in variables that add the passthrough layout
92qualifier are exempted from the rule requiring location assignment because
93built-in variables do not have locations and are matched by code:BuiltIn
94decoration.
95
96
97=== Sample Code
98
99Consider the following simple geometry shader in unextended GLSL:
100
101[source,c]
102---------------------------------------------------
103layout(triangles) in;
104layout(triangle_strip) out;
105layout(max_vertices=3) out;
106
107in Inputs {
108    vec2 texcoord;
109    vec4 baseColor;
110} v_in[];
111out Outputs {
112    vec2 texcoord;
113    vec4 baseColor;
114};
115
116void main()
117{
118    int layer = compute_layer();
119    for (int i = 0; i < 3; i++) {
120        gl_Position = gl_in[i].gl_Position;
121        texcoord = v_in[i].texcoord;
122        baseColor = v_in[i].baseColor;
123        gl_Layer = layer;
124        EmitVertex();
125    }
126}
127---------------------------------------------------
128
129In this shader, the inputs code:gl_Position, code:Inputs.texcoord, and
130code:Inputs.baseColor are simply copied from the input vertex to the
131corresponding output vertex.
132The only "`interesting`" work done by the geometry shader is computing and
133emitting a code:gl_Layer value for the primitive.
134
135The following geometry shader, using this extension, is equivalent:
136
137[source,c]
138---------------------------------------------------
139#extension GL_NV_geometry_shader_passthrough : require
140
141layout(triangles) in;
142// No output primitive layout qualifiers required.
143
144// Redeclare gl_PerVertex to pass through "gl_Position".
145layout(passthrough) in gl_PerVertex {
146    vec4 gl_Position;
147} gl_in[];
148
149// Declare "Inputs" with "passthrough" to automatically copy members.
150layout(passthrough) in Inputs {
151    vec2 texcoord;
152    vec4 baseColor;
153} v_in[];
154
155// No output block declaration required.
156
157void main()
158{
159    // The shader simply computes and writes gl_Layer.  We do not
160    // loop over three vertices or call EmitVertex().
161    gl_Layer = compute_layer();
162}
163---------------------------------------------------
164
165
166=== Version History
167
168  * Revision 1, 2017-02-15 (Daniel Koch)
169  ** Internal revisions
170