1 2Name 3 4 ATI_vertex_array_object 5 6 7Name Strings 8 9 GL_ATI_vertex_array_object 10 11 12Contact 13 14 Rick Hammerstone, AMD (rick.hammerstone 'at' amd.com) 15 16 17Version 18 19 1.11 - 11/04/06 20 Updated contact info after ATI/AMD merger. 21 22 1.1 - 01/08/02 23 Changed DeleteObjectBufferATI to FreeObjectBufferATI to match the 24 glati.h header file. Removed objbuf attribute. 25 26 1.01 - 09/18/01 27 Added clarification that ArrayObectATI and VariantArrayObjectATI 28 are not allowed between Begin/End but may not return an error. 29 30 1.0 - 09/06/01 31 Changed references to ATI_vertex_shader to EXT_vertex_shader. 32 33 0.9 - 08/15/01 34 Added support for variant arrays. 35 36 0.8 - 07/06/01 37 Added table of new state. 38 39 0.7 - 07/02/01 40 Added official enumerants. 41 42 0.6 - 05/07/01 43 Chopped out most of the new entry points. Back to just object 44 buffers and one call to define vertex arrays in an object buffer. 45 46 0.5 - 04/18/01 47 The great renaming. Added sample usage section. Expanded issues 48 section. 49 50 0.4 - 04/09/01 51 Rewrote to use new entry points. 52 53 0.3 - 04/06/01 54 Changed Allocate and Free to New and Delete. 55 56 0.2 - 03/26/01 57 Added error description, additions to section 5 and 6 of the spec. 58 59 0.1 60 Original version 61 62Number 63 64 247 65 66Dependencies 67 68 This extension is written against the OpenGL 1.2.1 Specification. 69 OpenGL 1.1 is required. GL_EXT_vertex_shader affects the 70 definition of this extension. 71 72 73Overview 74 75 This extension defines an interface that allows multiple sets of 76 vertex array data to be cached in persistent server-side memory. 77 It is intended to allow client data to be stored in memory that 78 can be directly accessed by graphics hardware. 79 80 81Issues 82 83 Should this extension include support for allowing vertex indices 84 to be stored on the server? 85 86 RESOLUTION: NO. This might not be universally supported, and 87 seems simple enough to layer on top of this extension. 88 89 Is there a better name for this extension? 90 91 RESOLUTION: YES. The ArrayStore vs. StoredArray terminology 92 was confusing. StoredArrays have been changed to be 93 ArrayObjects. Since any type of object could be stored in the 94 ArrayStore, these have been changed to ObjectBuffers. 95 96 Should the layout of an array store be defined at array store 97 creation time? 98 99 RESOLUTION: NO. This could provide better performance if the 100 client specifies a data type that the hardware doesn't 101 support, but this isn't a performance path anyways, and it 102 adds a cumbersome interface on top of the extension. 103 104 Should the client be able to retrieve a pointer to the array store 105 instead of a handle? 106 107 RESOLUTION: NO. For now, it doesn't seem like this is a big 108 win, and it presents problems on certain OS's. It also 109 requires using an explicit synchronization mechanism. This 110 would be pretty trivial to add, however. 111 112 Should this just sit on top of the existing vertex array 113 implementation, instead of introducing a new set of API calls? 114 115 RESOLUTION: NO. Trying to fit something on top existing vertex 116 arrays introduces a lot of confusion as to where the data is 117 stored (on the client side vs. on the server side). Adding new 118 API that mirrors traditional vertex arrays doesn't seem to 119 cumbersome. 120 121 122New Procedures and Functions 123 124 For creating, updating, and querying object buffers: 125 126 uint NewObjectBufferATI(sizei size, const void *pointer, enum usage) 127 128 boolean IsObjectBufferATI(uint buffer) 129 130 void UpdateObjectBufferATI(uint buffer, uint offset, sizei size, 131 const void *pointer, enum preserve) 132 133 void GetObjectBufferfvATI(uint buffer, enum pname, float *params) 134 135 void GetObjectBufferivATI(uint buffer, enum pname, int *params) 136 137 void FreeObjectBufferATI(uint buffer) 138 139 140 For defining vertex arrays inside an object buffer: 141 142 void ArrayObjectATI(enum array, int size, enum type, 143 sizei stride, uint buffer, uint offset) 144 145 For querying vertex arrays inside an object buffer: 146 147 void GetArrayObjectfvATI(enum array, enum pname, float *params) 148 149 void GetArrayObjectivATI(enum array, enum pname, int *params) 150 151 If EXT_vertex_shader is defined, for defining variant arrays inside 152 an object buffer: 153 154 void VariantArrayObjectATI(uint id, enum type, sizei stride, 155 uint buffer, uint offset) 156 157 If EXT_vertex_shader is defined, for querying variant arrays inside 158 an object buffer: 159 160 void GetVariantArrayObjectfvATI(uint id, enum pname, 161 float *params) 162 163 void GetVariantArrayObjectivATI(uint id, enum pname, 164 int *params) 165 166 167New Tokens 168 169 Accepted by the <usage> parameter of NewObjectBufferATI: 170 171 STATIC_ATI 0x8760 172 DYNAMIC_ATI 0x8761 173 174 Accepted by the <preserve> parameter of UpdateObjectBufferATI: 175 176 PRESERVE_ATI 0x8762 177 DISCARD_ATI 0x8763 178 179 Accepted by the <pname> parameter of GetObjectBufferivATI and 180 GetObjectBufferfvATI: 181 182 OBJECT_BUFFER_SIZE_ATI 0x8764 183 OBJECT_BUFFER_USAGE_ATI 0x8765 184 185 Accepted by the <pname> parameter of GetArrayObjectivATI and 186 GetArrayObjectfvATI: 187 188 ARRAY_OBJECT_BUFFER_ATI 0x8766 189 ARRAY_OBJECT_OFFSET_ATI 0x8767 190 191 192Additions to Chapter 2 of the GL Specification (OpenGL Operation) 193 194 In section 2.6.3, GL Commands within Begin/End, add ArrayObjectATI 195 to the list of commands that are not allowed within any Begin/End 196 pair, but may or may not generate an error. If EXT_vertex_shader 197 is defined, add VariantArrayObjectATI to the list of commands that 198 are not allowed within any Begin/End pair, but may or may not 199 generate an error. 200 201 202 Inserted between section 2.8, Vertex Arrays, and section 2.9, 203 Rectangles, a new section titled Vertex Array Objects. 204 205 In order to provide more a more efficient mechanism for storing 206 frequently used vertex array data on the server side, a client may 207 use the command 208 209 uint NewObjectBufferATI(sizei size, const void *pointer, 210 enum usage); 211 212 to allocate a persistent buffer in which client data may be 213 stored. <size> specifies the size of the allocation in machine 214 units (hereafter assumed to be unsigned bytes). <pointer> 215 specifies a region of client memory that contains data to 216 initialize the object buffer. If <pointer> is null, then the 217 object buffer is created but not initialized. 218 219 <usage> provides a hint to the implementation of whether the 220 contents of the object buffer will be static or dynamic. <usage> 221 must be either STATIC_ATI or DYNAMIC_ATI. If the client specifies 222 an object buffer as static, its contents may still be updated, 223 however this may result in reduced performance. 224 225 The return value is a positive integer that uniquely identifies 226 the object buffer. If the object buffer cannot be allocated, the 227 return value is zero. 228 229 When the client creates an object buffer using NewObjectBufferATI, 230 the implementation can provide more efficient transfers of data 231 between the client and the graphics controller by allocating the 232 object buffer in memory that can be directly addressed by the 233 graphics controller. In addition, because the object buffer is 234 persistent across multiple drawing commands, static data must only 235 be copied to the object buffer once. 236 237 To modify the data contained in the object buffer, the client may 238 use the command 239 240 void UpdateObjectBufferATI(uint buffer, uint offset, 241 sizei size, const void *pointer, 242 enum preserve); 243 244 <buffer> identifies the object buffer to be updated. <offset> and 245 <size> indicate the range of data in the object buffer that is to 246 be updated. <pointer> specifies a region of client memory that 247 contains data to update the object buffer. 248 249 The client can use the <preserve> parameter of 250 UpdateObjectBufferATI to indicate whether data outside the region 251 being updated must be preserved. <preserve> must be one of 252 PRESERVE_ATI or DISCARD_ATI. If a client specifies that data 253 outside the range being updated may be discarded, the 254 implementation may be able process updates in a more optimal 255 fashion. 256 257 Whenever UpdateObjectBufferATI is called, the byte values in the 258 object buffer from <offset> to <offset> + <size> - 1 are updated 259 with the data referenced by <pointer>. If the client specifies 260 PRESERVE_ATI, all other byte values in the object buffer remain 261 unchanged. If the client specifies DISCARD_ATI, then all byte 262 values outside the range that has been updated become undefined. 263 264 Once created, an object buffer remains available for use until it 265 is destroyed by calling 266 267 void FreeObjectBufferATI(uint buffer); 268 269 <buffer> identifies the object buffer to be destroyed. 270 271 After creating an object buffer, the client can use the command 272 273 void ArrayObjectATI(enum array, int size, enum type, 274 sizei stride, uint buffer, uint offset); 275 276 to allow a portion of the object buffer to be used as a vertex 277 array. <array> specifies the array to be defined. This must match 278 one of the allowable enumerants accepted by EnableClientState and 279 DisableClientState. <size>, <type>, and <stride> specify the 280 format and packing of the data stored in the array in the same 281 manner as the corresponding vertex array pointer command. <size> 282 and <type> must match the allowed sizes and types given for the 283 corresponding commands in table 2.4. 284 285 <buffer> specifies the object buffer that contains the data to be 286 used as a vertex array. <offset> specifies the offset in machine 287 units into the object buffer at which the vertex array data 288 begins. When a vertex array is specified in this manner, the 289 memory pointer that is part of the client state for the vertex 290 array is set to null to indicate that the vertex array has been 291 defined using ArrayObjectATI instead of one of the pointer 292 commands. 293 294 Vertex arrays that are defined to reside within an object buffer 295 function in the same manner as normal vertex arrays. They are 296 enabled and disabled by using the commands EnableClientState and 297 DisableClientState. Primitives can be constructed using 298 ArrayElement, DrawArrays, DrawElements, and DrawRangeElements. 299 Clients may use mix of traditional vertex arrays and vertex array 300 objects to specify geometry. 301 302 There is no explicit mechanism to define interleaved vertex arrays 303 in an object buffer. This can be implicitly done by storing the 304 arrays in an interleaved fashion during NewObjectBufferATI or 305 UpdateObjectBufferATI. 306 307 If EXT_vertex_shader is defined, then a client can define an array 308 of variant data using the command: 309 310 void VariantArrayObjectATI(uint id, enum type, sizei stride, 311 uint buffer, uint offset); 312 313 <id> indicates the variant that this array should be associated 314 with. The <type>, <stride>, <buffer>, and <offset> parameters 315 have the same meaning as the corresponding parameters of 316 ArrayObjectATI. As always, variant arrays have a fixed size of 4 317 components. 318 319 Variant arrays defined by VariantArrayObjectATI are enabled and 320 disabled in the same way as variant arrays defined by 321 VariantPointerATI, by using EnableVariantClientStateATI and 322 DisableVariantClientStateATI. 323 324 325Additions to Chapter 3 of the 1.2.1 Specification (Rasterization) 326 327 None 328 329 330Additions to Chapter 4 of the 1.2.1 Specification (Per-Fragment 331Operations and the Frame Buffer) 332 333 None 334 335 336Additions to Chapter 5 of the 1.2.1 Specification (Special Functions) 337 338 Added to section 5.4, as part of the discussion of what commands 339 are compiled into display lists: 340 341 The commands defined by this extension function in the same manner 342 as the traditional vertex array commands when they are compiled 343 into a display list. 344 345 Commands that are used to create and manage memory for stored 346 arrays are not included in display lists, but are executed 347 immediately. These include NewObjectBufferATI, IsObjectBufferATI, 348 UpdateObjectBufferATI, GetObjectBufferfvATI, GetObjectBufferivATI, 349 and FreeObjectBufferATI. 350 351 Commands that are used to define and query vertex arrays within an 352 object buffer are not included in display lists, but are executed 353 immediately. These include ArrayObjectATI, GetArrayObjectfvATI, 354 and GetArrayObjectivATI. 355 356 357Additions to Chapter 6 of the 1.2.1 Specification (State and State 358Requests) 359 360 Added to section 6.1 in a subsection titled Object Buffer Queries: 361 362 The command 363 364 boolean IsObjectBufferATI(uint buffer) 365 366 returns TRUE if <buffer> is the name of an object buffer. If 367 <buffer> is zero, or if <buffer> is a non-zero value that is not 368 the name of an object buffer, IsObjectBufferATI return FALSE. 369 370 Added to the list of queries in section 6.1.3, Enumerated Queries: 371 372 void GetObjectBuffer{if}vATI(uint buffer, enum value, T data); 373 void GetArrayObject{if}vATI(enum array, enum value, T data); 374 375 If EXT_vertex_shader is defined: 376 377 void GetVariantArrayObject{if}vATI(uint id, enum value, T data); 378 379 Appended to the description of the queries in section 6.1.3, 380 Enumerated Queries: 381 382 GetObjectBuffer is used to retrieve information about an object 383 buffer. <buffer> must identify a valid object buffer. <value> must 384 be one of OBJECT_BUFFER_SIZE_ATI or OBJECT_BUFFER_USAGE_ATI. 385 386 If <value> is OBJECT_BUFFER_SIZE_ATI, then the size of the object 387 buffer in bytes is returned in <data>. The exact size of the 388 object buffer is an implementation dependent value, but is 389 guaranteed to be at least as large as the value specified by the 390 <size> parameter of NewObjectBufferATI. If <value> is 391 OBJECT_BUFFER_USAGE_ATI, then the value returned in <data> will be 392 either STATIC_ATI or DYNAMIC_ATI. The return value will match the 393 value specified by the <usage> parameter of NewObjectBufferATI. 394 395 GetArrayObjectATI is used to retrieve information on a vertex 396 array located in an object buffer. <array> indicates the vertex 397 array that is to be queried. It must match one of the allowable 398 enumerants accepted by EnableClientState and DisableClientState. 399 400 If EXT_vertex_shader is defined, GetVariantArrayObjectATI is used 401 to retrieve information on a variant array located in an object 402 buffer. <id> indicates the variant that is to be queried. 403 404 For both queries, <value> must be one of ARRAY_OBJECT_BUFFER_ATI, 405 or ARRAY_OBJECT_OFFSET_ATI. For each of these enumerants, the 406 value returned in <data> represents the object buffer that 407 contains the vertex data, or the byte offset from the object 408 buffer at which the first vertex starts, respectively. If the 409 specified vertex array or variant array has not been defined to 410 reside in an object buffer, GetArrayObjectATI will return zero for 411 both enumerants. 412 413 414Errors 415 416 INVALID_ENUM is generated if the <usage> parameter of 417 NewObjectBufferATI is not STATIC_ATI or DYNAMIC_ATI. 418 419 OUT_OF_MEMORY may be generated if an object buffer cannot be 420 allocated because the <size> argument of NewObjectBufferATI is 421 too large. 422 423 INVALID_VALUE is generated if the <buffer> argument of 424 UpdateObjectBufferATI, GetObjectBufferfvATI, GetObjectBufferivATI, 425 FreeObjectBufferATI, and ArrayObjectATI does not identify a 426 valid object buffer. 427 428 INVALID_VALUE is generated if the <offset> and <size> parameters 429 of UpdateObjectBufferATI would reference a region of memory 430 outside that allocated by the call to NewObjectBufferATI. 431 432 INVALID_ENUM is generated if the <pname> parameter of 433 GetObjectBufferfvATI and GetObjectBufferivATI is not 434 OBJECT_BUFFER_SIZE_ATI or OBJECT_BUFFER_USAGE_ATI. 435 436 INVALID_ENUM is generated if the <array> parameter of 437 ArrayObjectATI, GetArrayObjectfvATI, and GetArrayObjectivATI does 438 not match one of the enumerants allowed by EnableClientState and 439 DisableClientState. 440 441 INVALID_VALUE is generated if the <id> parameter of 442 VariantArrayObjectATI, GetVariantArrayObjectfvATI, and 443 GetVariantArrayObjectivATI does not correspond to a previously 444 defined variant. 445 446 INVALID_VALUE is generated if the <size> and <type> parameters of 447 ArrayObjectATI do not match the allowable sizes and types given 448 for the pointer command corresponding to the <array> parameter. 449 450 INVALID_VALUE is generated if the <offset> parameter of 451 ArrayObjectATI is larger than the size of the object buffer as 452 specified by NewObjectBufferATI. 453 454 INVALID_ENUM is generated if the <pname> parameter of 455 GetArrayObjectfvATI and GetArrayObjectivATI is not 456 ARRAY_OBJECT_BUFFER_ATI or ARRAY_OBJECT_OFFSET_ATI. 457 458 459New State 460 461 In a new table, Object Buffers 462 463 Get Value Get Command Type Initial Value Attrib 464 --------- ----------- ---- ------------- ------ 465 OBJECT_BUFFER_SIZE_ATI GetIntegerv Z+ 0 - 466 OBJECT_BUFFER_USAGE_ATI GetIntegerv Z4 STATIC_ATI - 467 468 ARRAY_OBJECT_BUFFER_ATI GetIntegerv Z+ 0 - 469 ARRAY_OBJECT_OFFSET_ATI GetIntegerv Z+ 0 - 470 471 472Usage Example 473 474 Here is a simple example that demonstrates usage of the extension. 475 The example provides a comparison between traditional vertex 476 arrays and vertex array objects. Note that this is not a 477 particularly efficient use of vertex array objects, since the 478 array object are only used once before being destroyed. Typically 479 the client will create many array objects and transfer all of its 480 vertex data to the server before beginning any rendering. 481 482 Traditional vertex arrays: 483 484 // Define 485 VertexPointer(4, FLOAT, 16, data); 486 ColorPointer(4, UNSIGNED_BYTE, 4, data + 256); 487 488 // Enable 489 EnableClientState(VERTEX_ARRAY); 490 EnableClientState(COLOR_ARRAY); 491 492 // Draw 493 DrawArrays(TRIANGLES, 0, 16); 494 495 // Disable 496 DisableClientState(VERTEX_ARRAY); 497 DisableClientState(COLOR_ARRAY); 498 499 Vertex array objects: 500 501 // Create object buffer 502 buffer = NewObjectBufferATI(320, data, STATIC_ATI); 503 504 // Define 505 ArrayObjectATI(VERTEX_ARRAY, 4, FLOAT, 16, buffer, 0); 506 ArrayObjectATI(COLOR_ARRAY, 4, UNSIGNED_BYTE, 4, buffer, 256); 507 508 // Enable 509 EnableClientState(VERTEX_ARRAY); 510 EnableClientState(COLOR_ARRAY); 511 512 // Draw 513 DrawArrays(TRIANGLES, 0, 16); 514 515 // Disable 516 DisableClientState(VERTEX_ARRAY); 517 DisableClientState(COLOR_ARRAY); 518 519 // Free object buffer 520 FreeObjectBufferATI(buffer); 521 522 523Implementation Notes 524 525 For maximum hardware performance, all vertex arrays except for 526 color and secondary color should always be specified to use float 527 as the component type. Color and secondary color arrays may be 528 specified to use either float or 4-component unsigned byte as the 529 component type. 530 531 Typically, an object buffer will contain all of the vertex 532 information associated with a given object in a scene. This can 533 include multiple arrays of geometry, color, and texture data. If 534 portions of this data are static, and portions are dynamic, 535 greater performance can be achieved by placing the dynamic vertex 536 data in a separate object buffer and updating the entire object 537 buffer at once. 538 539