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 parameter in glDrawArrays and the 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 parameter to several new procedures. The 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 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 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 as specified by VertexAttribDivisor), the element index that is transferred to the GL, for all vertices, is given by floor( / ) + " (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 instances of the range of elements are executed and the value of advances for each iteration. Those attributes that have non-zero values for , as specified by VertexAttribDivisor, advance once every instances. Additionally, the first element within those instanced vertex attributes is specified in . DrawArraysInstancedBaseInstanceEXT is equivalent to if (, , or is invalid) generate appropriate error else { for (i = 0; i < ; i++) { DrawArraysOneInstance(, , , i, ); } } The command void DrawArraysInstanced(enum mode, int first, sizei count, sizei primcount); is equivalent to DrawArraysInstancedBaseInstanceEXT(, , , , 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 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 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( / ) + " (Update the text describing DrawElements, p.250, to mention the parameter) "The command void DrawElements(enum mode, sizei count, enum type, const void *indices); behaves identically to DrawElementsOneInstance with the and 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 instances of the set of elements are executed, the value of advances between each set. Instanced attributes are advanced as they do during execution of DrawArraysInstancedBaseInstaceEXT, and has the same effect. It is equivalent to: if (, , or is invalid) generate appropriate error else { for (int i = 0; i < ; i++) { DrawElementsOneInstance(, , , , i, ); } } The command void DrawElementsInstanced(enum mode, sizei count, enum type, const void *indices, sizei instancecount); behaves identically to DrawElementsInstancedBaseInstanceEXT except that is zero. It is equivalent to DrawElementsInstancedBaseInstanceEXT(, , , , , 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, 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 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 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 is not one of the primitive types defined in section 10.1. - Specifying < 0 results in undefined behavior. Generating an INVALID_VALUE error is recommended in this case. - An INVALID_VALUE error is generated if 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 is not one of the primitive types defined in section 10.1. - An INVALID_ENUM error is generated if 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 parameter was renamed to (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.