1Name 2 3 NV_instanced_arrays 4 5Name Strings 6 7 GL_NV_instanced_arrays 8 9Contributors 10 11 Contributors to ARB_instanced_arrays and ANGLE_instanced_arrays 12 Mathias Heyer, NVIDIA 13 Greg Roth, NVIDIA 14 15Contact 16 17 Greg Roth, NVIDIA (groth 'at' nvidia 'dot' com) 18 19Status 20 21 Complete 22 23Version 24 25 Last Modified Date: Aug 28, 2012 26 Author Revision: 4 27 28Number 29 30 OpenGL ES Extension #145 31 32Dependencies 33 34 OpenGL ES 2.0 is required. 35 36 This extension is written against the OpenGL ES 2.0.25 37 Specification. 38 39 NV_draw_instanced affects the definition of this extension. 40 41 OES_element_index_uint affects the definition of this extension. 42 43 OES_vertex_array_object affects the definition of this extension. 44 45Overview 46 47 A common use case in GL for some applications is to be able to 48 draw the same object, or groups of similar objects that share 49 vertex data, primitive count and type, multiple times. This 50 extension provides a means of accelerating such use cases while 51 limiting the number of required API calls, and keeping the amount 52 of duplicate data to a minimum. 53 54 In particular, this extension specifies an alternative to the 55 read-only shader variable introduced by NV_draw_instanced. It 56 uses the same draw calls introduced by that extension, but 57 redefines them so that a vertex shader can instead use vertex 58 array attributes as a source of instance data. 59 60 This extension introduces an array "divisor" for generic 61 vertex array attributes, which when non-zero specifies that the 62 attribute is "instanced." An instanced attribute does not 63 advance per-vertex as usual, but rather after every <divisor> 64 conceptual draw calls. 65 66 (Attributes which aren't instanced are repeated in their entirety 67 for every conceptual draw call.) 68 69 By specifying transform data in an instanced attribute or series 70 of instanced attributes, vertex shaders can, in concert with the 71 instancing draw calls, draw multiple instances of an object with 72 one draw call. 73 74New Procedures and Functions 75 76 void VertexAttribDivisorNV(uint index, uint divisor); 77 78New Tokens 79 80 Accepted by the <pname> parameters of GetVertexAttribfv, and 81 GetVertexAttribiv: 82 83 VERTEX_ATTRIB_ARRAY_DIVISOR_NV 0x88FE 84 85Additions to Chapter 2 of the OpenGL ES 2.0.25 Specification 86(OpenGL ES Operation) 87 88 Modify section 2.8 (Vertex Arrays) 89 90 After description of EnableVertexAttribArray / 91 DisableVertexAttribArray add the following: 92 93 The internal counter <instanceID> is a 32-bit integer value which 94 may be read by a vertex shader as <gl_InstanceIDNV>, as 95 described in section 2.10.5.2. The value of this counter is 96 always zero, except as noted below. 97 98 The command 99 100 void VertexAttribDivisorNV(uint index, uint divisor); 101 102 modifies the rate at which generic vertex attributes advance when 103 rendering multiple instances of primitives in a single draw call. 104 If <divisor> is zero, the attribute at slot <index> advances once 105 per vertex. If <divisor> is non-zero, the attribute advances once 106 per <divisor> instances of the set(s) of vertices being rendered. 107 An attribute is referred to as "instanced" if its <divisor> value is 108 non-zero. 109 110 Replace the text describing DrawArrays and DrawElements in the 111 "Transferring Array Elements" subsection of 2.8, from the second paragraph 112 through the end of the section with the following: 113 114 The function 115 116 void DrawArraysOneInstance( enum mode, int first, sizei count, int instance ); 117 118 does not exist in the GL, but is used to describe functionality in 119 the rest of this section. This function constructs a sequence of 120 geometric primitives using the indicated elements of enabled arrays. 121 <mode> specifies what kind of primitives are constructed, as defined 122 in section 2.6.1. Elements <first> through <first> + <count> - 1 of 123 enabled non-instanced arrays are transferred to the GL. 124 If an enabled vertex attribute array is instanced (it has a non-zero 125 attribute <divisor> as specified by VertexAttribDivisorNV), the 126 element that is transferred to the GL is given by: 127 128 floor( <instance> / <divisor> ). 129 130 If an array corresponding to a generic attribute required by a 131 vertex shader is not enabled, then the corresponding element is 132 taken from the current generic attribute state (see section 2.7). 133 134 If an array corresponding to a attribute required by a vertex 135 shader is enabled, the corresponding current generic attribute value 136 is unaffected by the execution of DrawArraysOneInstance. 137 138 Specifying <first> < 0 results in undefined behavior. Generating 139 the error INVALID_VALUE is recommended in this case. 140 141 The command 142 143 void DrawArrays( enum mode, int first, sizei count ); 144 145 behaves identically to DrawArraysOneInstance with the instance 146 set to zero; the effect of calling 147 148 DrawArrays(mode, first, count); 149 150 is equivalent to the command sequence: 151 152 if (mode or count is invalid ) 153 generate appropriate error 154 else 155 DrawArraysOneInstance(mode, first, count, 0); 156 157 The command 158 159 void DrawArraysInstancedNV(enum mode, int first, sizei count, 160 sizei primcount); 161 162 behaves identically to DrawArrays except that <primcount> 163 instances of the range of elements are executed, the value of 164 <instanceID> advances for each iteration, and the instance advances 165 between each set. Instanced attributes that have <divisor> N, (where 166 N > 0, as specified by VertexAttribDivisorNV advance once every N 167 instances. 168 169 It has the same effect as: 170 171 if (mode, count, or primcount is invalid) 172 generate appropriate error 173 else { 174 for (i = 0; i < primcount; i++) { 175 instanceID = i; 176 DrawArraysOneInstance(mode, first, count, i); 177 } 178 instanceID = 0; 179 } 180 181 The function 182 183 void DrawElementsOneInstance( enum mode, sizei count, enum type, 184 void *indices, int instance ); 185 186 does not exist in the GL, but is used to describe functionality in 187 the rest of this section. This function constructs a sequence of 188 geometric primitives by successively transferring the <count> 189 elements whose indices are stored in <indices>. <type> must be one 190 of UNSIGNED_BYTE, UNSIGNED_SHORT, or UNSIGNED_INT, indicating that 191 the values in <indices> are indices of GL type ubyte, ushort, or 192 uint respectively. <mode> specifies what kind of primitives are 193 constructed, as defined in section 2.6.1. 194 195 If an enabled vertex attribute array is instanced (it has a non-zero 196 attribute <divisor> as specified by VertexAttribDivisorNV), the 197 element that is transferred to the GL is given by: 198 199 floor( <instance> / <divisor> ); 200 201 If an array corresponding to a generic attribute required by a 202 vertex shader is not enabled, then the corresponding element is 203 taken from the current generic attribute state (see section 2.7). 204 Otherwise, if an array is enabled, the corresponding current 205 generic attribute value is unaffected by the execution of 206 DrawElementsOneInstance. 207 208 The command 209 210 void DrawElements( enum mode, sizei count, enum type, 211 void *indices ); 212 213 behaves identically to DrawElementsOneInstance with <instance> set 214 to zero; the effect of calling 215 216 DrawElements(mode, count, type, indices); 217 218 is equivalent to the command sequence: 219 220 if (mode, count or type is invalid ) 221 generate appropriate error 222 else 223 DrawElementsOneInstance(mode, count, type, indices, 0); 224 225 The command 226 227 void DrawElementsInstancedNV(enum mode, sizei count, enum type, 228 const void *indices, sizei primcount); 229 230 behaves identically to DrawElements except that <primcount> 231 instances of the set of elements are executed, the value of 232 <instanceID> advances for each iteration, and the instance 233 advances between each set. Instanced attributes are advanced as 234 they do during the execution of DrawArraysInstancedNV. It has the 235 same effect as: 236 237 if (mode, count, primcount, or type is invalid ) 238 generate appropriate error 239 else { 240 for (int i = 0; i < primcount; i++) { 241 instanceID = i; 242 DrawElementsOneInstance(mode, count, type, indices, i); 243 } 244 instanceID = 0; 245 } 246 247 If the number of supported generic vertex attributes (the value of 248 MAX_VERTEX_ATTRIBS) is <n>, then the client state required to 249 implement vertex arrays consists of <n> boolean values, <n> memory 250 pointers, <n> integer stride values, <n> symbolic constants 251 representing array types, <n> integers representing values per 252 element, <n> boolean values indicating normalization, and <n> 253 integers representing vertex attribute divisors. 254 255 In the initial state, the boolean values are each false, the memory 256 pointers are each NULL, the strides are each zero, the array types 257 are each FLOAT, the integers representing values per element are 258 each four, and the divisors are each zero. 259 260 Modify section 2.10, "Vertex Array Objects" (Added by OES_vertex_array_object) 261 262 Add VERTEX_ATTRIB_ARRAY_DIVISOR_NV to the list of state included in 263 the vertex array object type vector. 264 265Additions to Chapter 6 of the OpenGL ES 2.0.25 Specification (State and 266State Requests) 267 268 In section 6.1.8, add VERTEX_ATTRIB_ARRAY_DIVISOR_NV to the list of 269 pnames accepted by GetVertexAttribfv and GetVertexAttribiv: 270 271Dependencies on OES_element_index_uint 272 273 If OES_element_index_uint is not supported, removed all references 274 to UNSIGNED_INT indices and the associated GL data type uint in 275 the description of DrawElementsOneInstance. 276 277Dependencies on NV_draw_instanced 278 279 If NV_draw_instanced is not supported, all references to 280 instanceID should be removed from section 2.8. This extension 281 will introduce the following additional New Procedures and 282 Functions: 283 284 void DrawArraysInstancedNV(enum mode, int first, sizei count, 285 sizei primcount); 286 void DrawElementsInstancedNV(enum mode, sizei count, enum type, 287 const void *indices, sizei primcount); 288 289Dependencies on OES_vertex_array_object 290 291 If OES_vertex_array_object is not supported, ignore all edits to 292 section 2.10, "Vertex Array Objects". 293 294Errors 295 296 INVALID_VALUE is generated by VertexAttribDivisorNV if <index> 297 is greater than or equal to MAX_VERTEX_ATTRIBS. 298 299 INVALID_ENUM is generated by DrawElementsInstancedNV if <type> is 300 not one of UNSIGNED_BYTE, UNSIGNED_SHORT or UNSIGNED_INT. 301 302 INVALID_VALUE is generated by DrawArraysInstancedNV if <first>, 303 <count>, or <primcount> is less than zero. 304 305 INVALID_ENUM is generated by DrawArraysInstancedNV or 306 DrawElementsInstancedNV if <mode> is not one of the modes described in 307 section 2.6.1. 308 309 INVALID_VALUE is generated by DrawElementsInstancedNV if <count> or 310 <primcount> is less than zero. 311 312New State 313 314 Changes to table 6.2 (Vertex Array Data) 315 316 Initial 317 Get Value Type Get Command Value Description Sec. Attribute 318 --------- ---- --------------- ------- ----------- ---- --------- 319 VERTEX_ATTRIB_ARRAY_DIVISOR_NV 8xZ+ GetVertexAttrib 0 Instance Divisor 2.8 vertex-array 320 321Issues 322 323 324 1) Should generic attrib zero be instance-able? 325 326 Resolved: Yes. Attribute zero does not necessarily contain 327 position information. 328 329 2) This extension must elaborate on the definition of functions 330 added by NV_draw_instanced. How do we do this in a manner such 331 that both extensions may coexist? 332 333 Resolved: This extension is specified so that it applies on 334 top of NV_draw_instanced. As a result, some portions modified 335 by that extension are replaced in this extension. In the 336 event that NV_draw_instanced is not supported, this extension 337 reintroduces the draw calls from NV_draw_instanced. 338 339 3) Should current generic attributes be affected by the execution of 340 DrawArraysOneInstance? 341 342 Resolved: No. ANGLE says no. ARB says maybe. Defined behavior is 343 always better. The wishy washy ARB language is likely to permit 344 a software implementation without excessive state resetting. This 345 Is not terribly useful if implemented in software. 346 347 348 4) Can all vertex attributes be instanced simultaneously? 349 350 Resolved: No. In rare cases it is possible for no attribute to 351 have a divisor of 0, meaning that all attributes are instanced 352 and none of them are regularly indexed. This in turn means each 353 instance can only have a single position element, and so it only 354 actually renders something when rendering point primitives. This 355 is not a very meaningful way of using instancing (which is likely 356 why D3D restricts stream 0 to be indexed regularly for position 357 data in the first place). 358 359Revision History 360 361 Rev. Date Author Changes 362 ---- ------------- --------- ---------------------------------------- 363 4 28 Aug 2012 groth Various spelling corrections and minor clarifications 364 3 20 Aug 2012 groth Add interaction with VAOs 365 2 19 Aug 2012 groth Correct section number 366 1 12 Aug 2012 groth Initial GLES2 version from ARB_instanced_arrays 367 with inspiration from ANGLE_instanced_arrays 368