1Name 2 3 APPLE_vertex_array_range 4 5Name Strings 6 7 GL_APPLE_vertex_array_range 8 9Contact 10 11 Geoff Stahl, Apple Computer (gstahl 'at' apple.com) 12 13Status 14 15 Complete 16 17Version 18 19 $Date: 2009/01/07 22:05:21 $ $Revision: 1.13 $ 20 21Number 22 23 274 24 25Dependencies 26 27 APPLE_fence can affect this extension. 28 29Overview 30 31 This extension is designed to allow very high vertex processing rates which 32 are facilitated both by relieving the CPU of as much processing burden as 33 possible and by allowing graphics hardware to directly access vertex data. 34 Because this extension is implemented as an addition to the vertex array 35 specification provided by OpenGL 1.1, applications can continue to use 36 existing vertex submission logic while taking advantage of vertex array 37 ranges to more efficiently process those arrays. 38 39 The vertex array coherency model provided by OpenGL 1.1 requires that 40 vertex data specified in vertex arrays be transferred from system memory 41 each time Begin, DrawArrays, or DrawElements is called. Further, OpenGL 42 1.1 requires that the transfer of data be completed by the time End, 43 DrawArrays, or DrawElements returns. Both of these requirements are 44 relaxed by the vertex array range extension. Vertex data may be cached 45 by the GL so there is no guarantee that changes to the vertex data will 46 be reflected in following drawing commands unless it is flushed with 47 FlushVertexArrayRangeAPPLE. The reading of vertex data may be deferred 48 by the GL so there is no guarantee that the GL will be finished reading 49 the data until completion is forced by the use of Finish or the APPLE_fence 50 extension. 51 52 Vertex array range can be enabled in two ways. EnableClientState can be 53 used with the VERTEX_ARRAY_RANGE_APPLE param to enable vertex array range 54 for the client context. One can also simply set the vertex array storage 55 hint to either STORAGE_CACHED_APPLE or STORAGE_SHARED_APPLE (as discussed 56 below) to enable a particular vertex array range. Once this is done, use of 57 vertex array range requires the definition of a specific memory range for 58 vertex data through VertexArrayRangeAPPLE. It is recommended this data be 59 page aligned (4096 byte boundaries) and a multiple of page size in length 60 for maximum efficiency in data handling and internal flushing, but this is 61 not a requirement and any location and length of data can be defined as a 62 vertex array. This extension provides no memory allocators as any 63 convenient memory allocator can be used. 64 65 Once a data set is established, using VertexArrayRangeAPPLE, it can be can 66 be drawn using standard OpenGL vertex array commands, as one would do 67 without this extension. Note, if any the data for any enabled array for a 68 given array element index falls outside of the vertex array range, an 69 undefined vertex is generated. One should also understand removing or 70 replacing all calls to vertex array range functions with no-ops or disabling 71 the vertex array range by disabling the VERTEX_ARRAY_RANGE_APPLE client 72 state should not change the results of an application's OpenGL drawing. 73 74 For static data no additional coherency nor synchronization must be done and 75 the client is free to draw with the specified draw as it sees fit. 76 77 If data is dynamic, thus to be modified, FlushVertexArrayRangeAPPLE should 78 be used. The command is issued when data has been modified since the last 79 call to VertexArrayRangeAPPLE or FlushVertexArrayRangeAPPLE and prior to 80 drawing with such data. FlushVertexArrayRangeAPPLE only provides memory 81 coherency prior to drawing (such as ensuring CPU caches are flushed or VRAM 82 cached copies are updated) and does not provide any synchronization with 83 previously issued drawing commands. The range flushed can be the specific 84 range modified and does not have to be the entire vertex array range. 85 Additionally, data maybe read immediately after a flush without need for 86 further synchronization, thus overlapping areas of data maybe read, modified 87 and written between two successive flushes and the data will be 88 consistent. 89 90 To synchronize data modification after drawing two methods can be used. A 91 Finish command can be issued which will not return until all previously 92 issued commands are complete, forcing completely synchronous operation. 93 While this guarantees all drawing is complete it may not be the optimal 94 solution for clients which just need to ensure drawing with the vertex array 95 range or a specific range with the array is compete. The APPLE_fence 96 extension can be used when dynamic data modifications need to be 97 synchronized with drawing commands. Specifically, if data is to be modified, 98 a fence can be set immediately after drawing with the data. Once it comes 99 time to modify the data, the application must test (or finish) this fence to 100 ensure the drawing command has completed. Failure to do this could result in 101 new data being used by the previously issued drawing commands. It should be 102 noted that providing the maximum time between the drawing set fence and the 103 modification test/finish fence allows the most asynchronous behavior and 104 will result in the least stalling waiting for drawing completion. Techniques 105 such as double buffering vertex data can be used to help further prevent 106 stalls based on fence completion but are beyond the scope of this extension. 107 108 Once an application is finished with a specific vertex array range or at 109 latest prior to exit, and prior to freeing the memory associated with this 110 vertex array, the client should call VertexArrayRangeAPPLE with a data 111 location and length of 0 to allow the internal memory managers to complete 112 any commitments for the array range. In this case once 113 VertexArrayRangeAPPLE returns it is safe to de-allocate the memory. 114 115 Three types of storage hints are available for vertex array ranges; client, 116 shared, and cached. These hints are set by passing the 117 STORAGE_CLIENT_APPLE, STORAGE_SHARED_APPLE, or STORAGE_CACHED_APPLE param to 118 VertexArrayParameteriAPPLE with VERTEX_ARRAY_STORAGE_HINT_APPLE pname. 119 Client storage, the default OpenGL behavior, occurs when 120 VERTEX_ARRAY_RANGE_APPLE is disabled AND the STORAGE_CLIENT_APPLE hint is 121 set. Note, STORAGE_CLIENT_APPLE is also the default hint setting. Shared 122 memory usage is normally used for dynamic data that is expected to be 123 modified and is likely mapped to AGP memory space for access by both the 124 graphics hardware and client. It is set when either 125 VERTEX_ARRAY_RANGE_APPLE is enabled, without the STORAGE_CACHED_APPLE hint 126 being set, or in all cases when the STORAGE_SHARED_APPLE hint is set. 127 Finally, the cached storage is designed to support static data and data which 128 could be cached in VRAM. This provides maximum access bandwidth for the 129 vertex array and occurs when the STORAGE_CACHED_APPLE hint is set. 130 131 The following pseudo-code represents the treatment of a vertex array range 132 memory depending on the hint setting and whether vertex array range is 133 enabled for the client context: 134 135 if (VERTEX_ARRAY_STORAGE_HINT_APPLE == STORAGE_CACHED_APPLE) 136 vertex array is treated as cached 137 else if (VERTEX_ARRAY_STORAGE_HINT_APPLE == STORAGE_SHARED_APPLE) 138 vertex array is treated as shared 139 else if (VERTEX_ARRAY_RANGE_APPLE enabled) 140 vertex array is treated as shared 141 else 142 vertex array is treated as client 143 144 Note, these hints can affect how array flushes are handled and the overhead 145 associated with flushing the array, it is recommended that data be handled 146 as shared unless it really is static and there are no plans to modify it. 147 148 To summarize the vertex array range extension provides relaxed 149 synchronization rules for handling vertex array data allowing high bandwidth 150 asynchronous data transfer from client memory to graphics hardware. 151 Different flushing and synchronization rules are required to ensure data 152 coherency when modifying data. Lastly, memory handling hints are provided 153 to allow the tunning of memory storage and access for maximum efficiency. 154 155Issues 156 157 How does one get the current VERTEX_ARRAY_STORAGE_HINT_APPLE (storage hint) 158 for a vertex array range? 159 160 RESOLUTION: The current VERTEX_ARRAY_STORAGE_HINT_APPLE can be retrieved 161 via GetIntegerv with VERTEX_ARRAY_STORAGE_HINT_APPLE as the pname. 162 163 How does this extension interact with the compiled_vertex_array extension? 164 165 RESOLUTION: They are independent and not interfere with each other. In 166 practice, if you use APPLE_vertex_array_range, you can surpass the 167 performance of compiled_vertex_array 168 169 Should we give a programmer a sense of how big a vertex array range they can 170 specify? 171 172 RESOLUTION: Not completely resolved. There should be a query for 173 determining the maximum safe size of a vertex array range which, we do 174 not have as of yet. Currently, the vertex array range size plus the 175 command buffers must not exceed available GART space, which in real world 176 terms, means the smallest maximum vertex array range size is about 24 MB 177 on any currently supported hardware on Mac OS X and get's larger normally 178 with more RAM and/or more advanced graphics hardware. Failure modes are 179 likely either failure to speed up the vertex processing or failure to 180 draw all the vertex data. So clients should plan on single vertex array 181 ranges of less than 24 MB if they intend to run on all Mac OS X hardware. 182 183 Should Flush be the same as FlushVertexArrayRangeAPPLE? 184 185 RESOLUTION: No. A Flush is a different concept than 186 FlushVertexArrayRangeAPPLE. a Flush submits pending OpenGL commands to the 187 OpenGL engine for processing while, a FlushVertexArrayRangeAPPLE just ensures 188 memory coherency for the vertex array range and does not perform a Flush 189 in OpenGL terms. 190 191New Procedures and Functions 192 193 void VertexArrayRangeAPPLE(sizei length, void *pointer); 194 void FlushVertexArrayRangeAPPLE(sizei length, void *pointer); 195 void VertexArrayParameteriAPPLE(enum pname, int param); 196 197New Tokens 198 199 Accepted by the <cap> parameter of EnableClientState, DisableClientState, 200 and IsEnabled: 201 202 VERTEX_ARRAY_RANGE_APPLE 0x851D 203 204 Accepted by the <pname> parameter of GetBooleanv, GetIntegerv, GetFloatv, 205 and GetDoublev: 206 207 VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E 208 MAX_VERTEX_ARRAY_RANGE_ELEMENT_APPLE 0x8520 209 210 Accepted by the <pname> parameter of GetPointerv: 211 212 VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521 213 214 Accepted by the <pname> parameter of VertexArrayParameteriAPPLE, 215 GetBooleanv, GetIntegerv, GetFloatv, and GetDoublev: 216 217 VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F 218 219 Accepted by the <param> parameter of VertexArrayParameteriAPPLE: 220 221 STORAGE_CLIENT_APPLE 0x85B4 222 STORAGE_CACHED_APPLE 0x85BE 223 STORAGE_SHARED_APPLE 0x85BF 224 225Additions to Chapter 2 of the OpenGL 1.1 Specification (OpenGL Operation) 226 227 After the discussion of vertex arrays (Section 2.8) add a 228 description of the vertex array range: 229 230 "The command 231 232 void VertexArrayRangeAPPLE(sizei length, void *pointer) 233 234 specifies the current vertex array range. When the vertex array range is 235 specified and valid, vertex transfers from within the vertex array 236 range are potentially faster. The vertex array range is a contiguous 237 region of address space for placing vertex arrays. The "pointer" parameter 238 is a pointer to the base of the vertex array range. The "length" pointer is 239 the length of the vertex array range in basic machine units (typically 240 unsigned bytes). Memory associated with a vertex array range should be 241 allocated by the client and the responsibility for maintaining it rests with 242 the client as long as it is being used as a vertex array range. 243 244 The vertex array range address space region extends from "pointer" to 245 "pointer + length - 1" inclusive. When specified, vertex array vertex 246 transfers from within the vertex array range are potentially faster. 247 248 There is some system burden associated with establishing a vertex array 249 range (typically, the memory range must be locked down). If either the 250 vertex array range pointer or size is set to zero, the previously 251 established vertex array range is released (typically, unlocking the 252 memory). This should always be done prior to freeing of the memory by the 253 client. 254 255 The vertex array range may not be established for operating system dependent 256 reasons, and therefore, not valid. Reasons that a vertex array range cannot 257 be established include exceeding the maximum vertex array range size, the 258 memory could not be locked down, etc. 259 260 The vertex array range is considered enabled after VERTEX_ARRAY_RANGE_APPLE 261 client state is enabled and as soon as a valid vertex array range is 262 specified and disabled once the size length and/or pointer is set to zero or 263 VERTEX_ARRAY_RANGE_APPLE client state is disabled. 264 265 When the vertex array range is enabled, ArrayElement commands may generate 266 undefined vertices if and only if any indexed elements of the enabled arrays 267 are not within the vertex array range or if the index is negative or greater 268 or equal to the implementation-dependent value of 269 MAX_VERTEX_ARRAY_RANGE_ELEMENT_APPLE. If an undefined vertex is generated, 270 an INVALID_OPERATION error may or may not be generated. 271 272 The vertex array coherency model specifies when vertex data must be extracted 273 from the vertex array memory. When the vertex array range is not valid, 274 (quoting the specification) `Changes made to array data between the 275 execution of Begin and the corresponding execution of End may effect calls 276 to ArrayElement that are made within the same Begin/End period in 277 non-sequential ways. That is, a call to ArrayElement that precedes a change 278 to array data may access the changed data, and a call that follows a change 279 to array data may access the original data.' 280 281 When the vertex array range is valid, the vertex array coherency model is 282 relaxed so that changes made to array data may affect calls to ArrayElement 283 in non-sequential ways. That is a call to ArrayElement that precedes a 284 change to array data may access the changed data, and a call that follows a 285 change to array data may access original data. This requires in two points 286 of synchronization to maintain coherency. 287 288 The first point where synchronization must occur to maintain coherency is 289 post data modification, prior to drawing. FlushVertexArrayRangeAPPLE should 290 be used by the client on all ranges of memory which have been modified since 291 the last call to VertexArrayRangeAPPLE or FlushVertexArrayRangeAPPLE. 292 293 The second point of synchronization is after drawing with a vertex array 294 range and prior to modifying it's data. In this case either Finish or a 295 fence must be used. Finish will create a synchronization point for all 296 drawing an may not be the optimal method to ensure drawing completion prior 297 to data modification. A fence, defined in the APPLE_fence extension, on the 298 other hand allows more selective synchronization. The client can set a fence 299 immediately after drawing with the data in question and test or finish that 300 fence prior to modifying the data. See the APPLE_fence extension for more 301 details. 302 303 To maintain full coherency, once a vertex array range is enabled, requires 304 the client to both flush the vertex array after data modification, prior to 305 drawing, and synchronize with Finish or a fence after drawing, prior to 306 modifying the data. 307 308 The command 309 310 void VertexArrayParameteriAPPLE(enum pname, int param) 311 312 allows the client to hint at the expected use of the vertex array range. 313 pname must be VERTEX_ARRAY_STORAGE_HINT_APPLE. param can either be 314 STORAGE_CACHED_APPLE or STORAGE_SHARED_APPLE and can be used by the system 315 to tune the handling of the vertex array range data. These 316 parameters are just hints and require no specific handling by the system. 317 The default state is STORAGE_SHARED_APPLE which, indicates that the vertex 318 data is expected to be dynamic and should be handled in a way to optimize 319 modification and flushing of the vertex array range, if possible. 320 STORAGE_CACHED_APPLE indicates the data is expected to static and techniques 321 such as VRAM caching could be employed to optimize memory bandwidth to the 322 vertex array range. Proper use of FlushVertexArrayRangeAPPLE guarantees 323 memory coherency in all cases and will result in deterministic defined 324 behavior in all cases, whether hints are employed or not. 325 326 The client state required to implement the vertex array range consists of an 327 enable bit, a memory pointer, an integer size, and a valid bit." 328 329Additions to Chapter 5 of the OpenGL 1.1 Specification (Special Functions) 330 331 Add to the end of Section 5.4 "Display Lists" 332 333 "VertexArrayRangeAPPLE and FlushVertexArrayRangeAPPLE are not complied into 334 display lists but are executed immediately. 335 336 If a display list is compiled while VERTEX_ARRAY_RANGE_APPLE is enabled, the 337 commands ArrayElement, DrawArrays, DrawElements, and DrawRangeElements are 338 accumulated into a display list as if VERTEX_ARRAY_RANGE_APPLE is disabled." 339 340Additions to the CGL interface: 341 342 None 343 344Additions to the WGL interface: 345 346 None 347 348Additions to the GLX Specification 349 350 None 351 352GLX Protocol 353 354 None 355 356Errors 357 358 INVALID_OPERATION is generated if VertexArrayRangeAPPLE or 359 FlushVertexArrayRangeAPPLE is called between the execution of Begin and the 360 corresponding execution of End. 361 362 INVALID_OPERATION may be generated if an undefined vertex is generated. 363 364New State 365 366 Initial 367 Get Value Get Command Type Value Attrib 368 --------- ----------- ---- ------- ------------ 369 VERTEX_ARRAY_RANGE_APPLE IsEnabled B False vertex-array 370 VERTEX_ARRAY_RANGE_POINTER_APPLE GetPointerv Z+ 0 vertex-array 371 VERTEX_ARRAY_RANGE_LENGTH_APPLE GetIntegerv Z+ 0 vertex-array 372 VERTEX_ARRAY_STORAGE_HINT_APPLE GetIntegerv Z3 STORAGE_CLIENT_APPLE vertex-array 373 374New Implementation Dependent State 375 376 Get Value Get Command Type Minimum Value 377 --------- ----------- ----- ------------- 378 MAX_VERTEX_ARRAY_RANGE_ELEMENT_APPLE GetIntegerv Z+ 65535 379 380Revision History 381 382 None 383