1Name 2 3 EXT_multi_draw_indirect 4 5Name Strings 6 7 GL_EXT_multi_draw_indirect 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_multi_draw_indirect 19 20Notice 21 22 Copyright (c) 2012-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 Revision: 4 35 36Number 37 38 OpenGL ES Extension #205 39 40Dependencies 41 42 OpenGL ES 3.1 is required. 43 44 This specification is written against the OpenGL ES 3.1 (June 4, 2014) 45 Specification. 46 47 This extension interacts with EXT_base_instance. 48 49 This extension interacts with EXT_geometry_shader. 50 51Overview 52 53 The ARB_draw_indirect extension (included in OpenGL 4.0 and OpenGL ES 3.1) 54 introduced mechanisms whereby the parameters for a draw function may be 55 provided in a structure contained in a buffer object rather than as 56 parameters to the drawing procedure. This is known as an indirect draw and 57 is exposed as two new functions, glDrawArraysIndirect and 58 glDrawElementsIndirect. Each of these functions generates a single batch 59 of primitives. 60 61 This extension builds on this functionality by providing procedures to 62 invoke multiple draws from a single procedure call. This allows large 63 batches of drawing commands to be assembled in server memory (via a buffer 64 object) which may then be dispatched through a single function call. 65 66New Procedures and Functions 67 68 void MultiDrawArraysIndirectEXT(enum mode, 69 const void *indirect, 70 sizei drawcount, 71 sizei stride); 72 73 void MultiDrawElementsIndirectEXT(enum mode, 74 enum type, 75 const void *indirect, 76 sizei drawcount, 77 sizei stride); 78 79New Tokens 80 81 None. 82 83Additions to Chapter 10 of the OpenGL ES 3.1 Specification (Vertex 84Specification and Drawing Commands) 85 86 Additions to 10.3.8, "Indirect Commands in Buffer Objects", p. 244 87 88 Add MultiDrawArraysIndirectEXT and MultiDrawElementsIndirectEXT 89 to the list of "indirect commands" in the first paragraph of the section. 90 91 In the second paragraph of the section replace the reference to 92 "Draw*Indirect" commands with a reference to "*Draw*Indirect" so 93 that it is clear that this statement applies to the MultiDraw 94 variants of the commands as well. 95 96 Update Table 10.3 "Indirect commands and corresponding indirect buffer 97 targets" adding the following two rows: 98 99 Indirect Command Name | Indirect Buffer <target> 100 --------------------------------------------------------- 101 MultiDrawArraysIndirectEXT | DRAW_INDIRECT_BUFFER 102 MultiDrawElementsIndirectEXT | DRAW_INDIRECT_BUFFER 103 104 105 Additions to Section 10.5, "Drawing Commands using Vertex Arrays" 106 107 (After the description of DrawArraysIndirect and before the introduction of 108 DrawElementsOneInstance, insert the following on p.249) 109 110 "The command 111 112 void MultiDrawArraysIndirectEXT(enum mode, 113 const void *indirect, 114 sizei drawcount, 115 sizei stride); 116 117 behaves identically to DrawArraysIndirect, except that <indirect> is 118 treated as an array of <drawcount> DrawArraysIndirectCommand structures. 119 <indirect> contains the offset of the first element of the array within the 120 buffer currently bound to the DRAW_INDIRECT buffer binding. <stride> 121 specifies the distance, in basic machine units, between the elements of the 122 array. If <stride> is zero, the array elements are treated as tightly 123 packed. 124 125 It is equivalent to 126 127 if (<mode> is invalid) 128 generate appropriate error 129 else { 130 const ubyte * ptr = (const ubyte *)<indirect>; 131 for (i = 0; i < <drawcount>; i++) { 132 DrawArraysIndirect(<mode>, 133 (DrawArraysIndirectCommand*)ptr); 134 if (<stride> == 0) { 135 ptr += sizeof(DrawArraysIndirectCommand); 136 } else { 137 ptr += <stride>; 138 } 139 } 140 } 141 142 MultiDrawArraysIndirectEXT requires that all data sourced for the command, 143 including the DrawArraysIndirectCommand structure, be in buffer objects, 144 and cannot be called when the default vertex array object is bound. 145 146 Errors 147 148 An INVALID_VALUE is generated if <stride> is neither zero nor a multiple 149 of four. 150 151 An INVALID_VALUE error is generated if <drawcount> is not positive. 152 153 An INVALID_OPERATION error is generated if zero is bound to 154 VERTEX_ARRAY_BINDING, DRAW_INDIRECT_BUFFER, or to any enabled vertex array. 155 156 An INVALID_OPERATION error is generated if the command would source data 157 beyond the end of the buffer object. 158 159 An INVALID_VALUE error is generated if <indirect> is not a multiple of 160 the size, in basic machine units of uint. 161 162 [[ If EXT_geometry_shader is not supported. ]] 163 An INVALID_OPERATION error is generated if transform feedback is active 164 and not paused. 165 166 [[ If EXT_base_instance is not supported. ]] 167 Results are undefined if <reservedMustBeZero> is non-zero, but may not 168 result in program termination." 169 170 171 (After the description of DrawElementsIndirect insert the following on 172 p.253) 173 174 "The command 175 176 void MultiDrawElementsIndirectEXT(enum mode, 177 enum type, 178 const void *indirect, 179 sizei drawcount, 180 sizei stride); 181 182 behaves identically to DrawElementsIndirect, except that <indirect> is 183 treated as an array of <drawcount> DrawElementsIndirectCommand structures. 184 <indirect> contains the offset of the first element of the array within the 185 buffer currently bound to the DRAW_INDIRECT buffer binding. <stride> 186 specifies the distance, in basic machine units, between the elements of the 187 array. If <stride> is zero, the array elements are treated as tightly 188 packed. 189 <stride> must be a multiple of four, otherwise an INVALID_VALUE 190 error is generated. 191 192 It is equivalent to 193 194 if (<mode> or <type> is invalid) 195 generate appropriate error 196 else { 197 const ubyte * ptr = (const ubyte *)<indirect>; 198 for (i = 0; i < <drawcount>; i++) { 199 DrawElementsIndirect(<mode>, 200 <type>, 201 (DrawElementsIndirectCommand*)ptr); 202 if (<stride> == 0) { 203 ptr += sizeof(DrawElementsIndirectCommand); 204 } else { 205 ptr += <stride>; 206 } 207 } 208 } 209 210 MultiDrawElementsIndirectEXT requires that all data sourced for the 211 command, including the DrawElementsIndirectCommand structure, be in buffer 212 objects, and cannot be called when the default vertex array object is bound. 213 214 Errors 215 216 An INVALID_VALUE is generated if <stride> is neither zero nor a multiple 217 of four. 218 219 An INVALID_VALUE error is generated if <drawcount> is not positive. 220 221 An INVALID_OPERATION error is generated if zero is bound to 222 VERTEX_ARRAY_BINDING, DRAW_INDIRECT_BUFFER, ELEMENT_ARRAY_BUFFER, or to 223 any enabled vertex array. 224 225 An INVALID_OPERATION error is generated if the command would source data 226 beyond the end of the buffer object. 227 228 An INVALID_VALUE error is generated if <indirect> is not a multiple of 229 the size, in basic machine units of uint. 230 231 [[ If EXT_geometry_shader is not supported. ]] 232 An INVALID_OPERATION error is generated if transform feedback is active 233 and not paused. 234 235 [[ If EXT_base_instance is not supported. ]] 236 Results are undefined if <reservedMustBeZero> is non-zero, but may not 237 result in program termination." 238 239Additions to the EGL/AGL/GLX/WGL Specifications 240 241 None. 242 243Dependencies on EXT_base_instance 244 245 If EXT_base_instance is not supported, the <baseInstance> 246 parameter in the Draw*IndirectCommand structures is not supported. 247 248Dependencies on EXT_geometry_shader 249 250 If EXT_geometry_shader is not supported, transform feedback cannot 251 be used with the Multi*DrawIndirect commands. 252 253GLX Protocol 254 255 None. 256 257New State 258 259 None. 260 261New Implementation Dependent State 262 263 None. 264 265Issues 266 267 Note: These issues apply specifically to the definition of the 268 EXT_multi_draw_indirect specification, which is based on the OpenGL 269 extension ARB_multi_draw_indirect as updated in OpenGL 4.x. 270 ARB_multi_draw_indirect can be found in the OpenGL Registry. 271 272 (0) This extension is based on ARB_multi_draw_indirect. What are the 273 major differences? 274 275 - Rebased against the ES 3.1 restructured specification 276 - renamed the <primcount> parameter to <drawcount> to match 277 the GL 4.4 spec (and reflect what the parameter really is). 278 - using the new commands with the default vertex array object, 279 or client-side memory the draw indirect buffer, vertex arrays 280 or index data is not permitted. 281 - these commands cannot be used when transform feedback is enabled 282 unless EXT_geometry_shader is supported. 283 - these commands do not support the baseInstance parameter unless 284 EXT_base_instance is supported. 285 286 (1) What about the "baseInstance" parameter for indirect draws? 287 288 It is still listed as reserved in the DrawElementsIndirectCommand 289 structure. It is separately added as orthogonal functionality in 290 the EXT_base_instance extension, although that should really be 291 supported in order to get the full benefit of multi_draw_indirect. 292 Since MultiDrawElementsIndirectEXT is defined in terms of 293 DrawElementsIndirect the extension that adds support for base instance 294 will automatically add support for in via MDI as well. 295 296 (2) Should the new drawing commands be supported on the default 297 vertex array object? 298 299 RESOLVED: No. This extension follows the precedent of ES 3.1's 300 Draw*Indirect capabilities, which disallow the commands with the 301 default vertex array object. 302 303 (3) Should the new drawing commands be supported with client-side 304 memory? 305 306 RESOLVED. No. Again, this extension follows the precedent of OpenGL ES 307 3.1's Draw*Indirect capabilities, which disallow the commands with 308 client-side memory for the vertex arrays, element array, and draw 309 indirect buffers. 310 311 (4) The resolution of Issues (2) and (3) take the opposite resolution 312 to the same questions raised in EXT_base_instance. Isn't that a little 313 strange? 314 315 RESOLVED. Yes, but that's the way we roll. The non-indirect drawing 316 commands must support the ES2-level features for compatibility. 317 318 319Revision History 320 321 Rev. Date Author Changes 322 ---- -------- -------- ----------------------------------------- 323 4 10/24/2014 dkoch Mark as complete. 324 325 3 06/24/2014 dkoch Fixes from Dominik, dangling primcount refs, 326 formatting of pseudocode. 327 328 2 06/20/2014 dkoch Require VAO and client-side memory for 329 the MultiDraw*Indirect commands. 330 List the full set of errors for the new cmds. 331 Rebase to Jun 4 ES 3.1 spec. 332 Add interactions with EXT_base_instance. 333 Add interactions with EXT_geometry_shader. 334 335 1 03/18/2014 dkoch EXT version based on ARB_multi_draw_indirect v.3 336