1Name 2 3 EXT_base_instance 4 5Name Strings 6 7 GL_EXT_base_instance 8 9Contact 10 11 Daniel Koch, NVIDIA (dkoch 'at' nvidia.com) 12 13Contributors 14 15 Dominik Witczak, Mobica 16 Jonas Gustavsson, Sony Mobile 17 Slawomir Grajewski, Intel 18 Contributors to ARB_base_instance 19 20Notice 21 22 Copyright (c) 2011-2014 The Khronos Group Inc. Copyright terms at 23 http://www.khronos.org/registry/speccopyright.html 24 25 Portions Copyright (c) 2014 NVIDIA Corporation. 26 27Status 28 29 Complete 30 31Version 32 33 Last Modified Date: October 24, 2014 34 Author Revision: 4 35 36Number 37 38 OpenGL ES Extension #203 39 40Dependencies 41 42 This specification is written against the OpenGL ES 3.1 (June 4, 2014) 43 Specification, although it can apply to previous versions. 44 45 OpenGL ES 3.0 is required. 46 47 EXT_draw_elements_base_vertex is required. 48 49 This extension interacts with EXT_multi_draw_indirect. 50 51Overview 52 53 This extension allows the offset within buffer objects used for instanced 54 rendering to be specified. This is congruent with the <first> parameter 55 in glDrawArrays and the <basevertex> parameter in glDrawElements. When 56 instanced rendering is performed (for example, through 57 glDrawArraysInstanced), instanced vertex attributes whose vertex attribute 58 divisors are non-zero are fetched from enabled vertex arrays per-instance 59 rather than per-vertex. However, in unextended OpenGL ES, there is no way 60 to define the offset into those arrays from which the attributes are 61 fetched. This extension adds that offset in the form of a <baseinstance> 62 parameter to several new procedures. 63 64 The <baseinstance> parameter is added to the index of the array element, 65 after division by the vertex attribute divisor. This allows several sets of 66 instanced vertex attribute data to be stored in a single vertex array, and 67 the base offset of that data to be specified for each draw. Further, this 68 extension exposes the <baseinstance> parameter as the final and previously 69 undefined structure member of the draw-indirect data structure. 70 71IP Status 72 73 None. 74 75New Procedures and Functions 76 77 void DrawArraysInstancedBaseInstanceEXT(enum mode, 78 int first, 79 sizei count, 80 sizei instancecount, 81 uint baseinstance); 82 83 void DrawElementsInstancedBaseInstanceEXT(enum mode, 84 sizei count, 85 enum type, 86 const void *indices, 87 sizei instancecount, 88 uint baseinstance); 89 90 void DrawElementsInstancedBaseVertexBaseInstanceEXT(enum mode, 91 sizei count, 92 enum type, 93 const void *indices, 94 sizei instancecount, 95 int basevertex, 96 uint baseinstance); 97 98New Tokens 99 100 None. 101 102Modifications to Chapter 10 of the OpenGL ES 3.1 Specification (Vertex 103Specification and Drawing Commands) 104 105 Modification to Section 10.5, "Drawing Commands using Vertex Arrays" 106 107 (Modify the definition of DrawArraysOneInstance, to define the 108 behaviour of the <baseinstance> parameter. Modify the 3rd paragraph 109 of the definition of the command, p.247, as follows) 110 111 "If an enabled vertex attribute array is instanced (it has a non-zero 112 <divisor> as specified by VertexAttribDivisor), the element index that 113 is transferred to the GL, for all vertices, is given by 114 115 floor(<instance> / <divisor>) + <baseinstance>" 116 117 118 (Replace the description of DrawArraysInstanced, p.248, with the 119 following) 120 121 "The command 122 123 void DrawArraysInstancedBaseInstanceEXT(enum mode, 124 int first, 125 sizei count, 126 sizei instancecount, 127 uint baseinstance); 128 129 behaves identically to DrawArrays, except that <instancecount> instances of 130 the range of elements are executed and the value of <instance> advances for 131 each iteration. Those attributes that have non-zero values for <divisor>, 132 as specified by VertexAttribDivisor, advance once every <divisor> 133 instances. Additionally, the first element within those instanced vertex 134 attributes is specified in <baseinstance>. 135 136 DrawArraysInstancedBaseInstanceEXT is equivalent to 137 138 if (<mode>, <count>, or <instancecount> is invalid) 139 generate appropriate error 140 else { 141 for (i = 0; i < <instancecount>; i++) { 142 DrawArraysOneInstance(<mode>, <first>, <count>, i, 143 <baseinstance>); 144 } 145 } 146 147 The command 148 149 void DrawArraysInstanced(enum mode, 150 int first, 151 sizei count, 152 sizei primcount); 153 154 is equivalent to 155 156 DrawArraysInstancedBaseInstanceEXT(<mode>, <first>, <count>, 157 <instancecount>, 0);" 158 159 160 161 (Update the definition of DrawArraysIndirect on p.248 as follows) 162 163 "The command 164 165 void DrawArraysIndirect(enum mode, const void *indirect); 166 167 is equivalent to 168 169 typedef struct { 170 uint count; 171 uint instanceCount; 172 uint first; 173 uint baseInstance; 174 } DrawArraysIndirectCommand; 175 176 DrawArraysIndirectCommand *cmd = 177 (DrawArraysIndirectCommand *)indirect; 178 179 DrawArraysInstancedBaseInstanceEXT(mode, 180 cmd->first, 181 cmd->count, 182 cmd->instanceCount, 183 cmd->baseInstance);" 184 185 (Retain the remainder the description of DrawArraysIndirect, but 186 delete the sentence "Results are undefined if <reservedMustBeZero> is 187 non-zero, but may not result in program termination." from the Errors 188 section.) 189 190 191 (Modify the definition of DrawElementsOneInstance, to define the 192 behaviour of the <baseinstance> parameter. Modify the 3rd paragraph 193 of the definition of the command, p.249, as follows) 194 195 "If an enabled vertex attribute array is instanced (it has a non-zero 196 attribute divisor as specified by VertexAttribDivisor), the element that 197 is transferred to the GL is given by: 198 199 floor(<instance> / <divisor>) + <baseinstance>" 200 201 202 (Update the text describing DrawElements, p.250, to mention the 203 <baseinstance> parameter) 204 205 "The command 206 207 void DrawElements(enum mode, 208 sizei count, 209 enum type, 210 const void *indices); 211 212 behaves identically to DrawElementsOneInstance with the <instance> and 213 <baseinstance> parameters set to zero; the effect of calling ..." 214 215 216 (Replace the description of DrawElementsInstanced, p.251, with the 217 following) 218 219 "The command 220 221 void DrawElementsInstancedBaseInstanceEXT(enum mode, 222 sizei count, 223 enum type, 224 const void *indices, 225 sizei instancecount, 226 uint baseinstance); 227 228 behaves identically to DrawElements except that <instancecount> instances 229 of the set of elements are executed, the value of <instance> advances 230 between each set. Instanced attributes are advanced as they do during 231 execution of DrawArraysInstancedBaseInstaceEXT, and <baseinstance> has 232 the same effect. It is equivalent to: 233 234 if (<mode>, <count>, <type> or <instancecount> is invalid) 235 generate appropriate error 236 else { 237 for (int i = 0; i < <instancecount>; i++) { 238 DrawElementsOneInstance(<mode>, <count>, <type>, <indices>, 239 i, <baseinstance>); 240 } 241 } 242 243 The command 244 245 void DrawElementsInstanced(enum mode, sizei count, enum type, 246 const void *indices, sizei instancecount); 247 248 behaves identically to DrawElementsInstancedBaseInstanceEXT except that 249 <baseinstance> is zero. It is equivalent to 250 251 DrawElementsInstancedBaseInstanceEXT(<mode>, <count>, <type>, 252 <indices>, <instancecount>, 0);" 253 254 255 (Add to the list of functions which include DrawElementsBaseVertexEXT, 256 DrawRangeElementsBaseVertexEXT, and DrawElementsInstancedBaseVertexEXT 257 (as added by EXT_draw_elements_base_vertex)) 258 259 void DrawElementsInstancedBaseVertexBaseInstanceEXT(enum mode, 260 sizei count, 261 enum type, 262 const void *indices, 263 sizei instancecount, 264 int basevertex, 265 uint baseinstance); 266 267 (Append a new paragraph after the description of DrawElementsBaseVertexEXT, 268 DrawRangeElementsBaseVertexEXT, and DrawElementsInstancedBaseVertexEXT 269 (as added by EXT_draw_elements_base_vertex)) 270 271 "For DrawElementsInstancedBaseVertexBaseInstanceEXT, <baseinstance> is 272 used to offset the element from which instanced vertex attributes (those 273 with a non-zero divisor as specified by VertexAttribDivisor) are taken." 274 275 276 (Update the definition of DrawElementsIndirect on p.252 as follows) 277 278 "The command 279 280 void DrawElementsIndirect(enum mode, 281 enum type, 282 const void *indirect ); 283 284 is equivalent to: 285 286 typedef struct { 287 uint count; 288 uint instanceCount; 289 uint firstIndex; 290 int baseVertex; 291 uint baseInstance; 292 } DrawElementsIndirectCommand; 293 294 if (no element array buffer is bound) { 295 generate appropriate error 296 } else { 297 DrawElementsIndirectCommand *cmd = 298 (DrawElementsIndirectCommand *)indirect; 299 300 DrawElementsInstancedBaseVertexBaseInstanceEXT( 301 mode, 302 cmd->count, 303 type, 304 cmd->firstIndex * size-of-type, 305 cmd->instanceCount, 306 cmd->baseVertex, 307 cmd->baseInstance); 308 }" 309 310 (Retain the remainder of the description of DrawElementsIndirect, but 311 delete the sentence "Results are undefined if <reservedMustBeZero> is 312 non-zero, but may not result in program termination." from the Errors 313 section.) 314 315Additions to the EGL/AGL/GLX/WGL Specifications 316 317 None. 318 319Dependencies on EXT_multi_draw_indirect. 320 321 If EXT_multi_draw_indirect is supported, this extension adds <baseInstance> 322 support for the MultiDraw*Indirect commands as well, because they share 323 the same command structures. 324 325Errors 326 327 The errors for DrawArraysInstancedBaseInstanceEXT are equivalent to the 328 errors for DrawArraysInstanced, but are repeated here for clarity: 329 330 - An INVALID_ENUM error is generated if <mode> is not one of the primitive 331 types defined in section 10.1. 332 - Specifying <first> < 0 results in undefined behavior. Generating an 333 INVALID_VALUE error is recommended in this case. 334 - An INVALID_VALUE error is generated if <count> is negative. 335 336 The errors for DrawElementsInstancedBaseInstanceEXT and 337 DrawElementsInstancedBaseVertexBaseInstanceEXT are equivalent to the 338 errors for DrawElementsInstanced, but are repeated here for clarity: 339 340 - An INVALID_ENUM error is generated if <mode> is not one of the primitive 341 types defined in section 10.1. 342 - An INVALID_ENUM error is generated if <type> is not UNSIGNED_BYTE, 343 UNSIGNED_SHORT, or UNSIGNED_INT. 344 - Using an index value greater than MAX_ELEMENT_INDEX will result in 345 undefined implementation-dependent behavior, unless primitive restart is 346 enabled (see section 10.3.4) and the index value is 2^32 − 1. 347 348New State 349 350 None. 351 352New Implementation Dependent State 353 354 None. 355 356Conformance Testing 357 358 TBD. 359 360Issues 361 362 Note: These issues apply specifically to the definition of the 363 EXT_base_instance specification, which is based on the OpenGL 364 extension ARB_base_instance as updated in OpenGL 4.4. 365 ARB_base_instance can be found in the OpenGL Registry. 366 367 (1) What functionality was removed from ARB_base_instance? 368 369 Nothing. Although there is less language here because ES 3.1 already 370 includes some of the reorganizing that the original extension added. 371 372 (2) What functionality was changed and added relative to 373 ARB_base_instance? 374 375 - EXT_base_instance more closely matches the language of OpenGL 4.4 376 - the <primCount> parameter was renamed to <instanceCount> 377 378 (3) Do these new draw calls require a vertex array object to be bound? 379 380 RESOLVED: No. The DrawArrays and DrawArraysInstanced commands do not 381 require a vertex array object to be bound in ES 3.1 and since these are 382 specializations of DrawArraysInstancedBaseInstanceEXT, it also does not 383 require one to be bound. Similarly the DrawElements and 384 DrawElementsInstanced commands do not require a vertex array object to be 385 bound in ES 3.1, and since these commands are specializations of 386 DrawElementsInstancedBaseInstanceEXT and 387 DrawElementsInstancedBaseVertexBaseInstanceEXT, these commands also do not 388 require one to be bound. 389 390 (4) Do these new draw calls support client memory arrays? 391 392 RESOLVED: Yes. There are no restrictions on using client-side memory for 393 the other direct drawing commands in ES 3.1, so these command support 394 them as well. As per issue (3), the old commands are specializations of 395 the new commands, so we keep a comparable feature set. 396 397 398Revision History 399 400 Rev. Date Author Changes 401 ---- ---------- -------- ----------------------------------------- 402 4 10/24/2014 dkoch Mark complete and issues resolved. 403 404 3 06/24/2014 dkoch Fix typographical issues noted by Dominik. 405 406 2 06/20/2014 dkoch Add interaction with EXT_multi_draw_indirect. 407 408 1 06/13/2014 dkoch Initial version for ES based on v6 of 409 ARB_base_instance. 410