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