back  Return to list

GL_NV_geometry_program4
homeprevnext Name
  
    NV_geometry_program4  
  
homeprevnext Name Strings
  
    (none)  
  
homeprevnext Contact
  
    Pat Brown, NVIDIA Corporation (pbrown 'at' nvidia.com)  
  
homeprevnext Status
  
    Shipping for GeForce 8 Series (November 2006)  
  
homeprevnext Version
  
    Last Modified Date:         11/06/2006  
    NVIDIA Revision:            6  
  
homeprevnext Number
  
    323  
  
homeprevnext 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.  
  
homeprevnext 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.  
  
homeprevnext 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);  
  
homeprevnext New Tokens
  
    Accepted by the <cap> parameter of Disable, Enable, and IsEnabled, and by  
    the <pname> parameter of GetBooleanv, GetIntegerv, GetFloatv, and  
    GetDoublev:  
  
        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.)  
          
homeprevnext 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 limited in the 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"  
                              | <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.5, Program Options.)  
  
    Section 2.X.5.Y, Geometry Program Options  
  
    No options are supported at present for geometry programs.  
  
    (add the following subsection to section 2.X.6, Program Declarations.)  
  
    Section 2.X.6.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.7, Program Instruction Set.)  
  
    Section 2.X.7.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.7.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.  
  
homeprevnext 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. ...  
  
homeprevnext Additions to Chapter 4 of the OpenGL 1.5 Specification (Per-Fragment Operations and the Frame Buffer)
  
    None.  
  
homeprevnext Additions to Chapter 5 of the OpenGL 1.5 Specification (Special Functions)
  
    None.  
  
homeprevnext Additions to Chapter 6 of the OpenGL 1.5 Specification (State and State Requests)
  
    None.  
  
homeprevnext Additions to Appendix A of the OpenGL 1.5 Specification (Invariance)
  
    None.  
  
homeprevnext Additions to the AGL/GLX/WGL Specifications
  
    None.  
  
homeprevnext GLX Protocol
  
    None.  
  
homeprevnext 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.  
  
homeprevnext 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 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.  
  
homeprevnext 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.  
  
homeprevnext 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.  
  
homeprevnext 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.  
  
homeprevnext 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.  
  
homeprevnext 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.  
  
homeprevnext 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/transform  
  
    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  
  
homeprevnext 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.  
  
homeprevnext 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.  
  
  
homeprevnext Revision History
  
    None  
    None  
Valid XHTML 1.1! Valid CSS! Last update: November 14, 2006.
Cette page doit être lue avec un navigateur récent respectant le standard XHTML 1.1.