| Name |
| |
| EXT_multi_draw_indirect |
| |
| Name Strings |
| |
| GL_EXT_multi_draw_indirect |
| |
| Contact |
| |
| Daniel Koch, NVIDIA (dkoch 'at' nvidia.com) |
| |
| Contributors |
| |
| Dominik Witczak, Mobica |
| Jonas Gustavsson, Sony Mobile |
| Slawomir Grajewski, Intel |
| Contributors to ARB_multi_draw_indirect |
| |
| Notice |
| |
| Copyright (c) 2012-2014 The Khronos Group Inc. Copyright terms at |
| http://www.khronos.org/registry/speccopyright.html |
| |
| Portions Copyright (c) 2014 NVIDIA Corporation. |
| |
| Status |
| |
| Complete |
| |
| Version |
| |
| Last Modified Date: October 24, 2014 |
| Revision: 4 |
| |
| Number |
| |
| OpenGL ES Extension #205 |
| |
| Dependencies |
| |
| OpenGL ES 3.1 is required. |
| |
| This specification is written against the OpenGL ES 3.1 (June 4, 2014) |
| Specification. |
| |
| This extension interacts with EXT_base_instance. |
| |
| This extension interacts with EXT_geometry_shader. |
| |
| Overview |
| |
| The ARB_draw_indirect extension (included in OpenGL 4.0 and OpenGL ES 3.1) |
| introduced mechanisms whereby the parameters for a draw function may be |
| provided in a structure contained in a buffer object rather than as |
| parameters to the drawing procedure. This is known as an indirect draw and |
| is exposed as two new functions, glDrawArraysIndirect and |
| glDrawElementsIndirect. Each of these functions generates a single batch |
| of primitives. |
| |
| This extension builds on this functionality by providing procedures to |
| invoke multiple draws from a single procedure call. This allows large |
| batches of drawing commands to be assembled in server memory (via a buffer |
| object) which may then be dispatched through a single function call. |
| |
| New Procedures and Functions |
| |
| void MultiDrawArraysIndirectEXT(enum mode, |
| const void *indirect, |
| sizei drawcount, |
| sizei stride); |
| |
| void MultiDrawElementsIndirectEXT(enum mode, |
| enum type, |
| const void *indirect, |
| sizei drawcount, |
| sizei stride); |
| |
| New Tokens |
| |
| None. |
| |
| Additions to Chapter 10 of the OpenGL ES 3.1 Specification (Vertex |
| Specification and Drawing Commands) |
| |
| Additions to 10.3.8, "Indirect Commands in Buffer Objects", p. 244 |
| |
| Add MultiDrawArraysIndirectEXT and MultiDrawElementsIndirectEXT |
| to the list of "indirect commands" in the first paragraph of the section. |
| |
| In the second paragraph of the section replace the reference to |
| "Draw*Indirect" commands with a reference to "*Draw*Indirect" so |
| that it is clear that this statement applies to the MultiDraw |
| variants of the commands as well. |
| |
| Update Table 10.3 "Indirect commands and corresponding indirect buffer |
| targets" adding the following two rows: |
| |
| Indirect Command Name | Indirect Buffer <target> |
| --------------------------------------------------------- |
| MultiDrawArraysIndirectEXT | DRAW_INDIRECT_BUFFER |
| MultiDrawElementsIndirectEXT | DRAW_INDIRECT_BUFFER |
| |
| |
| Additions to Section 10.5, "Drawing Commands using Vertex Arrays" |
| |
| (After the description of DrawArraysIndirect and before the introduction of |
| DrawElementsOneInstance, insert the following on p.249) |
| |
| "The command |
| |
| void MultiDrawArraysIndirectEXT(enum mode, |
| const void *indirect, |
| sizei drawcount, |
| sizei stride); |
| |
| behaves identically to DrawArraysIndirect, except that <indirect> is |
| treated as an array of <drawcount> DrawArraysIndirectCommand structures. |
| <indirect> contains the offset of the first element of the array within the |
| buffer currently bound to the DRAW_INDIRECT buffer binding. <stride> |
| specifies the distance, in basic machine units, between the elements of the |
| array. If <stride> is zero, the array elements are treated as tightly |
| packed. |
| |
| It is equivalent to |
| |
| if (<mode> is invalid) |
| generate appropriate error |
| else { |
| const ubyte * ptr = (const ubyte *)<indirect>; |
| for (i = 0; i < <drawcount>; i++) { |
| DrawArraysIndirect(<mode>, |
| (DrawArraysIndirectCommand*)ptr); |
| if (<stride> == 0) { |
| ptr += sizeof(DrawArraysIndirectCommand); |
| } else { |
| ptr += <stride>; |
| } |
| } |
| } |
| |
| MultiDrawArraysIndirectEXT requires that all data sourced for the command, |
| including the DrawArraysIndirectCommand structure, be in buffer objects, |
| and cannot be called when the default vertex array object is bound. |
| |
| Errors |
| |
| An INVALID_VALUE is generated if <stride> is neither zero nor a multiple |
| of four. |
| |
| An INVALID_VALUE error is generated if <drawcount> is not positive. |
| |
| An INVALID_OPERATION error is generated if zero is bound to |
| VERTEX_ARRAY_BINDING, DRAW_INDIRECT_BUFFER, or to any enabled vertex array. |
| |
| An INVALID_OPERATION error is generated if the command would source data |
| beyond the end of the buffer object. |
| |
| An INVALID_VALUE error is generated if <indirect> is not a multiple of |
| the size, in basic machine units of uint. |
| |
| [[ If EXT_geometry_shader is not supported. ]] |
| An INVALID_OPERATION error is generated if transform feedback is active |
| and not paused. |
| |
| [[ If EXT_base_instance is not supported. ]] |
| Results are undefined if <reservedMustBeZero> is non-zero, but may not |
| result in program termination." |
| |
| |
| (After the description of DrawElementsIndirect insert the following on |
| p.253) |
| |
| "The command |
| |
| void MultiDrawElementsIndirectEXT(enum mode, |
| enum type, |
| const void *indirect, |
| sizei drawcount, |
| sizei stride); |
| |
| behaves identically to DrawElementsIndirect, except that <indirect> is |
| treated as an array of <drawcount> DrawElementsIndirectCommand structures. |
| <indirect> contains the offset of the first element of the array within the |
| buffer currently bound to the DRAW_INDIRECT buffer binding. <stride> |
| specifies the distance, in basic machine units, between the elements of the |
| array. If <stride> is zero, the array elements are treated as tightly |
| packed. |
| <stride> must be a multiple of four, otherwise an INVALID_VALUE |
| error is generated. |
| |
| It is equivalent to |
| |
| if (<mode> or <type> is invalid) |
| generate appropriate error |
| else { |
| const ubyte * ptr = (const ubyte *)<indirect>; |
| for (i = 0; i < <drawcount>; i++) { |
| DrawElementsIndirect(<mode>, |
| <type>, |
| (DrawElementsIndirectCommand*)ptr); |
| if (<stride> == 0) { |
| ptr += sizeof(DrawElementsIndirectCommand); |
| } else { |
| ptr += <stride>; |
| } |
| } |
| } |
| |
| MultiDrawElementsIndirectEXT requires that all data sourced for the |
| command, including the DrawElementsIndirectCommand structure, be in buffer |
| objects, and cannot be called when the default vertex array object is bound. |
| |
| Errors |
| |
| An INVALID_VALUE is generated if <stride> is neither zero nor a multiple |
| of four. |
| |
| An INVALID_VALUE error is generated if <drawcount> is not positive. |
| |
| An INVALID_OPERATION error is generated if zero is bound to |
| VERTEX_ARRAY_BINDING, DRAW_INDIRECT_BUFFER, ELEMENT_ARRAY_BUFFER, or to |
| any enabled vertex array. |
| |
| An INVALID_OPERATION error is generated if the command would source data |
| beyond the end of the buffer object. |
| |
| An INVALID_VALUE error is generated if <indirect> is not a multiple of |
| the size, in basic machine units of uint. |
| |
| [[ If EXT_geometry_shader is not supported. ]] |
| An INVALID_OPERATION error is generated if transform feedback is active |
| and not paused. |
| |
| [[ If EXT_base_instance is not supported. ]] |
| Results are undefined if <reservedMustBeZero> is non-zero, but may not |
| result in program termination." |
| |
| Additions to the EGL/AGL/GLX/WGL Specifications |
| |
| None. |
| |
| Dependencies on EXT_base_instance |
| |
| If EXT_base_instance is not supported, the <baseInstance> |
| parameter in the Draw*IndirectCommand structures is not supported. |
| |
| Dependencies on EXT_geometry_shader |
| |
| If EXT_geometry_shader is not supported, transform feedback cannot |
| be used with the Multi*DrawIndirect commands. |
| |
| GLX Protocol |
| |
| None. |
| |
| New State |
| |
| None. |
| |
| New Implementation Dependent State |
| |
| None. |
| |
| Issues |
| |
| Note: These issues apply specifically to the definition of the |
| EXT_multi_draw_indirect specification, which is based on the OpenGL |
| extension ARB_multi_draw_indirect as updated in OpenGL 4.x. |
| ARB_multi_draw_indirect can be found in the OpenGL Registry. |
| |
| (0) This extension is based on ARB_multi_draw_indirect. What are the |
| major differences? |
| |
| - Rebased against the ES 3.1 restructured specification |
| - renamed the <primcount> parameter to <drawcount> to match |
| the GL 4.4 spec (and reflect what the parameter really is). |
| - using the new commands with the default vertex array object, |
| or client-side memory the draw indirect buffer, vertex arrays |
| or index data is not permitted. |
| - these commands cannot be used when transform feedback is enabled |
| unless EXT_geometry_shader is supported. |
| - these commands do not support the baseInstance parameter unless |
| EXT_base_instance is supported. |
| |
| (1) What about the "baseInstance" parameter for indirect draws? |
| |
| It is still listed as reserved in the DrawElementsIndirectCommand |
| structure. It is separately added as orthogonal functionality in |
| the EXT_base_instance extension, although that should really be |
| supported in order to get the full benefit of multi_draw_indirect. |
| Since MultiDrawElementsIndirectEXT is defined in terms of |
| DrawElementsIndirect the extension that adds support for base instance |
| will automatically add support for in via MDI as well. |
| |
| (2) Should the new drawing commands be supported on the default |
| vertex array object? |
| |
| RESOLVED: No. This extension follows the precedent of ES 3.1's |
| Draw*Indirect capabilities, which disallow the commands with the |
| default vertex array object. |
| |
| (3) Should the new drawing commands be supported with client-side |
| memory? |
| |
| RESOLVED. No. Again, this extension follows the precedent of OpenGL ES |
| 3.1's Draw*Indirect capabilities, which disallow the commands with |
| client-side memory for the vertex arrays, element array, and draw |
| indirect buffers. |
| |
| (4) The resolution of Issues (2) and (3) take the opposite resolution |
| to the same questions raised in EXT_base_instance. Isn't that a little |
| strange? |
| |
| RESOLVED. Yes, but that's the way we roll. The non-indirect drawing |
| commands must support the ES2-level features for compatibility. |
| |
| |
| Revision History |
| |
| Rev. Date Author Changes |
| ---- -------- -------- ----------------------------------------- |
| 4 10/24/2014 dkoch Mark as complete. |
| |
| 3 06/24/2014 dkoch Fixes from Dominik, dangling primcount refs, |
| formatting of pseudocode. |
| |
| 2 06/20/2014 dkoch Require VAO and client-side memory for |
| the MultiDraw*Indirect commands. |
| List the full set of errors for the new cmds. |
| Rebase to Jun 4 ES 3.1 spec. |
| Add interactions with EXT_base_instance. |
| Add interactions with EXT_geometry_shader. |
| |
| 1 03/18/2014 dkoch EXT version based on ARB_multi_draw_indirect v.3 |