1Name 2 3 ARB_vertex_attrib_binding 4 5Name Strings 6 7 GL_ARB_vertex_attrib_binding 8 9Contact 10 11 Jeff Bolz, NVIDIA Corporation (jbolz 'at' nvidia.com) 12 13Contributors 14 15 Pat Brown, NVIDIA 16 Bruce Merry 17 Mark Kilgard 18 19Notice 20 21 Copyright (c) 2012-2013 The Khronos Group Inc. Copyright terms at 22 http://www.khronos.org/registry/speccopyright.html 23 24Specification Update Policy 25 26 Khronos-approved extension specifications are updated in response to 27 issues and bugs prioritized by the Khronos OpenGL Working Group. For 28 extensions which have been promoted to a core Specification, fixes will 29 first appear in the latest version of that core Specification, and will 30 eventually be backported to the extension document. This policy is 31 described in more detail at 32 https://www.khronos.org/registry/OpenGL/docs/update_policy.php 33 34Status 35 36 Complete. 37 Approved by the ARB on 2012/06/12. 38 39Version 40 41 Last Modified Date: October 22, 2013 42 Revision: 5 43 44 EXT_direct_state_access interacton added with revision 3. 45 46Number 47 48 ARB Extension #125 49 50Dependencies 51 52 This extension is written against the OpenGL 4.2 Core specification. 53 54 NV_vertex_buffer_unified_memory affects the definition of this 55 extension. 56 57 EXT_direct_state_access affects the definition of this extension. 58 59 The Compatibility specification affects the definition of this extension. 60 61Overview 62 63 OpenGL currently supports (at least) 16 vertex attributes and 16 vertex 64 buffer bindings, with a fixed mapping between vertex attributes and 65 vertex buffer bindings. This extension allows the application to change 66 the mapping between attributes and bindings, which can make it more 67 efficient to update vertex buffer bindings for interleaved vertex formats 68 where many attributes share the same buffer. 69 70 This extension also separates the vertex binding update from the vertex 71 attribute format update, which saves applications the effort of 72 redundantly specifying the same format state over and over. 73 74 Conceptually, this extension splits the state for generic vertex attribute 75 arrays into: 76 77 - An array of vertex buffer binding points, each of which specifies: 78 79 - a bound buffer object, 80 81 - a starting offset for the vertex attribute data in that buffer object, 82 83 - a stride used by all attributes using that binding point, and 84 85 - a frequency divisor used by all attributes using that binding point. 86 87 - An array of generic vertex attribute format information records, each of 88 which specifies: 89 90 - a reference to one of the new buffer binding points above, 91 92 - a component count and format, and a normalization flag for the 93 attribute data, and 94 95 - the offset of the attribute data relative to the base offset of each 96 vertex found at the associated binding point. 97 98 99New Procedures and Functions 100 101 void BindVertexBuffer(uint bindingindex, uint buffer, intptr offset, 102 sizei stride); 103 104 void VertexAttribFormat(uint attribindex, int size, enum type, 105 boolean normalized, uint relativeoffset); 106 void VertexAttribIFormat(uint attribindex, int size, enum type, 107 uint relativeoffset); 108 void VertexAttribLFormat(uint attribindex, int size, enum type, 109 uint relativeoffset); 110 111 void VertexAttribBinding(uint attribindex, uint bindingindex); 112 113 void VertexBindingDivisor(uint bindingindex, uint divisor); 114 115 When EXT_direct_state_access is present: 116 117 void VertexArrayBindVertexBufferEXT(uint vaobj, uint bindingindex, uint buffer, intptr offset, 118 sizei stride); 119 120 void VertexArrayVertexAttribFormatEXT(uint vaobj, uint attribindex, int size, enum type, 121 boolean normalized, uint relativeoffset); 122 void VertexArrayVertexAttribIFormatEXT(uint vaobj, uint attribindex, int size, enum type, 123 uint relativeoffset); 124 void VertexArrayVertexAttribLFormatEXT(uint vaobj, uint attribindex, int size, enum type, 125 uint relativeoffset); 126 127 void VertexArrayVertexAttribBindingEXT(uint vaobj, uint attribindex, uint bindingindex); 128 129 void VertexArrayVertexBindingDivisorEXT(uint vaobj, uint bindingindex, uint divisor); 130 131New Tokens 132 133 Accepted by the <pname> parameter of GetVertexAttrib*v: 134 135 VERTEX_ATTRIB_BINDING 0x82D4 136 VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5 137 138 Accepted by the <target> parameter of GetBooleani_v, GetIntegeri_v, 139 GetFloati_v, GetDoublei_v, and GetInteger64i_v: 140 141 VERTEX_BINDING_DIVISOR 0x82D6 142 VERTEX_BINDING_OFFSET 0x82D7 143 VERTEX_BINDING_STRIDE 0x82D8 144 VERTEX_BINDING_BUFFER 0x8F4F 145 146 Accepted by the <pname> parameter of GetIntegerv, ... 147 148 MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9 149 MAX_VERTEX_ATTRIB_BINDINGS 0x82DA 150 151 152Additions to Chapter 2 of the OpenGL 2.0 Specification (OpenGL Operation) 153 154 Modify Section 2.8, "Vertex Arrays" 155 156 Vertex data are placed into arrays that are stored in the server's address 157 space (described in section 2.9). Blocks of data in these arrays may then 158 be used to specify multiple geometric primitives through the execution of 159 a single GL command. The client may specify up to the value of 160 MAX_VERTEX_ATTRIBS arrays to store one or more generic vertex attributes. 161 A generic vertex attribute array is described by an index into an array of 162 vertex buffer bindings which contain the vertex data and state describing 163 how that data is organized. 164 165 The commands 166 167 [Compatibility profile only: Keep the named attribute *Pointer 168 commands in this list] 169 170 void VertexAttribFormat(uint attribindex, int size, enum type, 171 boolean normalized, uint relativeoffset); 172 void VertexAttribIFormat(uint attribindex, int size, enum type, 173 uint relativeoffset); 174 175 describe the organizations of vertex arrays. For each command, <type> 176 specifies the data type of the values stored in the array. <size> 177 indicates the number of values per vertex that are stored in the array as 178 well as their component ordering. Table 2.5 indicates the allowable values 179 for <size> and <type> (when present). For <type> the values BYTE, SHORT, 180 INT, FIXED, FLOAT, HALF_FLOAT, and DOUBLE indicate types byte, short, int, 181 fixed, float, half, and double, respectively; the values UNSIGNED_BYTE, 182 UNSIGNED_SHORT, and UNSIGNED_INT indicate types ubyte, ushort, and uint, 183 respectively; and the values INT_2_10_10_10_REV and UNSIGNED_INT_2_- 184 10_10_10_REV, indicating respectively four signed or unsigned elements 185 packed into a single uint, both correspond to the term <packed> in that 186 table. <relativeoffset> is a byte offset of the first element relative 187 to the start of the vertex buffer binding this attribute fetches from. 188 189 An INVALID_VALUE error is generated if <size> is not one of the values 190 allowed in table 2.5 for the corresponding command. 191 192 An INVALID_OPERATION error is generated under any of the following 193 conditions: 194 - if no vertex array object is currently bound (see section 2.10); 195 - <size> is BGRA and <type> is not UNSIGNED_BYTE, INT_2_10_10_10_REV or 196 UNSIGNED_INT_2_10_10_10_REV; 197 - <type> is INT_2_10_10_10_REV or UNSIGNED_INT_2_10_10_10_REV, and <size> 198 is neither 4 or BGRA; 199 - <size> is BGRA and <normalized> is FALSE; 200 201 An INVALID_VALUE error is generated if <relativeoffset> is larger than 202 the value of MAX_VERTEX_ATTRIB_RELATIVE_OFFSET. 203 204 The <attribIndex> parameter in the VertexAttribFormat and VertexAttribIFormat 205 commands identifies the generic vertex attribute array being described. 206 The error INVALID_VALUE is generated if index is greater than or equal to 207 the value of MAX_VERTEX_ATTRIBS. Generic attribute arrays with integer 208 type arguments can be handled in one of three ways: converted to float by 209 normalizing to [0, 1] or [-1, 1] as described in equations 2.1 and 2.2, 210 respectively; converted directly to float, or left as integers. Data for 211 an array specified by VertexAttribPointer will be converted to floating- 212 point by normalizing if <normalized> is TRUE, and converted directly to 213 floating-point otherwise. Data for an array specified by 214 VertexAttribIFormat will always be left as integer values; such data are 215 referred to as pure integers. 216 217 The command 218 219 void BindVertexBuffer(uint bindingindex, uint buffer, intptr offset, 220 sizei stride); 221 222 binds a buffer indicated by <buffer> to the vertex buffer bind point 223 indicated by <bindingindex>, and sets the <stride> between elements 224 and <offset> (in basic machine units) of the first element in the buffer. 225 The error INVALID_VALUE is generated if <stride> or <offset> are negative. 226 Otherwise pointers to the ith and (i + 1)st elements of an array differ 227 by stride basic machine units (typically unsigned bytes), the pointer to 228 the (i + 1)st element being greater. An INVALID_OPERATION error is 229 generated if no vertex array object is bound. If <buffer> is zero, any 230 buffer object attached to this bindpoint is detached. An INVALID_VALUE 231 error is generated if <bindingindex> is greater than the value of 232 MAX_VERTEX_ATTRIB_BINDINGS. 233 [Core profile only:] 234 An INVALID_OPERATION error is generated if buffer is not zero or a 235 name returned from a previous call to GenBuffers, or if such a name 236 has since been deleted with DeleteBuffers. 237 238 The association between a vertex attribute and the vertex buffer binding 239 used by that attribute is set by the command 240 241 void VertexAttribBinding(uint attribindex, uint bindingindex); 242 243 <attribindex> must be less than the value of MAX_VERTEX_ATTRIBS and 244 <bindingindex> must be less than the value of MAX_VERTEX_ATTRIB_BINDINGS, 245 otherwise the error INVALID_VALUE is generated. An INVALID_OPERATION error 246 is generated if no vertex array object is bound. 247 248 Modify Table 2.5 to add the command VertexAttribFormat to the first row 249 and VertexAttribIFormat to the second row. 250 251 The one, two, three, or four values in an array that correspond to a 252 single vertex comprise an array element. When size is BGRA, it indicates 253 four values. The values within each array element are stored sequentially 254 in memory. However, if size is BGRA, the first, second, third, and fourth 255 values of each array element are taken from the third, second, first, and 256 fourth values in memory respectively. 257 [Compatibility profile only:] 258 For each *Pointer command, <pointer> specifies the location in 259 memory of the first value of the first element of the array being 260 specified. 261 262 The command 263 264 void VertexAttribLFormat(uint attribindex, int size, enum type, 265 uint relativeoffset); 266 267 specifies state for a generic vertex attribute array associated with a 268 shader attribute variable declared with 64-bit double precision components. 269 <type> must be DOUBLE. <attribindex> and <size> behave as defined in all 270 other VertexAttrib*Format commands; <size> may be one, two, three or four. 271 272 Each component of an array specified by VertexAttribLFormat will be 273 encoded into one or more generic attribute components as specified for the 274 VertexAttribL* commands in section 2.7. The error INVALID_VALUE is 275 generated if <attribindex> is greater than or equal to the value of 276 MAX_VERTEX_ATTRIBS. 277 278 The commands 279 280 void VertexAttribPointer(uint index, int size, enum type, 281 boolean normalized, sizei stride, 282 const void *pointer); 283 void VertexAttribIPointer(uint index, int size, enum type, 284 sizei stride, const void *pointer); 285 void VertexAttribLPointer(uint index, int size, enum type, 286 sizei stride, const void *pointer); 287 288 control vertex attribute state, a vertex buffer binding, and the mapping 289 between a vertex attribute and a vertex buffer binding. They are 290 equivalent to (assuming no errors are generated): 291 292 if (no buffer is bound to ARRAY_BUFFER and pointer != NULL) { 293 generate INVALID_OPERATION; 294 } 295 VertexAttrib*Format(index, size, type, {normalized, }, 0); 296 VertexAttribBinding(index, index); 297 if (stride != 0) { 298 effectiveStride = stride; 299 } else { 300 compute effectiveStride based on size/type; 301 } 302 VERTEX_ATTRIB_ARRAY_STRIDE[index] = stride; 303 // VERTEX_BINDING_STRIDE will be set to effectiveStride 304 // by BindVertexBuffer. 305 BindVertexBuffer(index, <buffer bound to ARRAY_BUFFER>, 306 (char *)pointer - (char *)NULL, effectiveStride); 307 308 If <stride> is specified as zero, then array elements are stored 309 sequentially. 310 311 An individual generic vertex attribute array is 312 enabled or disabled by calling one of 313 314 void EnableVertexAttribArray(uint index); 315 void DisableVertexAttribArray(uint index); 316 317 where <index> identifies the generic vertex attribute array to enable or 318 disable. An INVALID_VALUE error is generated if <index> is greater than or 319 equal to MAX_VERTEX_ATTRIBS. 320 321 An INVALID_OPERATION error is generated if no vertex array object is 322 bound. 323 324 The command 325 326 void VertexBindingDivisor(uint bindingindex, uint divisor); 327 328 modifies the rate at which generic vertex attributes advance when 329 rendering multiple instances of primitives in a single draw call. If 330 <divisor> is zero, the attributes using the buffer bound to <bindingindex> 331 advance once per vertex. If <divisor> is non-zero, the attributes advance 332 once per <divisor> instances of the set(s) of vertices being rendered. An 333 attribute is referred to as <instanced> if the corresponding <divisor> 334 value is non-zero. 335 336 An INVALID_VALUE error is generated if <bindingindex> is greater than or 337 equal to the value of MAX_VERTEX_ATTRIB_BINDINGS. 338 339 An INVALID_OPERATION error is generated if no vertex array object is 340 bound. 341 342 The command 343 344 void VertexAttribDivisor(uint index, uint divisor); 345 346 is equivalent to (assuming no errors are generated): 347 348 VertexAttribBinding(index, index); 349 VertexBindingDivisor(index, divisor); 350 351 An INVALID_VALUE error is generated if <attribindex> is greater than or 352 equal to the value of MAX_VERTEX_ATTRIBS. 353 354 355 Modify Section 2.8.3, "Drawing Commands" 356 357 For any vertex attribute whose divisor is non-zero as set by 358 VertexBindingDivisor, the value "baseinstance" is used to determine the 359 element of the enabled instanced attribute arrays that will be transferred 360 for all vertices transferred by this function. 361 362 ... 363 364 Those attributes that have divisor N where N is other than zero (as 365 specified by VertexBindingDivisor) advance once every N instances. 366 367 ... 368 369 If an enabled vertex attribute array is instanced (it has a non-zero 370 binding divisor as specified by VertexAttribBinding and 371 VertexBindingDivisor), the element that is transferred to the GL is given 372 by: 373 374 floor(instance/divisor) + baseinstance 375 376 ... 377 378 If the number of supported generic vertex attributes (the value of MAX_- 379 VERTEX_ATTRIBS) is <n> and the number of vertex attribute bindings (the 380 value of MAX_VERTEX_ATTRIB_BINDINGS) is <k>, then the state required to 381 implement vertex arrays consists of <n> boolean values (enables), <n> 382 memory pointers, <n> integer stride values (VERTEX_ATTRIB_ARRAY_STRIDE), 383 <n> symbolic constants representing array types, <n> integers representing 384 values per element, <n> boolean values indicating normalization, <n> 385 boolean values indicating whether the attribute values are pure integers, 386 <k> integers representing vertex attribute divisors, <n> integer vertex 387 attribute binding indices, <n> integer relative offsets, <k> integer stride 388 values (VERTEX_BINDING_STRIDE), <k> 64-bit integer buffer offsets, and an 389 unsigned integer representing the restart index. 390 391 In the initial state, the boolean values are each false, the memory 392 pointers are each NULL, the VERTEX_ATTRIB_ARRAY_STRIDE strides are each 393 zero, the array types are each FLOAT, the integers representing values per 394 element are each four, the normalized and pure integer flags are each 395 false, the divisors are each zero, the vertex attribute binding indices 396 are <i> for attribute <i>, the relative offsets are each zero, the 397 VERTEX_BINDING_STRIDE values are each 16, the buffer offsets are each zero, 398 and the restart index is zero. 399 400 401 Modify Section 2.9.6, "Vertex Arrays in Buffer Objects" 402 403 When an array is sourced from a buffer object, the vertex attribute's 404 VERTEX_ATTRIB_BINDING indicates which vertex buffer binding is used. The 405 sum of the attribute's VERTEX_ATTRIB_RELATIVE_OFFSET and the vertex 406 buffer binding's VERTEX_BINDING_OFFSET is used as the offset (in basic 407 machine units) of the first element in that buffer's data store. 408 409 (Compatibility Only) Add to the final paragraph: 410 411 Attributes using client memory ignore the VERTEX_ATTRIB_BINDING state. 412 That is, the logic for computing the address of the base of a vertex array 413 is: 414 415 bindingIndex = VERTEX_ATTRIB_BINDING[attribIndex]; 416 buffer = VERTEX_BINDING_BUFFER[bindingIndex]; 417 418 if (buffer->name != 0) { 419 address = buffer->baseAddress + 420 VERTEX_BINDING_OFFSET[bindingIndex] + 421 VERTEX_ATTRIB_RELATIVE_OFFSET[attribIndex]; 422 } else { 423 address = VERTEX_ATTRIB_ARRAY_POINTER[attribIndex]; 424 } 425 426 427Additions to Chapter 3 of the OpenGL 2.0 Specification (Rasterization) 428 429 None. 430 431Additions to Chapter 4 of the OpenGL 2.0 Specification (Per-Fragment 432Operations and the Frame Buffer) 433 434 None. 435 436Additions to Chapter 5 of the OpenGL 2.0 Specification (Special Functions) 437 438 None. 439 440Additions to Chapter 6 of the OpenGL 2.0 Specification (State and 441State Requests) 442 443 Modify Section 6.1.18, "Shader and Program Queries", p. 500 444 445 (Append to the description of GetVertexAttrib) 446 447 Queries of VERTEX_ATTRIB_ARRAY_BUFFER_BINDING and VERTEX_ATTRIB_ARRAY_- 448 DIVISOR first map the requested attribute index to a binding index via 449 the VERTEX_ATTRIB_BINDING state, and then return the value of 450 VERTEX_BINDING_BUFFER or VERTEX_BINDING_DIVISOR, respectively. 451 452Additions to the AGL/GLX/WGL Specifications 453 454 None. 455 456GLX Protocol 457 458 TBD 459 460Dependencies on NV_vertex_buffer_unified_memory 461 462 When this extension is present, the GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV 463 state is modified to correspond to the <i>'th vertex buffer binding 464 rather than vertex attribute. Additionally, while the <buffer> and 465 <offset> set by BindVertexBuffer are irrelevant while 466 GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV is enabled, the command 467 468 BindVertexBuffer(bindingindex, 0, 0, stride); 469 470 can still be used to set the stride for a particular binding. 471 472 Note that NV_vertex_buffer_unified_memory uses the same function names 473 (VertexAttrib*FormatNV) as this extension, however the behavior of the 474 these functions is different. 475 476Dependencies on EXT_direct_state_access 477 478 When this extension is not present, ignore references to 479 480 VertexArrayBindVertexBufferEXT 481 VertexArrayVertexAttribFormatEXT 482 VertexArrayVertexAttribIFormatEXT 483 VertexArrayVertexAttribLFormatEXT 484 VertexArrayVertexAttribBindingEXT 485 VertexArrayVertexBindingDivisorEXT 486 487 When EXT_direct_state_access is present, add new entry points that take a 488 vertex array object handle: 489 490 void VertexArrayBindVertexBufferEXT(uint vaobj, uint bindingindex, uint buffer, intptr offset, 491 sizei stride); 492 493 void VertexArrayVertexAttribFormatEXT(uint vaobj, uint attribindex, int size, enum type, 494 boolean normalized, uint relativeoffset); 495 void VertexArrayVertexAttribIFormatEXT(uint vaobj, uint attribindex, int size, enum type, 496 uint relativeoffset); 497 void VertexArrayVertexAttribLFormatEXT(uint vaobj, uint attribindex, int size, enum type, 498 uint relativeoffset); 499 500 void VertexArrayVertexAttribBindingEXT(uint vaobj, uint attribindex, uint bindingindex); 501 502 void VertexArrayVertexBindingDivisorEXT(uint vaobj, uint bindingindex, uint divisor); 503 504 These commands behave identically to their 505 non-VertexArray/EXT-suffixed commands except they modify the state 506 of the vertex array object named by their initial vaobj parameter 507 (rather than the currently bound vertex array object). The vertex 508 array object named by vaobj must be generated by GenVertexArrays 509 (and not since deleted); otherwise an INVALID_OPERATION error is 510 generated. 511 512 Modify the description of GetVertexArrayIntegeri_vEXT to allow 513 queries of VERTEX_BINDING_OFFSET and VERTEX_BINDING_STRIDE state: 514 515 "For GetVertexArrayIntegeri_vEXT, <pname> must be one of the 516 'Get value' tokens in tables 6.8 and 6.9 that use GetVertexAttribiv 517 or GetVertexAttribPointerv (so allowing only the VERTEX_ATTRIB_* and 518 VERTEX_BINDING_* tokens) or a token of the form TEXTURE_COORD_ARRAY_*; 519 <index> identifies the vertex attribute array to query, vertex binding to 520 query, or texture coordinate set index." 521 522Dependencies on the Compatibility profile 523 524 If the context is created with a compatibility profile, remove the 525 INVALID_OPERATION errors from all new commands if no vertex array 526 object is currently bound, and remove the INVALID_OPERATION error 527 from VertexAttrib*Pointer if no buffer is bound to ARRAY_BUFFER and 528 pointer != NULL. 529 530 Client vertex arrays are not changed to use the new state, that is, 531 VERTEX_ATTRIB_ARRAY_POINTER is still attribute state. 532 533Errors 534 535 !!!TODO 536 537New State 538 539 (Modify Table 6.5 -- Vertex Array Object State) 540 541 Initial 542 Get Value Type Get Command Value Description Sec. 543 --------- ------- ----------- ------- ------------------------ ------ 544 VERTEX_ATTRIB_BINDING 16*Z16* GetVertexAttribiv <i>[fn1] Vertex buffer binding 2.8 545 used by vertex attrib <i> 546 VERTEX_ATTRIB_RELATIVE_ 16*Z+ GetVertexAttribiv 0 Byte offset added to 2.8 547 OFFSET vertex binding offset 548 for this attribute 549 VERTEX_BINDING_OFFSET 16*Z GetInteger64i_v 0 Byte offset of the first 2.8 550 element in data store of 551 the buffer bound to vertex 552 binding <i> 553 VERTEX_BINDING_STRIDE 16*Z GetIntegeri_v 16 Stride between elements in 2.8 554 vertex binding <i> 555 VERTEX_BINDING_DIVISOR 16*Z+ GetIntegeri_v 0 Instance divisor used for 2.8 556 vertex binding <i> 557 VERTEX_BINDING_BUFFER 16*Z+ GetIntegeri_v 0 Name of buffer bound to 2.8 558 vertex binding <i> 559 560 [fn1] The <i>'th attribute defaults to a value of <i>. 561 562 If the compatibility profile is supported, then all of these new state 563 values belong to the 'vertex-array' attribute. 564 565New Implementation Dependent State 566 567 Minimum 568 Get Value Type Get Command Value Description Sec. 569 --------- ------- ----------- ------- -------------------- ------ 570 MAX_VERTEX_ATTRIB_ Z GetIntegerv 2047 Maximum offset added 2.8 571 RELATIVE_OFFSET to vertex buffer 572 binding offset 573 MAX_VERTEX_ATTRIB_BINDINGS Z16* GetIntegerv 16 Maxmimum number of 2.8 574 vertex buffers 575 576NVIDIA Implementation Details 577 578 The VertexArrayVertexBindingDivisorEXT function was not missing 579 from early versions of this specification's interactions with 580 EXT_direct_state_access (an oversight). NVIDIA driver implementations 581 (prior to Release 330.00, August 2013) do not advertise the function a 582 GetProcAddress call for the function name will return NULL. 583 584Examples 585 586 The following code will set up two interleaved vertex buffers, where 587 attribs 0 and 1 are vec3 position and vec3 color in buffer0, and attribs 588 2 and 3 come from are vec2 texcoords in buffer1. 589 590 // Set up formats and relative offsets within the interleaved data. 591 VertexAttribFormat(0, 3, FLOAT, FALSE, 0); 592 VertexAttribFormat(1, 3, FLOAT, FALSE, 12); 593 VertexAttribFormat(2, 2, FLOAT, FALSE, 0); 594 VertexAttribFormat(3, 2, FLOAT, FALSE, 8); 595 596 // Set up attrib->binding mapping 597 VertexAttribBinding(0, 0); 598 VertexAttribBinding(1, 0); 599 VertexAttribBinding(2, 1); 600 VertexAttribBinding(3, 1); 601 602 // Bind the vertex buffers to binding index 0 and 1. 603 BindVertexBuffer(0, buffer0, 0, 24); 604 BindVertexBuffer(1, buffer1, 0, 16); 605 606Issues 607 608 (1) Should the instance divisor (previously VertexAttribDivisor) be 609 attribute state or binding state? 610 611 RESOLVED: Make it per-binding, since some hardware requires this. 612 613 (2) How is a stride of zero interpreted in BindVertexBuffer? 614 615 RESOLVED: No error is generated, all array elements for a given 616 attribute will be sourced from the same location in the buffer. 617 618 (3) How is a stride of zero handled in VertexAttribPointer? 619 620 RESOLVED: BindVertexBuffer has no knowledge of the attrib format, 621 so VertexAttribPointer needs to compute the stride itself. However, 622 if an application specifies a stride of zero and then queries 623 VERTEX_ATTRIB_ARRAY_STRIDE, it returns zero. So the derived stride 624 that's passed to BindVertexBuffer must be tracked separately from the 625 stride originally passed to VertexAttribPointer, so this spec introduces 626 a separate piece of state (VERTEX_BINDING_STRIDE). Rendering always uses 627 VERTEX_BINDING_STRIDE. 628 629 This can potentially lead to misleading state queries if the API is 630 abused. For example: 631 632 VertexAttribPointer(0, 3, FLOAT, FALSE, 12, 0); 633 // VERTEX_ATTRIB_ARRAY_STRIDE = 12 634 // VERTEX_BINDING_STRIDE = 12 635 BindVertexBuffer(0, buffer, 0, 16) 636 // now VERTEX_ATTRIB_ARRAY_STRIDE is still 12, but 637 // VERTEX_BINDING_STRIDE = 16. 638 639 (4) How should the attrib->binding mapping be handled for legacy commands? 640 641 RESOLVED: Redefine legacy commands to reset the mapping to its initial 642 state for the attribute being operated on. This allows legacy code to 643 coexist in the same context/VAO with use of this extension even though 644 that code is oblivious to the fact that this mapping is now flexible. 645 As long as the legacy code sets up each attribute it wants to use, it 646 should operate as expected. This may be useful for applications using 647 middleware that they can't control. 648 649 (5) What is the minimum maximum value for VERTEX_ATTRIB_RELATIVE_OFFSET? 650 651 RESOLVED: Agreed on 2047 (inclusive). 652 653 (6) Can MAX_VERTEX_ATTRIBS and MAX_VERTEX_ATTRIB_BINDINGS have different 654 values? 655 656 RESOLVED: Decided that it's nice to have them be separate queries, but 657 that we don't want to deal with all the complexities that arise if the 658 two values are different. So this spec assumes that the two values are 659 the same. 660 661 (7) How does this extension interact with EXT_direct_state_access? 662 663 RESOLVED: The EXT commands in this specification are available only when 664 EXT_direct_state_access is also advertised. 665 666 Note: Early versions of this specification failed to document 667 the EXT_direct_state_access commands. Revision 3 (August 2013) 668 corrects this oversight. 669 670 (8) Which state queries return information from attributes vs from 671 bindings? 672 673 RESOLVED: The general convention is that tokens starting with 674 VERTEX_BINDING return information corresponding to a buffer binding and 675 are queried with GetIntegeri_v, whereas tokens starting with 676 VERTEX_ATTRIB_ARRAY return information corresponding to a vertex 677 attribute index and are queried with GetVertexAttribiv. 678 679 For cases where there is both an "attribute" and "binding" token for the 680 same state, the "attribute" query returns state for the binding that 681 attribute is currently using (set via VertexAttribBinding). Specifically, 682 VERTEX_ATTRIB_ARRAY_BUFFER_BINDING returns a value from VERTEX_BINDING_- 683 BUFFER, and VERTEX_ATTRIB_ARRAY_DIVISOR returns a value from VERTEX_- 684 BINDING_DIVISOR. 685 686 A notable exception to this is for VERTEX_BINDING_STRIDE and 687 VERTEX_ATTRIB_ARRAY_STRIDE. As described in issue (3), these tokens track 688 separate state. 689 690 691Revision History 692 693 Rev. Date Author Changes 694 ---- -------- -------- ------------------------------------------ 695 5 10/22/13 jbolz Added missing definition of 696 VERTEX_BINDING_DIVISOR, and added 697 VERTEX_BINDING_BUFFER, to keep things consistent. 698 4 08/06/13 mjk Added EXT_direct_state_access interactions 699 3 07/19/13 Jon Leech Add error to BindVertexBuffer for the core 700 profile if <buffer> is not a name returned 701 by GenBuffers (Bug 10486). 702 2 08/13/12 Jon Leech Renumbered from #143 to #125 703 1 jbolz Internal revisions. 704