
Name

    ATI_vertex_array_object


Name Strings

    GL_ATI_vertex_array_object


Contact

    Rick Hammerstone, AMD (rick.hammerstone 'at' amd.com)


Version

    1.11 - 11/04/06
    Updated contact info after ATI/AMD merger.

    1.1 - 01/08/02
    Changed DeleteObjectBufferATI to FreeObjectBufferATI to match the
    glati.h header file. Removed objbuf attribute.

    1.01 - 09/18/01
    Added clarification that ArrayObectATI and VariantArrayObjectATI
    are not allowed between Begin/End but may not return an error.

    1.0 - 09/06/01
    Changed references to ATI_vertex_shader to EXT_vertex_shader.

    0.9 - 08/15/01
    Added support for variant arrays.

    0.8 - 07/06/01
    Added table of new state.

    0.7 - 07/02/01
    Added official enumerants.

    0.6 - 05/07/01
    Chopped out most of the new entry points. Back to just object
    buffers and one call to define vertex arrays in an object buffer. 

    0.5 - 04/18/01
    The great renaming. Added sample usage section. Expanded issues
    section. 

    0.4 - 04/09/01 
    Rewrote to use new entry points.

    0.3 - 04/06/01
    Changed Allocate and Free to New and Delete.

    0.2 - 03/26/01
    Added error description, additions to section 5 and 6 of the spec.

    0.1
    Original version

Number

    247

Dependencies

    This extension is written against the OpenGL 1.2.1 Specification.
    OpenGL 1.1 is required. GL_EXT_vertex_shader affects the
    definition of this extension.


Overview

    This extension defines an interface that allows multiple sets of
    vertex array data to be cached in persistent server-side memory.
    It is intended to allow client data to be stored in memory that
    can be directly accessed by graphics hardware.


Issues

    Should this extension include support for allowing vertex indices
    to be stored on the server?
    
        RESOLUTION: NO. This might not be universally supported, and
        seems simple enough to layer on top of this extension.

    Is there a better name for this extension?

        RESOLUTION: YES. The ArrayStore vs. StoredArray terminology
        was confusing. StoredArrays have been changed to be
        ArrayObjects. Since any type of object could be stored in the
        ArrayStore, these have been changed to ObjectBuffers.

    Should the layout of an array store be defined at array store
    creation time?

        RESOLUTION: NO. This could provide better performance if the
        client specifies a data type that the hardware doesn't
        support, but this isn't a performance path anyways, and it
        adds a cumbersome interface on top of the extension.

    Should the client be able to retrieve a pointer to the array store
    instead of a handle?

        RESOLUTION: NO. For now, it doesn't seem like this is a big
        win, and it presents problems on certain OS's. It also
        requires using an explicit synchronization mechanism. This
        would be pretty trivial to add, however.

    Should this just sit on top of the existing vertex array
    implementation, instead of introducing a new set of API calls?

        RESOLUTION: NO. Trying to fit something on top existing vertex
        arrays introduces a lot of confusion as to where the data is
        stored (on the client side vs. on the server side). Adding new
        API that mirrors traditional vertex arrays doesn't seem to
        cumbersome.


New Procedures and Functions

  For creating, updating, and querying object buffers:

    uint NewObjectBufferATI(sizei size, const void *pointer, enum usage)

    boolean IsObjectBufferATI(uint buffer)

    void UpdateObjectBufferATI(uint buffer, uint offset, sizei size, 
                               const void *pointer, enum preserve)

    void GetObjectBufferfvATI(uint buffer, enum pname, float *params)

    void GetObjectBufferivATI(uint buffer, enum pname, int *params)

    void FreeObjectBufferATI(uint buffer)


  For defining vertex arrays inside an object buffer:

    void ArrayObjectATI(enum array, int size, enum type, 
                        sizei stride, uint buffer, uint offset)

  For querying vertex arrays inside an object buffer:

    void GetArrayObjectfvATI(enum array, enum pname, float *params)

    void GetArrayObjectivATI(enum array, enum pname, int *params)

  If EXT_vertex_shader is defined, for defining variant arrays inside
  an object buffer:

    void VariantArrayObjectATI(uint id, enum type, sizei stride,
			       uint buffer, uint offset)

  If EXT_vertex_shader is defined, for querying variant arrays inside
  an object buffer:

    void GetVariantArrayObjectfvATI(uint id, enum pname, 
                                    float *params)

    void GetVariantArrayObjectivATI(uint id, enum pname,
				    int *params)


New Tokens

    Accepted by the <usage> parameter of NewObjectBufferATI:

        STATIC_ATI                      0x8760
        DYNAMIC_ATI                     0x8761

    Accepted by the <preserve> parameter of UpdateObjectBufferATI:

        PRESERVE_ATI                    0x8762
        DISCARD_ATI                     0x8763

    Accepted by the <pname> parameter of GetObjectBufferivATI and
    GetObjectBufferfvATI: 

        OBJECT_BUFFER_SIZE_ATI          0x8764
        OBJECT_BUFFER_USAGE_ATI         0x8765

    Accepted by the <pname> parameter of GetArrayObjectivATI and
    GetArrayObjectfvATI: 

        ARRAY_OBJECT_BUFFER_ATI         0x8766
        ARRAY_OBJECT_OFFSET_ATI         0x8767


Additions to Chapter 2 of the GL Specification (OpenGL Operation)

    In section 2.6.3, GL Commands within Begin/End, add ArrayObjectATI
    to the list of commands that are not allowed within any Begin/End
    pair, but may or may not generate an error. If EXT_vertex_shader
    is defined, add VariantArrayObjectATI to the list of commands that
    are not allowed within any Begin/End pair, but may or may not
    generate an error.


    Inserted between section 2.8, Vertex Arrays, and section 2.9,
    Rectangles, a new section titled Vertex Array Objects.

    In order to provide more a more efficient mechanism for storing
    frequently used vertex array data on the server side, a client may
    use the command

        uint NewObjectBufferATI(sizei size, const void *pointer, 
                                enum usage);

    to allocate a persistent buffer in which client data may be
    stored. <size> specifies the size of the allocation in machine
    units (hereafter assumed to be unsigned bytes). <pointer>
    specifies a region of client memory that contains data to
    initialize the object buffer. If <pointer> is null, then the
    object buffer is created but not initialized.

    <usage> provides a hint to the implementation of whether the
    contents of the object buffer will be static or dynamic. <usage>
    must be either STATIC_ATI or DYNAMIC_ATI. If the client specifies
    an object buffer as static, its contents may still be updated,
    however this may result in reduced performance.

    The return value is a positive integer that uniquely identifies
    the object buffer. If the object buffer cannot be allocated, the
    return value is zero.

    When the client creates an object buffer using NewObjectBufferATI,
    the implementation can provide more efficient transfers of data
    between the client and the graphics controller by allocating the
    object buffer in memory that can be directly addressed by the
    graphics controller. In addition, because the object buffer is
    persistent across multiple drawing commands, static data must only
    be copied to the object buffer once.

    To modify the data contained in the object buffer, the client may
    use the command

        void UpdateObjectBufferATI(uint buffer, uint offset, 
                                   sizei size, const void *pointer, 
                                   enum preserve);

    <buffer> identifies the object buffer to be updated. <offset> and
    <size> indicate the range of data in the object buffer that is to
    be updated. <pointer> specifies a region of client memory that
    contains data to update the object buffer.

    The client can use the <preserve> parameter of
    UpdateObjectBufferATI to indicate whether data outside the region
    being updated must be preserved. <preserve> must be one of
    PRESERVE_ATI or DISCARD_ATI. If a client specifies that data
    outside the range being updated may be discarded, the
    implementation may be able process updates in a more optimal
    fashion.

    Whenever UpdateObjectBufferATI is called, the byte values in the
    object buffer from <offset> to <offset> + <size> - 1 are updated
    with the data referenced by <pointer>. If the client specifies
    PRESERVE_ATI, all other byte values in the object buffer remain
    unchanged. If the client specifies DISCARD_ATI, then all byte
    values outside the range that has been updated become undefined.

    Once created, an object buffer remains available for use until it
    is destroyed by calling

        void FreeObjectBufferATI(uint buffer);

    <buffer> identifies the object buffer to be destroyed.

    After creating an object buffer, the client can use the command

        void ArrayObjectATI(enum array, int size, enum type,
                            sizei stride, uint buffer, uint offset);

    to allow a portion of the object buffer to be used as a vertex
    array. <array> specifies the array to be defined. This must match
    one of the allowable enumerants accepted by EnableClientState and
    DisableClientState. <size>, <type>, and <stride> specify the
    format and packing of the data stored in the array in the same
    manner as the corresponding vertex array pointer command. <size>
    and <type> must match the allowed sizes and types given for the
    corresponding commands in table 2.4.

    <buffer> specifies the object buffer that contains the data to be
    used as a vertex array. <offset> specifies the offset in machine
    units into the object buffer at which the vertex array data
    begins. When a vertex array is specified in this manner, the
    memory pointer that is part of the client state for the vertex
    array is set to null to indicate that the vertex array has been
    defined using ArrayObjectATI instead of one of the pointer
    commands. 

    Vertex arrays that are defined to reside within an object buffer
    function in the same manner as normal vertex arrays. They are
    enabled and disabled by using the commands EnableClientState and
    DisableClientState. Primitives can be constructed using
    ArrayElement, DrawArrays, DrawElements, and DrawRangeElements.
    Clients may use mix of traditional vertex arrays and vertex array
    objects to specify geometry. 

    There is no explicit mechanism to define interleaved vertex arrays
    in an object buffer. This can be implicitly done by storing the
    arrays in an interleaved fashion during NewObjectBufferATI or
    UpdateObjectBufferATI. 

    If EXT_vertex_shader is defined, then a client can define an array
    of variant data using the command:

	void VariantArrayObjectATI(uint id, enum type, sizei stride,
				   uint buffer, uint offset);

    <id> indicates the variant that this array should be associated
    with.  The <type>, <stride>, <buffer>, and <offset> parameters
    have the same meaning as the corresponding parameters of
    ArrayObjectATI. As always, variant arrays have a fixed size of 4
    components.

    Variant arrays defined by VariantArrayObjectATI are enabled and
    disabled in the same way as variant arrays defined by
    VariantPointerATI, by using EnableVariantClientStateATI and
    DisableVariantClientStateATI. 


Additions to Chapter 3 of the 1.2.1 Specification (Rasterization)

    None


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

    None


Additions to Chapter 5 of the 1.2.1 Specification (Special Functions)

    Added to section 5.4, as part of the discussion of what commands
    are compiled into display lists:

    The commands defined by this extension function in the same manner
    as the traditional vertex array commands when they are compiled
    into a display list.
    
    Commands that are used to create and manage memory for stored
    arrays are not included in display lists, but are executed
    immediately. These include NewObjectBufferATI, IsObjectBufferATI,
    UpdateObjectBufferATI, GetObjectBufferfvATI, GetObjectBufferivATI,
    and FreeObjectBufferATI.

    Commands that are used to define and query vertex arrays within an
    object buffer are not included in display lists, but are executed
    immediately. These include ArrayObjectATI, GetArrayObjectfvATI,
    and GetArrayObjectivATI.


Additions to Chapter 6 of the 1.2.1 Specification (State and State
Requests)

    Added to section 6.1 in a subsection titled Object Buffer Queries:

    The command

        boolean IsObjectBufferATI(uint buffer)

    returns TRUE if <buffer> is the name of an object buffer. If
    <buffer> is zero, or if <buffer> is a non-zero value that is not
    the name of an object buffer, IsObjectBufferATI return FALSE.

    Added to the list of queries in section 6.1.3, Enumerated Queries:

        void GetObjectBuffer{if}vATI(uint buffer, enum value, T data);
        void GetArrayObject{if}vATI(enum array, enum value, T data);

      If EXT_vertex_shader is defined:

        void GetVariantArrayObject{if}vATI(uint id, enum value, T data);

    Appended to the description of the queries in section 6.1.3,
    Enumerated Queries:

    GetObjectBuffer is used to retrieve information about an object
    buffer. <buffer> must identify a valid object buffer. <value> must
    be one of OBJECT_BUFFER_SIZE_ATI or OBJECT_BUFFER_USAGE_ATI.

    If <value> is OBJECT_BUFFER_SIZE_ATI, then the size of the object
    buffer in bytes is returned in <data>. The exact size of the
    object buffer is an implementation dependent value, but is
    guaranteed to be at least as large as the value specified by the
    <size> parameter of NewObjectBufferATI. If <value> is
    OBJECT_BUFFER_USAGE_ATI, then the value returned in <data> will be
    either STATIC_ATI or DYNAMIC_ATI. The return value will match the
    value specified by the <usage> parameter of NewObjectBufferATI.

    GetArrayObjectATI is used to retrieve information on a vertex
    array located in an object buffer. <array> indicates the vertex
    array that is to be queried. It must match one of the allowable
    enumerants accepted by EnableClientState and DisableClientState.

    If EXT_vertex_shader is defined, GetVariantArrayObjectATI is used
    to retrieve information on a variant array located in an object
    buffer. <id> indicates the variant that is to be queried.

    For both queries, <value> must be one of ARRAY_OBJECT_BUFFER_ATI,
    or ARRAY_OBJECT_OFFSET_ATI. For each of these enumerants, the
    value returned in <data> represents the object buffer that
    contains the vertex data, or the byte offset from the object
    buffer at which the first vertex starts, respectively. If the
    specified vertex array or variant array has not been defined to
    reside in an object buffer, GetArrayObjectATI will return zero for
    both enumerants.


Errors

    INVALID_ENUM is generated if the <usage> parameter of
    NewObjectBufferATI is not STATIC_ATI or DYNAMIC_ATI.

    OUT_OF_MEMORY may be generated if an object buffer cannot be
    allocated because the <size> argument of NewObjectBufferATI is
    too large.

    INVALID_VALUE is generated if the <buffer> argument of
    UpdateObjectBufferATI, GetObjectBufferfvATI, GetObjectBufferivATI,
    FreeObjectBufferATI, and ArrayObjectATI does not identify a
    valid object buffer.

    INVALID_VALUE is generated if the <offset> and <size> parameters
    of UpdateObjectBufferATI would reference a region of memory
    outside that allocated by the call to NewObjectBufferATI.

    INVALID_ENUM is generated if the <pname> parameter of
    GetObjectBufferfvATI and GetObjectBufferivATI is not
    OBJECT_BUFFER_SIZE_ATI or OBJECT_BUFFER_USAGE_ATI. 

    INVALID_ENUM is generated if the <array> parameter of
    ArrayObjectATI, GetArrayObjectfvATI, and GetArrayObjectivATI does
    not match one of the enumerants allowed by EnableClientState and
    DisableClientState.

    INVALID_VALUE is generated if the <id> parameter of
    VariantArrayObjectATI, GetVariantArrayObjectfvATI, and
    GetVariantArrayObjectivATI does not correspond to a previously
    defined variant.

    INVALID_VALUE is generated if the <size> and <type> parameters of
    ArrayObjectATI do not match the allowable sizes and types given
    for the pointer command corresponding to the <array> parameter.

    INVALID_VALUE is generated if the <offset> parameter of
    ArrayObjectATI is larger than the size of the object buffer as
    specified by NewObjectBufferATI.

    INVALID_ENUM is generated if the <pname> parameter of
    GetArrayObjectfvATI and GetArrayObjectivATI is not 
    ARRAY_OBJECT_BUFFER_ATI or ARRAY_OBJECT_OFFSET_ATI.
    

New State

    In a new table, Object Buffers

    Get Value                   Get Command     Type    Initial Value   Attrib
    ---------                   -----------     ----    -------------   ------
    OBJECT_BUFFER_SIZE_ATI      GetIntegerv     Z+      0               -
    OBJECT_BUFFER_USAGE_ATI     GetIntegerv     Z4      STATIC_ATI      -

    ARRAY_OBJECT_BUFFER_ATI     GetIntegerv     Z+      0               -
    ARRAY_OBJECT_OFFSET_ATI     GetIntegerv     Z+      0               -
        
    
Usage Example

    Here is a simple example that demonstrates usage of the extension.
    The example provides a comparison between traditional vertex
    arrays and vertex array objects. Note that this is not a
    particularly efficient use of vertex array objects, since the
    array object are only used once before being destroyed. Typically
    the client will create many array objects and transfer all of its
    vertex data to the server before beginning any rendering.

    Traditional vertex arrays:

        // Define
        VertexPointer(4, FLOAT, 16, data);
        ColorPointer(4, UNSIGNED_BYTE, 4, data + 256);

        // Enable
        EnableClientState(VERTEX_ARRAY);
        EnableClientState(COLOR_ARRAY);

        // Draw
        DrawArrays(TRIANGLES, 0, 16);

        // Disable
        DisableClientState(VERTEX_ARRAY);
        DisableClientState(COLOR_ARRAY);

    Vertex array objects:

        // Create object buffer
        buffer = NewObjectBufferATI(320, data, STATIC_ATI);

        // Define
        ArrayObjectATI(VERTEX_ARRAY, 4, FLOAT, 16, buffer, 0);
        ArrayObjectATI(COLOR_ARRAY, 4, UNSIGNED_BYTE, 4, buffer, 256);

        // Enable
        EnableClientState(VERTEX_ARRAY);
        EnableClientState(COLOR_ARRAY);

        // Draw
        DrawArrays(TRIANGLES, 0, 16);

        // Disable
        DisableClientState(VERTEX_ARRAY);
        DisableClientState(COLOR_ARRAY);

        // Free object buffer
        FreeObjectBufferATI(buffer);


Implementation Notes

    For maximum hardware performance, all vertex arrays except for
    color and secondary color should always be specified to use float
    as the component type. Color and secondary color arrays may be
    specified to use either float or 4-component unsigned byte as the
    component type.

    Typically, an object buffer will contain all of the vertex
    information associated with a given object in a scene. This can
    include multiple arrays of geometry, color, and texture data. If
    portions of this data are static, and portions are dynamic,
    greater performance can be achieved by placing the dynamic vertex
    data in a separate object buffer and updating the entire object
    buffer at once.

