blob: 8844c71b57b84b49e2d8f7ffadbd7a24c8b63021 [file] [log] [blame]
Name
EXT_base_instance
Name Strings
GL_EXT_base_instance
Contact
Daniel Koch, NVIDIA (dkoch 'at' nvidia.com)
Contributors
Dominik Witczak, Mobica
Jonas Gustavsson, Sony Mobile
Slawomir Grajewski, Intel
Contributors to ARB_base_instance
Notice
Copyright (c) 2011-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
Author Revision: 4
Number
OpenGL ES Extension #203
Dependencies
This specification is written against the OpenGL ES 3.1 (June 4, 2014)
Specification, although it can apply to previous versions.
OpenGL ES 3.0 is required.
EXT_draw_elements_base_vertex is required.
This extension interacts with EXT_multi_draw_indirect.
Overview
This extension allows the offset within buffer objects used for instanced
rendering to be specified. This is congruent with the <first> parameter
in glDrawArrays and the <basevertex> parameter in glDrawElements. When
instanced rendering is performed (for example, through
glDrawArraysInstanced), instanced vertex attributes whose vertex attribute
divisors are non-zero are fetched from enabled vertex arrays per-instance
rather than per-vertex. However, in unextended OpenGL ES, there is no way
to define the offset into those arrays from which the attributes are
fetched. This extension adds that offset in the form of a <baseinstance>
parameter to several new procedures.
The <baseinstance> parameter is added to the index of the array element,
after division by the vertex attribute divisor. This allows several sets of
instanced vertex attribute data to be stored in a single vertex array, and
the base offset of that data to be specified for each draw. Further, this
extension exposes the <baseinstance> parameter as the final and previously
undefined structure member of the draw-indirect data structure.
IP Status
None.
New Procedures and Functions
void DrawArraysInstancedBaseInstanceEXT(enum mode,
int first,
sizei count,
sizei instancecount,
uint baseinstance);
void DrawElementsInstancedBaseInstanceEXT(enum mode,
sizei count,
enum type,
const void *indices,
sizei instancecount,
uint baseinstance);
void DrawElementsInstancedBaseVertexBaseInstanceEXT(enum mode,
sizei count,
enum type,
const void *indices,
sizei instancecount,
int basevertex,
uint baseinstance);
New Tokens
None.
Modifications to Chapter 10 of the OpenGL ES 3.1 Specification (Vertex
Specification and Drawing Commands)
Modification to Section 10.5, "Drawing Commands using Vertex Arrays"
(Modify the definition of DrawArraysOneInstance, to define the
behaviour of the <baseinstance> parameter. Modify the 3rd paragraph
of the definition of the command, p.247, as follows)
"If an enabled vertex attribute array is instanced (it has a non-zero
<divisor> as specified by VertexAttribDivisor), the element index that
is transferred to the GL, for all vertices, is given by
floor(<instance> / <divisor>) + <baseinstance>"
(Replace the description of DrawArraysInstanced, p.248, with the
following)
"The command
void DrawArraysInstancedBaseInstanceEXT(enum mode,
int first,
sizei count,
sizei instancecount,
uint baseinstance);
behaves identically to DrawArrays, except that <instancecount> instances of
the range of elements are executed and the value of <instance> advances for
each iteration. Those attributes that have non-zero values for <divisor>,
as specified by VertexAttribDivisor, advance once every <divisor>
instances. Additionally, the first element within those instanced vertex
attributes is specified in <baseinstance>.
DrawArraysInstancedBaseInstanceEXT is equivalent to
if (<mode>, <count>, or <instancecount> is invalid)
generate appropriate error
else {
for (i = 0; i < <instancecount>; i++) {
DrawArraysOneInstance(<mode>, <first>, <count>, i,
<baseinstance>);
}
}
The command
void DrawArraysInstanced(enum mode,
int first,
sizei count,
sizei primcount);
is equivalent to
DrawArraysInstancedBaseInstanceEXT(<mode>, <first>, <count>,
<instancecount>, 0);"
(Update the definition of DrawArraysIndirect on p.248 as follows)
"The command
void DrawArraysIndirect(enum mode, const void *indirect);
is equivalent to
typedef struct {
uint count;
uint instanceCount;
uint first;
uint baseInstance;
} DrawArraysIndirectCommand;
DrawArraysIndirectCommand *cmd =
(DrawArraysIndirectCommand *)indirect;
DrawArraysInstancedBaseInstanceEXT(mode,
cmd->first,
cmd->count,
cmd->instanceCount,
cmd->baseInstance);"
(Retain the remainder the description of DrawArraysIndirect, but
delete the sentence "Results are undefined if <reservedMustBeZero> is
non-zero, but may not result in program termination." from the Errors
section.)
(Modify the definition of DrawElementsOneInstance, to define the
behaviour of the <baseinstance> parameter. Modify the 3rd paragraph
of the definition of the command, p.249, as follows)
"If an enabled vertex attribute array is instanced (it has a non-zero
attribute divisor as specified by VertexAttribDivisor), the element that
is transferred to the GL is given by:
floor(<instance> / <divisor>) + <baseinstance>"
(Update the text describing DrawElements, p.250, to mention the
<baseinstance> parameter)
"The command
void DrawElements(enum mode,
sizei count,
enum type,
const void *indices);
behaves identically to DrawElementsOneInstance with the <instance> and
<baseinstance> parameters set to zero; the effect of calling ..."
(Replace the description of DrawElementsInstanced, p.251, with the
following)
"The command
void DrawElementsInstancedBaseInstanceEXT(enum mode,
sizei count,
enum type,
const void *indices,
sizei instancecount,
uint baseinstance);
behaves identically to DrawElements except that <instancecount> instances
of the set of elements are executed, the value of <instance> advances
between each set. Instanced attributes are advanced as they do during
execution of DrawArraysInstancedBaseInstaceEXT, and <baseinstance> has
the same effect. It is equivalent to:
if (<mode>, <count>, <type> or <instancecount> is invalid)
generate appropriate error
else {
for (int i = 0; i < <instancecount>; i++) {
DrawElementsOneInstance(<mode>, <count>, <type>, <indices>,
i, <baseinstance>);
}
}
The command
void DrawElementsInstanced(enum mode, sizei count, enum type,
const void *indices, sizei instancecount);
behaves identically to DrawElementsInstancedBaseInstanceEXT except that
<baseinstance> is zero. It is equivalent to
DrawElementsInstancedBaseInstanceEXT(<mode>, <count>, <type>,
<indices>, <instancecount>, 0);"
(Add to the list of functions which include DrawElementsBaseVertexEXT,
DrawRangeElementsBaseVertexEXT, and DrawElementsInstancedBaseVertexEXT
(as added by EXT_draw_elements_base_vertex))
void DrawElementsInstancedBaseVertexBaseInstanceEXT(enum mode,
sizei count,
enum type,
const void *indices,
sizei instancecount,
int basevertex,
uint baseinstance);
(Append a new paragraph after the description of DrawElementsBaseVertexEXT,
DrawRangeElementsBaseVertexEXT, and DrawElementsInstancedBaseVertexEXT
(as added by EXT_draw_elements_base_vertex))
"For DrawElementsInstancedBaseVertexBaseInstanceEXT, <baseinstance> is
used to offset the element from which instanced vertex attributes (those
with a non-zero divisor as specified by VertexAttribDivisor) are taken."
(Update the definition of DrawElementsIndirect on p.252 as follows)
"The command
void DrawElementsIndirect(enum mode,
enum type,
const void *indirect );
is equivalent to:
typedef struct {
uint count;
uint instanceCount;
uint firstIndex;
int baseVertex;
uint baseInstance;
} DrawElementsIndirectCommand;
if (no element array buffer is bound) {
generate appropriate error
} else {
DrawElementsIndirectCommand *cmd =
(DrawElementsIndirectCommand *)indirect;
DrawElementsInstancedBaseVertexBaseInstanceEXT(
mode,
cmd->count,
type,
cmd->firstIndex * size-of-type,
cmd->instanceCount,
cmd->baseVertex,
cmd->baseInstance);
}"
(Retain the remainder of the description of DrawElementsIndirect, but
delete the sentence "Results are undefined if <reservedMustBeZero> is
non-zero, but may not result in program termination." from the Errors
section.)
Additions to the EGL/AGL/GLX/WGL Specifications
None.
Dependencies on EXT_multi_draw_indirect.
If EXT_multi_draw_indirect is supported, this extension adds <baseInstance>
support for the MultiDraw*Indirect commands as well, because they share
the same command structures.
Errors
The errors for DrawArraysInstancedBaseInstanceEXT are equivalent to the
errors for DrawArraysInstanced, but are repeated here for clarity:
- An INVALID_ENUM error is generated if <mode> is not one of the primitive
types defined in section 10.1.
- Specifying <first> < 0 results in undefined behavior. Generating an
INVALID_VALUE error is recommended in this case.
- An INVALID_VALUE error is generated if <count> is negative.
The errors for DrawElementsInstancedBaseInstanceEXT and
DrawElementsInstancedBaseVertexBaseInstanceEXT are equivalent to the
errors for DrawElementsInstanced, but are repeated here for clarity:
- An INVALID_ENUM error is generated if <mode> is not one of the primitive
types defined in section 10.1.
- An INVALID_ENUM error is generated if <type> is not UNSIGNED_BYTE,
UNSIGNED_SHORT, or UNSIGNED_INT.
- Using an index value greater than MAX_ELEMENT_INDEX will result in
undefined implementation-dependent behavior, unless primitive restart is
enabled (see section 10.3.4) and the index value is 2^32 1.
New State
None.
New Implementation Dependent State
None.
Conformance Testing
TBD.
Issues
Note: These issues apply specifically to the definition of the
EXT_base_instance specification, which is based on the OpenGL
extension ARB_base_instance as updated in OpenGL 4.4.
ARB_base_instance can be found in the OpenGL Registry.
(1) What functionality was removed from ARB_base_instance?
Nothing. Although there is less language here because ES 3.1 already
includes some of the reorganizing that the original extension added.
(2) What functionality was changed and added relative to
ARB_base_instance?
- EXT_base_instance more closely matches the language of OpenGL 4.4
- the <primCount> parameter was renamed to <instanceCount>
(3) Do these new draw calls require a vertex array object to be bound?
RESOLVED: No. The DrawArrays and DrawArraysInstanced commands do not
require a vertex array object to be bound in ES 3.1 and since these are
specializations of DrawArraysInstancedBaseInstanceEXT, it also does not
require one to be bound. Similarly the DrawElements and
DrawElementsInstanced commands do not require a vertex array object to be
bound in ES 3.1, and since these commands are specializations of
DrawElementsInstancedBaseInstanceEXT and
DrawElementsInstancedBaseVertexBaseInstanceEXT, these commands also do not
require one to be bound.
(4) Do these new draw calls support client memory arrays?
RESOLVED: Yes. There are no restrictions on using client-side memory for
the other direct drawing commands in ES 3.1, so these command support
them as well. As per issue (3), the old commands are specializations of
the new commands, so we keep a comparable feature set.
Revision History
Rev. Date Author Changes
---- ---------- -------- -----------------------------------------
4 10/24/2014 dkoch Mark complete and issues resolved.
3 06/24/2014 dkoch Fix typographical issues noted by Dominik.
2 06/20/2014 dkoch Add interaction with EXT_multi_draw_indirect.
1 06/13/2014 dkoch Initial version for ES based on v6 of
ARB_base_instance.