| Name | 
 |  | 
 |     APPLE_vertex_array_range | 
 |  | 
 | Name Strings | 
 |  | 
 |     GL_APPLE_vertex_array_range | 
 |  | 
 | Contact | 
 |  | 
 |     Geoff Stahl, Apple Computer (gstahl 'at' apple.com) | 
 |  | 
 | Status | 
 |  | 
 |     Complete | 
 |  | 
 | Version | 
 |  | 
 |     $Date: 2009/01/07 22:05:21 $ $Revision: 1.13 $ | 
 |  | 
 | Number | 
 |  | 
 |     274 | 
 |  | 
 | Dependencies | 
 |  | 
 |     APPLE_fence can affect this extension. | 
 |  | 
 | Overview | 
 |  | 
 |     This extension is designed to allow very high vertex processing rates which | 
 |     are facilitated both by relieving the CPU of as much processing burden as | 
 |     possible and by allowing graphics hardware to directly access vertex data. | 
 |     Because this extension is implemented as an addition to the vertex array | 
 |     specification provided by OpenGL 1.1, applications can continue to use | 
 |     existing vertex submission logic while taking advantage of vertex array | 
 |     ranges to more efficiently process those arrays. | 
 |  | 
 |     The vertex array coherency model provided by OpenGL 1.1 requires that | 
 |     vertex data specified in vertex arrays be transferred from system memory | 
 |     each time Begin, DrawArrays, or DrawElements is called.  Further, OpenGL | 
 |     1.1 requires that the transfer of data be completed by the time End, | 
 |     DrawArrays, or DrawElements returns.  Both of these requirements are | 
 |     relaxed by the vertex array range extension.  Vertex data may be cached | 
 |     by the GL so there is no guarantee that changes to the vertex data will | 
 |     be reflected in following drawing commands unless it is flushed with | 
 |     FlushVertexArrayRangeAPPLE.  The reading of vertex data may be deferred  | 
 |     by the GL so there is no guarantee that the GL will be finished reading | 
 |     the data until completion is forced by the use of Finish or the APPLE_fence | 
 |     extension. | 
 |  | 
 |     Vertex array range can be enabled in two ways.  EnableClientState can be | 
 |     used with the VERTEX_ARRAY_RANGE_APPLE param to enable vertex array range | 
 |     for the client context.  One can also simply set the vertex array storage | 
 |     hint to either STORAGE_CACHED_APPLE or STORAGE_SHARED_APPLE (as discussed | 
 |     below) to enable a particular vertex array range.  Once this is done, use of | 
 |     vertex array range requires the definition of a specific memory range for | 
 |     vertex data through VertexArrayRangeAPPLE.  It is recommended this data be | 
 |     page aligned (4096 byte boundaries) and a multiple of page size in length | 
 |     for maximum efficiency in data handling and internal flushing, but this is | 
 |     not a requirement and any location and length of data can be defined as a | 
 |     vertex array.  This extension provides no memory allocators as any | 
 |     convenient memory allocator can be used. | 
 |  | 
 |     Once a data set is established, using VertexArrayRangeAPPLE, it can be can | 
 |     be drawn using standard OpenGL vertex array commands, as one would do | 
 |     without this extension.  Note, if any the data for any enabled array for a | 
 |     given array element index falls outside of the vertex array range, an | 
 |     undefined vertex is generated.  One should also understand removing or | 
 |     replacing all calls to vertex array range functions with no-ops or disabling | 
 |     the vertex array range by disabling the VERTEX_ARRAY_RANGE_APPLE client | 
 |     state should not change the results of an application's OpenGL drawing. | 
 |  | 
 |     For static data no additional coherency nor synchronization must be done and | 
 |     the client is free to draw with the specified draw as it sees fit. | 
 |  | 
 |     If data is dynamic, thus to be modified, FlushVertexArrayRangeAPPLE should | 
 |     be used.  The command is issued when data has been modified since the last | 
 |     call to VertexArrayRangeAPPLE or FlushVertexArrayRangeAPPLE and prior to | 
 |     drawing with such data. FlushVertexArrayRangeAPPLE only provides memory | 
 |     coherency prior to drawing (such as ensuring CPU caches are flushed or VRAM | 
 |     cached copies are updated) and does not provide any synchronization with | 
 |     previously issued drawing commands. The range flushed can be the specific | 
 |     range modified and does not have to be the entire vertex array range. | 
 |     Additionally, data maybe read immediately after a flush without need for | 
 |     further synchronization, thus overlapping areas of data maybe read, modified | 
 |     and written between two successive flushes and the data will be | 
 |     consistent. | 
 |  | 
 |     To synchronize data modification after drawing two methods can be used. A | 
 |     Finish command can be issued which will not return until all previously | 
 |     issued commands are complete, forcing completely synchronous operation. | 
 |     While this guarantees all drawing is complete it may not be the optimal | 
 |     solution for clients which just need to ensure drawing with the vertex array | 
 |     range or a specific range with the array is compete.  The APPLE_fence | 
 |     extension can be used when dynamic data modifications need to be | 
 |     synchronized with drawing commands. Specifically, if data is to be modified, | 
 |     a fence can be set immediately after drawing with the data.  Once it comes | 
 |     time to modify the data, the application must test (or finish) this fence to | 
 |     ensure the drawing command has completed. Failure to do this could result in | 
 |     new data being used by the previously issued drawing commands.  It should be | 
 |     noted that providing the maximum time between the drawing set fence and the | 
 |     modification test/finish fence allows the most asynchronous behavior and | 
 |     will result in the least stalling waiting for drawing completion. Techniques | 
 |     such as double buffering vertex data can be used to help further prevent | 
 |     stalls based on fence completion but are beyond the scope of this extension. | 
 |  | 
 |     Once an application is finished with a specific vertex array range or at | 
 |     latest prior to exit, and prior to freeing the memory associated with this | 
 |     vertex array, the client should call VertexArrayRangeAPPLE with a data | 
 |     location and length of 0 to allow the internal memory managers to complete | 
 |     any commitments for the array range.  In this case once | 
 |     VertexArrayRangeAPPLE returns it is safe to de-allocate the memory. | 
 |      | 
 |     Three types of storage hints are available for vertex array ranges; client, | 
 |     shared, and cached.  These hints are set by passing the | 
 |     STORAGE_CLIENT_APPLE, STORAGE_SHARED_APPLE, or STORAGE_CACHED_APPLE param to | 
 |     VertexArrayParameteriAPPLE with VERTEX_ARRAY_STORAGE_HINT_APPLE pname. | 
 |     Client storage, the default OpenGL behavior, occurs when | 
 |     VERTEX_ARRAY_RANGE_APPLE is disabled AND the STORAGE_CLIENT_APPLE hint is | 
 |     set. Note, STORAGE_CLIENT_APPLE is also the default hint setting.  Shared | 
 |     memory usage is normally used for dynamic data that is expected to be | 
 |     modified and is likely mapped to AGP memory space for access by both the | 
 |     graphics hardware and client.  It is set when either | 
 |     VERTEX_ARRAY_RANGE_APPLE is enabled, without the STORAGE_CACHED_APPLE hint | 
 |     being set, or in all cases when the STORAGE_SHARED_APPLE hint is set. | 
 |     Finally, the cached storage is designed to support static data and data which | 
 |     could be cached in VRAM. This provides maximum access bandwidth for the | 
 |     vertex array and occurs when the STORAGE_CACHED_APPLE hint is set.  | 
 |      | 
 |     The following pseudo-code represents the treatment of a vertex array range | 
 |     memory depending on the hint setting and whether vertex array range is | 
 |     enabled for the client context: | 
 | 	 | 
 |     if (VERTEX_ARRAY_STORAGE_HINT_APPLE == STORAGE_CACHED_APPLE) | 
 |         vertex array is treated as cached | 
 |     else if (VERTEX_ARRAY_STORAGE_HINT_APPLE == STORAGE_SHARED_APPLE) | 
 |     	vertex array is treated as shared | 
 |     else if (VERTEX_ARRAY_RANGE_APPLE enabled) | 
 |     	vertex array is treated as shared | 
 |     else  | 
 |     	vertex array is treated as client | 
 |     	 | 
 |     Note, these hints can affect how array flushes are handled and the overhead | 
 |     associated with flushing the array, it is recommended that data be handled | 
 |     as shared unless it really is static and there are no plans to modify it. | 
 | 	 | 
 |     To summarize the vertex array range extension provides relaxed | 
 |     synchronization rules for handling vertex array data allowing high bandwidth | 
 |     asynchronous data transfer from client memory to graphics hardware. | 
 |     Different flushing and synchronization rules are required to ensure data | 
 |     coherency when modifying data.  Lastly, memory handling hints are provided | 
 |     to allow the tunning of memory storage and access for maximum efficiency. | 
 |  | 
 | Issues | 
 |  | 
 | 	How does one get the current VERTEX_ARRAY_STORAGE_HINT_APPLE (storage hint) | 
 | 	for a vertex array range? | 
 | 	 | 
 | 	   RESOLUTION: The current VERTEX_ARRAY_STORAGE_HINT_APPLE can be retrieved | 
 | 	   via GetIntegerv with VERTEX_ARRAY_STORAGE_HINT_APPLE as the pname. | 
 |  | 
 |     How does this extension interact with the compiled_vertex_array extension? | 
 |  | 
 |        RESOLUTION:  They are independent and not interfere with each other.  In | 
 |        practice, if you use APPLE_vertex_array_range, you can surpass the | 
 |        performance of compiled_vertex_array | 
 |  | 
 |     Should we give a programmer a sense of how big a vertex array range they can | 
 |     specify? | 
 |  | 
 |        RESOLUTION:  Not completely resolved.  There should be a query for | 
 |        determining the maximum safe size of a vertex array range which, we do | 
 |        not have as of yet.  Currently, the vertex array range size plus the | 
 |        command buffers must not exceed available GART space, which in real world | 
 |        terms, means the smallest maximum vertex array range size is about 24 MB | 
 |        on any currently supported hardware on Mac OS X and get's larger normally | 
 |        with more RAM and/or more advanced graphics hardware. Failure modes are | 
 |        likely either failure to speed up the vertex processing or failure to | 
 |        draw all the vertex data.  So clients should plan on single vertex array | 
 |        ranges of less than 24 MB if they intend to run on all Mac OS X hardware. | 
 |  | 
 |     Should Flush be the same as FlushVertexArrayRangeAPPLE? | 
 |  | 
 |        RESOLUTION:  No.  A Flush is a different concept than | 
 |        FlushVertexArrayRangeAPPLE.  a Flush submits pending OpenGL commands to the | 
 |        OpenGL engine for processing while, a FlushVertexArrayRangeAPPLE just ensures | 
 |        memory coherency for the vertex array range and does not perform a Flush | 
 |        in OpenGL terms. | 
 |  | 
 | New Procedures and Functions | 
 |  | 
 |     void VertexArrayRangeAPPLE(sizei length, void *pointer); | 
 |     void FlushVertexArrayRangeAPPLE(sizei length, void *pointer); | 
 |     void VertexArrayParameteriAPPLE(enum pname, int param); | 
 |  | 
 | New Tokens | 
 |  | 
 |     Accepted by the <cap> parameter of EnableClientState, DisableClientState, | 
 |     and IsEnabled: | 
 |  | 
 |         VERTEX_ARRAY_RANGE_APPLE              0x851D | 
 |  | 
 |     Accepted by the <pname> parameter of GetBooleanv, GetIntegerv, GetFloatv, | 
 |     and GetDoublev: | 
 |  | 
 |         VERTEX_ARRAY_RANGE_LENGTH_APPLE       0x851E | 
 |         MAX_VERTEX_ARRAY_RANGE_ELEMENT_APPLE  0x8520 | 
 |  | 
 |     Accepted by the <pname> parameter of GetPointerv: | 
 |  | 
 |         VERTEX_ARRAY_RANGE_POINTER_APPLE      0x8521 | 
 |  | 
 |     Accepted by the <pname> parameter of VertexArrayParameteriAPPLE, | 
 | 	GetBooleanv, GetIntegerv, GetFloatv, and GetDoublev: | 
 |  | 
 |         VERTEX_ARRAY_STORAGE_HINT_APPLE       0x851F | 
 |  | 
 |     Accepted by the <param> parameter of VertexArrayParameteriAPPLE: | 
 |  | 
 |         STORAGE_CLIENT_APPLE                  0x85B4 | 
 |         STORAGE_CACHED_APPLE                  0x85BE | 
 |         STORAGE_SHARED_APPLE                  0x85BF | 
 |  | 
 | Additions to Chapter 2 of the OpenGL 1.1 Specification (OpenGL Operation) | 
 |  | 
 |     After the discussion of vertex arrays (Section 2.8) add a | 
 |     description of the vertex array range: | 
 |  | 
 |     "The command  | 
 |  | 
 |        void VertexArrayRangeAPPLE(sizei length, void *pointer) | 
 |  | 
 |     specifies the current vertex array range.  When the vertex array range is | 
 |     specified and valid, vertex transfers from within the vertex array | 
 |     range are potentially faster.  The vertex array range is a contiguous | 
 |     region of address space for placing vertex arrays.  The "pointer" parameter | 
 |     is a pointer to the base of the vertex array range.  The "length" pointer is | 
 |     the length of the vertex array range in basic machine units (typically | 
 |     unsigned bytes).  Memory associated with a vertex array range should be | 
 |     allocated by the client and the responsibility for maintaining it rests with | 
 |     the client as long as it is being used as a vertex array range. | 
 |  | 
 |     The vertex array range address space region extends from "pointer" to | 
 |     "pointer + length - 1" inclusive.  When specified, vertex array vertex | 
 |     transfers from within the vertex array range are potentially faster. | 
 |  | 
 |     There is some system burden associated with establishing a vertex array | 
 |     range (typically, the memory range must be locked down). If either the | 
 |     vertex array range pointer or size is set to zero, the previously | 
 |     established vertex array range is released (typically, unlocking the | 
 |     memory).  This should always be done prior to freeing of the memory by the | 
 |     client. | 
 |  | 
 |     The vertex array range may not be established for operating system dependent | 
 |     reasons, and therefore, not valid.  Reasons that a vertex array range cannot | 
 |     be established include exceeding the maximum vertex array range size, the | 
 |     memory could not be locked down, etc. | 
 |  | 
 |     The vertex array range is considered enabled after VERTEX_ARRAY_RANGE_APPLE | 
 |     client state is enabled and as soon as a valid vertex array range is | 
 |     specified and disabled once the size length and/or pointer is set to zero or | 
 |     VERTEX_ARRAY_RANGE_APPLE client state is disabled. | 
 |  | 
 |     When the vertex array range is enabled, ArrayElement commands may generate | 
 |     undefined vertices if and only if any indexed elements of the enabled arrays | 
 |     are not within the vertex array range or if the index is negative or greater | 
 |     or equal to the implementation-dependent value of | 
 |     MAX_VERTEX_ARRAY_RANGE_ELEMENT_APPLE.  If an undefined vertex is generated, | 
 |     an INVALID_OPERATION error may or may not be generated. | 
 |  | 
 |     The vertex array coherency model specifies when vertex data must be extracted | 
 |     from the vertex array memory.  When the vertex array range is not valid, | 
 |     (quoting the specification) `Changes made to array data between the | 
 |     execution of Begin and the corresponding execution of End may effect calls | 
 |     to ArrayElement that are made within the same Begin/End period in | 
 |     non-sequential ways.  That is, a call to ArrayElement that precedes a change | 
 |     to array data may access the changed data, and a call that follows a change | 
 |     to array data may access the original data.' | 
 |  | 
 |     When the vertex array range is valid, the vertex array coherency model is | 
 |     relaxed so that changes made to array data may affect calls to ArrayElement | 
 |     in non-sequential ways. That is a call to ArrayElement that precedes a | 
 |     change to array data may access the changed data, and a call that follows a | 
 |     change to array data may access original data.  This requires in two points | 
 |     of synchronization to maintain coherency. | 
 |  | 
 |     The first point where synchronization must occur to maintain coherency is | 
 |     post data modification, prior to drawing.  FlushVertexArrayRangeAPPLE should | 
 |     be used by the client on all ranges of memory which have been modified since | 
 |     the last call to VertexArrayRangeAPPLE or FlushVertexArrayRangeAPPLE. | 
 |  | 
 |     The second point of synchronization is after drawing with a vertex array | 
 |     range and prior to modifying it's data.  In this case either Finish or a | 
 |     fence must be used.  Finish will create a synchronization point for all | 
 |     drawing an may not be the optimal method to ensure drawing completion prior | 
 |     to data modification.  A fence, defined in the APPLE_fence extension, on the | 
 |     other hand allows more selective synchronization. The client can set a fence | 
 |     immediately after drawing with the data in question and test or finish that | 
 |     fence prior to modifying the data.  See the APPLE_fence extension for more | 
 |     details. | 
 |  | 
 |     To maintain full coherency, once a vertex array range is enabled, requires | 
 |     the client to both flush the vertex array after data modification, prior to | 
 |     drawing, and synchronize with Finish or a fence after drawing, prior to | 
 |     modifying the data. | 
 |  | 
 |     The command  | 
 |  | 
 |         void VertexArrayParameteriAPPLE(enum pname, int param) | 
 |  | 
 |     allows the client to hint at the expected use of the vertex array range. | 
 |     pname must be VERTEX_ARRAY_STORAGE_HINT_APPLE.  param can either be | 
 |     STORAGE_CACHED_APPLE or STORAGE_SHARED_APPLE and can be used by the system | 
 |     to tune the handling of the vertex array range data. These | 
 |     parameters are just hints and require no specific handling by the system.  | 
 |     The default state is STORAGE_SHARED_APPLE which, indicates that the vertex | 
 |     data is expected to be dynamic and should be handled in a way to optimize | 
 |     modification and flushing of the vertex array range, if possible. | 
 |     STORAGE_CACHED_APPLE indicates the data is expected to static and techniques | 
 |     such as VRAM caching could be employed to optimize memory bandwidth to the | 
 |     vertex array range.  Proper use of FlushVertexArrayRangeAPPLE guarantees | 
 |     memory coherency in all cases and will result in deterministic defined | 
 |     behavior in all cases, whether hints are employed or not. | 
 |  | 
 |     The client state required to implement the vertex array range consists of an | 
 |     enable bit, a memory pointer, an integer size, and a valid bit." | 
 |  | 
 | Additions to Chapter 5 of the OpenGL 1.1 Specification (Special Functions) | 
 |  | 
 |     Add to the end of Section 5.4 "Display Lists" | 
 |  | 
 |     "VertexArrayRangeAPPLE and FlushVertexArrayRangeAPPLE are not complied into | 
 |     display lists but are executed immediately. | 
 |  | 
 |     If a display list is compiled while VERTEX_ARRAY_RANGE_APPLE is enabled, the | 
 |     commands ArrayElement, DrawArrays, DrawElements, and DrawRangeElements are | 
 |     accumulated into a display list as if VERTEX_ARRAY_RANGE_APPLE is disabled." | 
 |  | 
 | Additions to the CGL interface: | 
 |  | 
 |     None | 
 |  | 
 | Additions to the WGL interface: | 
 |  | 
 |     None | 
 |  | 
 | Additions to the GLX Specification | 
 |  | 
 |     None | 
 |  | 
 | GLX Protocol | 
 |  | 
 |     None | 
 |  | 
 | Errors | 
 |  | 
 |     INVALID_OPERATION is generated if VertexArrayRangeAPPLE or | 
 |     FlushVertexArrayRangeAPPLE is called between the execution of Begin and the | 
 |     corresponding execution of End. | 
 |  | 
 |     INVALID_OPERATION may be generated if an undefined vertex is generated. | 
 |  | 
 | New State | 
 |  | 
 |                                                               Initial | 
 |    Get Value                          Get Command     Type    Value                Attrib | 
 |    ---------                          -----------     ----    -------              ------------ | 
 |    VERTEX_ARRAY_RANGE_APPLE           IsEnabled       B       False                vertex-array | 
 |    VERTEX_ARRAY_RANGE_POINTER_APPLE   GetPointerv     Z+      0                    vertex-array | 
 |    VERTEX_ARRAY_RANGE_LENGTH_APPLE    GetIntegerv     Z+      0                    vertex-array | 
 |    VERTEX_ARRAY_STORAGE_HINT_APPLE    GetIntegerv     Z3      STORAGE_CLIENT_APPLE vertex-array | 
 |  | 
 | New Implementation Dependent State | 
 |  | 
 |     Get Value                              Get Command     Type    Minimum Value | 
 |     ---------                              -----------     -----   ------------- | 
 |     MAX_VERTEX_ARRAY_RANGE_ELEMENT_APPLE   GetIntegerv     Z+      65535 | 
 |  | 
 | Revision History | 
 |  | 
 |     None |