| Name |
| |
| NV_geometry_program4 |
| |
| Name Strings |
| |
| (none) |
| |
| Contact |
| |
| Pat Brown, NVIDIA Corporation (pbrown 'at' nvidia.com) |
| |
| Status |
| |
| Shipping for GeForce 8 Series (November 2006) |
| |
| Version |
| |
| Last Modified Date: 12/14/09 |
| NVIDIA Revision: 13 |
| |
| Number |
| |
| 323 |
| |
| Dependencies |
| |
| OpenGL 1.1 is required. |
| |
| This extension is written against the OpenGL 2.0 specification. |
| |
| NV_gpu_program4 is required. This extension is supported if |
| "GL_NV_gpu_program4" is found in the extension string. |
| |
| 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. |
| |
| Overview |
| |
| NV_geometry_program4 defines a new type of program available to be run on |
| the GPU, called a geometry program. Geometry programs are run on full |
| primitives after vertices are transformed, but prior to flat shading and |
| clipping. |
| |
| A geometry program begins with a single primitive - a point, line, or |
| triangle. Quads and polygons are allowed, but are decomposed into |
| individual triangles prior to geometry program execution. It can read the |
| attributes of any of the vertex in the primitive and use them to generate |
| new primitives. A geometry program has a fixed output primitive type, |
| either a point, a line strip, or a triangle strip. It emits vertices |
| (using the EMIT opcode) to define the output primitive. The attributes of |
| emitted vertices are specified by writing to the same set of result |
| bindings (e.g., "result.position") provided for vertex programs. |
| Additionally, a geometry program can emit multiple disconnected primitives |
| by using the ENDPRIM opcode, which is roughly equivalent to calling End |
| and then Begin again. The primitives emitted by the geometry program are |
| then clipped and then processed like an equivalent OpenGL primitive |
| specified by the application. |
| |
| This extension 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 "adjacency" vertices can be accessed by |
| geometry programs and used to match up the outputs of the geometry program |
| with those of neighboring primitives. |
| |
| Additionally, geometry programs allow for layered rendering, where entire |
| three-dimensional, cube map, or array textures (EXT_texture_array) can be |
| bound to the current framebuffer. Geometry programs can use the |
| "result.layer" binding to select a layer or cube map face to render to. |
| Each primitive emitted by such a geometry program is rendered to the layer |
| taken from its provoking vertex. |
| |
| Since geometry programs expect a specific input primitive type, an error |
| will occur if the application presents primtives of a different type. For |
| example, if an enabled geometry program expects points, an error will |
| occur at Begin() time, if a primitive mode of TRIANGLES is specified. |
| |
| New Procedures and Functions |
| |
| void ProgramVertexLimitNV(enum target, int limit); |
| |
| 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 <cap> parameter of Disable, Enable, and IsEnabled, by |
| the <pname> parameter of GetBooleanv, GetIntegerv, GetFloatv, and |
| GetDoublev, and by the <target> parameter of ProgramStringARB, |
| BindProgramARB, ProgramEnvParameter4[df][v]ARB, |
| ProgramLocalParameter4[df][v]ARB, GetProgramEnvParameter[df]vARB, |
| GetProgramLocalParameter[df]vARB, GetProgramivARB and |
| GetProgramStringARB: |
| |
| GEOMETRY_PROGRAM_NV 0x8C26 |
| |
| Accepted by the <pname> parameter of GetProgramivARB: |
| |
| MAX_PROGRAM_OUTPUT_VERTICES_NV 0x8C27 |
| MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28 |
| 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 |
| |
| 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 |
| GetFramebufferAttachmentParameterivEXT: |
| |
| 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: The "EXT" tokens above are shared with the EXT_geometry_shader4 |
| extension.) |
| |
| (Note: FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 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 programs are |
| enabled, even if no vertex program is used.) |
| |
| Additions to Chapter 2 of the OpenGL 1.5 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 X.1 (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 program. |
| |
| 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 |
| program (Section 2.15). If geometry programs are disabled, 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 X.1. |
| |
| 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 |
| geometry programs (Section 2.15). If geometry programs are disabled, 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 |
| vertices are considered adjacent to the i + 2nd and i + 3rd vertices, |
| respectively. See Figure X.1. |
| |
| 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 X.2 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 program. |
| |
| 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 geometry |
| programs (Section 2.15). If geometry programs are disabled, 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 X.2. |
| |
| 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 X.3 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 |
| program. |
| |
| Triangle Strips with Adjacency |
| |
| Triangle strips with adjacency are similar to triangle strips, except that |
| each triangle edge has an adjacent vertex that can be accessed by geometry |
| programs (Section 2.15). If geometry programs are disabled, 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 X.1 describes |
| the vertices and order used to draw each triangle, and which vertices are |
| considered adjacent to each edge of the triangle. See Figure X.3. |
| |
| (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 X.1: 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 |
| and programs 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 program is active, programs can write front and |
| back colors using the available color result bindings. When a vertex or |
| geometry shader or program 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. |
| |
| Insert New Section 2.14.6, Geometry Programs (between 2.14.5, Color Index |
| Lighting and 2.14.6, Clamping and Masking, p. 69) |
| |
| Section 2.14.6, Geometry Programs |
| |
| Each primitive may be optionally transformed by a geometry program. |
| Geometry programs are enabled by calling Enable with the value |
| GEOMETRY_PROGRAM_NV. A geometry program takes a single input primitive |
| and generates vertices to be arranged into one or more output primitives. |
| The original input primitive is discarded, and the output primitives are |
| processed in order by the remainder of the GL pipeline. |
| |
| Section 2.14.6.1, Geometry Program Input Primitives |
| |
| A geometry program can operate on one of five input primitive types, as |
| specified by the mandatory "PRIMITIVE_IN" declaration. Depending on the |
| input primitive type, one to six vertices are available when the program |
| is executed. A geometry program will fail to load unless it contains |
| exactly one such declaration. |
| |
| Each input primitive type supports only a subset of the primitives |
| provided by the GL. If geometry programs are enabled, 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 current geometry program. |
| |
| The supported input primitive types are: |
| |
| Points (POINTS) |
| |
| Geometry programs that operate on points are valid only for the POINTS |
| primitive type. There is a only a single vertex available for each |
| program invocation: "vertex[0]" refers to the single point. |
| |
| Lines (LINES) |
| |
| Geometry programs 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 program invocation: "vertex[0]" and "vertex[1]" refer |
| to the beginning and end of the line segment. |
| |
| Lines with Adjacency (LINES_ADJACENCY) |
| |
| Geometry programs 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. "vertex[1]" and "vertex[2]" refer to the beginning and end of |
| the line segment. "vertex[0]" and "vertex[3]" refer to the vertices |
| adjacent to the beginning and end of the line segment, respectively. |
| |
| Triangles (TRIANGLES) |
| |
| Geometry programs that operate on triangles are valid for the TRIANGLES, |
| TRIANGLE_STRIP, TRIANGLE_FAN, QUADS, QUAD_STRIP, and POLYGON primitive |
| types. |
| |
| When used with a geometry program that operates on triangles, QUADS, |
| QUAD_STRIP, and POLYGON primitives are decomposed into triangles in an |
| unspecified, implementation-dependent manner. For convex polygons |
| (already required in the core GL specification), this decomposition |
| satisfies three properties: |
| |
| * the collection of triangles fully covers the area of the original |
| primitive, |
| |
| * no two triangles in the decomposition overlap, and |
| |
| * the orientation of each triangle is consistent with the orientation of |
| the original primitive. |
| |
| For such primitives, the program is executed once for each triangle in the |
| decomposition. |
| |
| There are three vertices available for each program invocation. |
| "vertex[0]", "vertex[1]", and "vertex[2]", refer to the first, second, and |
| third vertex of the triangle, respectively. |
| |
| Triangles with Adjacency (TRIANGLES_ADJACENCY) |
| |
| Geometry programs 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. "vertex[0]", "vertex[2]", and "vertex[4]" refer to the first, |
| second, and third vertex of the triangle respectively. "vertex[1]", |
| "vertex[3]", and "vertex[5]" refer to 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.14.6.2, Geometry Program Output Primitives |
| |
| A geometry program can generate primitives of one of three types, as |
| specified by the mandatory "PRIMITIVE_OUT" declaration. A geometry |
| program will fail to load unless it contains exactly one such declaration. |
| |
| The supported output primitive types are points (POINTS), line strips |
| (LINE_STRIP), and triangle strips (TRIANGLE_STRIP). The vertices output |
| by the geometry program are decomposed into points, lines, or triangles |
| based on the output primitive type in the manner described in section |
| 2.6.1. |
| |
| Section 2.14.6.3, Geometry Program Execution Environment |
| |
| Geometry programs execute using the instruction set documented in the |
| GL_NV_gpu_program4 extension specification and in a manner similar to |
| vertex programs. Each vertex attribute access must identify the vertex |
| number being accessed. For example, "vertex[1].position" identifies the |
| transformed position of "vertex[1]" as specified in teh description of the |
| input primitive type. Output vertices are specified by writing to vertex |
| result variables in the same manner as done by vertex programs. |
| |
| The special instruction "EMIT" specifies that a vertex is completed. A |
| vertex is added to the current output primitive using the current values |
| of the vertex result variables. The values of any unwritten result |
| variables (or components) are undefined. |
| |
| After an EMIT instruction is completed, the current values of all vertex |
| result variables become undefined. If a program wants to ensure that the |
| same result is used for every vertex written by the program, it is |
| necessary to write the corresponding value once per vertex. |
| |
| The special instruction "ENDPRIM" specifies that the current output |
| primitive should be completed and a new output primitive should be |
| started. A geometry program starts with an output primitive containing no |
| vertices. When a geometry program terminates, the current output |
| primitive is automatically completed. ENDPRIM has no effect if the |
| geometry program's output primitive type is POINTS. |
| |
| When a primitive generated by a geometry program is completed, the |
| vertices added by the EMIT instruction are decomposed into points, lines, |
| or triangles according to the output primitive type in the manner |
| described in Section 2.8.1. The resulting primitives are then clipped and |
| rasterized. If the number of vertices emitted by the geometry program is |
| not sufficient to produce a single primitive, nothing is drawn. |
| |
| Like vertex and fragment programs, geometry programs can access textures. |
| The maximum number of texture image units that can be accessed by a |
| geometry program is given by the value of |
| MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT. |
| |
| Section 2.14.6.4, Geometry Program Output Limits |
| |
| A geometry program may not emit an unlimited number of vertices per |
| invocation. Each geometry program must declare a vertex limit, which is |
| the maximum number of vertices that the program can ever produce. The |
| vertex limit is specified using the "VERTICES_OUT" declaration. A |
| geometry program will fail to load unless it contains exactly one such |
| declaration. |
| |
| There are two implementation-dependent limits that limit the total number |
| of vertices that a program can emit. First, the vertex limit may not |
| exceed the value of MAX_PROGRAM_OUTPUT_VERTICES_NV. Second, product of |
| the vertex limit and the number of result variable components written by |
| the program (PROGRAM_RESULT_COMPONENTS_NV, as described in section 2.X.3.5 |
| of NV_gpu_program4) may not exceed the value of |
| MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV. A geometry program will fail to |
| load if its maximum vertex count or maximum total component count exceeds |
| the implementation-dependent limit. The limits may be queried by calling |
| GetProgramiv with a <target> of GEOMETRY_PROGRAM_NV. Note that the |
| maximum number of vertices that a geometry program can emit may be much |
| lower than MAX_PROGRAM_OUTPUT_VERTICES_NV if the program writes a large |
| number of result variable components. |
| |
| After a geometry program is compiled, the vertex limit may be changed |
| using the command |
| |
| void ProgramVertexLimitNV(enum target, int limit); |
| |
| <target> must be GEOMETRY_PROGRAM_NV. <limit> is the new vertex limit, |
| which must satisfy the two rules described above. The error INVALID_VALUE |
| is generated if <limit> is less than or equal to zero, <limit> is greater |
| than or equal to MAX_PROGRAM_OUTPUT_VERTICES_NV, or if the total number of |
| components emitted would exceed MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV. |
| The error INVALID_OPERATION is generated if the current geometry program |
| has not been successfully loaded. |
| |
| When a program executes, the number of vertices it emits should not exceed |
| the vertex limit. Once a geometry program emits a number of vertices |
| equal to the vertex limit, subsequent EMIT instructions may or may not |
| have any effect. |
| |
| Modify Section 2.X.2, Program Grammar |
| |
| (replace third paragraph) |
| |
| Geometry programs are required to begin with the header string |
| "!!NVgp4.0". This header string identifies the subsequent program body as |
| being a geometry program and indicates that it should be parsed according |
| to the base NV_gpu_program4 grammar plus the additions below. Program |
| string parsing begins with the character immediately following the header |
| string. |
| |
| (add the following grammar rules to the NV_gpu_program4 base grammar) |
| |
| <declSequence> ::= <declaration> <declSequence> |
| |
| <instruction> ::= <SpecialInstruction> |
| |
| <attribUseV> ::= <attribVarName> <arrayMem> <arrayMem> |
| <swizzleSuffix> |
| |
| <attribUseS> ::= <attribVarName> <arrayMem> <arrayMem> |
| <scalarSuffix> |
| |
| <attribUseVNS> ::= <attribVarName> <arrayMem> <arrayMem> |
| |
| <resultUseW> ::= <resultVarName> <arrayMem> <optWriteMask> |
| | <resultColor> <optWriteMask> |
| | <resultColor> "." <colorType> <optWriteMask> |
| | <resultColor> "." <faceType> <optWriteMask> |
| | <resultColor> "." <faceType> "." <colorType> |
| "." <optWriteMask> |
| |
| <resultUseD> ::= <resultColor> |
| | <resultColor> "." <colorType> |
| | <resultMulti> |
| |
| <declaration> ::= "PRIMITIVE_IN" <declPrimInType> |
| | "PRIMITIVE_OUT" <declPrimOutType> |
| | "VERTICES_OUT" <int> |
| |
| <declPrimInType> ::= "POINTS" |
| | "LINES" |
| | "LINES_ADJACENCY" |
| | "TRIANGLES" |
| | "TRIANGLES_ADJACENCY" |
| |
| <declPrimOutType> ::= "POINTS" |
| | "LINE_STRIP" |
| | "TRIANGLE_STRIP" |
| |
| <SpecialInstruction> ::= "EMIT" |
| | "ENDPRIM" |
| |
| <attribBasic> ::= <vtxPrefix> "position" |
| | <vtxPrefix> "fogcoord" |
| | <vtxPrefix> "pointsize" |
| | <vtxPrefix> "id" |
| | <attribTexCoord> <optArrayMemAbs> |
| | <attribClip> <arrayMemAbs> |
| | <attribGeneric> <arrayMemAbs> |
| | "primitive" "." "id" |
| |
| <attribColor> ::= <vtxPrefix> "color" |
| |
| <attribMulti> ::= <attribTexCoord> <arrayRange> |
| | <attribClip> <arrayRange> |
| | <attribGeneric> <arrayRange> |
| |
| <attribTexCoord> ::= <vtxPrefix> "texcoord" |
| |
| <attribClip> ::= <vtxPrefix> "clip" |
| |
| <attribGeneric> ::= <vtxPrefix> "attrib" |
| |
| <vtxPrefix> ::= "vertex" <optArrayMemAbs> |
| |
| <resultBasic> ::= <resPrefix> "position" |
| | <resPrefix> "fogcoord" |
| | <resPrefix> "pointsize" |
| | <resPrefix> "primid" |
| | <resPrefix> "layer" |
| | <resultTexCoord> <optArrayMemAbs> |
| | <resultClip> <arrayMemAbs> |
| | <resultGeneric> <arrayMemAbs> |
| |
| <resultColor> ::= <resPrefix> "color" |
| |
| <resultMulti> ::= <resultTexCoord> <arrayRange> |
| | <resultClip> <arrayRange> |
| | <resultGeneric> <arrayRange> |
| |
| <resultTexCoord> ::= <resPrefix> "texcoord" |
| |
| <resultClip> ::= <resPrefix> "clip" |
| |
| <resultGeneric> ::= <resPrefix> "attrib" |
| |
| <resPrefix> ::= "result" "." |
| |
| (add the following subsection to section 2.X.3.2, Program Attribute |
| Variables) |
| |
| Geometry program attribute variables describe the attributes of each |
| transformed vertex accessible to the geometry program. Most attributes |
| correspond to the per-vertex results generated by vertex program execution |
| or fixed-function vertex processing. The "primitive.id" attribute is |
| generated specially, as described below. |
| |
| If vertex programs are enabled, attributes will be obtained from the |
| per-vertex outputs of the vertex program used to generate the vertex in |
| question. Geometry program attributes should be read using the same |
| component data type used to write the corresponding vertex program |
| results. The value of any attribute corresponding to a vertex output not |
| written by the vertex program is undefined. |
| |
| If vertex programs are disabled, attributes will be obtained from the |
| values computed by fixed-function vertex processing. All attributes, |
| except for the primitive ID should be read as floating-point values in |
| this case. |
| |
| Geometry Vertex Binding Components Description |
| ----------------------------- ---------- ---------------------------- |
| vertex[m].position (x,y,z,w) clip coordinates |
| vertex[m].color (r,g,b,a) front primary color |
| vertex[m].color.primary (r,g,b,a) front primary color |
| vertex[m].color.secondary (r,g,b,a) front secondary color |
| vertex[m].color.front (r,g,b,a) front primary color |
| vertex[m].color.front.primary (r,g,b,a) front primary color |
| vertex[m].color.front.secondary (r,g,b,a) front secondary color |
| vertex[m].color.back (r,g,b,a) back primary color |
| vertex[m].color.back.primary (r,g,b,a) back primary color |
| vertex[m].color.back.secondary (r,g,b,a) back secondary color |
| vertex[m].fogcoord (f,-,-,-) fog coordinate |
| vertex[m].pointsize (s,-,-,-) point size |
| vertex[m].texcoord (s,t,r,q) texture coordinate, unit 0 |
| vertex[m].texcoord[n] (s,t,r,q) texture coordinate, unit n |
| vertex[m].attrib[n] (x,y,z,w) generic interpolant n |
| vertex[m].clip[n] (d,-,-,-) clip plane distance |
| vertex[m].texcoord[n..o] (s,t,r,q) array of texture coordinates |
| vertex[m].attrib[n..o] (x,y,z,w) array of generic interpolants |
| vertex[m].clip[n..o] (d,-,-,-) array of clip distances |
| vertex[m].id (id,-,-,-) vertex id |
| primitive.id (id,-,-,-) primitive number |
| |
| Table X.2, Geometry Program Attribute Bindings. <m> refers to a vertex |
| number, while <n>, and <o> refer to integer constants. Only the |
| "vertex[m].texcoord" and "vertex.attrib" bindings are available in |
| arrays. |
| |
| For bindings that include "vertex[m]", <m> identifies the vertex number |
| whose attributes are used for the binding. For bindings in explicit |
| variable declarations, "[m]" is optional. If "[m]" is specified, <m> must |
| be an integer constant and must be in the valid range of vertices |
| supported for the input primitive type. If "[m]" is not specified, the |
| declared variable is accessed as an array, with the first array index |
| specifying the vertex number. If such a variable is declared an array, it |
| must have a second array index to identify the individual array element. |
| For bindings used directly in instructions, "[m]" is required and must be |
| an integer constant specifying a vertex number. The following examples |
| illustrate various legal and illegal geometry program bindings and their |
| meanings. |
| |
| ATTRIB pos = vertex.position; |
| ATTRIB pos2 = vertex[2].position; |
| ATTRIB texcoords[] = { vertex.texcoord[0..3] }; |
| ATTRIB tcoords1[4] = { vertex[1].texcoord[1..4] }; |
| INT TEMP A0; |
| ... |
| MOV R0, pos[1]; # position of vertex 1 |
| MOV R0, vertex[1].position; # position of vertex 1 |
| MOV R0, pos2; # position of vertex 2 |
| MOV R0, texcoords[A0.x][1]; # texcoord 1 of vertex A0.x |
| MOV R0, texcoords[A0.x][A0.y]; # texcoord A0.y of vertex A0.x |
| MOV R0, tcoords1[2]; # texcoord 3 of vertex 1 |
| MOV R0, vertex[A0.x].texcoord[1]; # ILLEGAL allowed -- vertex number |
| # must be constant here. |
| |
| If a geometry attribute binding matches "vertex[m].position", the "x", |
| "y", "z" and "w" components of the geometry attribute variable are filled |
| with the "x", "y", "z", and "w" components, respectively, of the |
| transformed position of vertex <m>, in clip coordinates. |
| |
| If a geometry attribute binding matches any binding in Table X.2 beginning |
| with "vertex[m].color", the "x", "y", "z", and "w" components of the |
| geometry attribute variable are filled with the "r", "g", "b", and "a" |
| components, respectively, of the corresponding color of vertex <m>. |
| Bindings containing "front" and "back" refer to the front and back colors, |
| respectively. Bindings containing "primary" and "secondary" refer to |
| primary and secondary colors, respectively. If face or color type is |
| omitted in the binding, the binding is treated as though "front" and |
| "primary", respectively, were specified. |
| |
| If a geometry attribute binding matches "vertex[m].fogcoord", the "x" |
| component of the geometry attribute variable is filled with the fog |
| coordinate of vertex <m>. The "y", "z", and "w" components are undefined. |
| |
| If a geometry attribute binding matches "vertex[m].pointsize", the "x" |
| component of the geometry attribute variable is filled with the point size |
| of vertex <m> computed by the vertex program. For fixed-function vertex |
| processing, the point size attribute is undefined. The "y", "z", and "w" |
| components are always undefined. |
| |
| If a geometry attribute binding matches "vertex[m].texcoord" or |
| "vertex[m].texcoord[n]", the "x", "y", "z", and "w" coordinates of the |
| geometry attribute variable are filled with the "s", "t", "r", and "q" |
| coordinates of texture coordinate set <n> of vertex <m>. If <n> is |
| omitted, texture coordinate set zero is used. |
| |
| If a geometry attribute binding matches "vertex[m].attrib[n]", the "x", |
| "y", "z", and "w" components of the geometry attribute variable are filled |
| with the "x", "y", "z", and "w" coordinates of generic interpolant <n> of |
| vertex <m>. All generic interpolants will be undefined when used with |
| fixed-function vertex processing. |
| |
| If a geometry attribute binding matches "vertex[m].clip[n]", the "x" |
| component of the geometry attribute variable is filled the clip distance |
| of vertex <m> for clip plane <n>, as written by the vertex program. If |
| fixed-function vertex processing or position-invariant vertex programs are |
| used, the clip distance is obtained by computing the per-clip plane dot |
| product: |
| |
| (p_1' p_2' p_3' p_4') dot (x_e y_e z_e w_e), |
| |
| at the vertex location, as described in section 2.12. The clip distance |
| for clip plane <n> is undefined if clip plane <n> is disabled. The "y", |
| "z", and "w" components of the attribute are undefined. |
| |
| If a geometry attribute binding matches "vertex[m].texcoord[n..o]", |
| "vertex[m].attrib[n..o]", or "vertex[m].clip[n..o]", a sequence of |
| 1+<o>-<n> texture coordinate bindings is created. For texture coordinate |
| bindings, it is as though the sequence "vertex[m].texcoord[n], |
| vertex[m].texcoord[n+1], ... vertex[m].texcoord[o]" were specfied. These |
| bindings are available only in explicit declarations of array variables. |
| A program will fail to load if <n> is greater than <o>. |
| |
| If a geometry attribute binding matches "vertex[m].id", the "x" component |
| is filled with the vertex ID. If a vertex program is currently active, |
| the attribute variable is filled with the vertex ID result written by the |
| vertex program. If fixed-function vertex processing is used, the vertex |
| ID is undefined. The "y", "z", and "w" components of the attribute are |
| undefined. |
| |
| If a geometry attribute binding matches "primitive.id", the "x" component |
| is filled with the number of primitives received by the GL 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 |
| polygon primitive is processed. For QUADS and QUAD_STRIP primitives that |
| are decomposed into triangles, the primitive ID is incremented after each |
| complete quad is processed. For POLYGON primitives, the primitive ID |
| counter is zero. Restarting a primitive topology using the primitive |
| restart index has no effect on the primitive ID counter. The "y", "z", |
| and "w" components of the variable are always undefined. |
| |
| (add the following subsection to section 2.X.3.5, Program Results.) |
| |
| Geometry programs emit vertices, and the set of result variables available |
| to such programs correspond to the attributes of each emitted vertex. The |
| set of allowable result variable bindings for geometry programs is given |
| in Table X.3. |
| |
| Binding Components Description |
| ----------------------------- ---------- ---------------------------- |
| result.position (x,y,z,w) position in clip coordinates |
| result.color (r,g,b,a) front-facing primary color |
| result.color.primary (r,g,b,a) front-facing primary color |
| result.color.secondary (r,g,b,a) front-facing secondary color |
| result.color.front (r,g,b,a) front-facing primary color |
| result.color.front.primary (r,g,b,a) front-facing primary color |
| result.color.front.secondary (r,g,b,a) front-facing secondary color |
| result.color.back (r,g,b,a) back-facing primary color |
| result.color.back.primary (r,g,b,a) back-facing primary color |
| result.color.back.secondary (r,g,b,a) back-facing secondary color |
| result.fogcoord (f,*,*,*) fog coordinate |
| result.pointsize (s,*,*,*) point size |
| result.texcoord (s,t,r,q) texture coordinate, unit 0 |
| result.texcoord[n] (s,t,r,q) texture coordinate, unit n |
| result.attrib[n] (x,y,z,w) generic interpolant n |
| result.clip[n] (d,*,*,*) clip plane distance |
| result.texcoord[n..o] (s,t,r,q) texture coordinates n thru o |
| result.attrib[n..o] (x,y,z,w) generic interpolants n thru o |
| result.clip[n..o] (d,*,*,*) clip distances n thru o |
| result.primid (id,*,*,*) primitive id |
| result.layer (l,*,*,*) layer for cube/array/3D FBOs |
| |
| Table X.3: Geometry Program Result Variable Bindings. |
| Components labeled "*" are unused. |
| |
| If a result variable binding matches "result.position", updates to the |
| "x", "y", "z", and "w" components of the result variable modify the "x", |
| "y", "z", and "w" components, respectively, of the transformed vertex's |
| clip coordinates. Final window coordinates will be generated for the |
| vertex as described in section 2.14.4.4. |
| |
| If a result variable binding match begins with "result.color", updates to |
| the "x", "y", "z", and "w" components of the result variable modify the |
| "r", "g", "b", and "a" components, respectively, of the corresponding |
| vertex color attribute in Table X.3. Color bindings that do not specify |
| "front" or "back" are consided to refer to front-facing colors. Color |
| bindings that do not specify "primary" or "secondary" are considered to |
| refer to primary colors. |
| |
| If a result variable binding matches "result.fogcoord", updates to the "x" |
| component of the result variable set the transformed vertex's fog |
| coordinate. Updates to the "y", "z", and "w" components of the result |
| variable have no effect. |
| |
| If a result variable binding matches "result.pointsize", updates to the |
| "x" component of the result variable set the transformed vertex's point |
| size. Updates to the "y", "z", and "w" components of the result variable |
| have no effect. |
| |
| If a result variable binding matches "result.texcoord" or |
| "result.texcoord[n]", updates to the "x", "y", "z", and "w" components of |
| the result variable set the "s", "t", "r" and "q" components, |
| respectively, of the transformed vertex's texture coordinates for texture |
| unit <n>. If "[n]" is omitted, texture unit zero is selected. |
| |
| If a result variable binding matches "result.attrib[n]", updates to the |
| "x", "y", "z", and "w" components of the result variable set the "x", "y", |
| "z", and "w" components of the generic interpolant <n>. |
| |
| If a result variable binding matches "result.clip[n]", updates to the "x" |
| component of the result variable set the clip distance for clip plane <n>. |
| |
| If a result variable binding matches "result.texcoord[n..o]", |
| "result.attrib[n..o]", or "result.clip[n..o]", a sequence of 1+<o>-<n> |
| bindings is created. For texture coordinates, it is as though the |
| sequence "result.texcoord[n], result.texcoord[n+1], |
| ... result.texcoord[o]" were specfied. These bindings are available only |
| in explicit declarations of array variables. A program will fail to load |
| if <n> is greater than <o>. |
| |
| If a result variable binding matches "result.primid", updates to the "x" |
| component of the result variable provide a single integer that serves as a |
| primitive identifier. The written primitive ID is available to fragment |
| programs using the "primitive.id" attribute binding. If a fragment |
| program using primitive IDs is active and a geometry program is also |
| active, the geometry program must write "result.primid" or the primitive |
| ID number is undefined. |
| |
| If a result variable binding matches "result.layer", updates to the "x" |
| component of the result variable provide a single integer that serves as a |
| layer selector for layered rendering (section 2.14.6.5). The layer must |
| be written as an integer value; writing a floating-point layer number will |
| produce undefined results. |
| |
| (modify Table X.13 in section 2.X.4, Program Instructions, to include the |
| following.) |
| |
| Modifiers |
| Instruction F I C S H D Inputs Out Description |
| ----------- - - - - - - ---------- --- -------------------------------- |
| EMIT - - - - - - - - emit vertex |
| ENDPRIM - - - - - - - - end of primitive |
| |
| (add the following subsection to section 2.X.6, Program Options.) |
| |
| Section 2.X.6.Y, Geometry Program Options |
| |
| No options are supported at present for geometry programs. |
| |
| (add the following subsection to section 2.X.7, Program Declarations.) |
| |
| Section 2.X.7.Y, Geometry Program Declarations |
| |
| Geometry programs support three types of declaration statements, as |
| described below. Each of the three must be included exactly once in the |
| geometry program. |
| |
| - Input Primitive Type (PRIMITIVE_IN) |
| |
| The PRIMITIVE_IN statement declares the type of primitives seen by a |
| geometry program. The single argument must be one of "POINTS", "LINES", |
| "LINES_ADJACENCY", "TRIANGLES", or "TRIANGLES_ADJACENCY". |
| |
| - Output Primitive Type (PRIMITIVE_OUT) |
| |
| The PRIMITIVE_OUT statement declares the type of primitive emitted by a |
| geometry program. The single argument must be one of "POINTS", |
| "LINE_STRIP", or "TRIANGLE_STRIP". |
| |
| - Maximum Vertex Count (VERTICES_OUT) |
| |
| The VERTICES_OUT statement declares the maximum number of vertices that |
| may be emitted by a geometry program. The single argument must be a |
| positive integer. A vertex program that emits more than the specified |
| number of vertices may terminate abnormally. |
| |
| (add the following subsections to section 2.X.8, Program Instruction Set.) |
| |
| Section 2.X.8.Z, EMIT: Emit Vertex |
| |
| The EMIT instruction emits a new vertex to be added to the current output |
| primitive of a geometry program. The attributes of the emitted vertex are |
| given by the current values of the vertex result variables. After the |
| EMIT instruction completes, a new vertex is started and all result |
| variables become undefined. |
| |
| Section 2.X.8.Z, ENDPRIM: End of Primitive |
| |
| A geometry program can emit multiple primitives in a single invocation. |
| The ENDPRIM instruction is used in a geometry program to signify the end |
| of the current primitive and the beginning of a new primitive of the same |
| type. The effect of ENDPRIM is roughly equivalent to calling End followed |
| by a new Begin, where the primitive mode is specified in the text of the |
| geometry program. |
| |
| Like End, the ENDPRIM instruction does not emit a vertex. Any result |
| registers written prior to an ENDPRIM instruction are unchanged, and will |
| be used in the vertex specified by the next EMIT instruction if they are |
| not overwritten first. |
| |
| When geometry program execution completes, the current primitive is |
| automatically terminated. It is not necessary to include an ENDPRIM |
| instruction if the geometry program writes only a single primitive. |
| |
| Additions to Chapter 3 of the OpenGL 1.5 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 program 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 program 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 |
| program is active, the point size is taken from the point size emitted by |
| the geometry program. If per-vertex point size is enabled an no geometry |
| program is active, the point size is taken from the point size result of |
| the vertex program. Otherwise, the point size is taken from the <size> |
| value provided to PointSize, with no distance attenuation applied. In all |
| cases, the 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. ... |
| |
| Additions to Chapter 4 of the OpenGL 1.5 Specification (Per-Fragment |
| Operations and the Frame Buffer) |
| |
| None. |
| |
| Additions to Chapter 5 of the OpenGL 1.5 Specification (Special Functions) |
| |
| None. |
| |
| Additions to Chapter 6 of the OpenGL 1.5 Specification (State and |
| State Requests) |
| |
| None. |
| |
| Additions to Appendix A of the OpenGL 1.5 Specification (Invariance) |
| |
| None. |
| |
| Additions to the AGL/GLX/WGL Specifications |
| |
| None. |
| |
| GLX Protocol |
| |
| The following rendering commands are sent to the server as part of a |
| glXRender request: |
| |
| ProgramVertexLimitNV |
| |
| 2 12 rendering command length |
| 2 4312 rendering command opcode |
| 4 ENUM target |
| 4 INT32 limit |
| |
| |
| The extension EXT_geometry_shader4 defines GLX protocol for |
| the following non-rendering commands: |
| |
| FramebufferTextureEXT, FramebufferTextureLayerEXT, |
| FramebufferTextureFaceEXT. |
| |
| Errors |
| |
| The error INVALID_OPERATION is generated if Begin, or any command that |
| implicitly calls Begin, is called when geometry program mode is enabled |
| and the currently bound geometry program object does not contain a valid |
| geometry program. |
| |
| The error INVALID_OPERATION is generated if Begin, or any command that |
| implicitly calls Begin, is called when geometry program mode is enabled |
| and: |
| |
| * the input primitive type of the current geometry program is POINTS and |
| <mode> is not POINTS, |
| |
| * the input primitive type of the current geometry program is LINES and |
| <mode> is not LINES, LINE_STRIP, or LINE_LOOP, |
| |
| * the input primitive type of the current geometry program is TRIANGLES |
| and <mode> is not TRIANGLES, TRIANGLE_STRIP, TRIANGLE_FAN, QUADS, |
| QUAD_STRIP, or POLYGON, |
| |
| * the input primitive type of the current geometry program is |
| LINES_ADJACENCY and <mode> is not LINES_ADJACENCY_EXT or |
| LINE_STRIP_ADJACENCY_EXT, or |
| |
| * the input primitive type of the current geometry program is |
| TRIANGLES_ADJACENCY and <mode> is not TRIANGLES_ADJACENCY_EXT or |
| TRIANGLE_STRIP_ADJACENCY_EXT. |
| |
| The error INVALID_ENUM is generated if GetProgramivARB is called with a |
| <pname> of MAX_PROGRAM_OUTPUT_VERTICES_NV or |
| MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV and the target isn't |
| GEOMETRY_PROGRAM_NV. |
| |
| Dependencies on EXT_framebuffer_object |
| |
| If EXT_framebuffer_object (or similar functionality) is not supported, the |
| "result.layer" binding should be removed. "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 programs 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 program 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 programs are disabled, or |
| |
| * the current geometry program does not contain an instruction that |
| writes to the layer result binding. |
| |
| Otherwise, the layer for each point, line, or triangle emitted by the |
| geometry program is taken from the layer output of the provoking vertex. |
| For line strips, the provoking vertex is the second vertex of each line |
| segment. For triangle strips, the provoking vertex is the third vertex of |
| each individual triangles. The per-fragment layer can be different for |
| fragments generated by each individual point, line, or triangle emitted by |
| a single geometry program invocation. A layer number written by a |
| geometry program has no effect if the framebuffer is not layered. |
| |
| When fragments are written to a layered framebuffer, the fragment's layer |
| number selects a single image from the array of images at each attachment |
| point to use for the stencil test (section 4.1.5), depth buffer test |
| (section 4.1.6), and for blending and color buffer writes (section 4.1.8). |
| 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. |
| |
| If BlitFramebufferEXT() is called with a layered read framebuffer, pixel |
| values are obtained from layer zero from the read framebuffer. If the |
| draw framebuffer is layered, pixel values are written to layer zero of the |
| draw framebuffer. If both framebuffers are layered, the two-dimensional |
| blit operation is still performed only on layer zero. |
| |
| 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. |
| |
| Dependencies on NV_primitive_restart |
| |
| The spec describes the behavior that primitive restart does not affect the |
| primitive ID counter, including for POLYGON primitives (where one could |
| argue that the restart index starts a new primitive without a new Begin to |
| reset the count). If NV_primitive_restart is not supported, references to |
| that extension in the discussion of the "primitive.id" attribute should be |
| removed. |
| |
| New State |
| Initial |
| Get Value Type Get Command Value Description Sec. Attribute |
| ------------------------- ---- ----------- ------- ---------------------- ------ --------- |
| GEOMETRY_PROGRAM_NV B IsEnabled FALSE Geometry shader enable 2.14.6 enable |
| FRAMEBUFFER_ATTACHMENT_ nxB GetFramebuffer- FALSE Framebuffer attachment 4.4.2.3 - |
| LAYERED_EXT Attachment- is layered |
| ParameterivEXT |
| GEOMETRY_VERTICES_OUT_EXT Z+ GetProgramivARB 0 vertex limit of the 2.14.6.4 - |
| current geometry |
| program |
| GEOMETRY_INPUT_TYPE_EXT Z+ GetProgramivARB 0 input primitive type 2.14.6.4 - |
| of the current geometry |
| program |
| GEOMETRY_OUTPUT_TYPE_EXT Z+ GetProgramivARB 0 output primitive type 2.14.6.4 - |
| of the current geometry |
| program |
| |
| New Implementation Dependent State |
| |
| Minimum |
| Get Value Type Get Command Value Description Sec Attrib |
| ------------------------------- ---- --------------- ---------- -------------------- ------------ ------ |
| MAX_GEOMETRY_TEXTURE_ Z+ GetIntegerv 16 maximum number of 2.14.6.3 - |
| IMAGE_UNITS_EXT texture image units |
| accessible in a |
| geometry program |
| MAX_PROGRAM_OUTPUT_VERTICES_NV Z+ GetProgramivARB 256 maximum number of 2.14.6.4 - |
| vertices that any |
| geometry program |
| could emit |
| MAX_PROGRAM_TOTAL_OUTPUT_ Z+ GetProgramivARB 1024 maximum number of 2.14.6.4 - |
| COMPONENTS_NV result components (all |
| vertices) that a |
| geometry program |
| can emit |
| |
| |
| 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 programs fit into the existing GL pipeline? |
| |
| RESOLVED: The following diagram illustrates how geometry programs 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 program 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 program only), and so on. Note |
| that on many current GL implementations, vertex processing is performed |
| by executing a "fixed function vertex program" 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 program is executed on each |
| individual point, line, or triangle primitive, if enabled. 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 program. |
| |
| 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 programs are never run on the raster position. |
| |
| |generic |conventional |
| |vertex |vertex |
| |attributes |attributes |
| | | |
| | +-------------------+ |
| | | | |
| V V V |
| vertex fixed-function |
| program vertex |
| | processing |
| | | |
| | | |
| +<-------------------+ |
| | Output |
| |position, color, Primitive |
| |other vertex data Type |
| | | |
| V | |
| Begin/ primitive geometry primitive | |
| End ------> assembly -----> program ----> 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_NV_geometry_program4? There aren't any previous |
| versions of this extension, let alone three? |
| |
| RESOLVED: The instruction set for GPU programs of all types (vertex, |
| fragment, and now geometry) have been unified in the GL_NV_gpu_program4 |
| extension, and the "4" suffix in this extension name indicates the |
| instruction set type. There are three previous NV_vertex_program |
| variants (four if you count NV_vertex_program1_1), so "4" is the next |
| available numeric suffix. |
| |
| (3) Should the GL produce errors at Begin time if an application specifies |
| a primitive mode that is "incompatible" with the geometry program? For |
| example, if the geometry program operates on triangles and the application |
| sends a POINTS primitive? |
| |
| RESOLVED: Yes. Mismatches of app-specified primitive types and |
| geometry program input primitive types seem like clear errors and would |
| produce weird and wonderful effects. |
| |
| (4) Can the input primitive type of a geometry program be changed at run |
| time? |
| |
| RESOLVED: Not in this extension. Each geometry program has a single |
| input primitive type, and vertices are presented to the program in a |
| specific order based on that type. |
| |
| (5) Can the output primitive type of a geometry program be determined at |
| run time? |
| |
| RESOLVED: Not in this extension. |
| |
| (6) Must the output primitive type of a geometry program match the input |
| primitive type in any way? |
| |
| RESOLVED: No, you can have a geometry program 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. |
| |
| (7) Are primitives emitted by a geometry program 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). |
| |
| (8) Should geometry programs support additional input primitive types? |
| |
| RESOLVED: Possibly in a future extension. It should be straightforward |
| to build a future extension to support geometry programs that operate on |
| quads. Other primitive types might be more demanding on hardware. |
| Quads with adjacency would require 12 vertices per program execution. |
| General polygons may require even more, since there is no fixed bound on |
| the number of vertices in a polygon. |
| |
| (9) Should geometry programs 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. |
| |
| (10) 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. |
| |
| (11) How do geometry programs interact with RasterPos? |
| |
| RESOLVED: Geometry programs are ignored when specifying the raster |
| position. While the raster position could be treated as a point, |
| turning it into a triangle strip would be quite bizarre. |
| |
| (12) How do geometry programs interact with pixel primitives (DrawPixels, |
| Bitmap)? |
| |
| RESOLVED: They do not. Fragments generated be DrawPixels and Bitmap |
| are injected into the pipeline after the point where geometry program |
| execution occurs. |
| |
| (13) Is there a limit on the number of vertices that can be emitted by a |
| geometry program? |
| |
| 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 the all the primitives generated by the first geometry program |
| invocation must be consumed before any of the primitives generated by |
| the second program invocation. Limiting the amount of data a geometry |
| program can write substantially eases the implementation burden. |
| |
| A geometry program must declare a maximum number of vertices that can be |
| emitted, called the vertex limit. There is an implementation-dependent |
| limit on the total number of vertices a program can emit (256 minimum) |
| and the product of the vertex limit and the number of active result |
| components (1024 minimum). A program will fail to load if doesn't |
| declare a limit or exceeds either of the two implementatoin-dependent |
| limits. |
| |
| It would be ideal if the limit could be inferred from the instructions |
| in the program itself, and that would be possible for many programs, |
| particularly ones with straight-line flow control. For programs 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 EMIT instructions that can be issued can not |
| always be enforced at compile time, or even at Begin time. We specify |
| that if a program tries to emit more vertices than the vertex limit |
| allows, emits that exceed the limit may or may not have any effect. |
| |
| (14) Should it be possible to change the limit on the number of vertices |
| emitted by a geometry program after the program is specified? |
| |
| RESOLVED: Yes, using the function ProgramVertexLimitNV(). Applications |
| may want to tweak a piece of data that affects the number of vertices |
| emitted, but doesn't necessarily require recompiling the entire program. |
| Examples might be a "circular point sprite" program, that reads a single |
| point, and draws a circle centered at that point with <N> vertices. An |
| application could change the value <N> at run time, but it could require |
| a change in the vertex limit. Another example might be a geometry |
| program that does some fancy subdivision, where the relevant parameter |
| might be a limit on how far the primitive is subdivided. |
| |
| Ideally, this program object state should be set by a "program |
| parameter" command, much like texture state is set by a "texture |
| parameter" (TexParameter) command. Unfortunately, there are already |
| several different "program parameter" functions: |
| |
| ProgramEnvParameter4fARB() -- sets global environment constants |
| ProgramLocalParameter4fARB() -- sets per-program constants |
| ProgramParameter4fNV() -- also sets global environment constants |
| |
| Additionally, GLSL and OpenGL 2.0 introduced "program objects" which are |
| linked collections of vertex, fragment, and now geometry shaders. A |
| GLSL vertex "shader" is equivalent to an ARB_vertex_program vertex |
| "program", which is nothing like a GLSL program. As of OpenGL 2.0, GLSL |
| programs do not have settable parameters, by subsequent extensions may |
| want to add them (for example, EXT_geometry_shader4, which has this same |
| functionality for GLSL). If that happens, they would want their own |
| ProgramParameter API, but with a different prototype than this extension |
| would want. |
| |
| Naming this function "ProgramVertexLimitNV" sidesteps this issue for |
| now. |
| |
| (15) 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. |
| |
| (16) How do geometry programs interact with color clamping? |
| |
| RESOLVED: Geometry program execution occurs prior to color clamping in |
| the pipeline. This means the colors written by vertex programs or |
| fixed-function vertex processing are not clamped to [0,1] before they |
| are read by geometry programs. If color clamping is enabled, any vertex |
| colors written by the geometry program will have their components |
| clamped to [0,1]. |
| |
| (17) How are QUADS, QUAD_STRIP, and POLYGON primitives decomposed into |
| triangles in the initial implementation of GL_NV_geometry_program4? |
| |
| RESOLVED: The specification leaves the decomposition undefined, subject |
| to a small number of rules. Assume that four vertices are specified in |
| the order V0, V1, V2, V3. |
| |
| For QUADS primitives, the quad V0->V1->V2->V3 is decomposed into the |
| triangles V0->V1->V2, and V0->V2->V3. The provoking vertex of the quad |
| (V3) is only found in the second triangle. If it's necessary to flat |
| shade over an entire quad, take the attributes from V0, which will be |
| the first vertex for both triangles in the decomposition. |
| |
| For QUAD_STRIP primitives, the quad V0->V1->V3->V2 is decomposed into |
| the triangles V0->V1->V3 and V2->V0->V3. This has the property of |
| leaving the provoking vertex for the polygon (V3) as the third vertex |
| for each triangle of the decomposition. |
| |
| For POLYGON primitives, the polygon V0->V1->V2->V3 is decomposed into |
| the triangles V1->V2->V0 and V2->V3->V0. This has the property of |
| leaving the provoking vertex for the polygon (V0) as the third vertex |
| for each triangle of the decomposition. |
| |
| (18) Should geometry programs be able to select a layer of a 3D texture, |
| cube map texture, or array texture at run time? If so, how? |
| |
| RESOLVED: This extension provides a per-vertex result binding called |
| "result.layer", which is an integer specifying the layer to render to. |
| When an each individual point, line, or triangle is emitted by a |
| geometry program, the layer number is taken from the provoking (last) |
| vertex of the primitive and 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) 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. |
| They can do anything that the old functions can do, except attach a |
| single face of a cube map texture. We considered adding a separate |
| function FramebufferTextureFaceEXT to provide this functionality, but |
| decided that the existing FramebufferTexture2DEXT API was adequate. We |
| also considered using FramebufferTextureLayerEXT for this purpose, but |
| it was not clear whether a layer number (0-5) or face enum (e.g, |
| TEXTURE_CUBE_MAP_POSITIVE_X) should be provided. |
| |
| 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 program that writes the layer result is enabled. When |
| rendering to a non-layered framebuffer, any layer result emitted from |
| geometry programs 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 program, or set as |
| a new property of the framebuffer object. There is presently |
| 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. |
| |
| (19) How can single-pass cube map rendering be done efficiently in a |
| geometry program? |
| |
| UNRESOLVED: To do single-pass cubemap rendering, attach entire cube map |
| textures to framebuffer attachment points using the new functions |
| provided by this extension. The vertex program used should only |
| transform the vertex position to eye coordinates (position relative to |
| the center of the cube map). A geometry program should be used that |
| effectively projects each input triangle onto each of the six faces of |
| the cube map, emitting a triangle for each. Each of the projected |
| vertices should be emitted with a "result.layer" value matching the face |
| number (0-5). When the projected triangle is drawn, it is automatically |
| drawn on the face corresponding to the emitted layer number. |
| |
| It should be simple to skip projecting primitives onto faces they won't |
| touch. For example, if all of the X eye coordinates are positive, there |
| is no reason to project to the "negative X" cube map face. |
| |
| An example should be provided for this issue. |
| |
| (20) How should per-vertex point size work with geometry programs? |
| |
| RESOLVED: We will generalize the existing VERTEX_PROGRAM_POINT_SIZE |
| enable to control the point size behavior if either vertex or geometry |
| programs are enabled. |
| |
| If geometry programs are enabled, the point size is taken from the point |
| size result of the emitted vertex if VERTEX_PROGRAM_POINT_SIZE is |
| enabled, or from the PointSize state otherwise. |
| |
| If no geometry program is enabled, it works like OpenGL 2.0. If a |
| vertex program is active, it's taken from the point size result or |
| PointSize state, depending on the VERTEX_PROGRAM_POINT_SIZE enable. If |
| no program is enabled, normal fixed-function point size handling |
| (including distance attenuation) is supported. |
| |
| This extension creates a new alias for the VERTEX_PROGRAM_POINT_SIZE |
| enum, called PROGRAM_POINT_SIZE_EXT, to reflect that the point size |
| enable now covers multiple program types. Both enums have the same |
| value. |
| |
| (21) How do vertex IDs work with geometry programs? |
| |
| RESOLVED: Vertex IDs are automatically provided to vertex programs |
| when applicable, via the "vertex.id" binding. However, they are not |
| automatically copied the transformed vertex results that are read by |
| geometry programs. |
| |
| Geometry programs can read the ID of vertex <n> via the |
| "vertex[<n>].id" binding, but the vertex ID must have been copied by |
| the vertex program using an instruction such as: |
| |
| MOV result.id.x, vertex.id.x; |
| |
| If a vertex program doesn't write vertex ID, or fixed-function vertex |
| processing is used, the vertex ID visible to geometry programs is |
| undefined. |
| |
| (22) How do primitive IDs work with geometry programs? |
| |
| RESOLVED: Primitive IDs are automatically available to geometry |
| programs via the "primitive.id" binding and indicate the number of |
| input primitives previously processed since the last explicit or |
| implicit Begin call. |
| |
| If a geometry program wants to make the primitive ID available to a |
| fragment program, it should copy the appropriate value to the |
| "result.primid" binding. |
| |
| (23) How do primitive IDs work with primitives not supported directly by |
| geometry program input topologies (e.g., QUADS, POLYGON)? |
| |
| RESOLVED: QUADS are decomposed into two triangles. Both triangles |
| will have the same primitive ID, which is the number of full quads |
| previously processed. POLYGON primitives are decomposed into a series |
| of triangles, and all of them will have the primitive ID -- zero. |
| |
| (24) This is an NV extension (NV_geometry_program4). Why do some of the |
| new tokens have an "EXT" extension? |
| |
| RESOLVED: Some of the tokens are shared between this extension and the |
| comparable high-level GLSL programmability extension |
| (EXT_geometry_shader4). Rather than provide a duplicate set of tokens, |
| we simply use the EXT versions here. The tokens specific to assembly |
| shader uses retain an NV suffix. |
| |
| (25) What happens if you try to do a framebuffer blit (via |
| EXT_framebuffer_blit) to/from a layered framebuffer? |
| |
| RESOLVED: BlitFramebufferEXT() is a two-dimensional operation (only has |
| a width and height), so only reads/writes layer zero. The framebuffer |
| blit operation is defined partially in terms of CopyPixels, which itself |
| is defined in terms of ReadPixels and DrawPixels. This spec defines |
| both operations to use layer zero when a layered framebuffer is |
| involved. |
| |
| It may be desirable to provide a three-dimensional framebuffer blit |
| operation or an explicit copy single-step operation between two |
| three-dimensional, cube map, or array textures. That functionality is |
| left for a future extension or OpenGL version. |
| |
| |
| Revision History |
| |
| Rev. Date Author Changes |
| ---- -------- -------- -------------------------------------------- |
| 13 12/14/09 mgodse Added GLX protocol. |
| |
| 12 07/21/09 pbrown Clarify that when doing layered rendering, |
| a layer specified in the shader is used to |
| select the depth and stencil layers accessed. |
| |
| Also document several additional entry points |
| that accept GEOMETRY_PROGRAM_NV. |
| |
| 11 03/11/09 pbrown Fix section numbers for option/declaration |
| sections. |
| |
| 10 07/29/08 pbrown Clean up garbled language describing vertex |
| output limits. |
| |
| 9 04/04/08 pbrown Fixed error in the state tables; the geometry |
| program enable should push/pop only with the |
| enable bit like all the other program enables. |
| |
| 8 03/15/08 pbrown Additional dependency on EXT_framebuffer_blit; |
| blits to/from layered targets affect only |
| layer zero. |
| |
| 7 03/07/08 pbrown Fix grammar to allow vertex ID, as already |
| allowed in the rest of the spec body. |
| |
| 6 pbrown Internal spec development. |
| |