1Name 2 3 ARB_base_instance 4 5Name Strings 6 7 GL_ARB_base_instance 8 9Contact 10 11 Graham Sellers, AMD (graham.sellers 'at' amd.com) 12 13Contributors 14 15 Daniel Koch, NVIDIA 16 17Notice 18 19 Copyright (c) 2011-2013 The Khronos Group Inc. Copyright terms at 20 http://www.khronos.org/registry/speccopyright.html 21 22Specification Update Policy 23 24 Khronos-approved extension specifications are updated in response to 25 issues and bugs prioritized by the Khronos OpenGL Working Group. For 26 extensions which have been promoted to a core Specification, fixes will 27 first appear in the latest version of that core Specification, and will 28 eventually be backported to the extension document. This policy is 29 described in more detail at 30 https://www.khronos.org/registry/OpenGL/docs/update_policy.php 31 32Status 33 34 Complete. Approved by the ARB on 2011/06/20. 35 Approved by the Khronos Promoters on 2011/07/29. 36 37Version 38 39 Last Modified Date: June 13, 2014 40 Author Revision: 7 41 42Number 43 44 ARB Extension #107 45 46Dependencies 47 48 This extension is written against the OpenGL Specification, Version 4.1 49 (Core Profile). 50 51 OpenGL 3.1 or ARB_draw_instanced is required. 52 53Overview 54 55 This extension allows the offset within buffer objects used for instanced 56 rendering to be specified. This is congruent with the <first> parameter 57 in glDrawArrays and the <basevertex> parameter in glDrawElements. When 58 instanced rendering is performed (for example, through 59 glDrawArraysInstanced), instanced vertex attributes whose vertex attribute 60 divisors are non-zero are fetched from enabled vertex arrays per-instance 61 rather than per-vertex. However, in unextended OpenGL, there is no way to 62 define the offset into those arrays from which the attributes are fetched. 63 This extension adds that offset in the form of a <baseinstance> parameter 64 to several new procedures. 65 66 The <baseinstance> parameter is added to the index of the array element, 67 after division by the vertex attribute divisor. This allows several sets of 68 instanced vertex attribute data to be stored in a single vertex array, and 69 the base offset of that data to be specified for each draw. Further, this 70 extension exposes the <baseinstance> parameter as the final and previously 71 undefined structure member of the draw-indirect data structure. 72 73IP Status 74 75 None. 76 77New Procedures and Functions 78 79 void DrawArraysInstancedBaseInstance(enum mode, 80 int first, 81 sizei count, 82 sizei primcount, 83 uint baseinstance); 84 85 void DrawElementsInstancedBaseInstance(enum mode, 86 sizei count, 87 enum type, 88 const void *indices, 89 sizei primcount, 90 uint baseinstance); 91 92 void DrawElementsInstancedBaseVertexBaseInstance(enum mode, 93 sizei count, 94 enum type, 95 const void *indices, 96 sizei primcount, 97 int basevertex, 98 uint baseinstance); 99 100New Tokens 101 102 None. 103 104Modifications to Chapter 2 of the the OpenGL 4.1 (Core Profile) Specification 105(OpenGL Operation) 106 107 Modification to Section 2.8.3, "Drawing Commands" 108 109 Modify the definition of DrawArraysOneInstance on p.33. 110 111 The command 112 113 void DrawArraysOneInstance(enum mode, 114 int first, 115 sizei count, 116 int instance, 117 uint baseinstance); 118 119 does not exist in the GL, but is used to describe functionality in the rest 120 of this section. This command constructs a sequence of geometric primitives 121 by transferring elements <first> through <first> + <count> - 1 of each 122 enabled array to the GL. <mode> specifies what kind of primitives are 123 constructed, as defined in section 2.6.1. If <mode> is not a valid primitive 124 type, an INVALID_ENUM error is generated. If <count> is negative, an 125 INVALID_VALUE error is generated. 126 127 For any vertex attribute whose divisor is non-zero as set by 128 VertexAttribDivisor, the value <baseinstance> is used to determine the element 129 of the enabled instanced attribute arrays that will be transferred for all 130 vertices transferred by this function. 131 132 If an array corresponding to a generic attribute required by a vertex 133 shader is not enabled, then the corresponding element is taken from the 134 current generic attribute state (see section 2.7). 135 136 If an array corresponding to a generic attribute required by a vertex 137 shader is enabled, the corresponding current generic attribute value is 138 unaffected by the execution of DrawArraysOneInstance. 139 140 Specifying <first> < 0 results in undefined behavior. Generating the 141 error INVALID_VALUE is recommended in this case. 142 143 The command 144 145 void DrawArrays( enum mode, int first, sizei count ); 146 147 is equivalent to the command sequence 148 149 DrawArraysOneInstance(mode, first, count, 0, 0); 150 151 Replace the description of DrawArraysInstanced with the following (p.35): 152 153 The command 154 155 void DrawArraysInstancedBaseInstance(enum mode, 156 int first, 157 sizei count, 158 sizei primcount, 159 uint baseinstance); 160 161 behaves identically to DrawArrays, except that <primcount> instances of the 162 range of elements are executed and the value of <instanceID> advances for 163 each iteration. Those attributes that have divisor N where N is other than 164 zero (as specified by VertexAttribDivisor) advance once every N instances. 165 Additionally, the first element within those instanced vertex attributes 166 is specified in <baseinstance>. Thus, the element transferred from instanced 167 vertex attributes is given by: 168 169 (<instanceID> / <divisor>) + <baseinstance> 170 171 DrawArraysInstancedBaseInstance has the same effect as: 172 173 if (<mode> or <count> is invalid) 174 generate appropriate error 175 else { 176 for (i = 0; i < <primcount>; i++) { 177 instanceID = i; 178 DrawArraysOneInstance(<mode>, <first>, <count>, i, <baseinstance>); 179 } 180 instanceID = 0; 181 } 182 183 The command 184 185 void DrawArraysInstanced(enum mode, 186 int first, 187 sizei count, 188 sizei primcount); 189 190 Is equivalent to calling DrawArraysInstancedBaseInstance with <baseinstance> 191 set to zero. 192 193 Update the definition of DrawArraysIndirect as follows (p.35): 194 195 The command 196 197 void DrawArraysIndirect(enum mode, 198 const void *indirect); 199 200 has the same effect as: 201 202 typedef struct { 203 uint count; 204 uint primCount; 205 uint first; 206 uint baseInstance; 207 } DrawArraysIndirectCommand; 208 209 const DrawArraysIndirectCommand *cmd = 210 (const DrawArraysIndirectCommand *)indirect; 211 212 DrawArraysInstancedBaseInstance(mode, 213 cmd->first, 214 cmd->count, 215 cmd->primCount, 216 cmd->baseInstance); 217 218 Remove the sentence "Results are undefined if reservedMustBeZero is non- 219 zero, but must not lead to GL interruption or termination." 220 221 Update the definition of DrawElementsOneInstance, p.36: 222 223 The command 224 225 void DrawElementsOneInstance(enum mode, 226 sizei count, 227 enum type, 228 const void *indices, 229 int instance, 230 uint baseinstance); 231 232 does not exist in the GL ... <retain the remainder of the description> 233 234 If an enabled vertex attribute array is instanced (it has a non-zero 235 attribute divisor as specified by VertexAttribDivisor), the element that is 236 transferred to the GL is given by: 237 238 floor(<instance> / <divisor>) + <baseinstance> 239 240 Update the text describing DrawElements: 241 242 The command 243 244 void DrawElements(enum mode, 245 sizei count, 246 enum type, 247 const void *indices); 248 249 behaves identically to DrawElementsOneInstance with the <instance> and 250 <baseinstance> parameters set to zero; the effect of calling 251 252 DrawElements(mode, count, type, indices); 253 254 is equivalent to the command sequence: 255 256 if (<mode>, <count> or <type> is invalid) 257 generate appropriate error 258 else 259 DrawElementsOneInstance(mode, count, type, indices, 0, 0); 260 261 Replace the description of DrawElementsInstanced with the following (p.37) 262 263 The command 264 265 void DrawElementsInstancedBaseInstance(enum mode, 266 sizei count, 267 enum type, 268 const void *indices, 269 sizei primcount, 270 uint baseinstance); 271 272 behaves identically to DrawElements except that <primcount> instances of the 273 set of elements are executed, the value of instanceID advances between each 274 set, and the instance advances between each set. Instanced attributes 275 are advanced as they do during execution of DrawArraysInstancedBaseInstace, 276 and <baseinstance> has the same effect. It has the same effect as: 277 278 if (<mode>, <count>, <type> or <primcount> is invalid) 279 generate appropriate error 280 else { 281 for (int i = 0; i < <primcount>; i++) { 282 instanceID = i; 283 DrawElementsOneInstance(<mode>, 284 <count>, 285 <type>, 286 <indices>, 287 i, 288 <baseinstance>); 289 } 290 instanceID = 0; 291 } 292 293 Add to the list of functions which include DrawElementsBaseVertex, 294 DrawRangeElementsBaseVertex, and DrawElementsInstancedBaseVertex (p.39): 295 296 void DrawElementsInstancedBaseVertexBaseInstance(enum mode, 297 sizei count, 298 enum type, 299 const void *indices, 300 sizei primcount, 301 int basevertex, 302 uint baseinstance); 303 304 Append to the paragraph describing DrawElementsBaseVertex, 305 DrawRangeElementsBaseVertex, and DrawElementsInstancedBaseVertex (p.40): 306 307 For DrawElementsInstancedBaseVertexBaseInstance, <baseinstance> is 308 used to offset the element from which instanced vertex attributes (those 309 with a non-zero divisor as specified by VertexAttribDivisor) are taken. 310 311 Update the definition of DrawElementsIndirect as follows (p.39): 312 313 The command 314 315 void DrawElementsIndirect(enum mode, 316 enum type, 317 const void *indirect ); 318 319 has the same effect as: 320 321 typedef struct { 322 uint count; 323 uint primCount; 324 uint firstIndex; 325 int baseVertex; 326 uint baseInstance; 327 } DrawElementsIndirectCommand; 328 329 if (no element array buffer is bound) { 330 generate appropriate error 331 } else { 332 const DrawElementsIndirectCommand *cmd = 333 (const DrawElementsIndirectCommand *)indirect; 334 335 DrawElementsInstancedBaseVertexBaseInstance( 336 mode, 337 cmd->count, 338 type, 339 cmd->firstIndex * size-of-type, 340 cmd->primCount, 341 cmd->baseVertex, 342 cmd->baseInstance); 343 } 344 345 Remove the sentence "Results are undefined if reservedMustBeZero is non- 346 zero, but must not lead to GL interruption or termination." 347 348Modifications to Chapter 3 of the the OpenGL 4.1 (Core Profile) Specification 349(Rasterization) 350 351 None. 352 353Modifications to Chapter 4 of the the OpenGL 4.1 (Core Profile) Specification 354(Per-Fragment Operations and the Framebuffer) 355 356 None. 357 358Modifications to Chapter 5 of the the OpenGL 4.1 (Core Profile) Specification 359(Special Functions) 360 361 None. 362 363Modifications to Chapter 6 of the the OpenGL 4.1 (Core Profile) Specification 364(State and State Requests) 365 366 None. 367 368Additions to the AGL/GLX/WGL Specifications 369 370 None. 371 372GLX Protocol 373 374 None. 375 376Errors 377 378 None. 379 380New State 381 382 None. 383 384New Implementation Dependent State 385 386 None. 387 388Conformance Testing 389 390 TBD. 391 392Issues 393 394 1) Does <baseinstance> offset gl_InstanceID? 395 396 RESOLVED: No. gl_InstanceID always starts from zero and counts up by one 397 for each instance rendered. If the shader author requires the actual value 398 of the instance index, including the base instance, they must pass the 399 base instance as a uniform. In OpenGL, the vertex attribute divisors are 400 not passed implicitly to the shader anyway, so the shader writer will need 401 to take care of this regardless. 402 403 2) Is <baseinstance> per-attribute, or global? 404 405 RESOLVED: It is global. The same base is used for all instanced attribute 406 arrays. 407 408 3) Do we need any more entry points? 409 410 DISCUSSION: Maybe. Technically, we could specify a base vertex to any 411 drawing command and any instanced vertex attributes would be taken from 412 that offset within their respective buffers. OpenGL already has enough 413 entry points. Another possibility is to actually make <baseinstance> OpenGL 414 state. The application would set it before any draw call (even non- 415 instanced ones) and this would affect the base used for any instanced vertex 416 attributes. However, this would introduce performance overhead and would not 417 work well with Draw{Arrays|Elements}Indirect. 418 419 4) DrawElementsInstancedBaseVertexBaseInstance? Really? The length of entry 420 point names is starting to get silly. Can we clean this up? 421 422 RESOLVED: Yes, we can, but not here. 423 424 5) What happens if baseInstance is > 2^31-1 (i.e., negative as a signed 425 integer)? 426 427 Need to check with hardware vendors. 428 429Revision History 430 431 Rev. Date Author Changes 432 ---- ---------- -------- ----------------------------------------- 433 7 06/13/2014 dkoch fix <baseinstance> typos in overview. 434 6 01/18/2011 Jon Leech Use floor() in computing element transferred 435 to the GL to match change in core spec. 436 5 01/10/2011 gsellers Address bugzilla 7185. Make baseinstance API 437 parameter unsigned to match structure member. 438 Add issue 5. 439 4 01/05/2011 Jon Leech Fix typos from Bug 7202. 440 3 11/09/2010 gsellers Address bugzilla 7011. Elaborate in overview 441 and issues. Add placeholder for conformance test 442 plan. 443 2 11/08/2010 gsellers Did some TODOs. Check in to SVN. 444 1 11/04/2010 gsellers Initial revision. 445