back  Return to list

GL_NV_transform_feedback
homeprevnext Name
  
    NV_transform_feedback  
  
homeprevnext Name Strings
  
    GL_NV_transform_feedback  
  
homeprevnext Contributors
  
    Cliff Woolley  
    Nick Carter  
  
homeprevnext Contact
  
    Barthold Lichtenbelt (blichtenbelt 'at' nvidia.com)  
    Pat Brown (pbrown 'at' nvidia.com)  
    Eric Werness (ewerness 'at' nvidia.com)  
  
homeprevnext Status
  
    Shipping for GeForce 8 Series (November 2006)   
  
homeprevnext Version
  
    Last Modified Date:         02/04/2008  
    NVIDIA Revision:            14  
  
homeprevnext Number
  
    341  
  
homeprevnext Dependencies
  
    OpenGL 1.5 is required.  
  
    This extension interacts with EXT_timer_query.  
  
    NV_vertex_program4, NV_geometry_program4 and NV_gpu_program4 affect this  
    extension.  
  
    EXT_geometry_shader4 trivially interacts with this extension.  
  
    This extension has an OpenGL Shading Language component.  As such it  
    interacts with ARB_shader_objects and OpenGL 2.0.  
  
    This extension is written against the OpenGL 2.0 specification.  
  
homeprevnext Overview
  
    This extension provides a new mode to the GL, called transform feedback,  
    which records vertex attributes of the primitives processed by the GL.  
    The selected attributes are written into buffer objects, and can be  
    written with each attribute in a separate buffer object or with all  
    attributes interleaved into a single buffer object.  If a geometry program  
    or shader is active, the primitives recorded are those emitted by the  
    geometry program.  Otherwise, transform feedback captures primitives whose  
    vertex are transformed by a vertex program or shader, or by fixed-function  
    vertex processing.  In either case, the primitives captured are those  
    generated prior to clipping.  Transform feedback mode is capable of  
    capturing transformed vertex data generated by fixed-function vertex  
    processing, outputs from assembly vertex or geometry programs, or varying  
    variables emitted from GLSL vertex or geometry shaders.  
  
    The vertex data recorded in transform feedback mode is stored into buffer  
    objects as an array of vertex attributes.  The regular representation and  
    the use of buffer objects allows the recorded data to be processed  
    directly by the GL without requiring CPU intervention to copy data.  In  
    particular, transform feedback data can be used for vertex arrays (via  
    vertex buffer objects), as the source for pixel data (via pixel buffer  
    objects), as program constant data (via the NV_parameter_buffer_object or  
    EXT_bindable_uniform extension), or via any other extension that makes use  
    of buffer objects.  
  
    This extension introduces new query object support to allow transform  
    feedback mode to operate asynchronously.  Query objects allow applications  
    to determine when transform feedback results are complete, as well as the  
    number of primitives processed and written back to buffer objects while in  
    transform feedback mode.  This extension also provides a new rasterizer  
    discard enable, which allows applications to use transform feedback to  
    capture vertex attributes without rendering anything.  
  
homeprevnext New Procedures and Functions
  
    void BindBufferRangeNV(enum target, uint index, uint buffer,  
                           intptr offset, sizeiptr size)  
    void BindBufferOffsetNV(enum target, uint index, uint buffer,  
                            intptr offset)  
    void BindBufferBaseNV(enum target, uint index, uint buffer)  
    void TransformFeedbackAttribsNV(sizei count, const int *attribs,  
                                    enum bufferMode)  
    void TransformFeedbackVaryingsNV(uint program, sizei count,  
                                     const int *locations,  
                                     enum bufferMode)  
    void BeginTransformFeedbackNV(enum primitiveMode)  
    void EndTransformFeedbackNV()  
  
    int GetVaryingLocationNV(uint program, const char *name)  
    void GetActiveVaryingNV(uint program, uint index,  
                            sizei bufSize, sizei *length, sizei *size,  
                            enum *type, char *name)  
    void ActiveVaryingNV(uint program, const char *name)  
    void GetTransformFeedbackVaryingNV(uint program, uint index,  
                                       int *location)  
  
    void GetIntegerIndexedvEXT(enum param, uint index, int *values);  
    void GetBooleanIndexedvEXT(enum param, uint index, boolean *values);  
  
    (Note: These indexed query functions are provided in the EXT_draw_buffers2  
    extension.  The boolean query is not useful for any queryable value in  
    this extension, but is supported for completeness and consistency with  
    base GL typed "Get" functions.)  
  
  
homeprevnext New Tokens
  
    Accepted by the <target> parameters of BindBuffer, BufferData,  
    BufferSubData, MapBuffer, UnmapBuffer, GetBufferSubData,  
    GetBufferPointerv, BindBufferRangeNV, BindBufferOffsetNV and  
    BindBufferBaseNV:  
  
      TRANSFORM_FEEDBACK_BUFFER_NV                      0x8C8E  
  
    Accepted by the <param> parameter of GetIntegerIndexedvEXT and  
    GetBooleanIndexedvEXT:  
  
      TRANSFORM_FEEDBACK_BUFFER_START_NV                0x8C84  
      TRANSFORM_FEEDBACK_BUFFER_SIZE_NV                 0x8C85  
      TRANSFORM_FEEDBACK_RECORD_NV                      0x8C86  
  
    Accepted by the <param> parameter of GetIntegerIndexedvEXT and  
    GetBooleanIndexedvEXT, and by the <pname> parameter of GetBooleanv,  
    GetDoublev, GetIntegerv, and GetFloatv:  
  
      TRANSFORM_FEEDBACK_BUFFER_BINDING_NV              0x8C8F  
  
    Accepted by the <bufferMode> parameter of TransformFeedbackAttribsNV and  
    TransformFeedbackVaryingsNV:  
  
      INTERLEAVED_ATTRIBS_NV                            0x8C8C  
      SEPARATE_ATTRIBS_NV                               0x8C8D  
  
    Accepted by the <target> parameter of BeginQuery, EndQuery, and  
    GetQueryiv:  
  
      PRIMITIVES_GENERATED_NV                           0x8C87  
      TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV          0x8C88  
  
    Accepted by the <cap> parameter of Enable, Disable, and IsEnabled, and by  
    the <pname> parameter of GetBooleanv, GetIntegerv, GetFloatv, and  
    GetDoublev:  
  
      RASTERIZER_DISCARD_NV                             0x8C89  
  
    Accepted by the <pname> parameter of GetBooleanv, GetDoublev, GetIntegerv,  
    and GetFloatv:  
  
      MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_NV  0x8C8A  
      MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV        0x8C8B  
      MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV     0x8C80  
      TRANSFORM_FEEDBACK_ATTRIBS_NV                     0x8C7E  
  
    Accepted by the <pname> parameter of GetProgramiv:  
  
      ACTIVE_VARYINGS_NV                                0x8C81  
      ACTIVE_VARYING_MAX_LENGTH_NV                      0x8C82  
      TRANSFORM_FEEDBACK_VARYINGS_NV                    0x8C83  
  
   Accepted by the <pname> parameter of GetBooleanv, GetDoublev, GetIntegerv,  
   GetFloatv, and GetProgramiv:  
  
      TRANSFORM_FEEDBACK_BUFFER_MODE_NV                 0x8C7F  
  
   Accepted by the <attribs> parameter of TransformFeedbackAttribsNV:  
  
      BACK_PRIMARY_COLOR_NV                             0x8C77  
      BACK_SECONDARY_COLOR_NV                           0x8C78  
      TEXTURE_COORD_NV                                  0x8C79  
      CLIP_DISTANCE_NV                                  0x8C7A  
      VERTEX_ID_NV                                      0x8C7B  
      PRIMITIVE_ID_NV                                   0x8C7C  
      GENERIC_ATTRIB_NV                                 0x8C7D  
      POINT_SIZE                                        0x0B11  
      FOG_COORDINATE                                    0x8451  
      SECONDARY_COLOR_NV                                0x852D  
      PRIMARY_COLOR                                     0x8577  
      POSITION                                          0x1203  
      LAYER_NV                                          0x8DAA  
  
      (note:  POINT_SIZE, FOG_COORDINATE, PRIMARY_COLOR, and POSITION are  
       defined in the core OpenGL specification; SECONDARY_COLOR_NV is defined  
       in NV_register_combiners.)  
  
    Returned by the <type> parameter of GetActiveVaryingNV:  
  
      UNSIGNED_INT_VEC2_EXT                             0x8DC6  
      UNSIGNED_INT_VEC3_EXT                             0x8DC7  
      UNSIGNED_INT_VEC4_EXT                             0x8DC8  
  
      (note:  All three of these are defined in the EXT_gpu_shader4  
      extension.)  
  
homeprevnext Additions to Chapter 2 of the OpenGL 2.0 Specification (OpenGL Operation)
  
    Insert three new sections between Sections 2.11, Coordinate Transforms and  
    2.12, Clipping:  
  
    (Move the "Asynchronous Queries" language out of Section 4.1.7)  
  
    Section 2.X, Asynchronous Queries  
  
    Asynchronous queries provide a mechanism to return information about the  
    processing of a sequence of GL commands.  There are two query types  
    supported by the GL.  Transform feedback queries (section 2.Y) returns  
    information on the number of vertices and primitives processed by the GL  
    and written to one or more buffer objects.  Occlusion queries (section  
    4.1.7.1) count the number of fragments or samples that pass the depth  
    test.  
  
    The results of asynchronous queries are not returned by the GL immediately  
    after the completion of the last command in the set; subsequent commands  
    can be processed while the query results are not complete.  When  
    available, the query results are stored in an associated query object.  
    The commands described in section 6.1.12 provide mechanisms to determine  
    when query results are available and return the actual results of the  
    query.  The name space for query objects is the unsigned integers, with  
    zero reserved by the GL.  
  
    Each type of query supported by the GL has an active query object name. If  
    the active query object name for a query type is non-zero, the GL is  
    currently tracking the information corresponding to that query type and  
    the query results will be written into the corresponding query object.  If  
    the active query object for a query type name is zero, no such information  
    is being tracked.  
  
    A query object is created by calling  
  
      void BeginQuery(enum target, uint id);  
  
    with an unused name <id>.  <target> indicates the type of query to be  
    performed; valid values of <target> are defined in subsequent  
    sections. When a query object is created, the name <id> is marked as used  
    and associated with a new query object.  
  
    BeginQuery sets the active query object name for the query type given by  
    <target> to <id>.  If BeginQuery is called with an <id> of zero, if the  
    active query object name for <target> is non-zero, or if <id> is the  
    active query object name for any query type, the error INVALID OPERATION  
    is generated.  
  
    The command  
  
      void EndQuery(enum target);  
  
    marks the end of the sequence of commands to be tracked for the query type  
    given by <target>.  The active query object for <target> is updated to  
    indicate that query results are not available, and the active query object  
    name for <target> is reset to zero.  When the commands issued prior to  
    EndQuery have completed and a final query result is available, the query  
    object, active when EndQuery is, called is updated by the GL.  The query  
    object is updated to indicate that the query results are available and to  
    contain the query result.  If the active query object name for <target> is  
    zero when EndQuery is called, the error INVALID_OPERATION is generated.  
  
   The command  
  
      void GenQueries(sizei n, uint *ids);  
  
    returns <n> previously unused query object names in <ids>. These names are  
    marked as used, but no object is associated with them until the first time  
    they are used by BeginQuery.  
  
    Query objects are deleted by calling  
  
      void DeleteQueries(sizei n, const uint *ids);  
  
    <ids> contains <n> names of query objects to be deleted. After a query  
    object is deleted, its name is again unused.  Unused names in <ids> are  
    silently ignored.  
  
    Calling either GenQueries or DeleteQueries while any query of any target  
    is active causes an INVALID_OPERATION error to be generated.  
  
    Query objects contain two pieces of state:  a single bit indicating  
    whether a query result is available, and an integer containing the query  
    result value.  The number of bits used to represent the query result is  
    implementation-dependent.  In the initial state of a query object, the  
    result is available and its value is zero.  
  
    The necessary state for each query type is an unsigned integer holding the  
    active query object name (zero if no query object is active), and any  
    state necessary to keep the current results of an asynchronous query in  
    progress.  
  
    Section 2.Y, Transform Feedback  
  
    In 'transform feedback' mode the vertices of transformed primitives are  
    written out to one or more buffer objects. The vertices are fed back after  
    the geometry shader stage, if it exists, or otherwise after vertex  
    processing right before clipping (section 2.12) but after color  
    clamping. Optionally the transformed vertices can be discarded after being  
    stored into one or more buffer objects, or they can be passed on down to  
    the clipping stage for further processing.  
  
    Transform feedback is started and finished by calling  
  
      void BeginTransformFeedbackNV(enum primitiveMode)  
  
    and  
  
      void EndTransformFeedbackNV(),  
  
    respectively. Transform feedback is said to be active after a call to  
    BeginTransformFeedbackNV and inactive after a call to  
    EndTransformFeedbackNV. Transform feedback is initially inactive.  
    Transform feedback is performed after color clamping, but immediately  
    before clipping in the OpenGL pipeline. <primitiveMode> is one of  
    TRIANGLES, LINES, or POINTS, and specifies the output type of primitives  
    that will be recorded into the buffer objects bound for transform feedback  
    (see below). <primitiveMode> places a restriction on the primitive types  
    that may be rendered during an instance of transform feedback. See table  
    X.1.  
  
      Transform Feedback  
      primitiveMode               allowed render primitive modes  
      ----------------------      ---------------------------------  
      POINTS                       POINTS  
      LINES                        LINES, LINE_LOOP, and LINE_STRIP  
      TRIANGLES                    TRIANGLES, TRIANGLE_STRIP,  
                                   TRIANGLE_FAN, QUADS, QUAD_STRIP,  
                                   and POLYGON  
  
    Table X.1 Legal combinations between the transform feedback primitive  
    mode, as passed to BeginTransformFeedbackNV and the current primitive  
    mode.  
  
    If a geometry program or geometry shader is active, the output primitive  
    type of the currently active program is used as the render primitive in  
    table X.1, otherwise the Begin mode is used.  
  
    Quads and polygons will be tessellated and recorded as triangles (the  
    order of tessellation within a primitive is undefined); primitives  
    specified in strips or fans will be assembled and recorded as individual  
    primitives. Incomplete primitives are not recorded. Begin or any operation  
    that implicitly calls Begin (such as DrawElements) will generate  
    INVALID_OPERATION if the begin mode is not an allowed begin mode for the  
    current transform feedback buffer state. If a geometry program or geometry  
    shader is active, its output primtive mode is used for the error check  
    instead of the begin mode.  
  
    It is an invalid operation error to call BeginTransformFeedbackNV,  
    TransformFeedbackBufferNV, TransformFeedbackVaryingsNV,  
    TransformFeedbackAttribsNV, or UseProgram or LinkProgram on the currently  
    active program object while transform feedback is active.  It is an  
    invalid operation error to call EndTransformFeedbackNV while transform  
    feedback is inactive.  
  
    Transform feedback can operate in either INTERLEAVED_ATTRIBS_NV or  
    SEPARATE_ATTRIBS_NV mode. In the INTERLEAVED_ATTRIBS_NV mode, several  
    vertex attributes can be written, interleaved, into a single buffer  
    object.  In the SEPARATE_ATTRIBS_NV mode, vertex attributes are recorded,  
    non-interleaved, into several buffer objects simultaneously.  
  
    It is an INVALID_OPERATION error to call BeginTransformFeedbackNV if there  
    is no buffer object bound to index 0 (see the description of the  
    BindBuffer* commands below) in INTERLEAVED_ATTRIBS_NV mode. It is also an  
    INVALID_OPERATION error to call BeginTransformFeedbackNV if the number of  
    buffer objects bound in SEPARATE_ATTRIBS_NV mode is less than the number  
    of buffer objects required, as given by the current transform feedback  
    state.  It is also an INVALID_OPERATION error to call  
    BeginTransformFeedbackNV if no attributes are specified to be captured in  
    either separate or interleaved mode.  
  
    Buffer objects are made to be targets of transform feedback by calling one  
    of  
  
      void BindBufferRangeNV(enum target, uint index, uint buffer,  
                             intptr offset, sizeiptr size)  
      void BindBufferOffsetNV(enum target, uint index, uint buffer,  
                              intptr offset)  
      void BindBufferBaseNV(enum target, uint index, uint buffer)  
  
    where <target> is set to TRANSFORM_FEEDBACK_BUFFER_NV. Any of the three  
    BindBuffer* commands perform the equivalent of BindBuffer(target,  
    buffer). <buffer> specifies which buffer object to bind to the target at  
    index number <index>. <index> exists for use with the SEPARATE_ATTRIBS_NV  
    mode and must be less than the value of  
    MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV.  <offset> specifies a starting  
    offset into the buffer object <buffer>.  <size> specifies the number of  
    elements that can be written during transform feedback mode. This is  
    useful to prevent the GL from writing past a certain position in the  
    buffer object. Both <offset> and <size> are in basic machine units. The  
    error INVALID_VALUE is generated if the value of <size> is less than or  
    equal to zero.  The error INVALID_VALUE is generated if <offset> or <size>  
    are not word-aligned. The error INVALID_OPERATION is generated when any of  
    the BindBuffer* commands is called while transform feedback is active.  
  
    BindBufferBaseNV is equivalent to calling BindBufferOffsetNV with an  
    <offset> of 0. BindBufferOffsetNV is the equivalent of calling  
    BindBufferRangeNV with <size> = sizeof(buffer) - <offset> and rounding  
    <size> down so that it is word-aligned.  
  
    If recording the vertices of a primitive to the buffer objects being used  
    for transform feedback purposes would result in either exceeding the  
    limits of any buffer object's size, or in exceeding the end position  
    <offset> + <size> - 1, as set by BindbufferRangeNV, then no vertices of  
    the primitive are recorded, and the counter corresponding to the  
    asynchronous query target TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV (see  
    Section 2.Z) is not incremented.  
  
    Two methods exist to specify which transformed vertex attributes are  
    streamed to one, or more, buffer objects in transform feedback mode.  If  
    an OpenGL Shading Language vertex and/or geometry shader is active, then  
    the state set with the TransformFeedbackVaryingsNV() command determines  
    which attributes to record. If neither a vertex nor geometry shader is  
    active, the state set with the TransformFeedbackAttribsNV() command  
    determines which attributes to record.  
  
    When a program object containing a vertex shader and/or geometry shader is  
    active, the set of vertex attributes recorded in transform feedback mode  
    is specified by  
  
      void TransformFeedbackVaryingsNV(uint program, sizei count,  
                                       const int *locations,   
                                       enum bufferMode)  
  
    This command sets the transform feedback state for <program> and specifies  
    which varying variables to record when transform feedback is active. The  
    array <locations> contains <count> locations of active varying variables,  
    as queried with GetActiveVaryingNV(), to stream to a buffer object. See  
    section 2.15.3. <bufferMode> is one of INTERLEAVED_ATTRIBS_NV or  
    SEPARATE_ATTRIBS_NV.  The error INVALID_OPERATION is generated if any  
    value in <locations> does not reference an active varying variable, or if  
    any value in <locations> appears more than once in the array. The same  
    error is generated if <program> has not been linked successfully. The  
    program object's state value TRANSFORM_FEEDBACK_BUFFER_MODE_NV will be set  
    to <bufferMode> and the program object's state value  
    TRANSFORM_FEEDBACK_VARYINGS_NV set to <count>. These values can be queried  
    with GetProgramiv (see section 6.1.14).  
  
    In the INTERLEAVED_ATTRIBS_NV mode, varying variables are written,  
    interleaved, into one buffer object. This is the buffer object bound to  
    index 0. Varying variables are written out to that buffer object in the  
    order that they appear in the array <locations>. The error  
    INVALID_OPERATION is generated if the total number of components of all  
    varying variables specified in the array <locations> is greater than  
    MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_NV.  
  
    In the SEPARATE_ATTRIBS_NV mode, varying variables are recorded,  
    non-interleaved, into several buffer objects simultaneously. The first  
    varying variable in the array <locations> is written to the buffer bound  
    to index 0. The last varying variable is written to the buffer object  
    bound to index <count> - 1. No more than  
    MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV buffer objects can be written  
    to simultaneously. The error INVALID_VALUE is generated if <count> is  
    greater than that limit. Furthermore, the number of components for each  
    varying variable in the array <locations> cannot exceed  
    MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV. The error INVALID_VALUE is  
    generated if any varying variable in <locations> exceeds this limit.  
  
    It is not necessary to (re-)link <program> after calling  
    TransformFeedbackVaryingsNV(). Changes to the transform feedback state  
    will be picked up right away after calling TransformFeedbackVaryingsNV().  
  
    The value for any attribute specified to be streamed to a buffer object  
    but not actually written by a vertex or geometry shader is undefined.  
  
    When neither a vertex nor geometry shader is active, the vertex attributes  
    produced by fixed-function vertex processing or an assembly vertex or  
    geometry program can be recorded in transform feedback mode.  The set of  
    attributes to record is specified by  
  
      void TransformFeedbackAttribsNV(sizei count, const int *attribs,  
                                      enum bufferMode)  
  
    This command specifies which attributes to record into one, or more,  
    buffer objects. The value TRANSFORM_FEEDBACK_BUFFER_MODE_NV will be set  
    to <bufferMode> and the value TRANSFORM_FEEDBACK_ATTRIBS_NV set to  
    <count>.  The array <attribs> contains an interleaved representation of  
    the attributes desired to be fed back containing 3*count values. For  
    attrib i, the value at 3*i+0 is the enum corresponding to the attrib, as  
    given in table X.2. The value at 3*i+1 is the number of components of the  
    provided attrib to be fed back and is between 1 and 4. The value at 3*i+2  
    is the index for attribute enumerants corresponding to more than one real  
    attribute. For an attribute enumerant corresponding to only one attribute,  
    the index is ignored. For an attribute enumerant corresponding to more  
    than one attribute, the error INVALID_VALUE is generated if the index  
    value is outside the allowable range for that attribute.  
  
                               permitted            GPU_program_4  
     attrib                    sizes     index?     result name  
     ---------------------     --------  --------   --------------  
     POSITION                  1,2,3,4     no       position  
     PRIMARY_COLOR             1,2,3,4     no       color.front.primary  
     SECONDARY_COLOR_NV        1,2,3,4     no       color.front.secondary  
     BACK_PRIMARY_COLOR_NV     1,2,3,4     no       color.back.primary  
     BACK_SECONDARY_COLOR_NV   1,2,3,4     no       color.back.secondary  
     FOG_COORDINATE            1           no       fogcoord  
     POINT_SIZE                1           no       pointsize  
     TEXTURE_COORD_NV          1,2,3,4     yes      texcoord[index]  
     CLIP_DISTANCE_NV          1           yes      clip[index]  
     VERTEX_ID_NV              1           no       vertexid  
     PRIMITIVE_ID_NV           1           no       primid  
     GENERIC_ATTRIB_NV         1,2,3,4     yes      attrib[index]  
     LAYER_NV                  1           no       layer  
  
    Table X.2:  Transform Feedback Attribute Specifiers.The 'attrib' column  
    specifies which attribute to record. The 'permitted sizes' column  
    indicates how many components of the attribute can be recorded. The  
    'index' column indicates if the attribute is indexed.  The 'gpu program 4'  
    column shows which result variable of a vertex or geometry program  
    corresponds to the attribute to record.  
  
    The TransformFeedbackAttribsNV() command sets transform feedback state  
    which is used both when the GL is in fixed-function vertex processing  
    mode, as well as when an assembly vertex and/or geometry program is  
    active.  
  
    The parameter <bufferMode> has the same meaning as described for  
    TransformFeedbackVaryingsNV(). Attributes are either written interleaved,  
    or into separate buffer objects, in the same manner as described earlier  
    for TransformFeedbackVaryingsNV().  
  
    In the INTERLEAVED_ATTRIBS_NV mode, the error INVALID_VALUE is generated  
    if the sum of the values of elements 3*i+1 in the array <attribs> is  
    greater than MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_NV.  
  
    In the SEPARATE_ATTRIBS_NV mode, no more than  
    MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV buffer objects can be written  
    to simultaneously. The error INVALID_VALUE is generated if <count> is  
    greater than that limit.  
  
    The error INVALID_OPERATION is generated if any attribute appears more  
    than once in the array <attribs>.  
  
    The value for any attribute specified to be streamed to a buffer object  
    but not actually written by a vertex or geometry program is undefined.  
    The values of PRIMITIVE_ID_NV or LAYER_NV for a vertex is defined if and  
    only if a geometry program is active and that program writes to the result  
    variables "result.primid" or "result.layer", respectively.  The value of  
    VERTEX_ID_NV is only defined if and only if a vertex program is active, no  
    geometry program is active, and the vertex program writes to the output  
    attribute "result.id".  
  
    Section 2.Z, Primitive Queries  
   
    Primitive queries use query objects to track the number of primitives  
    generated by the GL and to track the number of primitives written to  
    transform feedback buffers.  
  
    When BeginQuery is called with a <target> of PRIMITIVES_GENERATED_NV, the  
    primitives-generated count maintained by the GL is set to zero. When the  
    generated primitive query is active, the primitives-generated count is  
    incremented every time a primitive reaches the Discarding Rasterization  
    stage (see Section 3.x) right before rasterization. This counter counts  
    the number of primitives emitted by a geometry shader, if active, possibly  
    further tessellated into separate primitives during the transform-feedback  
    stage, if active.  
  
    When BeginQuery is called with a <target> of  
    TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV, the transform-feedback-  
    primitives-written count maintained by the GL is set to zero. When the  
    transform feedback primitive written query is active, the  
    transform-feedback-primitives-written count is incremented every time a  
    primitive is recorded into a buffer object. If transform feedback is not  
    active, this counter is not incremented. If the primitive does not fit in  
    the buffer object, the counter is not incremented.  
  
    These two queries can be used together to determine if all primitives have  
    been written to the bound feedback buffers; if both queries are run  
    simultaneously and the query results are equal, all primitives have been  
    written to the buffer(s). If the number of primitives written is less than  
    the number of primitives generated, the buffer is full.  
  
    Modify section 2.15.3 "Shader Variables", page 75.  
  
    Change the second sentence in the first paragraph on p. 84 as follows:  
  
    . . . or read by a fragment shader, will count against this limit.  The  
    transformed vertex position (gl_Position) does not count against this  
    limit.  
  
    Add the following paragraphs on p.84:  
  
    A varying variable is considered active if it is determined by the linker  
    that the varying will actually be used when the executable code in a  
    program object is executed. The linker will make this determination  
    regardless of the transform-feedback state set with the  
    TransformFeedbackVaryingsNV() command. In cases where the linker cannot  
    make a conclusive determination, the varying will be considered active. It  
    is possible to override this determination and force the linker to  
    consider a varying variable as active by calling ActiveVaryingNV(). This  
    can be useful in transform feedback mode if there are varying variables to  
    be recorded but not otherwise needed.  
  
    To find the location of an active varying variable, call  
  
      int GetVaryingLocationNV(uint program, const char *name)  
  
    This command will return the location of varying variable <name>.  <name>  
    is a null-terminated string without whitespace. If <name> is not the name  
    of an active varying variable in <program>, -1 is returned. Locations for  
    both user-defined as well as built-in varying variables can be queried. If  
    <program> has not been successfully linked, the error INVALID_OPERATION is  
    generated. After a program is linked, the location will not change, unless  
    the program is re- linked. A valid name cannot be any portion of a single  
    vector or matrix, but can be a single element of an array or the whole  
    array.  Note that varying variables cannot be structures.  
  
    To determine the set of active varying variables used by a program object,  
    and their data types, use the command:  
  
      void GetActiveVaryingNV(uint program, uint index,  
                              sizei bufSize, sizei *length, sizei *size,  
                              enum *type, char *name);  
  
    This command provides information about the varying selected by  
    <index>. An <index> of 0 selects the first active varying variable, and an  
    <index> of ACTIVE_VARYINGS_NV-1 selects the last active varying  
    variable. The value of ACTIVE_VARYINGS_NV can be queried with  
    GetProgramiv (see section 6.1.14). If <index> is greater than or equal to  
    ACTIVE_VARYINGS_NV, the error INVALID_VALUE is generated.  The parameter  
    <program> is the name of a program object for which the command  
    LinkProgram has been issued in the past. It is not necessary for <program>  
    to have been linked successfully. The link could have failed because the  
    number of active varying variables exceeded the limit.  
  
    The name of the selected varying is returned as a null-terminated string  
    in <name>. The actual number of characters written into <name>, excluding  
    the null terminator, is returned in <length>. If <length> is NULL, no  
    length is returned. The maximum number of characters that may be written  
    into <name>, including the null terminator, is specified by <bufSize>. The  
    returned varying name can be the name of a user defined varying variable  
    or the name of a built- in varying (which begin with the prefix "gl_", see  
    the OpenGL Shading Language specification for a complete list). The length  
    of the longest varying name in program is given by  
    ACTIVE_VARYING_MAX_LENGTH_NV, which can be queried with GetProgramiv (see  
    section 6.1.14).  
  
    For the selected varying variable, its type is returned into <type>.  The  
    size of the varying is returned into <size>. The value in <size> is in  
    units of the type returned in <type>. The type returned can be any of  
    FLOAT, FLOAT_VEC2, FLOAT_VEC3, FLOAT_VEC4, INT, INT_VEC2, INT_VEC3,  
    INT_VEC4, UNSIGNED_INT, UNSIGNED_INT_VEC2_EXT, UNSIGNED_INT_VEC3_EXT,  
    UNSIGNED_INT_VEC4_EXT, FLOAT_MAT2, FLOAT_MAT3, or FLOAT_MAT4. If an error  
    occurred, the return parameters <length>, <size>, <type> and <name> will  
    be unmodified. This command will return as much information about active  
    varying variables as possible. If no information is available, <length>  
    will be set to zero and <name> will be an empty string. This situation  
    could arise if GetActiveVaryingNV is issued after a failed link.  
  
    To force the linker to mark a varying variable as active, call  
  
      void ActiveVaryingNV(uint program, const char *name)  
  
    to specify that the varying variable <name> in <program> should be marked  
    as active when the program is next linked. In particular, it does not  
    modify the list of active varying variables in a program object that has  
    already been linked. For any varying variable in <program> not passed to  
    ActiveVaryingNV, the linker will determine their active status. <name>  
    must be a null-terminated string without whitespace. A valid name cannot  
    be an element of an array, or any portion of a single vector or  
    matrix. ActiveVaryingNV may be issued before any shader objects are  
    attached to <program>. Hence, <name> can contain any string, including a  
    name that is never used as a varying variable in any shader object. Such  
    names are ignored by the GL.  
  
    The application is advised to force any varying variable live that it  
    needs for transform feedback purposes. The set of active varying variables  
    are linker dependent.  
  
homeprevnext Additions to Chapter 3 of the OpenGL 2.0 Specification (Rasterization)
  
   (Add new section 3.X, Discarding Rasterization)  
  
    Primitives can be optionally discarded before rasterization by calling  
    Enable and Disable with RASTERIZER_DISCARD_NV. When enabled, primitives  
    are discared right before the rasterization stage, but after the optional  
    transform feedback stage. When disabled, primitives are passed through to  
    the rasterization stage to be processed normally. RASTERIZER_DISCARD_NV  
    applies to the DrawPixels, CopyPixels, Bitmap, Clear and Accum commands as  
    well.  
  
homeprevnext Additions to Chapter 4 of the OpenGL 2.0 Specification (Per-Fragment Operations and the Frame Buffer)
  
    (Replace section 4.1.7, "Occlusion Queries", p. 204, with the following)  
  
    Occlusion queries use query objects to track the number of fragments or  
    samples that pass the depth test.  An occlusion query can be started and  
    finished by calling BeginQuery and EndQuery, respectively, with a <target>  
    of SAMPLES_PASSED.  
  
    When an occlusion query starts, the samples-passed count maintained by the  
    GL is set to zero.  When an occlusion query is active, the samples-passed  
    count is incremented for each fragment that passes the depth test.  If the  
    value of SAMPLE BUFFERS is 0, then the samples- passed count is  
    incremented by 1 for each fragment. If the value of SAMPLE BUFFERS is 1,  
    then the samples-passed count is incremented by the number of samples  
    whose coverage bit is set. However, implementations, at their discretion,  
    may instead increase the samples-passed count by the value of SAMPLES if  
    any sample in the fragment is covered.  When an occlusion query finishes  
    and all fragments generated by the commands issued prior to EndQuery have  
    been generated, the samples-passed count is written to the corresponding  
    query object as the query result value, and the query result for that  
    object is marked as available.  
  
    If the samples-passed count overflows, (i.e., exceeds the value 2^n - 1,  
    where n is the number of bits in the samples-passed count), its value  
    becomes undefined.  It is recommended, but not required, that  
    implementations handle this overflow case by saturating at 2^n - 1 and  
    incrementing no further.  
  
homeprevnext Additions to Chapter 5 of the OpenGL 2.0 Specification (Special Functions)
  
    (Add to section 5.4, Display Lists p. 237)  
  
    On p. 241, add the following to the list of vertex buffer object commands  
    not compiled into a display list: BindBufferRangeNV, BindBufferOffsetNV,  
    BindBufferBaseNV, TransformFeedbackAttribsNV,  
    TransformFeedbackVaryingsNV, and ActiveVaryingNV.  
  
homeprevnext Additions to Chapter 6 of the OpenGL 2.0 Specification (State and State Requests)
  
    Modify the second paragraph of section 6.1.1 (Simple Queries) p244 to read  
    as follows:  
  
    ...<data> is a pointer to a scalar or array of the indicated type in which  
    to place the returned data. The commands  
  
      void GetIntegerIndexedvEXT(enum param, uint index, int *values);  
      void GetBooleanIndexedvEXT(enum param, uint index, boolean *values);  
  
    are used to query indexed state.  <target> is the name of the indexed  
    state and <index> is the index of the particular element being queried.  
    <data> is a pointer to a scalar or array of the indicated type in which to  
    place the returned data. In addition ...  
  
   (Replace Section 6.1.12, Occlusion Queries, p. 254)  
  
    Section 6.1.12, Asynchronous Queries  
  
    The command  
  
      boolean IsQuery(uint id);  
  
    returns TRUE if <id> is the name of a query object. If <id> is zero, or if  
    <id> is a non-zero value that is not the name of a query object, IsQuery  
    returns FALSE.  
  
    Information about a query target can be queried with the command  
  
      void GetQueryiv(enum target, enum pname, int *params);  
  
    <target> identifies the query target and can be SAMPLES_PASSED for  
    occlusion queries or PRIMITIVES_GENERATED_NV and  
    TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV for primitive queries.  
  
    If <pname> is CURRENT_QUERY, the name of the currently active query for  
    <target>, or zero if no query is active, will be placed in <params>.  
  
    If <pname> is QUERY_COUNTER_BITS, the implementation-dependent number of  
    bits used to hold the query result for <target> will be placed in  
    params. The number of query counter bits may be zero, in which case the  
    counter contains no useful information.  
  
    For primitive queries (PRIMITIVES_GENERATED_NV and  
    TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV) if the number of bits is  
    non-zero, the minimum number of bits allowed is 32.  
  
    For occlusion queries (SAMPLES_PASSED), if the number of bits is non-  
    zero, the minimum number of bits allowed is a function of the  
    implementation's maximum viewport dimensions (MAX_VIEWPORT_DIMS).  The  
    counter must be able to represent at least two overdraws for every pixel  
    in the viewport. The formula to compute the allowable minimum value (where  
    n is the minimum number of bits) is:  
  
      n = min(32, ceil(log_2(maxViewportWidth *  
                             maxViewportHeight * 2))).  
  
    The state of a query object can be queried with the commands  
  
      void GetQueryObjectiv(uint id, enum pname, int *params);  
      void GetQueryObjectuiv(uint id, enum pname, uint *params);  
  
    If <id> is not the name of a query object, or if the query object named by  
    <id> is currently active, then an INVALID_OPERATION error is generated.  
  
    If <pname> is QUERY_RESULT, then the query object's result value is  
    returned as a single integer in <params>.  If the value is so large in  
    magnitude that it cannot be represented with the requested type, then the  
    nearest value representable using the requested type is returned.  If the  
    number of query counter bits for any <target> is zero, then the result is  
    returned as a single integer with a value of 0.  
  
    There may be an indeterminate delay before the above query returns.  If  
    <pname> is QUERY_RESULT_AVAILABLE, FALSE is returned if such a delay would  
    be required, TRUE is returned otherwise. It must always be true that if  
    any query object returns a result available of TRUE, all queries of the  
    same type issued prior to that query must also return TRUE.  
  
    Querying the state for any given query object forces the corresponding  
    query to complete within a finite amount of time.  
  
    If multiple queries are issued using the same object name prior to calling  
    GetQueryObject[u]iv, the result and availability information returned will  
    always be from the last query issued.  The results from any queries before  
    the last one will be lost if they are not retrieved before starting a new  
    query on the same <target> and <id>.  
  
    (Add to Section 6.1.13, Buffer Objects, p. 255)  
  
    Add the following paragraph to the bottom of this section, p. 256.  
  
    To query which buffer objects are the target(s) when transform feedback is  
    active, call GetIntegerIndexedvEXT() with <param> set to  
    TRANSFORM_FEEDBACK_BUFFER_BINDING_NV. <index> has to be in the range 0 to  
    MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV - 1, otherwise the error  
    INVALID_VALUE is generated. The name of the buffer object bound to <index>  
    is returned in <values>. If no buffer object is bound for <index>, zero is  
    returned in <values>.  
  
    To query the starting offset or size of the range of each buffer object  
    binding used for transform feedback, call GetIntegerIndexedvEXT() with  
    <param> set to TRANSFORM_FEEDBACK_BUFFER_START_NV or  
    TRANSFORM_FEEDBACK_BUFFER_SIZE_NV respectively.  The error INVALID_VALUE  
    is generated if <index> not in the range 0 to  
    MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV - 1.  If the parameter  
    (starting offset or size) was not specified when the buffer object was  
    bound, zero is returned.  If no buffer object is bound to <index>, -1 is  
    returned.  
  
    (Add a new Section 6.1.14 "Transform Feedback " and rename 6.1.14 to  
    6.1.15)  
  
    To query the attributes to stream to a buffer object when neither an  
    OpenGL Shading Language vertex nor geometry shader is active, call  
    GetIntegerIndexedvEXT() with <param> set to  
    TRANSFORM_FEEDBACK_RECORD_NV. This will return three values in <values>  
    for each <index>. The first value returned is the attribute.  The second  
    value the number of components of the attribute, and the third value the  
    index of the attribute, if applicable. If the attribute is not indexed,  
    the third component will return 0. The parameter <index> has to be in the  
    range 0 to TRANSFORM_FEEDBACK_ATTRIBS_NV - 1, otherwise the error  
    INVALID_VALUE is generated. If no data exists for <index> 0 is returned  
    three times in <values>.  
  
    To query the attributes to stream to a buffer object when a vertex and/or  
    geometry shader is active, use the command  
    GetTransformFeedbackVaryingNV(), as explained in section 6.1.14.  
  
    (add to Section 6.1.14, Shader and Program Queries, p. 256)  
  
    Add the following paragraph to the bottom of page 257:  
  
    If <pname> is TRANSFORM_FEEDBACK_BUFFER_MODE_NV, the buffer mode,  
    used when transform feedback is active, is returned. It can be one of  
    SEPARATE_ATTRIBS_NV or INTERLEAVED_ATTRIBS_NV. If <pname> is  
    TRANSFORM_FEEDBACK_VARINGS_NV, the number of varying variables to stream  
    to one, or more, buffer objects are returned. If <pname> is  
    ACTIVE_VARYINGS_NV, the number of active varying variables is  
    returned. If no active varyings exist, 0 is returned. If <pname> is  
    ACTIVE_VARYINGS_MAX_LENGTH_NV, the length of the longest active varying  
    name, including a null terminator, is returned. If no active varying  
    variable exists, 0 is returned.  
  
    The command  
  
      void GetTransformFeedbackVaryingNV(uint program, uint index,  
                                         int *location)  
  
    returns, for each <index>, the location of a varying variable to stream to  
    a buffer object in <location>. The <index> element of the array  
    <locations>, as passed to TransformFeedbackVaryingsNV, is  
    returned. <index> has to be in the program object specific range 0 to  
    TRANSFORM_FEEDBACK_VARYINGS_NV - 1, otherwise the error INVALID_VALUE is  
    generated. If no location exists for <index>, -1 is returned. If <program>  
    is not the name of a program object, or if program object has not been  
    linked successfully, the error INVALID_OPERATION is generated.  
  
homeprevnext Additions to Appendix A of the OpenGL 2.0 Specification (Invariance)
  
    None.  
  
homeprevnext Additions to the AGL/GLX/WGL Specifications
  
    None.  
  
homeprevnext Interactions with EXT_timer_query
  
    EXT_timer_query is the first extension to generalize the BeginQuery and  
    EndQuery mechanism introduced by ARB_occlusion_query and OpenGL 1.5 to  
    cover an additional query type.  This extension is the second.  This  
    extension is written against the OpenGL 2.0 specification and uses most of  
    the modifications in the EXT_timer_query specification.  If  
    EXT_timer_query is supported, timer queries need to be added as a third  
    query type.  
  
homeprevnext Dependencies on NV_geometry_program4 and EXT_geometry_shader4
  
    If NV_geometry_program4 is not supported, delete the reference to the  
    output primitive type in Section 2.Y.  Delete the reference to  
    PRIMITIVE_ID_NV and LAYER_NV.  
  
    If EXT_geometry_shader4 is not supported, delete any reference to a  
    geometry shader.  
  
homeprevnext Dependencies on NV_vertex_program4 and NV_gpu_program4
  
    If NV_vertex_program4 is not supported, delete any reference to  
    VERTEX_ID_NV.  If NV_gpu_program4 is not supported, table X.2 needs to  
    refer to the "result" variables defined in the ARB_vertex_program  
    specification instead.  
  
homeprevnext Interactions with ARB_shader_objects and OpenGL 2.0
  
    If neither ARB_shader_objects nor OpenGL 2.0 is supported, all references  
    to shader and program objects, as well as varying variables, should be  
    removed.  This also means that functions including  
    TransformFeedbackVaryingsNV, GetVaryingLocationNV, GetActiveVaryingNV,  
    ActiveVaryingNV, and GetTransformFeedbackVaryingNV will not be  
    supported, and enums that are relevant only in the context of shader and  
    program objects will not be accepted.  
  
homeprevnext Errors
  
    The error INVALID_OPERATION is generated by BeginQuery if called with an  
    <id> of zero, if the active query object name for <target> is non- zero,  
    or if <id> is the active query object name for any query type.  
  
    The error INVALID_OPERATION is generated by EndQuery if the active query  
    object name for <target> is zero.  
  
    The error INVALID_OPERATION is generated if Begin, or any command that  
    performs an explicit Begin, is called when:  
  
      * A geometry program or shader is not active AND the begin mode does not  
        match the allowed begin modes for the current transform feedback state  
        as given by table X.1.  
  
      * A geometry program or shader is active AND the output primitive type  
        (of the geometry program / shader) does not match the allowed begin  
        modes for the current transform feedback state as given by table X.1.  
  
    The error INVALID_OPERATION is generated by BeginTransformFeedbackNV if  
    there is no buffer object bound to index 0 in INTERLEAVED_ATTRIBS_NV  
    mode.  
  
    The error INVALID_OPERATION is generated by BeginTransformFeedbackNV if  
    the number of buffer objects bound in SEPARATE_ATTRIBS_NV mode is less  
    than the number of buffer objects required, as given by the current  
    transform feedback state.  
  
    The error INVALID_OPERATION is generated by BeginTransformFeedbackNV if  
    no attributes are specified to be captured.  
  
    The error INVALID_OPERATION is generated by BeginTransformFeedbackNV,  
    TransformFeedbackBufferNV, TransformFeedbackVaryingsNV,  
    TransformFeedbackAttribsNV, or UseProgram or LinkProgram, called on the  
    currently in use program object, while transform feedback is active.  
  
    The error INVALID_OPERATION is generated by EndTransformFeedbackNV while  
    transform feedback is inactive.  
  
    The error INVALID_OPERATION is generated by BindBufferRangeNV,  
    BindBufferOffsetNV or BindBufferBaseNV if <index> is greater or equal  
    than MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV.  
  
    The error INVALID_VALUE is generated by BindBufferRangeNV if the value of  
    <size> <= 0.  
  
    The error INVALID_VALUE is generated by BindBufferRangeNV or  
    BindBufferOffsetNV if <start> or <end> are not word-aligned.  
  
    The error INVALID_OPERATION is generated when any of the BindBuffer*  
    commands is called while transform feedback is active.  
  
    The error INVALID_OPERATION is generated by TransformFeedbackVaryingsNV  
    commands if any location appears more than once in the array <locations.  
  
    The error INVALID_OPERATION is generated by TransformFeedbackVaryingsNV  
    if any location in <locations> references a non-existing varying variable.  
  
    The error INVALID_OPERATION is generated by TransformFeedbackVaryingsNV  
    if <program> has not been linked successfully.  
  
    The error INVALID_OPERATION is generated by TransformFeedbackVaryingsNV  
    in INTERLEAVED_ATTRIBS_NV mode if the total number of components of all  
    varying variables specified in the array <locations> is greater than  
    MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_NV.  
  
    The error INVALID_VALUE is generated by TransformFeedbackVaryingsNV or  
    TransformFeedbackAttribsNV in SEPARATE_ATTRIBS_NV mode if <count> is  
    greater than MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV.  
  
    The error INVALID_VALUE is generated by TransformFeedbackVaryingsNV in  
    SEPARATE_ATTRIBS_NV mode if the number of components for each varying  
    variable in the array <locations> is greater than  
    MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV.  
  
    The error INVALID_VALUE is generated by TransformFeedbackAttribsNV in  
    INTERLEAVED_ATTRIBS_NV mode if the sum of the values of the components of  
    the attributes in the array <attribs> is greater than  
    MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_NV.  
  
    The error INVALID_OPERATION is generated by TransformFeedbackAttribsNV if  
    an enum value is specified more than once in the array <attribs>.  
  
    The error INVALID_OPERATION is generated by TransformFeedbackAttribsNV if  
    the number of components for each attribute in the array <attribs> is  
    outside the range [0,4].  
  
    The error INVALID_VALUE is generated by TransformFeedbackAttribsNV if the  
    index value is in the array <attribs> is outside the allowable range for  
    an attribute enumerant corresponding to more than one real attribute.  
  
    The error INVALID_OPERATION is generated by GetVaryingLocationNV if  
    <program> is not the name of a program object or if <program> has not been  
    linked successfully.  
  
    The error INVALID_OPERATION is generated by GetActiveVaryingNV or  
    ActiveVaryingNV if <program> is not the name of a program object.  
  
    The error INVALID_VALUE is generated by GetActiveVaryingNV if <index> is  
    greater than or equal to ACTIVE_VARYINGS_NV.  
  
    The error INVALID_VALUE is generated by GetIntegerIndexedvEXT() or  
    GetBooleanIndexedv() with <param> set to TRANSFORM_FEEDBACK_RECORD_NV if  
    <index> is greater than or equal to TRANSFORM_FEEDBACK_ATTRIBS_NV.  
  
    The error INVALID_VALUE is generated by GetIntegerIndexedvEXT() or  
    GetBooleanIndexedvEXT() with <param> set to  
    TRANSFORM_FEEDBACK_BUFFER_BINDING_NV if <index> is greater than or equal  
    to MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV.  
  
    The error INVALID_VALUE is generated by GetTransformFeedbackVaryingsNV if  
    <index> is greater than the program object specific value  
    TRANSFORM_FEEDBACK_VARYINGS_NV - 1.  
  
    The error INVALID_OPERATION is generated by  
    GetTransformFeedbackVaryingsNV if <program> is not the name of a program  
    object, or if program object has not been linked successfully.  
  
homeprevnext New State
  
    (Add a new table:  Table 6.X,  Transform Feedback State)  
  
    Get Value             Type    Get Command     Init. Value  Description                Sec    Attrib  
    ------------------    ------  --------------  ------------ -------------------------  -----  ------  
    TRANSFORM_FEEDBACK_   Z2      GetIntegerv     INTERLEAVED_  Transform feedback mode   2.Y      -  
      BUFFER_MODE_NV                              ATTRIBS_NV  
    TRANSFORM_FEEDBACK_   Z2      GetIntegerv          0        Number of attributes to   2.Y      -  
      ATTRIBS_NV                                                capture in transform  
                                                                feedback mode  
    TRANSFORM_FEEDBACK_   Z+      GetIntegerv          0        Buffer object bound to    6.1.13   -  
      BUFFER_BINDING_NV                                         generic bind point for  
                                                                transform feedback.  
    TRANSFORM_FEEDBACK_   nx3*Z+  GetInteger-          0        Name, component count,    6.1.14   -  
      RECORD_NV                   IndexedvEXT                   and index of each   
                                                                attribute captured  
    TRANSFORM_FEEDBACK_   nxZ+    GetInteger-          0        Buffer object bound to    6.1.13   -  
      BUFFER_BINDING_NV           IndexedvEXT                   each transform feedback  
                                                                attribute stream.  
    TRANSFORM_FEEDBACK_   nxZ+    GetInteger-          0        Start offset of binding   6.1.13   -  
      BUFFER_START_NV             IndexedvEXT                   range for each transform  
                                                                feedback attrib. stream  
    TRANSFORM_FEEDBACK_   nxZ+    GetInteger-          0        Size of binding range     6.1.13   -  
      BUFFER_SIZE_NV              IndexedvEXT                   for each transform  
                                                                feedback attrib. stream  
  
   (Modify Table 6.37, p 298, updating the query object state to cover  
   transform feedback.)  
  
    Get Value         Type  Get Command       Init. Value  Description                Sec    Attribute  
    ----------------  ----  ----------------  -----------  -------------------------  -----  ---------  
    CURRENT_QUERY     3xZ+  GetQueryiv        0            Active query object name   2.X        -  
                                                           (occlusion, timer, xform  
                                                            feedback)  
    QUERY_RESULT      3xZ+  GetQueryObjectiv  0            Query object result        2.X        -  
                                                           (samples passed, Time  
                                                           elapsed, feedback data amount)  
    QUERY_RESULT_AVAILABLE  3xZ+  GetQueryObjectiv  TRUE   Query object result        2.X        -  
                                                             available?  
  
   (Modify Table 6.29, p. 290, Program Object State. Add the following state.)  
  
    Get Value           Type  Get Command   Init. Value  Description                 Sec    Attribute  
    ----------------    ----  ------------  -----------  -------------------------   -----  ---------  
   ACTIVE_VARYINGS_NV   Z+    GetProgramiv       0       Number of active varyings   2.15.3     -  
   ACTIVE_VARYING_MAX_  Z+    GetProgramiv       0       Maximum active varying      2.15.3     -  
     LENGTH_NV                                           name length  
   TRANSFORM_FEEDBACK_  Z2    GetProgramiv  INTERLEAVED_ Transform feedback mode     6.1.14     -  
     BUFFER_MODE_NV                         ATTRIBS_NV   for the program  
   TRANSFORM_FEEDBACK_  Z+    GetProgramiv       0       Number of varyings to       6.1.14     -  
     VARYINGS_NV                                         stream to buffer object(s)  
        -               nxZ+  GetVarying-        -       Location of each active     2.15.3     -  
                              LocationNV                 varying variable  
        -               Z+    GetActive-          -      Size of each active         2.15.3     -  
                              VaryingNV                  varying variable  
        -               Z+    GetActive-          -      Type of each active         2.15.3     -  
                              VaryingNV                  varying variable  
        -               0+x-  GetActive-          -      Name of each active         2.15.3     -  
                        char  VaryingNV                  varying variable  
        -               Z+    GetTransform-       -      Varying location for one    6.1.14     -  
                              Feedback-                  of the multiple varyings  
                              VaryingNV                  to capture  
  
homeprevnext New Implementation Dependent State
  
   (Modify Table 6.34, p. 295.  Update the query object state to cover  
   transform feedback.)  
  
    Get Value               Type Get Command  Minimum Value  Description                  Sec     Attribute  
    --------------------    ---- -----------  -------------  --------------------------   ------  ---------  
    QUERY_COUNTER_BITS      2xZ+ GetQueryiv   see 6.1.12     Asynchronous query counter   6.1.12    -  
                                                             bits (occlusion, timer,   
                                                             tranform feedback queries)  
  
   (Add a new table, Table 6.X. Transform Feedback State.)  
  
   NOTE:  In the "GetValue" columns below, MXFB stands for  
   "MAX_TRANSFORM_FEEDBACK".  
  
    Get Value               Type Get Command  Minimum Value  Description                  Sec     Attribute  
    --------------------    ---- -----------  -------------  --------------------------   ------  ---------  
    MXFB_INTERLEAVED_       Z+   GetIntegerv  64             Max number of components to  2.Y       -  
    COMPONENTS_NV                                            write to a single buffer in  
                                                             interleaved mode  
    MXFB_SEPARATE_          Z+   GetIntegerv  4              Max number of separate       2.Y       -  
    ATTRIBS_NV                                               attributes or vayings that  
                                                             can be captured in transform  
                                                             feedback  
    MXFB_SEPARATE           Z+   GetIntegerv  16             Max number of components     2.Y       -  
    COMPONENTS_NV                                            per attribute or varying   
                                                             in separate mode  
  
homeprevnext Issues
  
    1. How does transform feedback differ from core GL feedback?  
  
      * Transform feedback writes vertex data to buffer objects, which allows  
        the data returned to be used directly by vertex pulling.  GL feedback  
        mode writes vertex data to a buffer in system memory.  
  
      * Transform feedback is done after transformation, but prior to  
        clipping.  The primitives returned contain the original transformed  
        vertices produced by vertex or geometry program execution, and does  
        not contain any primitives inserted by clipping.  
  
      * Transform feedback supports only a single basic output primitive type  
        (points, lines, or triangles), while core GL feedback mode supports  
        all primitive types.  Since only one primitive type is supported, the  
        data returned does not contain tokens describing each primitive being  
        fed back.  Primitive tokens make the data returned by GL feedback mode  
        irregular and unsuitable for vertex pulling.  
  
    2. What should this extension be called?  
  
      RESOLVED: The current name is "NV_transform_feedback", playing off the  
      fact that it is transformed primitives that are handled and the  
      similarities to GL feedback mode.  
  
    3. What happens if you bind a buffer for transform feedback that is  
       currently bound for other purposes?  Should we somehow detect this case  
       and produce an error?  
  
      !!! NBC I feel strongly that we should follow the precedent for  
      Map/Unmap. The reason that MapBuffer and UnmapBuffer are a precedent  
      here is because while a buffer object is in the mapped state, no GL  
      commands are allowed to operate on the buffer object's data.  So by  
      analogy, while a buffer is being used for transform feedback, no other  
      GL commands should be allowed to operate on the buffer object's data.  
      This includes initiating any rendering which would cause the GL to  
      source data from an active transform feedback buffer object.  
  
      UNRESOLVED  
  
    4. Should this extension include any new buffer object binding targets, or  
       should it overload ARRAY_BUFFER, or should we skip the binding target  
       altogether in favor of a buffer object name accepted directly by the  
       new GL commands?  
  
      RESOLVED: There are new binding points for XFB along with a new API  
      (BindBufferBase etc) to set the internal binding points. A new binding  
      point, TRANSFORM_FEEDBACK_BUFFER_NV is also introduced.  
  
    5. Previous buffer object extensions provided a way to have existing GL  
       commands reference a buffer object instead of a user-supplied buffer.  
       Should the new commands introduced here allow referencing a  
       user-supplied buffer in addition to a buffer object?  
  
      RESOLVED: No. A program can get the contents of the feedback buffer back  
      to the CPU using MapBuffer and GetBufferSubData  
  
    6. Is BeginTransformFeedback really necessary? Could the query just  
       initiate the transform feedback mode?  
  
      RESOLUTION: Using BeginTransformFeedback and EndTransformFeedback gives  
      a clean place to spec all of the transform-feedback-specific issues  
      without cluttering up the query language. Also, the queries don't have  
      to be done at the same time as beginning and ending the feedback  
      process.  
  
    7. What usage enums should be provided to glBufferData for use in  
       conjunction with transform feedback?  
  
      RESOLVED: STREAM_COPY or STREAM_READ are expected to be the most common  
      usages. If a buffer object is being written by the GL through transform  
      feedback, and the contents of the buffer object are subsequently being  
      consumed by the GL (e.g. by being used as a vertex buffer object), then  
      this is a *_COPY usage. If the buffer object is being written by the GL  
      through transform feedback, but is being consumed by the application  
      (e.g. being mapped for read), this is a *_READ usage.  The temporal  
      (STREAM, STATIC, or DYNAMIC) component of the usage enum is determined  
      by the ratio between how often the contents of the buffer object are  
      modified and how often operations that source data from the buffer  
      object occur.  
  
    8. What should the behavior be when a buffer object is the active target  
       of transform feedback, and it is deleted via DeleteBuffers?  
  
      RESOLVED: Deletion is deferred until the EndTransformFeedback if  
      transform feedback is active.  
  
    9. Should we allow more buffers to be bound than are used?  
  
      RESOLVED: Yes. The extra buffers are not in the way and can stay bound.  
  
    10. Should we allow feedback to buffer lists with holes (i.e. 0 and 2  
        bound)?  
  
      RESOLVED: No. This makes for an ugly API with the potential for bugs,  
      without any real benefit. The application can as well bind all buffers  
      needed to incremented indices. It is an invalid operation to not have a  
      buffer bound where one is required.  
  
    11. Why only one feedback primitive mode per feedback invocation?  
  
      RESOLVED: Having primitive tokens breaks up the stream and makes it less  
      amenable to being read back in as a vertex buffer. Also, mixing multiple  
      primitive types makes the counting of primitives less clear for the  
      application.  
  
    12. Is RasterPos fed back?  
  
      RESOLVED: No.  
  
    13. Is DrawPixels/CopyPixels/Bitmap fed back?  
  
      RESOLVED: No. Rasterization occurs as normal, but there is no  
      output to the feedback buffer. This is consistent with taking a  
      tap out of the pipe before clipping.  
  
    14. Why do we need new BindBuffer* functions?  
  
      RESOLVED: All previous buffer object extensions have been retrofits of  
      existing pointer-based APIs. New extensions built assuming buffer  
      objects don't have that history, so need a new API. The functionality of  
      these new functions combines the functionality of BindBuffer, to set the  
      external bind point used by calls like MapBuffer and BufferSubData, with  
      the functionality to set an internal bind point like VertexAttribPointer  
      does.  
  
   15. How do the transform feedback indices, passed to the BindBuffer*  
       commands, work with multiple bindings?  
  
      RESOLVED: The same way that they work with vertex arrays. There is one  
      external bind point, TRANSFORM_FEEDBACK_BUFFER_NV. There are n internal  
      bind points, selected with the <index> parameter to the BindBuffer*  
      commands, where n is some implementation dependent limit. The  
      BindBuffer* commands take the buffer passed and bind it to the external  
      bind point, as well as to the selected internal bind point.  
  
      For example:  
  
        BindBufferOffsetNV(TRANSFORM_FEEDBACK_BUFFER_NV, 0, 1, 12);   
        // XFB index 0 points at buffer 1 with offset 12  
  
        BindBuffer(TRANSFORM_FEEDBACK_BUFFER_NV, 2);   
        // Buffer 2 is now bound to the external bind point. XFB index 0 still  
        // points at buffer 1  
  
        MapBuffer(TRANSFORM_FEEDBACK_BUFFER_NV, ...);   
        // Maps buffer 2  
  
    16. How are quads/quadstrips/polygons tesselated into triangles?  
  
      RESOLVED: In an implementation-dependent manner. OpenGL doesn't define  
      quads or polygons in terms of triangles, so there is no one correct way  
      to do it, and different gpus may implement the behavior differently. A  
      quad may be split into two triangles in several different ways, and an  
      application may not rely on this behavior.  
  
    17. How does this extension interact with display lists?  
  
      RESOLVED: Just like the VBO extension, none of the BindBuffer* commands  
      are compiled into a display list.  
  
    18. Does polygon mode state affect the logic that determines if the  
        transform feed back primitive mode and the render mode states are  
        valid at the start of transform feedback mode?  
  
      RESOLVED: PolygonMode has no influence on the BeginTransFormFeedback  
      primitiveMode check since it is performed later, in raster.  
  
    19. What to do with incomplete primitives?  
  
      RESOLVED: If there is no room to store one or more vertices of a  
      primitive in a buffer object, none of the vertices in that primitive are  
      written to the buffer. If a partial primitive enters transform feedback  
      (i.e. only two vertices sent in triangles mode), none of the vertices in  
      that primitive are written to the buffer object.  
  
    20. Why does TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV have a  
        TRANSFORM_FEEDBACK prefix but PRIMITIVES_GENERATED_NV doesn't?  
  
      RESOLVED: The number of primitives generated is independent of any  
      feedback that is active. The number of primitives that are written is  
      only valid for transform feedback - another extension could conceivably  
      have a different way of writing out primitives that would require a  
      similar but distinct token.  
  
    21. When a GLSL vertex shader is active, what happens in transform  
        feedback mode if non-active varying variables are specified?  
  
      DISCUSSION: Active varying variables are varying variables, declared in  
      the shader, that the linker determined are actually needed. As an  
      optimization, the linker can discard the ones declared, but not  
      needed. If non-active varying variables need to be fed into a buffer  
      object, the linker should not perform this optimization.  
  
      There are three suggested resolutions to this problem:  
  
        1. The set of varying variables that need to be streamed to a buffer  
           object in transform feedback mode are set as a property of the  
           program object, and are taken into account during the link step.  
           This means that changing the set means the application will have to  
           re-link the program object in order to have the change take effect.  
  
        2. The set of varying variables that need to be streamed to a buffer  
           object in transform feedback mode are specified after the program  
           object has been linked. This is the most flexible option from the  
           applications perspective, but this might mean that a) specifying  
           this set could force the GL to re-link 'under the covers', and b)  
           could mean that the GL runs out of varying variable slots because  
           the combined total of the set of active varyings and the varyings  
           to stream in transform feedback mode is too large.  
  
        3. This solution is a hybrid of the above two approaches. The set of  
           potential varying variables that need to be streamed to a buffer  
           object are set as a property of the program object. These varying  
           variables are marked as active by the application and therefore  
           cannot be eliminated during the link step. However, a sub-set of  
           varying variables to actually stream to a buffer object can be  
           changed without the application having to re-link the program  
           object. This approach gives the application flexibility to change  
           the set of varying variables to stream, while it eliminates the  
           need for the GL to compile 'under the covers'.  
  
      RESOLUTION: Option 3 offers a good compromise, and therefore we'll go  
      with that.  
  
    22. Given option 3 in the previous resolution, how to specify that a  
        varying variable has to be considered active by the linker?  
  
      DISCUSSION: There are two approaches to the application specifying which  
      varying variables are active. We can either provide a simple flag that  
      specifies that all varying variables are considered active, or we can  
      provide a more complex mechanism where the application can specify an  
      individual varying variable as being active.  
  
      RESOLUTION: RESOLVED. The 'all or nothing' flag is a simple idea, but  
      has a drawback when used with a 'uber-shader' that implements many paths  
      to achieve an effect, but only one path is used during any run of the  
      shader. In this case, a lot more varying variables might be flagged as  
      active then really is necessary, running the risk of running out of  
      resources. Therefore, we'll provide a mechanism for the application to  
      specify on a per varying variable basis if it is active.  
  
    23. Given the discussion in the previous issues, should a  
        GetActiveVarying() command be added, modeled after the existing  
        getActiveUniform() command?  
  
      DISCUSSION: Such a command will return the list of active uniforms,  
      after the program object has been linked. As per issue 22's resolution,  
      the complete set of varying variables that could be streamed to a buffer  
      object needs to be specified before the program object is linked.  
  
      It can be useful to an application to stream out a subset of the active  
      varying variables or to find out the whole set of active varyings,  
      especially since the set can be implementation dependent.  
  
      RESOLUTION: YES.  
  
    24. What is proper use of the command ActiveVaryingNV()?  
  
      RESOLVED: The application is well advised to force any varying variable  
      live that it needs for transform feedback purposes. The set of active  
      varying variables are linker dependent. For example, if a program object  
      has no fragment shader, then the LinkProgram command cannot typically  
      determine which built-in varying variables, output by a geometry or  
      vertex shader, are active. This is because the fragment processing state  
      can change, and therefore such a determination cannot be made until a  
      render command is issued. Furthermore, any user-defined varyings are  
      likely to be marked as non-active if there is no fragment shader because  
      they are guaranteed to have no effect on fixed-function fragment  
      processing. If there is both a vertex (or geometry) and fragment shader  
      in a program object, the application can probably deduce what will be an  
      active varying variable, or not. But beware of any (static) flow-control  
      that the linker can use to do cross vertex- fragment optimization to  
      cull any varying variables.  
  
    25. Are primitives sent down the pipeline after transform feedback, or  
        discarded?  
  
      RESOLVED: Primitives can be optionally discarded before rasterization by  
      calling Enable and Disable with RASTERIZER_DISCARD_NV. When enabled,  
      primitives are discarded after vertex attributes are recorded into the  
      buffer objects bound to transform feedback.  When disabled, primitives  
      are passed through to the rasterization stage to be clipped and  
      rasterized normally. All rasterization operations are discarded, not  
      just those that are fed back into the buffer.  
  
      This applies to DrawPixels, CopyPixels, Bitmap, Clear, Accum as well.  
  
    26. If a varying is declared as an array, is the whole array streamed out?  
  
      RESOLVED: No, the application has to specify which elements of an array  
      it wants to stream out. Implementations might not be able to stream out  
      a large number of components to a single buffer object.  If that is the  
      case, the application can stream each element of an array to a different  
      buffer object in TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS mode.  
  
    27. Is it possible to capture attributes when using the fixed-function  
        pipeline?  
  
      RESOLVED: Yes, there is nothing that precludes this. The application is  
      responsible for sending down the needed vertex attributes and setting  
      the GL state, as desired, for the attributes it wants to stream to a  
      buffer object. Note that VERTEX_ID_NV is not defined in fixed-function.  
  
    28. Is it possible to record hardware-generated primitive ID values that  
        would be available to a pixel shader?  
  
      RESOLVED:  Transform feedback can only record the primitive ID values  
      emitted per-vertex by a geometry shader or program.  While each  
      primitive recorded for transform-feedback has a well-defined primitive  
      ID, transform feedback is only capable of recording the attributes of  
      individual vertices.  
  
    29.  Does transform feedback support the ability to capture per-vertex  
         layer outputs, as provided by EXT_geometry_shader4 and  
         NV_geometry_program4?  
  
      RESOLVED:  Yes.  For GLSL shaders, it is sufficient to reference the  
      built-in varying "gl_Layer".  For assembly geometry programs, the  
      original version of the spec did not provide an enum allowing you to  
      name "result.layer" in TransformFeedbackAttribsNV.  This was an  
      oversight in the original spec, which was fixed by version 14.  An  
      updated driver will be required to take advantage of this capability;  
      NVIDIA drivers supporting this extension published prior to February  
      2008 will not be able to capture "result.layer".  The value captured for  
      LAYER_NV will be undefined unless a geometry program that writes  
      "result.layer" is active.  
  
homeprevnext Revision History
  
      Rev.    Date    Author    Changes  
      ----  --------  --------  -----------------------------------------  
       14   02/04/08  pbrown    Fixed a problem with the spec where we were  
                                unable to record "result.layer" using the  
                                assembly interface.  Added a new enum to   
                                address.  
  
       13   11/28/07  pbrown    Specified the captured primitive ID to be  
                                undefined unless a geometry shader emits it  
                                as a vertex output.  XFB can only record  
                                per-vertex data.  
  
       12   09/27/07  pbrown    Removed incorrect error description from  
                                the errors section -- buffer objects don't  
                                need to be bound before calling Transform-  
                                Feedback{Attribs,Varyings}NV, just before  
                                BeginTransformFeedbackNV.  
  
       11   08/28/07  pbrown    Added an error calling BeginTransformFeedback  
                                if no attributes would be captured (i.e.,  
                                attribute count is 0 for ASM or no attributes  
                                specified in the active GLSL program).  
  
       10   02/09/07  pbrown    Updated status section (now released).  
  
        9   10/23/06  pbrown    Fixed prototype for GetIntegerIndexedEXT and  
                                GetBooleanIndexedEXT:  <index> is unsigned.  
  
        8   10/19/06  pbrown    Removed stray addition of GetFloatIndexedvEXT  
                                and GetDoubleIndexedvEXT.  Minor wording  
                                fixes.  
  
        7   10/17/06  pbrown    Rename from EXT to NV while working on  
                                standardizing a functional subset extension  
                                that will be named EXT_transform_feedback.  We  
                                expect that the EXT should be equivalent to  
                                the NV, except that it (a) removes support for  
                                non-GLSL usage, (b) removes the ability to  
                                change the set of varyings captured without  
                                relinking.  NVIDIA expects to support both the  
                                NV and EXT forms of this extension going  
                                forward.  Fix state table formatting.  Removed  
                                GetFloatIndexedvEXT and GetDoubleIndexedvEXT,  
                                which are not needed by this and related  
                                extensions.  
  
        6   09/11/06  pbrown    Fix bad prototype for GetActiveVaryingEXT  
                                and bad references to "GetActiveVaryingsEXT".  
                                Fix enum names for INTERLEAVED_ATTRIBS_EXT and  
                                SEPARATE_ATTRIBS_EXT (no TRANSFORM_ FEEDBACK  
                                prefix).  Remove erroneous state table entries  
                                that were obsoleted by the introduction of the  
                                TRANSFORM_FEEDBACK_RECORD_EXT query.  
         
        5   08/31/06  pbrown    Fix miscellaneous spec errata.   Record enum  
                                values that weren't documented in previous  
                                spec versions.  Use correct function names for  
                                indexed "Get" functions.  Clarify that GLSL  
                                interactions mean that some functions and  
                                enums defined here aren't supported if GLSL  
                                isn't supported.  Fixed the double-assignment  
                                of several TransformFeedbackAttribsEXT enums  
                                and re-packed that portion of the enum range.  
                                Clarify that several new functions are  
                                non-listable.  Fix the query tokens for buffer  
                                object range bindings to match the API  
                                (start/size, not start/end).  
  
        4   08/30/06  pbrown    Reformatting as a plaintext document   
                                instead of an exported MS Word document.  
  
        3   07/26/06  barthold  Forgot a few changes w.r.t. version 2.  
  
        2   07/14/06  barthold  Change BindBufferRangeEXT to take an  
                                offset and size parameter. Change   
                                BindBufferOffsetEXT to take an offset  
                                parameter.  
  
        1             barthold  Internal spec development.  
        1             barthold  Internal spec development.  
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.