blob: a56abdebb6df3ea150bd6dedab46bf3ad32a2fa9 [file] [log] [blame]
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