/ appendices / VK_NV_geometry_shader_passthrough.txt
VK_NV_geometry_shader_passthrough.txt
  1  include::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  
 17  This extension adds support for the following SPIR-V extension in Vulkan:
 18  
 19    * `SPV_NV_geometry_shader_passthrough`
 20  
 21  Geometry shaders provide the ability for applications to process each
 22  primitive sent through the graphics pipeline using a programmable shader.
 23  However, one common use case treats them largely as a "`passthrough`".
 24  In this use case, the bulk of the geometry shader code simply copies inputs
 25  from each vertex of the input primitive to corresponding outputs in the
 26  vertices of the output primitive.
 27  Such shaders might also compute values for additional built-in or
 28  user-defined per-primitive attributes (e.g., code:Layer) to be assigned to
 29  all the vertices of the output primitive.
 30  
 31  This extension provides access to the code:PassthroughNV decoration under
 32  the code:GeometryShaderPassthroughNV capability.
 33  Adding this to a geometry shader input variable specifies that the values of
 34  this input are copied to the corresponding vertex of the output primitive.
 35  
 36  When using GLSL source-based shading languages, the code:passthrough layout
 37  qualifier from `GL_NV_geometry_shader_passthrough` maps to the
 38  code:PassthroughNV decoration.
 39  To use the code:passthrough layout, in GLSL the
 40  `GL_NV_geometry_shader_passthrough` extension must be enabled.
 41  Behaviour is described in the `GL_NV_geometry_shader_passthrough` extension
 42  specification.
 43  
 44  === New Object Types
 45  
 46  None.
 47  
 48  === New Enum Constants
 49  
 50  None.
 51  
 52  === New Enums
 53  
 54  None.
 55  
 56  === New Structures
 57  
 58  None.
 59  
 60  === New Functions
 61  
 62  None.
 63  
 64  === New Built-In Variables
 65  
 66  None.
 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  
 79  1) Should we require or allow a passthrough geometry shader to specify the
 80  output layout qualifiers for the output primitive type and maximum vertex
 81  count in the SPIR-V?
 82  
 83  *RESOLVED*: Yes they should be required in the SPIR-V.
 84  Per GL_NV_geometry_shader_passthrough they are not permitted in the GLSL
 85  source shader, but SPIR-V is lower-level.
 86  It is straightforward for the GLSL compiler to infer them from the input
 87  primitive type and to explicitly emit them in the SPIR-V according to the
 88  following 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  
 98  2) How does interface matching work with passthrough geometry shaders?
 99  
100  *RESOLVED*: This is described in <<geometry-passthrough-interface,
101  Passthrough Interface Matching>>.
102  In GL when using passthough geometry shaders in separable mode, all inputs
103  must also be explicitly assigned location layout qualifiers.
104  In Vulkan all SPIR-V shader inputs (except built-ins) must also have
105  location decorations specified.
106  Redeclarations of built-in varables that add the passthrough layout
107  qualifier are exempted from the rule requiring location assignment because
108  built-in variables do not have locations and are matched by code:BuiltIn
109  decoration.
110  
111  
112  === Sample Code
113  
114  Consider the following simple geometry shader in unextended GLSL:
115  
116  [source,c]
117  ---------------------------------------------------
118  layout(triangles) in;
119  layout(triangle_strip) out;
120  layout(max_vertices=3) out;
121  
122  in Inputs {
123      vec2 texcoord;
124      vec4 baseColor;
125  } v_in[];
126  out Outputs {
127      vec2 texcoord;
128      vec4 baseColor;
129  };
130  
131  void 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  
144  In this shader, the inputs code:gl_Position, code:Inputs.texcoord, and
145  code:Inputs.baseColor are simply copied from the input vertex to the
146  corresponding output vertex.
147  The only "`interesting`" work done by the geometry shader is computing and
148  emitting a code:gl_Layer value for the primitive.
149  
150  The following geometry shader, using this extension, is equivalent:
151  
152  [source,c]
153  ---------------------------------------------------
154  #extension GL_NV_geometry_shader_passthrough : require
155  
156  layout(triangles) in;
157  // No output primitive layout qualifiers required.
158  
159  // Redeclare gl_PerVertex to pass through "gl_Position".
160  layout(passthrough) in gl_PerVertex {
161      vec4 gl_Position;
162  } gl_in[];
163  
164  // Declare "Inputs" with "passthrough" to automatically copy members.
165  layout(passthrough) in Inputs {
166      vec2 texcoord;
167      vec4 baseColor;
168  } v_in[];
169  
170  // No output block declaration required.
171  
172  void 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