1Name 2 3 ARB_draw_indirect 4 5Name Strings 6 7 GL_ARB_draw_indirect 8 9Contact 10 11 Jeff Bolz, NVIDIA Corporation (jbolz 'at' nvidia.com) 12 Pat Brown, NVIDIA Corporation (pbrown 'at' nvidia.com) 13 14Contributors 15 16 Barthold Lichtenbelt, NVIDIA 17 Bill Licea-Kane, AMD 18 Bruce Merry, ARM 19 Graham Sellers, AMD 20 Greg Roth, NVIDIA 21 Nick Haemel, AMD 22 Pierre Boudier, AMD 23 Piers Daniell, NVIDIA 24 25Notice 26 27 Copyright (c) 2010-2013 The Khronos Group Inc. Copyright terms at 28 http://www.khronos.org/registry/speccopyright.html 29 30Specification Update Policy 31 32 Khronos-approved extension specifications are updated in response to 33 issues and bugs prioritized by the Khronos OpenGL Working Group. For 34 extensions which have been promoted to a core Specification, fixes will 35 first appear in the latest version of that core Specification, and will 36 eventually be backported to the extension document. This policy is 37 described in more detail at 38 https://www.khronos.org/registry/OpenGL/docs/update_policy.php 39 40Status 41 42 Complete. Approved by the ARB at the 2010/01/22 F2F meeting. 43 Approved by the Khronos Board of Promoters on March 10, 2010. 44 45Version 46 47 Last Modified Date: 09/17/2012 48 Revision: 7 49 50Number 51 52 ARB Extension #87 53 54Dependencies 55 56 OpenGL 3.1 is required. 57 58 This extension is written against the OpenGL 3.2 specification with 59 the Compatibility Profile. 60 61 This extension interacts with NV_vertex_buffer_unified_memory. 62 63 This extension interacts with ARB_instanced_arrays. 64 65 This extension interacts with ARB_compatibility. 66 67Overview 68 69 This extension provides a mechanism for supplying the arguments to a 70 DrawArraysInstanced or DrawElementsInstancedBaseVertex from buffer object 71 memory. This is not particularly useful for applications where the CPU 72 knows the values of the arguments beforehand, but is helpful when the 73 values will be generated on the GPU through any mechanism that can write 74 to a buffer object including image stores, atomic counters, or compute 75 interop. This allows the GPU to consume these arguments without a round- 76 trip to the CPU or the expensive synchronization that would involve. This 77 is similar to the DrawTransformFeedbackEXT command from 78 EXT_transform_feedback2, but offers much more flexibility in both 79 generating the arguments and in the type of Draws that can be accomplished. 80 81IP Status 82 83 No known IP claims. 84 85New Procedures and Functions 86 87 void DrawArraysIndirect(enum mode, const void *indirect); 88 void DrawElementsIndirect(enum mode, enum type, const void *indirect); 89 90New Tokens 91 92 Accepted by the <target> parameters of BindBuffer, BufferData, 93 BufferSubData, MapBuffer, UnmapBuffer, GetBufferSubData, 94 GetBufferPointerv, MapBufferRange, FlushMappedBufferRange, 95 GetBufferParameteriv, and CopyBufferSubData: 96 97 DRAW_INDIRECT_BUFFER 0x8F3F 98 99 Accepted by the <value> parameter of GetIntegerv, GetBooleanv, GetFloatv, 100 and GetDoublev: 101 102 DRAW_INDIRECT_BUFFER_BINDING 0x8F43 103 104Additions to Chapter 2 of the OpenGL 3.2 Specification (OpenGL Operation) 105 106 Add to Section 2.8.1 p. 40 (Drawing Commands) 107 108 The command 109 110 DrawArraysIndirect(enum mode, const void *indirect); 111 112 behaves as follows: 113 114 typedef struct { 115 GLuint count; 116 GLuint primCount; 117 GLuint first; 118 GLuint reservedMustBeZero; 119 } DrawArraysIndirectCommand; 120 121 if (mode is invalid) { 122 generate appropriate error 123 } else { 124 DrawArraysIndirectCommand *cmd = (DrawArraysIndirectCommand *)indirect; 125 DrawArraysInstanced(mode, cmd->first, cmd->count, cmd->primCount); 126 } 127 128 As with regular DrawArraysInstanced commands, the vertex attributes 129 may be sourced from client arrays or vertex buffer objects (if buffers 130 are bound). Unlike regular DrawArraysInstanced commands, the <first> 131 argument is unsigned and cannot cause an error. The results are undefined 132 if <reservedMustBeZero> is non-zero and may not result in program 133 termination. 134 135 The command 136 137 DrawElementsIndirect(enum mode, enum type, const void *indirect); 138 139 behaves as follows: 140 141 typedef struct { 142 GLuint count; 143 GLuint primCount; 144 GLuint firstIndex; 145 GLint baseVertex; 146 GLuint reservedMustBeZero; 147 } DrawElementsIndirectCommand; 148 149 if (mode or type is invalid, or no index buffer) { 150 generate appropriate error 151 } else { 152 DrawElementsIndirectCommand *cmd = (DrawElementsIndirectCommand *)indirect; 153 154 DrawElementsInstancedBaseVertex(mode, cmd->count, type, 155 cmd->firstIndex * size-of-type, cmd->primCount, cmd->baseVertex); 156 } 157 158 As with regular DrawElementsInstancedBaseVertex commands, the vertex 159 attributes may be sourced from client arrays or vertex buffer objects 160 (if objects are bound). Unlike regular DrawElementsInstancedBaseVertex 161 commands, the indices may not come from a client array and must come from 162 an index buffer. If no element array buffer is bound, an INVALID_OPERATION 163 error is generated. The results are undefined if <reservedMustBeZero> is 164 non-zero and may not result in program termination. 165 166 All elements of DrawArraysIndirectCommand and 167 DrawElementsIndirectCommand are 32bit values, and both structures are 168 tightly packed. 169 170 Add to Section 2.9 (Buffer Objects) 171 172 Add to Table 2.7 (p. 48): 173 174 Target name Purpose Described in sections(s) 175 ----------------------- ---------- ------------------------- 176 DRAW_INDIRECT_BUFFER Indirect draw commands 2.9.9 177 178 Add a new Section 2.9.9 (Indirect Commands in Buffer Objects) 179 180 Arguments to DrawArraysIndirect and DrawElementsIndirect commands 181 may be stored in buffer objects. 182 183 Initially zero is bound to DRAW_INDIRECT_BUFFER. In the 184 compatibility profile, this indicates that DrawArraysIndirect and 185 DrawElementsIndirect are to source their arguments directly from the 186 pointer passed as their <indirect> parameters. In the core profile, 187 an INVALID_OPERATION error is generated if zero is bound to 188 DRAW_INDIRECT_BUFFER and DrawArraysIndirect or DrawElementsIndirect 189 is called. 190 191 A buffer object is bound to DRAW_INDIRECT_BUFFER by calling 192 BindBuffer with <target> set to DRAW_INDIRECT_BUFFER, and <buffer> 193 set to the name of the buffer object. If no corresponding buffer 194 object exists, one is initialized as defined in section 2.9. 195 196 While a non-zero buffer object name is bound to DRAW_INDIRECT_BUFFER, 197 DrawArraysIndirect and DrawElementsIndirect source their arguments 198 from that buffer object, using their <indirect> parameters as offsets 199 into the buffer object in the same fashion as described in section 2.9.3. 200 An INVALID_OPERATION error is generated if the commands source data 201 beyond the end of the buffer object or if <indirect> is not word aligned. 202 203Additions to Chapter 3 of the OpenGL 3.2 Specification (Rasterization) 204 205 None. 206 207Additions to Chapter 4 of the OpenGL 3.2 Specification (Per-Fragment 208Operations and the Frame Buffer) 209 210 None. 211 212Additions to Chapter 5 of the OpenGL 3.2 Specification (Special Functions) 213 214 None. 215 216Additions to Chapter 6 of the OpenGL 3.2 Specification (State and 217State Requests) 218 219 None. 220 221Additions to Appendix A of the OpenGL 3.2 Specification (Invariance) 222 223 None. 224 225Additions to the AGL/GLX/WGL Specifications 226 227 None. 228 229GLX Protocol 230 231 TBD. 232 233Errors 234 235 INVALID_ENUM is generated by DrawArraysIndirect/DrawElementsIndirect 236 if <mode> is not a valid begin mode. 237 238 INVALID_ENUM is generated by DrawElementsIndirect if <type> is not 239 one of UNSIGNED_BYTE, UNSIGNED_SHORT, or UNSIGNED_INT. 240 241 INVALID_OPERATION is generated by DrawElementsIndirect if no buffer 242 is bound to ELEMENT_ARRAY_BUFFER. 243 244 INVALID_OPERATION is generated by DrawArraysIndirect and 245 DrawElementsIndirect if zero is bound to DRAW_INDIRECT_BUFFER and if 246 the OpenGL context implements the core profile. 247 248 INVALID_OPERATION is generated by DrawArraysIndirect and 249 DrawElementsIndirect if commands source data beyond the end of a buffer 250 object or if <indirect> is not word aligned. 251 252New State 253 254 Update Table 6.11, p. 405 (Vertex Array Data not in Vertex Array objects) 255 256 Get Value Type Get Command Initial Value Sec Attribute 257 --------- ---- ----------- ------------- --- --------- 258 DRAW_INDIRECT_BUFFER_BINDING Z+ GetIntegerv 0 2.9 none 259 260New Implementation Dependent State 261 262 None. 263 264Dependencies on NV_vertex_buffer_unified_memory 265 266 If NV_vertex_buffer_unified_memory is supported, the following additional 267 edits are required: 268 269 Accepted by the <cap> parameter of GetBufferParameterui64vNV: 270 271 DRAW_INDIRECT_BUFFER. 272 273 Accepted by the <cap> parameter of DisableClientState, 274 EnableClientState, IsEnabled: 275 276 DRAW_INDIRECT_UNIFIED_NV 0x8F40 277 278 Accepted by the <pname> parameter of BufferAddressRangeNV 279 and the <value> parameter of GetIntegerui64vNV: 280 281 DRAW_INDIRECT_ADDRESS_NV 0x8F41 282 283 Accepted by the <value> parameter of GetIntegerv: 284 285 DRAW_INDIRECT_LENGTH_NV 0x8F42 286 287 In Section 2.8.1, mention that vertex attributes and indices may be 288 sourced from GPU addresses if VERTEX_ATTRIB_ARRAY_UNIFIED_NV/ 289 ELEMENT_ARRAY_UNIFIED_NV are enabled. 290 291 Add to Section 2.9: 292 293 While DRAW_INDIRECT_UNIFIED_NV is enabled, DrawArraysIndirect and 294 DrawElementsIndirect, source their arguments from the address 295 specified by the command BufferAddressRange where <pname> is 296 DRAW_INDIRECT_ADDRESS_NV and <index> is zero, added to the <indirect> 297 parameter. If the commands source data beyond and including (<address> 298 + <length>), an INVALID_OPERATION error will be generated. If the draw 299 indirect address range does not belong to a buffer object that is 300 resident at the time of the Draw, undefined results, possibly 301 including program termination, may occur. 302 303 INVALID_OPERATION is generated by DrawElementsIndirect if no buffer 304 is bound to ELEMENT_ARRAY_BUFFER and DRAW_INDIRECT_UNIFIED_NV is 305 disabled. 306 307 INVALID_OPERATION is generated by DrawArraysIndirect and 308 DrawElementsIndirect if DRAW_INDIRECT_UNIFIED_NV is enabled and 309 commands source data beyond and including (address + length). 310 311 Update Table 6.11: 312 313 Get Value Type Get Command Initial Value Sec Attribute 314 --------- ---- ----------- ------------- --- --------- 315 DRAW_INDIRECT_UNIFIED_NV B IsEnabled FALSE 2.9 none 316 DRAW_INDIRECT_ADDRESS_NV Z64+ GetIntegerui64vNV 0 2.9 none 317 DRAW_INDIRECT_LENGTH_NV Z+ GetIntegerv 0 2.9 none 318 319Dependencies on NV_vertex_buffer_unified_memory and ARB_compatibility 320 321 If the context version is greater than 3.0 and does not include 322 ARB_compatibility functionality, then EnableClientState and 323 DisableClientState have been deprecated and removed. This extension 324 adds back those commands if NV_vertex_buffer_unified_memory is supported, 325 but only requires that they accept the DRAW_INDIRECT_UNIFIED_NV token. 326 327Dependencies on ARB_compatibility 328 329 When the ARB_compatibility extension is not supported, client arrays 330 cannot be used to source vertex attribute data. 331 332Dependencies on ARB_instanced_arrays 333 334 This extension does not require ARB_instanced_arrays, but reserves 335 space in the Command structures such that a future extension could 336 add a "firstInstance" member which would initialize the instance 337 counter used for computing which vertex attrib array element to use. 338 Note that ARB_instanced_arrays does not currently support 339 "firstInstance", it only has a frequency divider. 340 341Issues 342 343 (1) What is this good for? 344 345 RESOLVED: Compute interoperability. Recirculating results written via 346 image stores or atomic counters. 347 348 (2) Should we allow indirect draws from client memory? Should we have a 349 buffer object binding for this? 350 351 RESOLVED: YES. Although, using client vertex arrays would somewhat defeat 352 the purpose of this extension. Note that this issue only applies to 353 implementations supporting the ARB_compatibility extension. 354 355 One non-obvious restriction is that DrawElementsIndirect doesn't accept 356 an <indices> parameter, so an index buffer is required. 357 358 (3) How do we specify the index size for DrawElements calls? 359 360 RESOLVED: Passed into the command, not pulled out of the struct. 361 362 (4) For DrawElements calls, in what unit are the offsets into the index 363 buffer. 364 365 RESOLVED: In indices, not in bytes. 366 367 (5) Should the new state be part of the VAO? 368 369 RESOLVED: No. 370 371 (6) Should gl.h/glext.h provide structure definitions? 372 373 RESOLVED. No. It is not possible to define the structures in such a way 374 that all compilers would pack them correctly. 375 376Revision History 377 378 Rev. Date Author Changes 379 ---- -------- -------- ------------------------------------------------ 380 7 09/17/2012 Jon Leech Remove BindBufferRange/Base from commands for 381 which DRAW_INDIRECT_BUFFER is a valid target 382 (Bug 7794). 383 384 6 03/07/2012 Jon Leech Add missing error when no indirect buffer is 385 bound and the indirect draw commands are 386 called (Bug 7211). 387 388 5 12/07/2009 pdaniell Remove ARB suffix from new tokens for core spec. 389 390 4 10/29/2009 pdaniell Convert to ARB. 391 392 3 10/21/2009 pdaniell Minor edits based on Bruce's feedback. Added 393 full list of Get* calls for new 394 DRAW_INDIRECT_BUFFER_BINDING_EXT token. 395 Specified behavior when reservedMustBeZero is 396 non-zero. Added INVALID_VALUE error when 397 <indirect> is not a multiple of GLuint. 398 399 2 jbolz Internal revisions. 400 401 1 pbrown Internal revisions. 402