Name

    ARB_base_instance

Name Strings

    GL_ARB_base_instance

Contact

    Graham Sellers, AMD (graham.sellers 'at' amd.com)

Contributors

    Daniel Koch, NVIDIA

Notice

    Copyright (c) 2011-2013 The Khronos Group Inc. Copyright terms at
        http://www.khronos.org/registry/speccopyright.html

Specification Update Policy

    Khronos-approved extension specifications are updated in response to
    issues and bugs prioritized by the Khronos OpenGL Working Group. For
    extensions which have been promoted to a core Specification, fixes will
    first appear in the latest version of that core Specification, and will
    eventually be backported to the extension document. This policy is
    described in more detail at
        https://www.khronos.org/registry/OpenGL/docs/update_policy.php

Status

    Complete. Approved by the ARB on 2011/06/20.
    Approved by the Khronos Promoters on 2011/07/29.

Version

    Last Modified Date:         June 13, 2014
    Author Revision:            7

Number

    ARB Extension #107

Dependencies

    This extension is written against the OpenGL Specification, Version 4.1
    (Core Profile).

    OpenGL 3.1 or ARB_draw_instanced is required.

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, 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 DrawArraysInstancedBaseInstance(enum mode,
                                             int first,
                                             sizei count,
                                             sizei primcount,
                                             uint baseinstance);

        void DrawElementsInstancedBaseInstance(enum mode,
                                               sizei count,
                                               enum type,
                                               const void *indices,
                                               sizei primcount,
                                               uint baseinstance);

        void DrawElementsInstancedBaseVertexBaseInstance(enum mode,
                                                         sizei count,
                                                         enum type,
                                                         const void *indices,
                                                         sizei primcount,
                                                         int basevertex,
                                                         uint baseinstance);

New Tokens

    None.

Modifications to Chapter 2 of the the OpenGL 4.1 (Core Profile) Specification
(OpenGL Operation)

    Modification to Section 2.8.3, "Drawing Commands"

    Modify the definition of DrawArraysOneInstance on p.33.

    The command

        void DrawArraysOneInstance(enum mode,
                                   int first,
                                   sizei count,
                                   int instance,
                                   uint baseinstance);

    does not exist in the GL, but is used to describe functionality in the rest
    of this section. This command constructs a sequence of geometric primitives
    by transferring elements <first> through <first> + <count> - 1 of each
    enabled array to the GL. <mode> specifies what kind of primitives are
    constructed, as defined in section 2.6.1. If <mode> is not a valid primitive
    type, an INVALID_ENUM error is generated. If <count> is negative, an
    INVALID_VALUE error is generated.

    For any vertex attribute whose divisor is non-zero as set by
    VertexAttribDivisor, the value <baseinstance> is used to determine the element
    of the enabled instanced attribute arrays that will be transferred for all
    vertices transferred by this function.

    If an array corresponding to a generic attribute required by a vertex
    shader is not enabled, then the corresponding element is taken from the
    current generic attribute state (see section 2.7).

    If an array corresponding to a generic attribute required by a vertex
    shader is enabled, the corresponding current generic attribute value is
    unaffected by the execution of DrawArraysOneInstance.

    Specifying <first> < 0 results in undefined behavior. Generating the
    error INVALID_VALUE is recommended in this case.

    The command

        void DrawArrays( enum mode, int first, sizei count );

    is equivalent to the command sequence

        DrawArraysOneInstance(mode, first, count, 0, 0);

    Replace the description of DrawArraysInstanced with the following (p.35):

    The command

        void DrawArraysInstancedBaseInstance(enum mode,
                                             int first,
                                             sizei count,
                                             sizei primcount,
                                             uint baseinstance);

    behaves identically to DrawArrays, except that <primcount> instances of the
    range of elements are executed and the value of <instanceID> advances for
    each iteration. Those attributes that have divisor N where N is other than
    zero (as specified by VertexAttribDivisor) advance once every N instances.
    Additionally, the first element within those instanced vertex attributes
    is specified in <baseinstance>. Thus, the element transferred from instanced
    vertex attributes is given by:

        (<instanceID> / <divisor>) + <baseinstance>

    DrawArraysInstancedBaseInstance has the same effect as:

        if (<mode> or <count> is invalid)
            generate  appropriate  error
        else {
            for  (i = 0; i < <primcount>; i++) {
                instanceID  =  i;
                DrawArraysOneInstance(<mode>, <first>, <count>, i, <baseinstance>);
            }
            instanceID  =  0;
        }

    The command

            void DrawArraysInstanced(enum mode,
                                     int first,
                                     sizei count,
                                     sizei primcount);

    Is equivalent to calling DrawArraysInstancedBaseInstance with <baseinstance>
    set to zero.

    Update the definition of DrawArraysIndirect as follows (p.35):

    The command

            void  DrawArraysIndirect(enum mode,
                                     const void *indirect);

    has the same effect as:

            typedef  struct {
                uint  count;
                uint  primCount;
                uint  first;
                uint  baseInstance;
        } DrawArraysIndirectCommand;

        const DrawArraysIndirectCommand  *cmd  =
            (const DrawArraysIndirectCommand *)indirect;

        DrawArraysInstancedBaseInstance(mode,
                                        cmd->first,
                                        cmd->count,
                                        cmd->primCount,
                                        cmd->baseInstance);

    Remove the sentence "Results are undefined if reservedMustBeZero is non-
    zero, but must not lead to GL interruption or termination."

    Update the definition of DrawElementsOneInstance, p.36:

    The command

        void DrawElementsOneInstance(enum mode,
                                     sizei count,
                                     enum type,
                                     const void *indices,
                                     int instance,
                                     uint baseinstance);

    does not exist in the GL ... <retain the remainder of the description>

    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:

    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

        DrawElements(mode, count, type, indices);

    is equivalent to the command sequence:

        if (<mode>, <count> or <type> is invalid)
            generate appropriate error
        else
            DrawElementsOneInstance(mode, count, type, indices, 0, 0);

    Replace the description of DrawElementsInstanced with the following (p.37)

    The command

            void DrawElementsInstancedBaseInstance(enum mode,
                                                   sizei count,
                                                   enum type,
                                                   const void *indices,
                                                   sizei primcount,
                                                   uint baseinstance);

    behaves identically to DrawElements except that <primcount> instances of the
    set of elements are executed, the value of instanceID advances between each
    set, and the instance advances between each set. Instanced attributes
    are advanced as they do during execution of DrawArraysInstancedBaseInstace,
    and <baseinstance> has the same effect. It has the same effect as:

        if  (<mode>, <count>, <type> or <primcount> is invalid)
            generate  appropriate  error
        else {
            for (int i = 0; i < <primcount>;  i++) {
                instanceID  =  i;
                DrawElementsOneInstance(<mode>,
                                        <count>,
                                        <type>,
                                        <indices>,
                                        i,
                                        <baseinstance>);
            }
            instanceID  =  0;
        }

    Add to the list of functions which include DrawElementsBaseVertex,
    DrawRangeElementsBaseVertex, and DrawElementsInstancedBaseVertex (p.39):

        void DrawElementsInstancedBaseVertexBaseInstance(enum mode,
                                                         sizei count,
                                                         enum type,
                                                         const void *indices,
                                                         sizei primcount,
                                                         int basevertex,
                                                         uint baseinstance);

    Append to the paragraph describing DrawElementsBaseVertex,
    DrawRangeElementsBaseVertex, and DrawElementsInstancedBaseVertex (p.40):

    For DrawElementsInstancedBaseVertexBaseInstance, <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 as follows (p.39):

    The command

        void  DrawElementsIndirect(enum mode,
                                   enum type,
                                   const void *indirect );

    has the same effect as:

        typedef  struct {
            uint  count;
            uint  primCount;
            uint  firstIndex;
            int   baseVertex;
            uint  baseInstance;
        } DrawElementsIndirectCommand;

        if  (no element array buffer is bound) {
            generate appropriate error
        } else {
            const DrawElementsIndirectCommand  *cmd  =
                (const DrawElementsIndirectCommand  *)indirect;

            DrawElementsInstancedBaseVertexBaseInstance(
                                                mode,
                                                cmd->count,
                                                type,
                                                cmd->firstIndex * size-of-type,
                                                cmd->primCount,
                                                cmd->baseVertex,
                                                cmd->baseInstance);
        }

    Remove the sentence "Results are undefined if reservedMustBeZero is non-
    zero, but must not lead to GL interruption or termination."

Modifications to Chapter 3 of the the OpenGL 4.1 (Core Profile) Specification
(Rasterization)

    None.

Modifications to Chapter 4 of the the OpenGL 4.1 (Core Profile) Specification
(Per-Fragment Operations and the Framebuffer)

    None.

Modifications to Chapter 5 of the the OpenGL 4.1 (Core Profile) Specification
(Special Functions)

    None.

Modifications to Chapter 6 of the the OpenGL 4.1 (Core Profile) Specification
(State and State Requests)

    None.

Additions to the AGL/GLX/WGL Specifications

    None.

GLX Protocol

    None.

Errors

    None.

New State

    None.

New Implementation Dependent State

    None.

Conformance Testing

    TBD.

Issues

    1) Does <baseinstance> offset gl_InstanceID?

    RESOLVED: No. gl_InstanceID always starts from zero and counts up by one
    for each instance rendered. If the shader author requires the actual value
    of the instance index, including the base instance, they must pass the
    base instance as a uniform. In OpenGL, the vertex attribute divisors are
    not passed implicitly to the shader anyway, so the shader writer will need
    to take care of this regardless.

    2) Is <baseinstance> per-attribute, or global?

    RESOLVED: It is global. The same base is used for all instanced attribute
    arrays.

    3) Do we need any more entry points?

    DISCUSSION: Maybe. Technically, we could specify a base vertex to any
    drawing command and any instanced vertex attributes would be taken from
    that offset within their respective buffers. OpenGL already has enough
    entry points. Another possibility is to actually make <baseinstance> OpenGL
    state. The application would set it before any draw call (even non-
    instanced ones) and this would affect the base used for any instanced vertex
    attributes. However, this would introduce performance overhead and would not
    work well with Draw{Arrays|Elements}Indirect.

    4) DrawElementsInstancedBaseVertexBaseInstance? Really? The length of entry
    point names is starting to get silly. Can we clean this up?

    RESOLVED: Yes, we can, but not here.

    5) What happens if baseInstance is > 2^31-1 (i.e., negative as a signed
    integer)?

    Need to check with hardware vendors.

Revision History

    Rev.    Date      Author    Changes
    ----  ----------  --------  -----------------------------------------
    7     06/13/2014  dkoch     fix <baseinstance> typos in overview.
    6     01/18/2011  Jon Leech Use floor() in computing element transferred
                                to the GL to match change in core spec.
    5     01/10/2011  gsellers  Address bugzilla 7185. Make baseinstance API
                                parameter unsigned to match structure member.
                                Add issue 5.
    4     01/05/2011  Jon Leech Fix typos from Bug 7202.
    3     11/09/2010  gsellers  Address bugzilla 7011. Elaborate in overview
                                and issues. Add placeholder for conformance test
                                plan.
    2     11/08/2010  gsellers  Did some TODOs. Check in to SVN.
    1     11/04/2010  gsellers  Initial revision.
