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