/ 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