GL_EXT_geometry_shader4 |

- Name
- Name String
- Contact
- Status
- Version
- Number
- Dependencies
- Overview
- New Procedures and Functions
- New Tokens
- Additions to Chapter 2 of the OpenGL 2.0 Specification (OpenGL Operation)
- Additions to Chapter 3 of the OpenGL 2.0 Specification (Rasterization)
- Additions to Chapter 4 of the OpenGL 2.0 Specification (Per-Fragment Operations and the Frame Buffer)
- Additions to Chapter 5 of the OpenGL 2.0 Specification (Special Functions)
- Additions to Chapter 6 of the OpenGL 2.0 Specification (State and State Requests)
- Additions to Appendix A of the OpenGL 2.0 Specification (Invariance)
- Additions to the AGL/GLX/WGL Specifications
- Dependencies on NV_primitive_restart
- Dependencies on EXT_framebuffer_object
- Dependencies on EXT_framebuffer_blit
- Dependencies on EXT_texture_array
- Dependencies on ARB_texture_rectangle
- Dependencies on EXT_texture_buffer_object
- GLX protocol
- Errors
- New State
- New Implementation Dependent State
- Modifications to the OpenGL Shading Language Specification version 1.10.59
- Issues
- Revision History

Name |

EXT_geometry_shader4

Name String |

GL_EXT_geometry_shader4

Contact |

Pat Brown, NVIDIA (pbrown 'at' nvidia.com) Barthold Lichtenbelt, NVIDIA (blichtenbelt 'at' nvidia.com)

Status |

Multi-vendor extension Shipping for GeForce 8 Series (November 2006)

Version |

Last Modified Date: 05/22/2007 NVIDIA Revision: 17

Number |

324

Dependencies |

OpenGL 1.1 is required. This extension is written against the OpenGL 2.0 specification. EXT_framebuffer_object interacts with this extension. EXT_framebuffer_blit interacts with this extension. EXT_texture_array interacts with this extension. ARB_texture_rectangle trivially affects the definition of this extension. EXT_texture_buffer_object trivially affects the definition of this extension. NV_primitive_restart trivially affects the definition of this extension. This extension interacts with EXT_tranform_feedback.

Overview |

EXT_geometry_shader4 defines a new shader type available to be run on the GPU, called a geometry shader. Geometry shaders are run after vertices are transformed, but prior to color clamping, flat shading and clipping. A geometry shader begins with a single primitive (point, line, triangle). It can read the attributes of any of the vertices in the primitive and use them to generate new primitives. A geometry shader has a fixed output primitive type (point, line strip, or triangle strip) and emits vertices to define a new primitive. A geometry shader can emit multiple disconnected primitives. The primitives emitted by the geometry shader are clipped and then processed like an equivalent OpenGL primitive specified by the application. Furthermore, EXT_geometry_shader4 provides four additional primitive types: lines with adjacency, line strips with adjacency, separate triangles with adjacency, and triangle strips with adjacency. Some of the vertices specified in these new primitive types are not part of the ordinary primitives, instead they represent neighboring vertices that are adjacent to the two line segment end points (lines/strips) or the three triangle edges (triangles/tstrips). These vertices can be accessed by geometry shaders and used to match up the vertices emitted by the geometry shader with those of neighboring primitives. Since geometry shaders expect a specific input primitive type, an error will occur if the application presents primitives of a different type. For example, if a geometry shader expects points, an error will occur at Begin() time, if a primitive mode of TRIANGLES is specified.

New Procedures and Functions |

void ProgramParameteriEXT(uint program, enum pname, int value); void FramebufferTextureEXT(enum target, enum attachment, uint texture, int level); void FramebufferTextureLayerEXT(enum target, enum attachment, uint texture, int level, int layer); void FramebufferTextureFaceEXT(enum target, enum attachment, uint texture, int level, enum face);

New Tokens |

Accepted by the <type> parameter of CreateShader and returned by the <params> parameter of GetShaderiv: GEOMETRY_SHADER_EXT 0x8DD9 Accepted by the <pname> parameter of ProgramParameteriEXT and GetProgramiv: GEOMETRY_VERTICES_OUT_EXT 0x8DDA GEOMETRY_INPUT_TYPE_EXT 0x8DDB GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC Accepted by the <pname> parameter of GetBooleanv, GetIntegerv, GetFloatv, and GetDoublev: MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE MAX_VARYING_COMPONENTS_EXT 0x8B4B MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0 MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1 Accepted by the <mode> parameter of Begin, DrawArrays, MultiDrawArrays, DrawElements, MultiDrawElements, and DrawRangeElements: LINES_ADJACENCY_EXT 0xA LINE_STRIP_ADJACENCY_EXT 0xB TRIANGLES_ADJACENCY_EXT 0xC TRIANGLE_STRIP_ADJACENCY_EXT 0xD Returned by CheckFramebufferStatusEXT: FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9 Accepted by the <pname> parameter of GetFramebufferAttachment- ParameterivEXT: FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 Accepted by the <cap> parameter of Enable, Disable, and IsEnabled, and by the <pname> parameter of GetIntegerv, GetFloatv, GetDoublev, and GetBooleanv: PROGRAM_POINT_SIZE_EXT 0x8642 (Note: FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT is simply an alias for the FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT token provided in EXT_framebuffer_object. This extension generalizes the notion of "<zoffset>" to include layers of an array texture.) (Note: PROGRAM_POINT_SIZE_EXT is simply an alias for the VERTEX_PROGRAM_POINT_SIZE token provided in OpenGL 2.0, which is itself an alias for VERTEX_PROGRAM_POINT_SIZE_ARB provided by ARB_vertex_program. Program-computed point sizes can be enabled if geometry shaders are enabled.)

Additions to Chapter 2 of the OpenGL 2.0 Specification (OpenGL Operation) |

Modify Section 2.6.1 (Begin and End Objects), p. 13 (Add to end of section, p. 18) (add figure) 1 - - - 2----->3 - - - 4 1 - - - 2--->3--->4--->5 - - - 6 5 - - - 6----->7 - - - 8 (a) (b) Figure 2.X1 (a) Lines with adjacency, (b) Line strip with adjacency. The vertices connected with solid lines belong to the main primitives; the vertices connected by dashed lines are the adjacent vertices that may be used in a geometry shader. Lines with Adjacency Lines with adjacency are independent line segments where each endpoint has a corresponding "adjacent" vertex that can be accessed by a geometry shader (Section 2.16). If a geometry shader is not active, the "adjacent" vertices are ignored. A line segment is drawn from the 4i + 2nd vertex to the 4i + 3rd vertex for each i = 0, 1, ... , n-1, where there are 4n+k vertices between the Begin and End. k is either 0, 1, 2, or 3; if k is not zero, the final k vertices are ignored. For line segment i, the 4i + 1st and 4i + 4th vertices are considered adjacent to the 4i + 2nd and 4i + 3rd vertices, respectively. See Figure 2.X1. Lines with adjacency are generated by calling Begin with the argument value LINES_ADJACENCY_EXT. Line Strips with Adjacency Line strips with adjacency are similar to line strips, except that each line segment has a pair of adjacent vertices that can be accessed by a geometry shader (Section 2.15). If a geometry shader is not active, the "adjacent" vertices are ignored. A line segment is drawn from the i + 2nd vertex to the i + 3rd vertex for each i = 0, 1, ..., n-1, where there are n+3 vertices between the Begin and End. If there are fewer than four vertices between a Begin and End, all vertices are ignored. For line segment i, the i + 1st and i + 4th vertex are considered adjacent to the i + 2nd and i + 3rd vertices, respectively. See Figure 2.X1. Line strips with adjacency are generated by calling Begin with the argument value LINE_STRIP_ADJACENCY_EXT. (add figure) 2 - - - 3 - - - 4 8 - - - 9 - - - 10 ^\ ^\ \ | \ | \ | \ | | \ | \ \ | \ | \ | \ | | \ | \ \ | \ | \ | \ | | v | v 1<------5 7<------11 \ | \ | \ | \ | \ | \ | 6 12 Figure 2.X2 Triangles with adjacency. The vertices connected with solid lines belong to the main primitive; the vertices connected by dashed lines are the adjacent vertices that may be used in a geometry shader. Triangles with Adjacency Triangles with adjacency are similar to separate triangles, except that each triangle edge has an adjacent vertex that can be accessed by a geometry shader (Section 2.15). If a geometry shader is not active, the "adjacent" vertices are ignored. The 6i + 1st, 6i + 3rd, and 6i + 5th vertices (in that order) determine a triangle for each i = 0, 1, ..., n-1, where there are 6n+k vertices between the Begin and End. k is either 0, 1, 2, 3, 4, or 5; if k is non-zero, the final k vertices are ignored. For triangle i, the i + 2nd, i + 4th, and i + 6th vertices are considered adjacent to edges from the i + 1st to the i + 3rd, from the i + 3rd to the i + 5th, and from the i + 5th to the i + 1st vertices, respectively. See Figure 2.X2. Triangles with adjacency are generated by calling Begin with the argument value TRIANGLES_ADJACENCY_EXT. (add figure) 6 6 | \ | \ | \ | \ | \ | \ 2 - - - 3- - - >6 2 - - - 3------>7 2 - - - 3------>7- - - 10 ^\ ^^ | ^^ ^^ | \ | \ | \ | \ | \ \ | \ | \ | \ | \ | | \ | \ | \ | \ | \ | \ | \ \ | \ | \ | \ | \ | | \ | \ | \ | \ | \ | \ | \ \ | \ | \ | v | vv | vv v| 1<------5 1<------5 - - - 8 1<------5<------9 \ | \ | \ | \ | \ | \ | \ | \ | \ | \ | \ | \ | 4 4 4 8 6 10 | \ | \ | \ | \ | \ | \ 2 - - - 3------>7------>11 ^^ ^^ | \ | \ | \ | \ | \ | \ | \ | \ | \ | \ | \ | \ | \ | \ | \ | \ | vv vv 1<------5<------9 - - - 12 \ | \ | \ | \ | \ | \ | 4 8 Figure 2.X3 Triangle strips with adjacency. The vertices connected with solid lines belong to the main primitives; the vertices connected by dashed lines are the adjacent vertices that may be used in a geometry shader. Triangle Strips with Adjacency Triangle strips with adjacency are similar to triangle strips, except that each line triangle edge has an adjacent vertex that can be accessed by a geometry shader (Section 2.15). If a geometry shader is not active, the "adjacent" vertices are ignored. In triangle strips with adjacency, n triangles are drawn using 2 * (n+2) + k vertices between the Begin and End. k is either 0 or 1; if k is 1, the final vertex is ignored. If fewer than 6 vertices are specified between the Begin and End, the entire primitive is ignored. Table 2.X1 describes the vertices and order used to draw each triangle, and which vertices are considered adjacent to each edge of the triangle. See Figure 2.X3. (add table) primitive adjacent vertices vertices primitive 1st 2nd 3rd 1/2 2/3 3/1 --------------- ---- ---- ---- ---- ---- ---- only (i==0, n==1) 1 3 5 2 6 4 first (i==0) 1 3 5 2 7 4 middle (i odd) 2i+3 2i+1 2i+5 2i-1 2i+4 2i+7 middle (i even) 2i+1 2i+3 2i+5 2i-1 2i+7 2i+4 last (i==n-1, i odd) 2i+3 2i+1 2i+5 2i-1 2i+4 2i+6 last (i==n-1, i even) 2i+1 2i+3 2i+5 2i-1 2i+6 2i+4 Table 2.X1: Triangles generated by triangle strips with adjacency. Each triangle is drawn using the vertices in the "1st", "2nd", and "3rd" columns under "primitive vertices", in that order. The vertices in the "1/2", "2/3", and "3/1" columns under "adjacent vertices" are considered adjacent to the edges from the first to the second, from the second to the third, and from the third to the first vertex of the triangle, respectively. The six rows correspond to the six cases: the first and only triangle (i=0, n=1), the first triangle of several (i=0, n>0), "odd" middle triangles (i=1,3,5...), "even" middle triangles (i=2,4,6,...), and special cases for the last triangle inside the Begin/End, when i is either even or odd. For the purposes of this table, the first vertex specified after Begin is numbered "1" and the first triangle is numbered "0". Triangle strips with adjacency are generated by calling Begin with the argument value TRIANGLE_STRIP_ADJACENCY_EXT. Modify Section 2.14.1, Lighting (p. 59) (modify fourth paragraph, p. 63) Additionally, vertex and geometry shaders can operate in two-sided color mode, which is enabled and disabled by calling Enable or Disable with the symbolic value VERTEX_PROGRAM_TWO_SIDE. When a vertex or geometry shader is active, the shaders can write front and back color values to the gl_FrontColor, gl_BackColor, gl_FrontSecondaryColor and gl_BackSecondaryColor outputs. When a vertex or geometry shader is active and two-sided color mode is enabled, the GL chooses between front and back colors, as described below. If two-sided color mode is disabled, the front color output is always selected. Modify Section 2.15.2 Program Objects, p. 73 Change the first paragraph on p. 74 as follows: Program objects are empty when they are created. Default values for program object parameters are discussed in section 2.15.5, Required State. A non-zero name that can be used to reference the program object is returned. Change the language below the LinkProgram command on p. 74 as follows: ... Linking can fail for a variety of reasons as specified in the OpenGL Shading Language Specification. Linking will also fail if one or more of the shader objects, attached to <program> are not compiled successfully, or if more active uniform or active sampler variables are used in <program> than allowed (see sections 2.15.3 and 2.16.3). Linking will also fail if the program object contains objects to form a geometry shader (see section 2.16), but no objects to form a vertex shader or if the program object contains objects to form a geometry shader, and the value of GEOMETRY_VERTICES_OUT_EXT is zero. If LinkProgram failed, .. Add the following paragraphs above the description of DeleteProgram, p. 75: To set a program object parameter, call void ProgramParameteriEXT(uint program, enum pname, int value) <param> identifies which parameter to set for <program>. <value> holds the value being set. Legal values for <param> and <value> are discussed in section 2.16. Modify Section 2.15.3, Shader Variables, p. 75 Modify the first paragraph of section 'Varying Variables' p. 83 as follows: A vertex shader may define one or more varying variables (see the OpenGL Shading Language specification). Varying variables are outputs of a vertex shader. They are either used as the mechanism to communicate values to a geometry shader, if one is active, or to communicate values to the fragment shader. The OpenGL Shading Language specification also defines a set of built-in varying variables that vertex shaders can write to (see section 7.6 of the OpenGL Shading Language Specification). These variables can also be used to communicate values to a geometry shader, if one is active, or to communicate values to the fragment shader and to the fixed- function processing that occurs after vertex shading. If a geometry shader is not active, the values of all varying variables, including built-in variables, are expected to be interpolated across the primitive being rendered, unless flat shaded. The number of interpolators available for processing varying variables is given by the implementation-dependent constant MAX_VARYING_COMPONENTS_EXT. This value represents the number of individual components that can be interpolated; varying variables declared as vectors, matrices, and arrays will all consume multiple interpolators. When a program is linked, all components of any varying variable written by a vertex shader, or read by a fragment shader, will count against this limit. The transformed vertex position (gl_Position) does not count against this limit. A program whose vertex and/or fragment shaders access more than MAX_VARYING_COMPONENTS_EXT components worth of varying variables may fail to link, unless device-dependent optimizations are able to make the program fit within available hardware resources. Note that the two values MAX_VARYING_FLOATS and MAX_VARYING_COMPONENTS_EXT are aliases of each other. The use of MAX_VARYING_FLOATS however is discouraged; varying variables can be declared as integers as well. If a geometry shader is active, the values of varying variables are collected by the primitive assembly stage and passed on to the geometry shader once enough data for one primitive has been collected (see also section 2.16). The OpenGL Shading Language specification also defines a set of built-in varying and built-in special variables that vertex shaders can write to (see sections 7.1 and 7.6 of the OpenGL Shading Language Specification). These variables are also collected and passed on to the geometry shader once enough data has been collected. The number of components of varying and special variables that can be collected per vertex by the primitive assembly stage is given by the implementation dependent constant MAX_VERTEX_VARYING_COMPONENTS_EXT. This value represents the number of individual components that can be collected; varying variables declared as vectors, matrices, and arrays will all consume multiple components. When a program is linked, all components of any varying variable written by a vertex shader, or read by a geometry shader, will count against this limit. A program whose vertex and/or geometry shaders access more than MAX_VERTEX_VARYING_COMPONENTS_EXT components worth of varying variables may fail to link, unless device-dependent optimizations are able to make the program fit within available hardware resources. Modify Section 2.15.4 Shader Execution, p. 84 Change the following sentence: "The following operations are applied to vertex values that are the result of executing the vertex shader:" As follows: If no geometry shader (see section 2.16) is present in the program object, the following operations are applied to vertex values that are the result of executing the vertex shader: [bulleted list of operations] On page 85, below the list of bullets, add the following: If a geometry shader is present in the program object, geometry shading (section 2.16) is applied to vertex values that are the result of executing the vertex shader. Modify the first paragraph of the section 'Texture Access', p. 85, as follows: Vertex shaders have the ability to do a lookup into a texture map, if supported by the GL implementation. The maximum number of texture image units available to a vertex shader is MAX_VERTEX_TEXTURE_IMAGE_UNITS; a maximum number of zero indicates that the GL implementation does not support texture accesses in vertex shaders. The vertex shader, geometry shader, if exists, and fragment processing combined cannot use more than MAX_COMBINED_TEXTURE_IMAGE_UNITS texture image units. If the vertex shader, geometry shader and the fragment processing stage access the same texture image unit, then that counts as using three texture image units against the MAX_COMBINED_TEXTURE_IMAGE_UNITS limit. Modify Section 2.15.5, Required State, p. 88 Add the following bullets to the state required per program object: * One integer to store the value of GEOMETRY_VERTICES_OUT_EXT, initially zero. * One integer to store the value of GEOMETRY_INPUT_TYPE_EXT, initially set to TRIANGLES. * One integer to store the value of GEOMETRY_OUTPUT_TYPE_EXT, initially set to TRIANGLE_STRIP. Insert New Section 2.16, Geometry Shaders after p. 89 After vertices are processed, they are arranged into primitives, as described in section 2.6.1 (Begin/End Objects). This section described a new pipeline stage that processes those primitives. A geometry shader defines the operations that are performed in this new pipeline stage. A geometry shader is an array of strings containing source code. The source code language used is described in the OpenGL Shading Language specification. A geometry shader operates on a single primitive at a time and emits one or more output primitives, all of the same type, which are then processed like an equivalent OpenGL primitive specified by the application. The original primitive is discarded after the geometry shader completes. The inputs available to a geometry shader are the transformed attributes of all the vertices that belong to the primitive. Additional "adjacency" primitives are available which also make the transformed attributes of neighboring vertices available to the shader. The results of the shader are a new set of transformed vertices, arranged into primitives by the shader. This new geometry shader pipeline stage is inserted after primitive assembly, right before color clamping (section 2.14.6), flat shading (section 2.14.7) and clipping (sections 2.12 and 2.14.8). A geometry shader only applies when the GL is in RGB mode. Its operation in color index mode is undefined. Geometry shaders are created as described in section 2.15.1 using a type parameter of GEOMETRY_SHADER_EXT. They are attached to and used in program objects as described in section 2.15.2. When the program object currently in use includes a geometry shader, its geometry shader is considered active, and is used to process primitives. If the program object has no geometry shader, or no program object is in use, this new primitive processing pipeline stage is bypassed. A program object that includes a geometry shader must also include a vertex shader; otherwise a link error will occur. Section 2.16.1, Geometry shader Input Primitives A geometry shader can operate on one of five input primitive types. Depending on the input primitive type, one to six input vertices are available when the shader is executed. Each input primitive type supports a subset of the primitives provided by the GL. If a geometry shader is active, Begin, or any function that implicitly calls Begin, will produce an INVALID_OPERATION error if the <mode> parameter is incompatible with the input primitive type of the currently active program object, as discussed below. The input primitive type is a parameter of the program object, and must be set before linking by calling ProgramParameteriEXT with <pname> set to GEOMETRY_INPUT_TYPE_EXT and <value> set to one of POINTS, LINES, LINES_ADJACENCY_EXT, TRIANGLES or TRIANGLES_ADJACENCY_EXT. This setting will not be in effect until the next time LinkProgram has been called successfully. Note that queries of GEOMETRY_INPUT_TYPE_EXT will return the last value set. This is not necessarily the value used to generate the executable code in the program object. After a program object has been created it will have a default value for GEOMETRY_INPUT_TYPE_EXT, as discussed in section 2.15.5, Required State. Note that a geometry shader that accesses more input vertices than are available for a given input primitive type can be successfully compiled, because the input primitive type is not part of the shader object. However, a program object, containing a shader object that access more input vertices than are available for the input primitive type of the program object, will not link. The supported input primitive types are: Points (POINTS) Geometry shaders that operate on points are valid only for the POINTS primitive type. There is only a single vertex available for each geometry shader invocation. Lines (LINES) Geometry shaders that operate on line segments are valid only for the LINES, LINE_STRIP, and LINE_LOOP primitive types. There are two vertices available for each geometry shader invocation. The first vertex refers to the vertex at the beginning of the line segment and the second vertex refers to the vertex at the end of the line segment. See also section 2.16.4. Lines with Adjacency (LINES_ADJACENCY_EXT) Geometry shaders that operate on line segments with adjacent vertices are valid only for the LINES_ADJACENCY_EXT and LINE_STRIP_ADJACENCY_EXT primitive types. There are four vertices available for each program invocation. The second vertex refers to attributes of the vertex at the beginning of the line segment and the third vertex refers to the vertex at the end of the line segment. The first and fourth vertices refer to the vertices adjacent to the beginning and end of the line segment, respectively. Triangles (TRIANGLES) Geometry shaders that operate on triangles are valid for the TRIANGLES, TRIANGLE_STRIP and TRIANGLE_FAN primitive types. There are three vertices available for each program invocation. The first, second and third vertices refer to attributes of the first, second and third vertex of the triangle, respectively. Triangles with Adjacency (TRIANGLES_ADJACENCY_EXT) Geometry shaders that operate on triangles with adjacent vertices are valid for the TRIANGLES_ADJACENCY_EXT and TRIANGLE_STRIP_ADJACENCY_EXT primitive types. There are six vertices available for each program invocation. The first, third and fifth vertices refer to attributes of the first, second and third vertex of the triangle, respectively. The second, fourth and sixth vertices refer to attributes of the vertices adjacent to the edges from the first to the second vertex, from the second to the third vertex, and from the third to the first vertex, respectively. Section 2.16.2, Geometry Shader Output Primitives A geometry shader can generate primitives of one of three types. The supported output primitive types are points (POINTS), line strips (LINE_STRIP), and triangle strips (TRIANGLE_STRIP). The vertices output by the geometry shader are decomposed into points, lines, or triangles based on the output primitive type in the manner described in section 2.6.1. The resulting primitives are then further processed as shown in figure 2.16.xxx. If the number of vertices emitted by the geometry shader is not sufficient to produce a single primitive, nothing is drawn. The output primitive type is a parameter of the program object, and can be set by calling ProgramParameteriEXT with <pname> set to GEOMETRY_OUTPUT_TYPE_EXT and <value> set to one of POINTS, LINE_STRIP or TRIANGLE_STRIP. This setting will not be in effect until the next time LinkProgram has been called successfully. Note that queries of GEOMETRY_OUTPUT_TYPE_EXT will return the last value set; which is not necessarily the value used to generate the executable code in the program object. After a program object has been created it will have a default value for GEOMETRY_OUTPUT_TYPE_EXT, as discussed in section 2.15.5, Required State. . Section 2.16.3 Geometry Shader Variables Geometry shaders can access uniforms belonging to the current program object. The amount of storage available for geometry shader uniform variables is specified by the implementation dependent constant MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT. This value represents the number of individual floating-point, integer, or Boolean values that can be held in uniform variable storage for a geometry shader. A link error will be generated if an attempt is made to utilize more than the space available for geometry shader uniform variables. Uniforms are manipulated as described in section 2.15.3. Geometry shaders also have access to samplers, to perform texturing operations, as described in sections 2.15.3 and 3.8. Geometry shaders can access the transformed attributes of all vertices for its input primitive type through input varying variables. A vertex shader, writing to output varying variables, generates the values of these input varying variables. This includes values for built-in as well as user-defined varying variables. Values for any varying variables that are not written by a vertex shader are undefined. Additionally, a geometry shader has access to a built-in variable that holds the ID of the current primitive. This ID is generated by the primitive assembly stage that sits in between the vertex and geometry shader. Additionally, geometry shaders can write to one, or more, varying variables for each primitive it outputs. These values are optionally flat shaded (using the OpenGL Shading Language varying qualifier "flat") and clipped, then the clipped values interpolated across the primitive (if not flat shaded). The results of these interpolations are available to a fragment shader, if one is active. Furthermore, geometry shaders can write to a set of built- in varying variables, defined in the OpenGL Shading Language, that correspond to the values required for the fixed-function processing that occurs after geometry processing. Section 2.16.4, Geometry Shader Execution Environment If a successfully linked program object that contains a geometry shader is made current by calling UseProgram, the executable version of the geometry shader is used to process primitives resulting from the primitive assembly stage. The following operations are applied to the primitives that are the result of executing a geometry shader: * color clamping or masking (section 2.14.6), * flat shading (section 2.14.7), * clipping, including client-defined clip planes (section 2.12), * front face determination (section 2.14.1), * color and associated data clipping (section 2.14.8), * perspective division on clip coordinates (section 2.11), * final color processing (section 2.14.9), and * viewport transformation, including depth-range scaling (section 2.11.1). There are several special considerations for geometry shader execution described in the following sections. Texture Access Geometry shaders have the ability to do a lookup into a texture map, if supported by the GL implementation. The maximum number of texture image units available to a geometry shader is MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT; a maximum number of zero indicates that the GL implementation does not support texture accesses in geometry shaders. The vertex shader, geometry shader and fragment processing combined cannot use more than MAX_COMBINED_TEXTURE_IMAGE_UNITS texture image units. If the vertex shader, geometry shader and the fragment processing stage access the same texture image unit, then that counts as using three texture image units against the MAX_COMBINED_TEXTURE_IMAGE_UNITS limit. When a texture lookup is performed in a geometry shader, the filtered texture value tau is computed in the manner described in sections 3.8.8 and 3.8.9, and converted to a texture source color Cs according to table 3.21 (section 3.8.13). A four component vector (Rs,Gs,Bs,As) is returned to the geometry shader. In a geometry shader it is not possible to perform automatic level-of- detail calculations using partial derivatives of the texture coordinates with respect to window coordinates as described in section 3.8.8. Hence, there is no automatic selection of an image array level. Minification or magnification of a texture map is controlled by a level-of-detail value optionally passed as an argument in the texture lookup functions. If the texture lookup function supplies an explicit level-of-detail value lambda, then the pre-bias level-of-detail value LAMBDAbase(x, y) = lambda (replacing equation 3.18). If the texture lookup function does not supply an explicit level-of-detail value, then LAMBDAbase(x, y) = 0. The scale factor Rho(x, y) and its approximation function f(x, y) (see equation 3.21) are ignored. Texture lookups involving textures with depth component data can either return the depth data directly or return the results of a comparison with the R value (see section 3.8.14) used to perform the lookup. The comparison operation is requested in the shader by using any of the shadow sampler and in the texture using the TEXTURE COMPARE MODE parameter. These requests must be consistent; the results of a texture lookup are undefined if: * the sampler used in a texture lookup function is not one of the shadow sampler types, and the texture object's internal format is DEPTH COMPONENT, and the TEXTURE COMPARE MODE is not NONE; * the sampler used in a texture lookup function is one of the shadow sampler types, and the texture object's internal format is DEPTH COMPONENT, and the TEXTURE COMPARE MODE is NONE; or * the sampler used in a texture lookup function is one of the shadow sampler types, and the texture object's internal format is not DEPTH COMPONENT. If a geometry shader uses a sampler where the associated texture object is not complete as defined in section 3.8.10, the texture image unit will return (R,G,B,A) = (0, 0, 0, 1). Geometry Shader Inputs The OpenGL Shading Language specification describes the set of built-in variables that are available as inputs to the geometry shader. This set receives the values from the equivalent built-in output variables written by the vertex shader. These built-in variables are arrays; each element in the array holds the value for a specific vertex of the input primitive. The length of each array depends on the value of the input primitive type, as determined by the program object value GEOMETRY_INPUT_TYPE_EXT, and is set by the GL during link. Each built-in variable is a one-dimensional array, except for the built-in texture coordinate variable, which is a two- dimensional array. The vertex shader built-in output gl_TexCoord[] is a one-dimensional array. Therefore, the geometry shader equivalent input variable gl_TexCoordIn[][] becomes a two- dimensional array. See the OpenGL Shading Language Specification, sections 4.3.6 and 7.6 for more information. The built-in varying variables gl_FrontColorIn[], gl_BackColorIn[], gl_FrontSecondaryColorIn[] and gl_BackSecondaryColorIn[] hold the per-vertex front and back colors of the primary and secondary colors, as written by the vertex shader to its equivalent built-in output variables. The built-in varying variable gl_TexCoordIn[][] holds the per- vertex values of the array of texture coordinates, as written by the vertex shader to its built-in output array gl_TexCoord[]. The built-in varying variable gl_FogFragCoordIn[] holds the per- vertex fog coordinate, as written by the vertex shader to its built- in output variable gl_FogFragCoord. The built-in varying variable gl_PositionIn[] holds the per-vertex position, as written by the vertex shader to its output variable gl_Position. Note that writing to gl_Position from either the vertex or fragment shader is optional. See also section 7.1 "Vertex and Geometry Shader Special Variables" of the OpenGL Shading Language specification. The built-in varying variable gl_ClipVertexIn[] holds the per-vertex position in clip coordinates, as written by the vertex shader to its output variable gl_ClipVertex. The built-in varying variable gl_PointSizeIn[] holds the per-vertex point size written by the vertex shader to its built-in output varying variable gl_PointSize. If the vertex shader does not write gl_PointSize, the value of gl_PointSizeIn[] is undefined, regardless of the value of the enable VERTEX_PROGRAM_POINT_SIZE. The built-in special variable gl_PrimitiveIDIn is not an array and has no vertex shader equivalent. It is filled with the number of primitives processed since the last time Begin was called (directly or indirectly via vertex array functions). The first primitive generated after a Begin is numbered zero, and the primitive ID counter is incremented after every individual point, line, or triangle primitive is processed. For triangles drawn in point or line mode, the primitive ID counter is incremented only once, even though multiple points or lines may be drawn. Restarting a primitive topology using the primitive restart index has no effect on the primitive ID counter. Similarly to the built-in varying variables, user-defined input varying variables need to be declared as arrays. Declaring a size is optional. If no size is specified, it will be inferred by the linker from the input primitive type. If a size is specified, it has to be of the size matching the number of vertices of the input primitive type, otherwise a link error will occur. The built-in variable gl_VerticesIn, if so desired, can be used to size the array correctly for each input primitive type. User-defined varying variables can be declared as arrays in the vertex shader. This means that those, on input to the geometry shader, must be declared as two-dimensional arrays. See sections 4.3.6 and 7.6 of the OpenGL Shading Language Specification for more information. Using any of the built-in or user-defined input varying variables can count against the limit MAX_VERTEX_VARYING_COMPONENTS_EXT as discussed in section 2.15.3. Geometry Shader outputs A geometry shader is limited in the number of vertices it may emit per invocation. The maximum number of vertices a geometry shader can possibly emit needs to be set as a parameter of the program object that contains the geometry shader. To do so, call ProgramParameteriEXT with <pname> set to GEOMETRY_VERTICES_OUT_EXT and <value> set to the maximum number of vertices the geometry shader will emit in one invocation. This setting will not be guaranteed to be in effect until the next time LinkProgram has been called successfully. If a geometry shader, in one invocation, emits more vertices than the value GEOMETRY_VERTICES_OUT_EXT, these emits may have no effect. There are two implementation-dependent limits on the value of GEOMETRY_VERTICES_OUT_EXT. First, the error INVALID_VALUE will be generated by ProgramParameteriEXT if the number of vertices specified exceeds the value of MAX_GEOMETRY_OUTPUT_VERTICES_EXT. Second, the product of the total number of vertices and the sum of all components of all active varying variables may not exceed the value of MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT. LinkProgram will fail if it determines that the total component limit would be violated. A geometry shader can write to built-in as well as user-defined varying variables. These values are expected to be interpolated across the primitive it outputs, unless they are specified to be flat shaded. In order to seamlessly be able to insert or remove a geometry shader from a program object, the rules, names and types of the output built-in varying variables and user-defined varying variables are the same as for the vertex shader. Refer to section 2.15.3 and the OpenGL Shading Language specification sections 4.3.6, 7.1 and 7.6 for more detail. The built-in output variables gl_FrontColor, gl_BackColor, gl_FrontSecondaryColor, and gl_BackSecondaryColor hold the front and back colors for the primary and secondary colors for the current vertex. The built-in output variable gl_TexCoord[] is an array and holds the set of texture coordinates for the current vertex. The built-in output variable gl_FogFragCoord is used as the "c" value, as described in section 3.10 "Fog" of the OpenGL 2.0 specification. The built-in special variable gl_Position is intended to hold the homogeneous vertex position. Writing gl_Position is optional. The built-in special variable gl_ClipVertex holds the vertex coordinate used in the clipping stage, as described in section 2.12 "Clipping" of the OpenGL 2.0 specification. The built-in special variable gl_PointSize, if written, holds the size of the point to be rasterized, measured in pixels. Additionally, a geometry shader can write to the built-in special variables gl_PrimitiveID and gl_Layer, whereas a vertex shader cannot. The built-in gl_PrimitiveID provides a single integer that serves as a primitive identifier. This written primitive ID is available to fragment shaders. If a fragment shader using primitive IDs is active and a geometry shader is also active, the geometry shader must write to gl_PrimitiveID or the primitive ID number is undefined. The built-in variable gl_Layer is used in layered rendering, and discussed in the next section. The number of components available for varying variables is given by the implementation-dependent constant MAX_GEOMETRY_VARYING_COMPONENTS_EXT. This value represents the number of individual components of a varying variable; varying variables declared as vectors, matrices, and arrays will all consume multiple components. When a program is linked, all components of any varying variable written by a geometry shader, or read by a fragment shader, will count against this limit. The transformed vertex position (gl_Position) does not count against this limit. A program whose geometry and/or fragment shaders access more than MAX_GEOMETRY_VARYING_COMPONENTS_EXT worth of varying variable components may fail to link, unless device-dependent optimizations are able to make the program fit within available hardware resources. Layered rendering Geometry shaders can be used to render to one of several different layers of cube map textures, three-dimensional textures, plus one- dimensional and two-dimensional texture arrays. This functionality allows an application to bind an entire "complex" texture to a framebuffer object, and render primitives to arbitrary layers computed at run time. For example, this mechanism can be used to project and render a scene onto all six faces of a cubemap texture in one pass. The layer to render to is specified by writing to the built-in output variable gl_layer. Layered rendering requires the use of framebuffer objects. Refer to the section 'Dependencies on EXT_framebuffer_object' for details.

Additions to Chapter 3 of the OpenGL 2.0 Specification (Rasterization) |

Modify Section 3.3, Points (p. 95) (replace all Section 3.3 text on p. 95) A point is drawn by generating a set of fragments in the shape of a square or circle centered around the vertex of the point. Each vertex has an associated point size that controls the size of that square or circle. If no vertex or geometry shader is active, the size of the point is controlled by void PointSize(float size); <size> specifies the requested size of a point. The default value is 1.0. A value less than or equal to zero results in the error INVALID_VALUE. The requested point size is multiplied with a distance attenuation factor, clamped to a specified point size range, and further clamped to the implementation-dependent point size range to produce the derived point size: derived size = clamp(size * sqrt(1/(a+b*d+c*d^2))) where d is the eye-coordinate distance from the eye, (0,0,0,1) in eye coordinates, to the vertex, and a, b, and c are distance attenuation function coefficients. If a vertex or geometry shader is active, the derived size depends on the per-vertex point size mode enable. Per-vertex point size mode is enabled or disabled by calling Enable or Disable with the symbolic value PROGRAM_POINT_SIZE_EXT. If per-vertex point size is enabled and a geometry shader is active, the derived point size is taken from the (potentially clipped) point size variable gl_PointSize written by the geometry shader. If per-vertex point size is enabled and no geometry shader is active, the derived point size is taken from the (potentially clipped) point size variable gl_PointSize written by the vertex shader. If per-vertex point size is disabled and a geometry and/or vertex shader is active, the derived point size is taken from the <size> value provided to PointSize, with no distance attenuation applied. In all cases, the derived point size is clamped to the implementation-dependent point size range. If multisampling is not enabled, the derived size is passed on to rasterization as the point width. ... Modify section 3.10 "Fog", p. 191 Modify the third paragraph of this section as follows. If a vertex or geometry shader is active, or if the fog source, as defined below, is FOG_COORD, then c is the interpolated value of the fog coordinate for this fragment. Otherwise, ...

Additions to Chapter 4 of the OpenGL 2.0 Specification (Per-Fragment Operations and the Frame Buffer) |

None.

Additions to Chapter 5 of the OpenGL 2.0 Specification (Special Functions) |

Change section 5.4 Display Lists, p. 237 Add the command ProgramParameteriEXT to the list of commands that are not compiled into a display list, but executed immediately, under "Program and Shader Objects", p. 241

Additions to Chapter 6 of the OpenGL 2.0 Specification (State and State Requests) |

Modify section 6.1.14, Shader and Program Objects, p. 256 Add to the second paragraph on p. 257: ... if <shader> is a fragment shader object, and GEOMETRY_SHADER_EXT is returned if <shader> is a geometry shader object. Add to the end of the description of GetProgramiv, p. 257: If <pname> is GEOMETRY_VERTICES_OUT_EXT, the current value of the maximum number of vertices the geometry shader will output is returned. If <pname> is GEOMETRY_INPUT_TYPE_EXT, the current geometry shader input type is returned and can be one of POINTS, LINES, LINES_ADJACENCY_EXT, TRIANGLES or TRIANGLES_ADJACENCY_EXT. If <pname> is GEOMETRY_OUTPUT_TYPE_EXT, the current geometry shader output type is returned and can be one of POINTS, LINE_STRIP or TRIANGLE_STRIP.

Additions to Appendix A of the OpenGL 2.0 Specification (Invariance) |

None.

Additions to the AGL/GLX/WGL Specifications |

None.

Dependencies on NV_primitive_restart |

The spec describes the behavior that primitive restart does not affect the primitive ID counter gl_PrimitiveIDIn. If NV_primitive_restart is not supported, references to that extension in the discussion of the primitive ID should be removed.

Dependencies on EXT_framebuffer_object |

If EXT_framebuffer_object (or similar functionality) is not supported, the gl_Layer output has no effect. "FramebufferTextureEXT" and "FramebufferTextureLayerEXT" should be removed from "New Procedures and Functions", and FRAMEBUFFER_ATTACHMENT_LAYERED_EXT, FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT, and FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT should be removed from "New Tokens". Otherwise, this extension modifies EXT_framebuffer_object to add the notion of layered framebuffer attachments and framebuffers that can be used in conjunction with geometry shaders to allow programs to direct primitives to a face of a cube map or layer of a three-dimensional texture or one- or two-dimensional array texture. The layer used for rendering can be selected by the geometry shader at run time. (insert before the end of Section 4.4.2, Attaching Images to Framebuffer Objects) There are several types of framebuffer-attachable images: * the image of a renderbuffer object, which is always two-dimensional, * a single level of a one-dimensional texture, which is treated as a two-dimensional image with a height of one, * a single level of a two-dimensional or rectangle texture, * a single face of a cube map texture level, which is treated as a two-dimensional image, or * a single layer of a one- or two-dimensional array texture or three-dimensional texture, which is treated as a two-dimensional image. Additionally, an entire level of a three-dimensional texture, cube map texture, or one- or two-dimensional array texture can be attached to an attachment point. Such attachments are treated as an array of two-dimensional images, arranged in layers, and the corresponding attachment point is considered to be layered. (replace section 4.4.2.3, "Attaching Texture Images to a Framebuffer") GL supports copying the rendered contents of the framebuffer into the images of a texture object through the use of the routines CopyTexImage{1D|2D}, and CopyTexSubImage{1D|2D|3D}. Additionally, GL supports rendering directly into the images of a texture object. To render directly into a texture image, a specified level of a texture object can be attached as one of the logical buffers of the currently bound framebuffer object by calling: void FramebufferTextureEXT(enum target, enum attachment, uint texture, int level); <target> must be FRAMEBUFFER_EXT. <attachment> must be one of the attachment points of the framebuffer listed in table 1.nnn. If <texture> is zero, any image or array of images attached to the attachment point named by <attachment> is detached, and the state of the attachment point is reset to its initial values. <level> is ignored if <texture> is zero. If <texture> is non-zero, FramebufferTextureEXT attaches level <level> of the texture object named <texture> to the framebuffer attachment point named by <attachment>. The error INVALID_VALUE is generated if <texture> is not the name of a texture object, or if <level> is not a supported texture level number for textures of the type corresponding to <target>. The error INVALID_OPERATION is generated if <texture> is the name of a buffer texture. If <texture> is the name of a three-dimensional texture, cube map texture, or one- or two-dimensional array texture, the texture level attached to the framebuffer attachment point is an array of images, and the framebuffer attachment is considered layered. The command void FramebufferTextureLayerEXT(enum target, enum attachment, uint texture, int level, int layer); operates like FramebufferTextureEXT, except that only a single layer of the texture level, numbered <layer>, is attached to the attachment point. If <texture> is non-zero, the error INVALID_VALUE is generated if <layer> is negative, or if <texture> is not the name of a texture object. The error INVALID_OPERATION is generated unless <texture> is zero or the name of a three-dimensional or one- or two-dimensional array texture. The command void FramebufferTextureFaceEXT(enum target, enum attachment, uint texture, int level, enum face); operates like FramebufferTextureEXT, except that only a single face of a cube map texture, given by <face>, is attached to the attachment point. <face> is one of TEXTURE_CUBE_MAP_POSITIVE_X, TEXTURE_CUBE_MAP_NEGATIVE_X, TEXTURE_CUBE_MAP_POSITIVE_Y, TEXTURE_CUBE_MAP_NEGATIVE_Y, TEXTURE_CUBE_MAP_POSITIVE_Z, TEXTURE_CUBE_MAP_NEGATIVE_Z. If <texture> is non-zero, the error INVALID_VALUE is generated if <texture> is not the name of a texture object. The error INVALID_OPERATION is generated unless <texture> is zero or the name of a cube map texture. The command void FramebufferTexture1DEXT(enum target, enum attachment, enum textarget, uint texture, int level); operates identically to FramebufferTextureEXT, except for two additional restrictions. If <texture> is non-zero, the error INVALID_ENUM is generated if <textarget> is not TEXTURE_1D and the error INVALID_OPERATION is generated unless <texture> is the name of a one-dimensional texture. The command void FramebufferTexture2DEXT(enum target, enum attachment, enum textarget, uint texture, int level); operates similarly to FramebufferTextureEXT. If <textarget> is TEXTURE_2D or TEXTURE_RECTANGLE_ARB, <texture> must be zero or the name of a two-dimensional or rectangle texture. If <textarget> is TEXTURE_CUBE_MAP_POSITIVE_X, TEXTURE_CUBE_MAP_NEGATIVE_X, TEXTURE_CUBE_MAP_POSITIVE_Y, TEXTURE_CUBE_MAP_NEGATIVE_Y, TEXTURE_CUBE_MAP_POSITIVE_Z, or TEXTURE_CUBE_MAP_NEGATIVE_Z, <texture> must be zero or the name of a cube map texture. For cube map textures, only the single face of the cube map texture level given by <textarget> is attached. The error INVALID_ENUM is generated if <texture> is not zero and <textarget> is not one of the values enumerated above. The error INVALID_OPERATION is generated if <texture> is the name of a texture whose type does not match the texture type required by <textarget>. The command void FramebufferTexture3DEXT(enum target, enum attachment, enum textarget, uint texture, int level, int zoffset); behaves identically to FramebufferTextureLayerEXT, with the <layer> parameter set to the value of <zoffset>. The error INVALID_ENUM is generated if <textarget> is not TEXTURE_3D. The error INVALID_OPERATION is generated unless <texture> is zero or the name of a three-dimensional texture. For all FramebufferTexture commands, if <texture> is non-zero and the command does not result in an error, the framebuffer attachment state corresponding to <attachment> is updated based on the new attachment. FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT is set to TEXTURE, FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT is set to <texture>, and FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL is set to <level>. FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_FACE is set to <textarget> if FramebufferTexture2DEXT is called and <texture> is the name of a cubemap texture; otherwise, it is set to TEXTURE_CUBE_MAP_POSITIVE_X. FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT is set to <layer> or <zoffset> if FramebufferTextureLayerEXT or FramebufferTexture3DEXT is called; otherwise, it is set to zero. FRAMEBUFFER_ATTACHMENT_LAYERED_EXT is set to TRUE if FramebufferTextureEXT is called and <texture> is the name of a three-dimensional texture, cube map texture, or one- or two-dimensional array texture; otherwise it is set to FALSE. (modify Section 4.4.4.1, Framebuffer Attachment Completeness -- add to the conditions necessary for attachment completeness) The framebuffer attachment point <attachment> is said to be "framebuffer attachment complete" if ...: * If FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT is TEXTURE and FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT names a three-dimensional texture, FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT must be smaller than the depth of the texture. * If FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT is TEXTURE and FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT names a one- or two-dimensional array texture, FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT must be smaller than the number of layers in the texture. (modify section 4.4.4.2, Framebuffer Completeness -- add to the list of conditions necessary for completeness) * If any framebuffer attachment is layered, all populated attachments must be layered. Additionally, all populated color attachments must be from textures of the same target (i.e., three-dimensional, cube map, or one- or two-dimensional array textures). { FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT } * If any framebuffer attachment is layered, all attachments must have the same layer count. For three-dimensional textures, the layer count is the depth of the attached volume. For cube map textures, the layer count is always six. For one- and two-dimensional array textures, the layer count is simply the number of layers in the array texture. { FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT } The enum in { brackets } after each clause of the framebuffer completeness rules specifies the return value of CheckFramebufferStatusEXT (see below) that is generated when that clause is violated. ... (add section 4.4.7, Layered Framebuffers) A framebuffer is considered to be layered if it is complete and all of its populated attachments are layered. When rendering to a layered framebuffer, each fragment generated by the GL is assigned a layer number. The layer number for a fragment is zero if * the fragment is generated by DrawPixels, CopyPixels, or Bitmap, * geometry shaders are disabled, or * the current geometry shader does not contain an instruction that statically assigns a value to the built-in output variable gl_Layer. Otherwise, the layer for each point, line, or triangle emitted by the geometry shader is taken from the layer output of one of the vertices of the primitive. The vertex used is implementation-dependent. To get defined results, all vertices of each primitive emitted should set the same value for gl_Layer. Since the EndPrimitive() built-in function starts a new output primitive, defined results can be achieved if EndPrimitive() is called between two vertices emitted with different layer numbers. A layer number written by a geometry shader has no effect if the framebuffer is not layered. When fragments are written to a layered framebuffer, the fragment's layer number selects an image from the array of images at each attachment point from which to obtain the destination R, G, B, A values for blending (Section 4.1.8) and to which to write the final color values for that attachment. If the fragment's layer number is negative or greater than the number of layers attached, the effects of the fragment on the framebuffer contents are undefined. When the Clear command is used to clear a layered framebuffer attachment, all layers of the attachment are cleared. When commands such as ReadPixels or CopyPixels read from a layered framebuffer, the image at layer zero of the selected attachment is always used to obtain pixel values. When cube map texture levels are attached to a layered framebuffer, there are six layers attached, numbered zero through five. Each layer number is mapped to a cube map face, as indicated in Table X.4. layer number cube map face ------------ --------------------------- 0 TEXTURE_CUBE_MAP_POSITIVE_X 1 TEXTURE_CUBE_MAP_NEGATIVE_X 2 TEXTURE_CUBE_MAP_POSITIVE_Y 3 TEXTURE_CUBE_MAP_NEGATIVE_Y 4 TEXTURE_CUBE_MAP_POSITIVE_Z 5 TEXTURE_CUBE_MAP_NEGATIVE_Z Table X.4, Layer numbers for cube map texture faces. The layers are numbered in the same sequence as the cube map face token values. (modify Section 6.1.3, Enumerated Queries -- Modify/add to list of <pname> values for GetFramebufferAttachmentParameterivEXT if FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT is TEXTURE) If <pname> is FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT and the attached image is a layer of a three-dimensional texture or one- or two-dimensional array texture, then <params> will contain the specified layer number. Otherwise, <params> will contain the value zero. If <pname> is FRAMEBUFFER_ATTACHMENT_LAYERED_EXT, then <params> will contain TRUE if an entire level of a three-dimesional texture, cube map texture, or one- or two-dimensional array texture is attached to the <attachment>. Otherwise, <params> will contain FALSE. (Modify the Additions to Chapter 5, section 5.4) Add the commands FramebufferTextureEXT, FramebufferTextureLayerEXT, and FramebufferTextureFaceEXT to the list of commands that are not compiled into a display list, but executed immediately.

Dependencies on EXT_framebuffer_blit |

If EXT_framebuffer_blit is supported, the EXT_framebuffer_object language should be further amended so that <target> values passed to FramebufferTextureEXT and FramebufferTextureLayerEXT can be DRAW_FRAMEBUFFER_EXT or READ_FRAMEBUFFER_EXT, and that those functions set/query state for the draw framebuffer if <target> is FRAMEBUFFER_EXT.

Dependencies on EXT_texture_array |

If EXT_texture_array is not supported, the discussion array textures the layered rendering edits to EXT_framebuffer_object should be removed. Layered rendering to cube map and 3D textures would still be supported. If EXT_texture_array is supported, the edits to EXT_framebuffer_object supersede those made in EXT_texture_array, except for language pertaining to mipmap generation of array textures. There are no functional incompatibilities between the FBO support in these two specifications. The only differences are that this extension supports layered rendering and also rewrites certain sections of the core FBO specification more aggressively.

Dependencies on ARB_texture_rectangle |

If ARB_texture_rectangle is not supported, all references to rectangle textures in the EXT_framebuffer_object spec language should be removed.

Dependencies on EXT_texture_buffer_object |

If EXT_buffer_object is not supported, the reference to an INVALID_OPERATION error if a buffer texture is passed to FramebufferTextureEXT should be removed.

GLX protocol |

TBD

Errors |

The error INVALID_VALUE is generated by ProgramParameteriEXT if <pname> is GEOMETRY_INPUT_TYPE_EXT and <value> is not one of POINTS, LINES, LINES_ADJACENCY_EXT, TRIANGLES or TRIANGLES_ADJACENCY_EXT. The error INVALID_VALUE is generated by ProgramParameteriEXT if <pname> is GEOMETRY_OUTPUT_TYPE_EXT and <value> is not one of POINTS, LINE_STRIP or TRIANGLE_STRIP. The error INVALID_VALUE is generated by ProgramParameteriEXT if <pname> is GEOMETRY_VERTICES_OUT_EXT and <value> is negative. The error INVALID_VALUE is generated by ProgramParameteriEXT if <pname> is GEOMETRY_VERTICES_OUT_EXT and <value> exceeds MAX_GEOMETRY_OUTPUT_VERTICES_EXT. The error INVALID_VALUE is generated by ProgramParameteriEXT if <pname> is set to GEOMETRY_VERTICES_OUT_EXT and the product of <value> and the sum of all components of all active varying variables exceeds MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT. The error INVALID_OPERATION is generated if Begin, or any command that implicitly calls Begin, is called when a geometry shader is active and: * the input primitive type of the current geometry shader is POINTS and <mode> is not POINTS, * the input primitive type of the current geometry shader is LINES and <mode> is not LINES, LINE_STRIP, or LINE_LOOP, * the input primitive type of the current geometry shader is TRIANGLES and <mode> is not TRIANGLES, TRIANGLE_STRIP or TRIANGLE_FAN, * the input primitive type of the current geometry shader is LINES_ADJACENCY_EXT and <mode> is not LINES_ADJACENCY_EXT or LINE_STRIP_ADJACENCY_EXT, or * the input primitive type of the current geometry shader is TRIANGLES_ADJACENCY_EXT and <mode> is not TRIANGLES_ADJACENCY_EXT or TRIANGLE_STRIP_ADJACENCY_EXT.

New State |

Initial Get Value Type Get Command Value Description Sec. Attribute ------------------------- ---- ----------- ------- ---------------------- ------ ---------- FRAMEBUFFER_ATTACHMENT_ nxB GetFramebuffer- FALSE Framebuffer attachment 4.4.2.3 - LAYERED_EXT Attachment- is layered ParameterivEXT Modify the following state value in Table 6.28, Shader Object State, p. 289. Get Value Type Get Command Value Description Sec. Attribute ------------------ ---- ----------- ------- ---------------------- ------ --------- SHADER_TYPE Z2 GetShaderiv - Type of shader (vertex, 2.15.1 - Fragment, geometry) Add the following state to Table 6.29, Program Object State, p. 290 Initial Get Value Type Get Command Value Description Sec. Attribute ------------------------- ---- ------------ ------- ----------------- ------ ------- GEOMETRY_VERTICES_OUT_EXT Z+ GetProgramiv 0 max # of output vertices 2.16.4 - GEOMETRY_INPUT_TYPE_EXT Z5 GetProgramiv TRIANGLES Primitive input type 2.16.1 - GEOMETRY_OUTPUT_TYPE_EXT Z3 GetProgramiv TRIANGLE_ Primitive output type 2.16.2 - STRIP

New Implementation Dependent State |

Min. Get Value Type Get Command Value Description Sec. Attrib ---------------------- ---- ----------- ----- -------------------- -------- ------ MAX_GEOMETRY_TEXTURE_ Z+ GetIntegerv 16 maximum number of 2.16.4 - IMAGE_UNITS_EXT texture image units accessible in a geometry shader MAX_GEOMETRY_OUTPUT_ Z+ GetIntegerv 256 maximum number of 2.16.4 - VERTICES_EXT vertices that any geometry shader can can emit MAX_GEOMETRY_TOTAL_ Z+ GetIntegerv 1024 maximum number of 2.16.4 - OUTPUT_COMPONENTS_EXT total components (all vertices) of active varyings that a geometry shader can emit MAX_GEOMETRY_UNIFORM_ Z+ GetIntegerv 512 Number of words for 2.16.3 - COMPONENTS_EXT geometry shader uniform variables MAX_GEOMETRY_VARYING_ Z+ GetIntegerv 32 Number of components 2.16.4 - COMPONENTS_EXT for varying variables between geometry and fragment shaders MAX_VERTEX_VARYING_ Z+ GetIntegerv 32 Number of components 2.15.3 - COMPONENTS_EXT for varying variables between Vertex and geometry shaders MAX_VARYING_ Z+ GetIntegerv 32 Alias for 2.15.3 - COMPONENTS_EXT MAX_VARYING_FLOATS

Modifications to the OpenGL Shading Language Specification version 1.10.59 |

Including the following line in a shader can be used to control the language features described in this extension: #extension GL_EXT_geometry_shader4 : <behavior> where <behavior> is as specified in section 3.3. A new preprocessor #define is added to the OpenGL Shading Language: #define GL_EXT_geometry_shader4 1 Change the introduction to Chapter 2 "Overview of OpenGL Shading" as follows: The OpenGL Shading Language is actually three closely related languages. These languages are used to create shaders for the programmable processors contained in the OpenGL processing pipeline. The precise definition of these programmable units is left to separate specifications. In this document, we define them only well enough to provide a context for defining these languages. Unless otherwise noted in this paper, a language feature applies to all languages, and common usage will refer to these languages as a single language. The specific languages will be referred to by the name of the processor they target: vertex, geometry or fragment. Change the last sentence of the first paragraph of section 3.2 "Source Strings" to: Multiple shaders of the same language (vertex, geometry or fragment) can be linked together to form a single program. Change the first paragraph of section 4.1.3, "Integers" as follows: ... integers are limited to 16 bits of precision, plus a sign representation in the vertex, geometry and fragment languages.. Change the first paragraph of section 4.1.9, "Arrays", as follows: Variables of the same type can be aggregated into one- and two- dimensional arrays by declaring a name followed by brackets ( [ ] for one-dimensional arrays and [][] for two-dimensional arrays) enclosing an optional size. When an array size is specified in a declaration, it must be an integral constant expression (see Section 4.3.3 "Integral Constant Expressions") greater than zero. If an array is indexed with an expression that is not an integral constant expression or passed as an argument to a function, then its size must be declared before any such use. It is legal to declare an array without a size and then later re-declare the same name as an array of the same type and specify a size. It is illegal to declare an array with a size, and then later (in the same shader) index the same array with an integral constant expression greater than or equal to the declared size. It is also illegal to index an array with a negative constant expression. Arrays declared as formal parameters in a function declaration must specify a size. Undefined behavior results from indexing an array with a non-constant expression that's greater than or equal to the array's size or less than 0. All basic types and structures can be formed into arrays. Two-dimensional arrays can only be declared as "varying in" variables in a geometry shader. See section 4.3.6 for details. All other declarations of two-dimensional arrays are illegal. Change the fourth paragraph of section 4.2 "Scoping", as follows: Shared globals are global variables declared with the same name in independently compiled units (shaders) of the same language (vertex, geometry or fragment) that are linked together . Change section 4.3 "Type Qualifiers" Change the "varying", "in" and "out" qualifiers as follows: varying - linkage between a vertex shader and geometry shader, or between a geometry shader and a fragment shader, or between a vertex shader and a fragment shader. in - for function parameters passed into a function or for input varying variables (geometry only) out - for function parameters passed back out of a function, but not initialized for use when passed in. Also for output varying variables (geometry only). Change section 4.3.6 "Varying" as follows: Varying variables provide the interface between the vertex shader and geometry shader and also between the geometry shader and fragment shader and the fixed functionality between them. If no geometry shader is present, varying variables also provide the interface between the vertex shader and fragment shader. The vertex, or geometry shader will compute values per vertex (such as color, texture coordinates, etc) and write them to output variables declared with the "varying" qualifier (vertex or geometry) or "varying out" qualifiers (geometry only). A vertex or geometry shader may also read these output varying variables, getting back the same values it has written. Reading an output varying variable in a vertex or geometry shader returns undefined results if it is read before being written. A geometry shader may also read from an input varying variable declared with the "varying in" qualifiers. The value read will be the same value as written by the vertex shader for that varying variable. Since a geometry shader operates on primitives, each input varying variable needs to be declared as an array. Each element of such an array corresponds to a vertex of the primitive being processed. If the varying variable is declared as a scalar or matrix in the vertex shader, it will be a one-dimensional array in the geometry shader. Each array can optionally have a size declared. If a size is not specified, it inferred by the linker and depends on the value of the input primitive type. See table 4.3.xxx to determine the exact size. The read-only built-in constant gl_VerticesIn will be set to this value by the linker. If a size is specified, it has to be the size as given by table 4.3.xxx, otherwise a link error will occur. The built-in constant gl_VerticesIn, if so desired, can be used to size the array correctly for each input primitive type. Varying variables can also be declared as arrays in the vertex shader. This means that those, on input to the geometry shader, must be declared as two- dimensional arrays. The first index to the two-dimensional array holds the vertex number. Declaring a size for the first range of the array is optional, just as it is for one-dimensional arrays. The second index holds the per-vertex array data. Declaring a size for the second range of the array is not optional, and has to match the declaration in the vertex shader. Value of built-in Input primitive type gl_VerticesIn ----------------------- ----------------- POINTS 1 LINES 2 LINES_ADJACENCY_EXT 4 TRIANGLES 3 TRIANGLES_ADJACENCY_EXT 6 Table 4.3.xxxx The value of the built-in variable gl_VerticesIn is determined at link time, based on the input primitive type. It is illegal to index these varying arrays, or in the case of two- dimensional arrays, the first range of the array, with a negative integral constant expression or an integral constant expression greater than or equal to gl_VerticesIn. A link error will occur in these cases. Varying variables that are part of the interface to the fragment shader are set per vertex and interpolated in a perspective correct manner, unless flat shaded, over the primitive being rendered. If single-sampling, the interpolated value is for the fragment center. If multi-sampling, the interpolated value can be anywhere within the pixel, including the fragment center or one of the fragment samples. A fragment shader may read from varying variables and the value read will be the interpolated value, as a function of the fragment's position within the primitive, unless the varying variable is flat shaded. A fragment shader cannot write to a varying variable. If a geometry shader is present, the type of the varying variables with the same name declared in the vertex shader and the input varying variables in the geometry shader must match, otherwise the link command will fail. Likewise, the type of the output varying variables with the same name declared in the geometry shader and the varying variables in the fragment shader must match. If a geometry shader is not present, the type of the varying variables with the same name declared in both the vertex and fragment shaders must match, otherwise the link command will fail. Only those varying variables used (i.e. read) in the geometry or fragment shader must be written to by the vertex or geometry shader; declaring superfluous varying variables in the vertex shader or declaring superfluous output varying variables in the geometry shader is permissible. Varying variables are declared as in the following example: varying in float foo[]; // geometry shader input. Size of the // array set as a result of link, based // on the input primitive type. varying in float foo[gl_VerticesIn]; // geometry shader input varying in float foo[3]; // geometry shader input. Only legal for // the TRIANGLES input primitive type varying in float foo[][5]; // Size of the first range set as a // result of link. Each vertex holds an // array of 5 floats. varying out vec4 bar; // geometry output varying vec3 normal; // vertex shader output or fragment // shader input The varying qualifier can be used only with the data types float, vec2, vec3, vec4, mat2, mat3 and mat4 or arrays of these. Structures cannot be varying. Additionally, the "varying in" and "varying out" qualifiers can only be used in a geometry shader. If no vertex shader is active, the fixed functionality pipeline of OpenGL will compute values for the built-in varying variables that will be consumed by the fragment shader. Similarly, if no fragment shader is active, the vertex shader or geometry shader is responsible for computing and writing to the built-in varying variables that are needed for OpenGL's fixed functionality fragment pipeline. Varying variables are required to have global scope, and must be declared outside of function bodies, before their first use. Change section 7.1 "Vertex Shader Special Variables" Rename this section to "Vertex and Geometry Shader Special Variables" Anywhere in this section where it reads "vertex language" replace it with "vertex and geometry language". Anywhere in this section where it reads "vertex shader" replace it with "vertex shader or geometry shader". Change the second paragraph to: The variable gl_Position is available only in the vertex and geometry language and is intended for writing the homogeneous vertex position. It can be written at any time during shader execution. It may also be read back by the shader after being written. This value will be used by primitive assembly, clipping, culling, and other fixed functionality operations that operate on primitives after vertex or geometry processing has occurred. Compilers may generate a diagnostic message if they detect gl_Position is read before being written, but not all such cases are detectable. Writing to gl_Position is optional. If gl_Position is not written but subsequent stages of the OpenGL pipeline consume gl_Position, then results are undefined. Change the last sentence of this section into the following: The read-only built-in gl_PrimitiveIDIn is available only in the geometry language and is filled with the number of primitives processed by the geometry shader since the last time Begin was called (directly or indirectly via vertex array functions). See section 2.16.4 for more information. This variable is intrinsically declared as: int gl_PrimitiveIDIn; // read only The built-in output variable gl_PrimitiveID is available only in the geometry language and provides a single integer that serves as a primitive identifier. This written primitive ID is available to fragment shaders. If a fragment shader using primitive IDs is active and a geometry shader is also active, the geometry shader must write to gl_PrimitiveID or the primitive ID in the fragment shader number is undefined. The built-in output variable gl_Layer is available only in the geometry language, and provides the number of the layer of textures attached to a FBO to direct rendering to. If a shader statically assigns a value to gl_Layer, layered rendering mode is enabled. See section 2.16.4 for a detailed explanation. If a shader statically assigns a value to gl_Layer, and there is an execution path through the shader that does not set gl_Layer, then the value of gl_Layer may be undefined for executions of the shader that take that path. These variables area intrinsically declared as: int gl_PrimitiveID; int gl_Layer; These variables can be read back by the shader after writing to them, to retrieve what was written. Reading the variable before writing it results in undefined behavior. If it is written more than once, the last value written is consumed by the subsequent operations. All built-in variables discussed in this section have global scope. Change section 7.2 "Fragment Shader Special Variables" Change the first paragraph on p. 44 as follows: The fragment shader has access to the read-only built-in variable gl_FrontFacing whose value is true if the fragment belongs to a front-facing primitive. One use of this is to emulate two-sided lighting by selecting one of two colors calculated by the vertex shader or geometry shader. Change the first sentence of section 7.4 "Built-in Constants" The following built-in constant is provided to geometry shaders. const int gl_VerticesIn; // Value set at link time The following built-in constants are provided to the vertex, geometry and fragment shaders: Change section 7.6 "Varing Variables" Unlike user-defined varying variables, the built-in varying variables don't have a strict one-to-one correspondence between the vertex language, geometry language and the fragment language. Four sets are provided, one set for the vertex language output, one set for the geometry language output, one set for the fragment language input and another set for the geometry language input. Their relationship is described below. The following built-in varying variables are available to write to in a vertex shader or geometry shader. A particular one should be written to if any functionality in a corresponding geometry shader or fragment shader or fixed pipeline uses it or state derived from it. Otherwise, behavior is undefined. Vertex language built-in outputs: varying vec4 gl_FrontColor; varying vec4 gl_BackColor; varying vec4 gl_FrontSecondaryColor; varying vec4 gl_BackSecondaryColor; varying vec4 gl_TexCoord[]; // at most will be gl_MaxTextureCoords varying float gl_FogFragCoord; Geometry language built-in outputs: varying out vec4 gl_FrontColor; varying out vec4 gl_BackColor; varying out vec4 gl_FrontSecondaryColor; varying out vec4 gl_BackSecondaryColor; varying out vec4 gl_TexCoord[]; // at most gl_MaxTextureCoords varying out float gl_FogFragCoord; For gl_FogFragCoord, the value written will be used as the "c" value on page 160 of the OpenGL 1.4 Specification by the fixed functionality pipeline. For example, if the z-coordinate of the fragment in eye space is desired as "c", then that's what the vertex or geometry shader should write into gl_FogFragCoord. Indices used to subscript gl_TexCoord must either be an integral constant expressions, or this array must be re-declared by the shader with a size. The size can be at most gl_MaxTextureCoords. Using indexes close to 0 may aid the implementation in preserving varying resources. The following input varying variables are available to read from in a geometry shader. varying in vec4 gl_FrontColorIn[gl_VerticesIn]; varying in vec4 gl_BackColorIn[gl_VerticesIn]; varying in vec4 gl_FrontSecondaryColorIn[gl_VerticesIn]; varying in vec4 gl_BackSecondaryColorIn[gl_VerticesIn]; varying in vec4 gl_TexCoordIn[gl_VerticesIn][]; // at most will be // gl_MaxTextureCoords varying in float gl_FogFragCoordIn[gl_VerticesIn]; varying in vec4 gl_PositionIn[gl_VerticesIn]; varying in float gl_PointSizeIn[gl_VerticesIn]; varying in vec4 gl_ClipVertexIn[gl_VerticesIn]; All built-in variables are one-dimensional arrays, except for gl_TexCoordIn, which is a two-dimensional array. Each element of a one-dimensional array, or the first index of a two-dimensional array, corresponds to a vertex of the primitive being processed and receives their value from the equivalent vertex output varying variables. See also section 4.3.6. The following varying variables are available to read from in a fragment shader. The gl_Color and gl_SecondaryColor names are the same names as attributes passed to the vertex shader. However, there is no name conflict, because attributes are visible only in vertex shaders and the following are only visible in a fragment shader. varying vec4 gl_Color; varying vec4 gl_SecondaryColor; varying vec4 gl_TexCoord[]; // at most will be gl_MaxTextureCoords varying float gl_FogFragCoord; The values in gl_Color and gl_SecondaryColor will be derived automatically by the system from gl_FrontColor, gl_BackColor, gl_FrontSecondaryColor, and gl_BackSecondaryColor. This selection process is described in section 2.14.1 of the OpenGL 2.0 Specification. If fixed functionality is used for vertex processing, then gl_FogFragCoord will either be the z-coordinate of the fragment in eye space, or the interpolation of the fog coordinate, as described in section 3.10 of the OpenGL 1.4 Specification. The gl_TexCoord[] values are the interpolated gl_TexCoord[] values from a vertex or geometry shader or the texture coordinates of any fixed pipeline based vertex functionality. Indices to the fragment shader gl_TexCoord array are as described above in the vertex and geometry shader text. Change section 8.7 "Texture Lookup Functions" Change the first paragraph to: Texture lookup functions are available to vertex, geometry and fragment shaders. However, level of detail is not computed by fixed functionality for vertex or geometry shaders, so there are some differences in operation between texture lookups. The functions. Change the third and fourth paragraphs to: In all functions below, the bias parameter is optional for fragment shaders. The bias parameter is not accepted in a vertex or geometry shader. For a fragment shader, if bias is present, it is added to the calculated level of detail prior to performing the texture access operation. If the bias parameter is not provided, then the implementation automatically selects level of detail: For a texture that is not mip-mapped, the texture is used directly. If it is mip- mapped and running in a fragment shader, the LOD computed by the implementation is used to do the texture lookup. If it is mip- mapped and running on the vertex or geometry shader, then the base LOD of the texture is used. The built-ins suffixed with "Lod" are allowed only in a vertex or geometry shader. For the "Lod" functions, lod is directly used as the level of detail. Change section 8.9 Noise Functions Change the first paragraph to: Noise functions are available to the vertex, geometry and fragment shaders. They are... Add a section 8.10 Geometry Shader Functions This section contains functions that are geometry language specific. Syntax: void EmitVertex(); // Geometry only void EndPrimitive(); // Geometry only Description: The function EmitVertex() specifies that a vertex is completed. A vertex is added to the current output primitive using the current values of the varying output variables and the current values of the special built-in output variables gl_PointSize, gl_ClipVertex, gl_Layer, gl_Position and gl_PrimitiveID. The values of any unwritten output variables are undefined. The values of all varying output variables and the special built-in output variables are undefined after a call to EmitVertex(). If a geometry shader, in one invocation, emits more vertices than the value GEOMETRY_VERTICES_OUT_EXT, these emits may have no effect. The function EndPrimitive() specifies that the current output primitive is completed and a new output primitive (of the same type) should be started. This function does not emit a vertex. The effect of EndPrimitive() is roughly equivalent to calling End followed by a new Begin, where the primitive mode is taken from the program object parameter GEOMETRY_OUTPUT_TYPE_EXT. If the output primitive type is POINTS, calling EndPrimitive() is optional. A geometry shader starts with an output primitive containing no vertices. When a geometry shader terminates, the current output primitive is automatically completed. It is not necessary to call EndPrimitive() if the geometry shader writes only a single primitive. Add/Change section 9 (Shading language grammar): init_declarator_list: single_declaration init_declarator_list COMMA IDENTIFIER init_declarator_list COMMA IDENTIFIER array_declarator_suffix init_declarator_list COMMA IDENTIFIER EQUAL initializer single_declaration: fully_specified_type fully_specified_type IDENTIFIER fully_specified_type IDENTIFIER array_declarator_suffix fully_specified_type IDENTIFIER EQUAL initializer array_declarator_suffix: LEFT_BRACKET RIGHT_BRACKET LEFT_BRACKET constant_expression RIGHT_BRACKET LEFT_BRACKET RIGHT_BRACKET array_declarator_suffix LEFT_BRACKET constant_expression RIGHT_BRACKET array_declarator_suffix type_qualifier: CONST ATTRIBUTE // Vertex only VARYING VARYING IN // Geometry only VARYING OUT // Geometry only UNIFORM NVIDIA Implementation Details Because of a hardware limitation, some GeForce 8 series chips use the odd vertex of an incomplete TRIANGLE_STRIP_ADJACENCY_EXT primitive as a replacement adjacency vertex rather than ignoring it.

Issues |

1. How do geometry shaders fit into the existing GL pipeline? RESOLVED: The following diagram illustrates how geometry shaders fit into the "vertex processing" portion of the GL (Chapter 2 of the OpenGL 2.0 Specification). First, vertex attributes are specified via immediate-mode commands or through vertex arrays. They can be conventional attributes (e.g., glVertex, glColor, glTexCoord) or generic (numbered) attributes. Vertices are then transformed, either using a vertex shader or fixed-function vertex processing. Fixed-function vertex processing includes position transformation (modelview and projection matrices), lighting, texture coordinate generation, and other calculations. The results of either method are a "transformed vertex", which has a position (in clip coordinates), front and back colors, texture coordinates, generic attributes (vertex shader only), and so on. Note that on many current GL implementations, vertex processing is performed by executing a "fixed function vertex shader" generated by the driver. After vertex transformation, vertices are assembled into primitives, according to the topology (e.g., TRIANGLES, QUAD_STRIP) provided by the call to glBegin(). Primitives are points, lines, triangles, quads, or polygons. Many GL implementations do not directly support quads or polygons, but instead decompose them into triangles as permitted by the spec. After initial primitive assembly, a geometry shader is executed on each individual point, line, or triangle primitive, if one is active. It can read the attributes of each transformed vertex, perform arbitrary computations, and emit new transformed vertices. These emitted vertices are themselves assembled into primitives according to the output primitive type of the geometry shader. Then, the colors of the vertices of each primitive are clamped to [0,1] (if color clamping is enabled), and flat shading may be performed by taking the color from the provoking vertex of the primitive. Each primitive is clipped to the view volume, and to any enabled user-defined clip planes. Color, texture coordinate, and other attribute values are computed for each new vertex introduced by clipping. After clipping, the position of each vertex (in clip coordinates) is converted to normalized device coordinates in the perspective division (divide by w) step, and to window coordinates in the viewport transformation step. At the same time, color values may be converted to normalized fixed-point values according to the "Final Color Processing" portion of the specification. After the vertices of the primitive are transformed to window coordinate, the GL determines if the primitive is front- or back-facing. That information is used for two-sided color selection, where a single set of colors is selected from either the front or back colors associated with each transformed vertex. When all this is done, the final transformed position, colors (primary and secondary), and other attributes are used for rasterization (Chapter 3 in the OpenGL 2.0 Specification). When the raster position is specified (via glRasterPos), it goes through the entire vertex processing pipeline as though it were a point. However, geometry shaders are never run on the raster position. |generic |conventional |vertex |vertex |attributes |attributes | | | +-------------------+ | | | V V V vertex fixed-function shader vertex | processing | | | | +<-------------------+ | Output |position, color, Primitive |other vertex data Type | | V | Begin/ primitive geometry primitive | End ------> assembly -----> shader ----> assembly <-+ State | | V | +<------------------------------+ | | | color flat +----------> clamping ----> shading | | V | +<------------------------------+ | | clipping | | perspective viewport +------> divide ----> transform | | | +---+-----+ | V | | final facing | +------> color determination | | processing | | | | | | | | | | | +-----+ +----+ | | | | | | V V | | two-sided | | coloring | | | | | | | +------------------+ | +-------------+ | | | V V V rasterization | | V 2. Why is this called GL_EXT_geometry_shader4? There aren't any previous versions of this extension, let alone three? RESOLVED: To match its sibling, EXT_gpu_shader4 and the assembly version NV_gpu_program4. This is the fourth generation of shading functionality, hence the "4" in the name. 3. Should the GL produce errors at Begin time if an application specifies a primitive mode that is "incompatible" with the geometry shader? For example, if the geometry shader operates on triangles and the application sends a POINTS primitive? RESOLVED: Yes. Mismatches of app-specified primitive types and geometry shader input primitive types appear to be errors and would produce weird and wonderful effects. 4. Can the input primitive type of a geometry shader be determined at run time? RESOLVED: No. Each geometry shader has a single input primitive type, and vertices are presented to the shader in a specific order based on that type. 5. Can the input primitive type of a geometry shader be changed? DISCUSSION: The input primitive type is a property of the program object. A change of the input primitive type means the program object will need to be re-linked. It would be nice if the input primitive type was known at compile time, so that the compiler can do error checking of the type and the number of vertices being accessed by the shader. Since we allow multiple compilation units to form one geometry shader, it is not clear how to achieve that. Therefore, the input primitive type is a property of the program object, and not of a shader object. RESOLVED: Yes, but each change means the program object will have to be re-linked. 6. Can the output primitive type of a geometry shader be determined at run time? RESOLVED: Not in this extension. 7. Can the output primitive type of a program object be changed? RESOLVED: Yes, but the program object will have to be re-linked in order for the change to have effect on program execution. 8. Must the output primitive type of a geometry shader match the input primitive type in any way? RESOLVED: No, you can have a geometry shader generate points out of triangles or triangles out of points. Some combinations are analogous to existing OpenGL operations: reading triangles and writing points or line strips can be used to emulate a subset of PolygonMode functionality. Reading points and writing triangle strips can be used to emulate point sprites. 9. Are primitives emitted by a geometry shader processed like any other OpenGL primitive? RESOLVED: Yes. Antialiasing, stippling, polygon offset, polygon mode, culling, two-sided lighting and color selection, point sprite operations, and fragment processing all work as expected. One limitation is that the only output primitive types supported are points, line strips, and triangle strips, none of which meaningfully support edge flags that are sometimes used in conjunction with the POINT and LINE polygon modes. Edge flags are always ignored for line-mode triangle strips. 10. Should geometry shaders support additional input primitive types? RESOLVED: Possibly in a future extension. It should be straightforward to build a future extension to support geometry shaders that operate on quads. Other primitive types might be more demanding on hardware. Quads with adjacency would require 12 vertices per shader execution. General polygons may require even more, since there is no fixed bound on the number of vertices in a polygon. 11. Should geometry shaders support additional output primitive types? RESOLVED: Possibly in a future extension. Additional output types (e.g., independent lines, line loops, triangle fans, polygons) may be useful in the future; triangle fans/polygons seem particularly useful. 12. How are adjacency primitives processed by the GL? RESOLVED: The primitive type of an adjacent primitive is set as a Begin mode parameter. Any vertex of an adjacency primitive will be treated as a regular vertex, and processed by a vertex shader as well as the geometry shader. The geometry shader cannot output adjacency primitives, thus processing stops with the geometry shader. If a geometry shader is not active, the GL ignores the "adjacent" vertices in the adjacency primitive. 13. Should we provide additional adjacency primitive types that can be used inside a Begin/End? RESOLVED: Not in this extension. It may be desirable to add new primitive types (e.g., TRIANGLE_FAN_ADJACENCY) in a future extension. 14. How do geometry shaders interact with RasterPos? RESOLVED: Geometry shaders are ignored when specifying the raster position. 15. How do geometry shaders interact with pixel primitives (DrawPixels, Bitmap)? RESOLVED: They do not. 16. Is there a limit on the number of vertices that can be emitted by a geometry shader? RESOLVED: Unfortunately, yes. Besides practical hardware limits, there may also be practical performance advantages when applications guarantee a tight upper bound on the number of vertices a geometry shader will emit. GPUs frequently excecute programs in parallel, and there are substantial implementation challenges to parallel execution of geometry threads that can write an unbounded number of results, particular given that all the primitives generated by the first geometry shader invocation must be consumed before any of the primitives generated by the second program invocation. Limiting the amount of data a geometry shader can write substantially eases the implementation burden. A program object, holding a geometry shader, must declare a maximum number of vertices that can be emitted. There is an implementation-dependent limit on the total number of vertices a program object can emit (256 minimum) and the product of the number of vertices emitted and the number of components of all active varying variables (1024 minimum). It would be ideal if the limit could be inferred from the instructions in the shader itself, and that would be possible for many shaders, particularly ones with straight-line flow control. For shaders with more complicated flow control (subroutines, data- dependent looping, and so on), it would be impossible to make such an inference and a "safe" limit would have to be used with adverse and possibly unexpected performance consequences. The limit on the number of EmitVertex() calls that can be issued can not always be enforced at compile time, or even at Begin time. We specify that if a shader tries to emit more vertices than allowed, emits that exceed the limit may or may not have any effect. 17. Should it be possible to change the limit GEOMETRY_VERTICES_OUT_EXT, the number of vertices emitted by a geometry shader, after the program object, containing the shader, is linked? RESOLVED: NO. See also issue 31. Changing this limit might require a re-compile and/or re-link of the shaders and program object on certain implementations. Pretending that this limit can be changed without re-linking does not reflect reality. 18. How do user clipping and geometry shaders interact? RESOLVED: Just like vertex shaders and user clipping interact. The geometry shader needs to provide the (eye) position gl_ClipVertex. Primitives are clipped after geometry shader execution, not before. 19. How do edge flags interact with adjacency primitives? RESOLVED: If geometry programs are disabled, adjacency primitives are still supported. For TRIANGLES_ADJACENCY_EXT, edge flags will apply as they do for TRIANGLES. Such primitives are rendered as independent triangles as though the adjacency vertices were not provided. Edge flags for the "real" vertices are supported. For all other adjacency primitive types, edge flags are irrelevant. 20. Now that a third shader object type is added, what combinations of GLSL, assembly (ARB or NV) low level and fixed-function do we want to support? DISCUSSION: With the addition of the geometry shader, the number of combinations the GL pipeline could support doubled (there is no fixed-function geometry shading). Possible combinations now are: vertex geometry fragment ff/ASM/GLSL none/ASM/GLSL ff/ASM/GLSL for a total of 3 x 3 x 3 is 27 combinations. Before the geometry shader was added, the number of combinations was 9, and those we need to support. We have a choice on the other 18. RESOLUTION: It makes sense to draw a line at raster in the GL pipeline. The 'north' side of this line covers vertex and geometry shaders, the 'south' side fragment shaders. We now add a simple rule that states that if a program object contains anything north of this line, the north side will be 100% GLSL. This means that: a) GLSL program objects with a vertex shader can only use a geometry shader and not an assembly geometry program. If an assembly geometry program is enabled, it is bypassed. This also avoids a tricky case -- a GLSL program object with a vertex and a fragment program linked together. Injecting an assembly geometry shader in the middle at run time won't work well. b) GLSL program objects with a geometry shader must have a vertex shader (cannot be ARB/NV or fixed-function vertex shading). The 'south' side in this program object still can be any of ff/ARB/NV/GLSL. 21. How do geometry shaders interact with color clamping? RESOLVED: Geometry shader execution occurs prior to color clamping in the pipeline. This means the colors written by vertex shaders are not clamped to [0,1] before they are read by geometry shaders. If color clamping is enabled, any vertex colors written by the geometry shader will have their components clamped to [0,1]. 22. What is a primitive ID and a vertex ID? I am confused. DISCUSSION: A vertex shader can read a built-in attribute that holds the ID of the current vertex it is processing. See the EXT_gpu_shader4 spec for more information on vertex ID. If the geometry shader needs access to a vertex ID as well, it can be passed as a user-defined varying variable. A geometry shader can read a built-in varying variable that holds the ID of the current primitive it is processing. It also has the ability to write to a built-in output primitive ID variable, to communicate the primitive ID to a fragment shader. A fragment shader can read a built-in attribute that holds the ID of the current primitive it is processing. A primitive ID will be generated even if no geometry shader is active. 23. After a call to EmitVertex(), should the values of the output varying variables be retained or be undefined? DISCUSSION: There is not a clear answer to this question .The underlying HW mechanism is as follows. An array of output registers is set aside to store vertices that make up primitives. After each EmitVertex() a pointer into that array is incremented. The shader no longer has access to the previous set of values. This argues that the values of output varying variables should be undefined after an EmitVertex() call. The shader is responsible for writing values to all varying variables it wants to emit, for each emit. The counter argument to this is that this is not a nice model for GLSL to program in. The compiler can store varying outputs in a temp register and preserve their values across EmitVertex() calls, at the cost of increased register pressure. RESOLUTION: For now, without being a clear winner, we've decided to go with the undefined option. The shader is responsible for writng values to all varying variabvles it wants to emit, for each emit. 24. How to distinguish between input and output "varying" variables? DISCUSSION: Geometry shader outputs are varying variables consistent with the existing definition of varying (used to communicate to the fragment processing stage). Geometry inputs are received from a vertex shader writing to its varying variable outputs. The inputs could be called "varying", to match with the vertex shader, or could be called "attributes" to match the vertex shader inputs (which are called attributes). RESOLUTION: We'll call input variables "varying", and not "attributes". To distinguish between input and output, they will be further qualified with the words "in" and "out" resulting in, for example: varying in float foo; varying out vec4 bar[]; 25. What is the syntax for declaring varying input variables? DISCUSSION: We need a way to distinguish between the vertices of the input primitive. Suggestions: 1. Declare each input varying variable as an unsized array. Its size is inferred by the linker based on the output primitive type. 2. Declare each input varying variable as a sized array. If the size does not match the output primitive type, a link error occurs. 3. Have an array of structures, where the structure contains the attributes for each vertex. RESOLUTION: Option 1 seems simple and solves the problem, but it is not a clear winner over the other two. To aid the shader writer in figuring out the size of each array, a new built-in constant, gl_VerticesIn, is defined that holds the number of vertices for the current input primitive type. 26. Does gl_PointSize, gl_Layer, gl_ClipVertex count agains the MAX_GEOMETRY_VARYING_COMPONENTS limit? RESOLUTION: Core OpenGL 2.0 makes a distinction between varying variables, output from a vertex shader and interpolated over a primitive, and 'special built-in variables' that are outputs, but not interpolated across a primitive. Only varying variables do count against the MAX_VERTEX_VARYING_COMPONENTS limit. gl_PointSize, gl_Layer, gl_ClipVertex and gl_Position are 'special built-in' variables, and therefore should not count against the limit. If HW does need to take components away to support those, that is ok. The actual spec language does mention possible implementation dependencies. 27. Should writing to gl_Position be optional? DISCUSSION: Before this extensions, the OpenGL Shading Language required that gl_Position be written to in a vertex shader. With the addition of geometry shaders, it is not necessary anymore for a vertex shader to output gl_Position. The geometry shader can do so. With the addition of transform-feedback (see the transform feedback specification) it is not necessary useful for the geometry shader to write out gl_Position either. RESOLUTION: Yes, this should be optional. 28. Should geometry shaders be able to select a layer of a 3D texture, cube map texture, or array texture at run time? If so, how? RESOLVED: See also issue 32. This extension provides a per-vertex output called "gl_Layer", which is an integer specifying the layer to render to. In order to get defined results, the value of gl_Layer needs to be constant for each primitive (point, line or triangle) being emitted by a geometry shader. This layer value is used for all fragments generated by that primitive. The EXT_framebuffer_object (FBO) extension is used for rendering to textures, but for cube maps and 3D textures, it only provides the ability to attach a single face or layer of such textures. This extension generalizes FBO by creates new entry points to bind an entire texture level (FramebufferTextureEXT) or a single layer of a texture level (FramebufferTextureLayerEXT) or a single face of a level of a cube map texture (FramebufferTextureFaceEXT) to an attachment point. The existing FBO binding functions, FramebufferTexture[123]DEXT are retained, and are defined in terms of the more general new functions. The new functions do not have a dimension in the function name or a <textarget> parameter, which can be inferred from the provided texture. When an entire texel level of a cube map, 3D, or array texture is attached, that attachment is considered layered. The framebuffer is considered layered if any attachment is layered. When the framebuffer is layered, there are three additional completeness requirements: * all attachments must be layered * all color attachments must be from textures of identical type * all attachments must have the same number of layers We expect subsequent versions of the FBO spec to relax the requirement that all attachments must have the same width and height, and plan to relax the similar requirement for layer count at that time. When rendering to a layered framebuffer, layer zero is used unless a geometry shader that writes (statically assings, to be precise) to gl_Layer. When rendering to a non-layered framebuffer, the value of gl_Layer is ignored and the set of single-image attachments are used. When reading from a layered framebuffer (e.g., ReadPixels), layer zero is always used. When clearing a layered framebuffer, all layers are cleared to the corresponding clear values. Several other approaches were considered, including leveraging existing FBO attachment functions and requiring the use of FramebufferTexture3D with a <zoffset> of zero to make a framebuffer attachment "layerable" (attaching layer zero means that the attachment could be used for either layered- or non- layered rendering). Whether rendering was layered or not could either be inferred from the active geometry shader, or set as a new property of the framebuffer object. There is presently no FramebufferParameter API to set a property of a framebuffer, so it would have been necessary to create new set/query APIs if this approach were chosen. 29. How should per-vertex point size work with geometry shaders? RESOLVED: The value of the existing VERTEX_PROGRAM_POINT_SIZE enable, to control the point size behavior of a vertex shader, does not affect geometry shaders. Specifically, If a geometry shader is active, the point size is taken from the point size output gl_PointSize of the vertex shader, regardless of the value of VERTEX_PROGRAM_POINT_SIZE. 30. Geometry shaders don't provide a QUADS or generic POLYGON input primitive type. In this extension, what happens if an application provides QUADS, QUAD_STRIP, or POLYGON primitives? RESOLVED: Not all vendors supporting this extension were able to accept quads and polygon primitives as input, so such functionality was not provided in this extension. This extension requires that primitives provided to the GL must match the input primitive type of the active geometry shader (if any). QUADS, QUAD_STRIP, and POLYGON primitives are considered not to match any input primitive type, so an INVALID_OPERATION error will result. The NV_geometry_shader4 extension (built on top of this one) allows applications to provide quads or general polygon primitives to a geometry shader with an input primitive type of TRIANGLES. Such primitives are decomposed into triangles, and a geometry shader is run on each triangle independently. 31. Geometry shaders provide a limit on the number of vertices that can be emitted. Can this limit be changed at dynamically? RESOLVED: See also issue 17. Not in this extension. This functionality was not provided because it would be an expensive operation on some implementations of this extension. The NV_geometry_shader4 extension (layered on top of this one) does allow applications to change this limit dynamically. An application can change the vertex output limit at any time. To allow for the possibility of dynamic changes (as in NV_geometry_shader4) but not require it, a limit change is not guaranteed to take effect unless the program object is re-linked. However, there is no guarantee that such limit changes will not take effect immediately. 32. See also issue 28. Each vertex emitted by a geometry shader can specify a layer to render to using the output variable "gl_Layer". For LINE_STRIP and TRIANGLE_STRIP output primitive types, which vertex's layer is used? RESOLVED: The vertex from which the layer is extracted is unfortunately undefined. In practice, some implementations of this extension will extract the layer number from the first vertex of the output primitive; others will extract it from the last (provoking) vertex. A future geometry shader extension may choose to define this behavior one way or the other. To get portable results, the layer number should be the same for all vertices in any single primitive emitted by the geometry shader. The EndPrimitive() built-in function available in a geometry shader starts a new primitive, and the layer number emitted can be safely changed after EndPrimitive() is called. 33. The grammar allows "varying", "varying out", and "varying in" as type-qualifiers for geometry shaders. What does "varying" without "in" or "out" mean for a geometry shader? RESOLVED: The "varying" type qualifier in a geometry shader not followed by "in" or "out" means the same as "varying out". This is consistent with the specification saying: "In order to seamlessly be able to insert or remove a geometry shader from a program object, the rules, names and types of the output built-in varying variables and user-defined varying variables are the same as for the vertex shader."

Revision History |

Rev. Date Author Changes ---- -------- -------- ----------------------------------------- 17 05/22/07 mjk Clarify that "varying" means the same as "varying out" in a geometry shader. 16 01/10/07 pbrown Specify that the total component limit is enforced at LinkProgram time. 15 12/15/06 pbrown Documented that the '#extension' token for this extension should begin with "GL_", as apparently called for per convention. 14 -- Pre-release revisions. 14 -- Pre-release revisions.

Last update: November 14, 2006.Cette page doit être lue avec un navigateur récent respectant le standard XHTML 1.1. |