• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1Name
2
3    ARB_instanced_arrays
4
5Name Strings
6
7    GL_ARB_instanced_arrays
8
9Contributors
10
11    Michael Gold, NVIDIA
12    James Helferty, TransGaming Inc.
13    Daniel Koch, TransGaming Inc.
14    John Rosasco, Apple
15    Mark Kilgard, NVIDIA
16    Piers Daniell, NVIDIA
17
18Contact
19
20    James Helferty, TransGaming Inc. (james 'at' transgaming.com)
21    Daniel Koch, TransGaming Inc. (daniel 'at' transgaming.com)
22
23Notice
24
25    Copyright (c) 2008-2013 The Khronos Group Inc. Copyright terms at
26        http://www.khronos.org/registry/speccopyright.html
27
28Specification Update Policy
29
30    Khronos-approved extension specifications are updated in response to
31    issues and bugs prioritized by the Khronos OpenGL Working Group. For
32    extensions which have been promoted to a core Specification, fixes will
33    first appear in the latest version of that core Specification, and will
34    eventually be backported to the extension document. This policy is
35    described in more detail at
36        https://www.khronos.org/registry/OpenGL/docs/update_policy.php
37
38Status
39
40    Approved by the ARB on July 11, 2008.
41
42Version
43
44    Last Modified Date:  August 8, 2013
45    Author Revision: 7
46
47    EXT_direct_state_access interacton added with revision 7.
48
49Number
50
51    ARB Extension #49
52
53Dependencies
54
55    OpenGL 1.1 is required.
56
57    This extension is written against the OpenGL 2.1 Specification.
58
59    ARB_draw_instanced affects the definition of this extension.
60
61    EXT_draw_instanced affects the definition of this extension.
62
63    EXT_gpu_shader4 affects the definition of this extension.
64
65Overview
66
67    A common use case in GL for some applications is to be able to
68    draw the same object, or groups of similar objects that share
69    vertex data, primitive count and type, multiple times.  This
70    extension provides a means of accelerating such use cases while
71    restricting the number of API calls, and keeping the amount of
72    duplicate data to a minimum.
73
74    In particular, this extension specifies an alternative to the
75    read-only shader variable introduced by ARB_draw_instanced.  It
76    uses the same draw calls introduced by that extension, but
77    redefines them so that a vertex shader can instead use vertex
78    array attributes as a source of instance data.
79
80    This extension introduces an array "divisor" for generic
81    vertex array attributes, which when non-zero specifies that the
82    attribute is "instanced."  An instanced attribute does not
83    advance per-vertex as usual, but rather after every <divisor>
84    conceptual draw calls.
85
86    (Attributes which aren't instanced are repeated in their entirety
87    for every conceptual draw call.)
88
89    By specifying transform data in an instanced attribute or series
90    of instanced attributes, vertex shaders can, in concert with the
91    instancing draw calls, draw multiple instances of an object with
92    one draw call.
93
94IP Status
95
96    No known IP claims.
97
98New Tokens
99
100    Accepted by the <pname> parameters of GetVertexAttribdv,
101    GetVertexAttribfv, and GetVertexAttribiv:
102
103        VERTEX_ATTRIB_ARRAY_DIVISOR_ARB                 0x88FE
104
105New Procedures and Functions
106
107    void VertexAttribDivisorARB(uint index, uint divisor);
108
109    When EXT_direct_state_access is present:
110
111        void VertexArrayVertexAttribDivisorEXT(uint vaobj, uint index, uint divisor);
112
113Additions to Chapter 2 of the OpenGL 2.1 Specification
114(OpenGL Operation)
115
116    Modify section 2.8 (Vertex Arrays), p. 23
117
118    (remove modifications to section 2.8 made by ARB_draw_instanced
119    and EXT_draw_instanced, and replace everything from the second
120    paragraph, p. 27 through the second paragraph, p. 30)
121    The internal counter <instanceID> is a 32-bit integer value which
122    may be read by a vertex program as <vertex.instance>, as described
123    in section 2.X.3.2, or vertex shader as <gl_InstanceIDARB>, as
124    described in section 2.15.4.2.  The value of this counter is
125    always zero, except as noted.
126
127    The command
128
129        void VertexAttribDivisorARB(uint index, uint divisor);
130
131    modifies the rate at which generic vertex attributes advance when
132    rendering multiple instances of primitives in a single draw call.
133    If <divisor> is zero, the attribute at slot <index> advances once
134    per vertex.  If <divisor> is non-zero, the attribute advances once
135    per <divisor> instances of the set(s) of vertices being rendered.
136    An attribute is referred to as <instanced> if its <divisor> value
137    is non-zero.
138
139    The function
140
141        void ArrayElementInstanced( int i, int instance );
142
143    does not exist in the GL, but is used to describe functionality in
144    the rest of this section.  This function transfers the <i>th
145    element of every enabled, non-instanced array and the
146    floor(<instance>/<divisor>)'th element of every enabled instanced
147    array to the GL. The effect of ArrayElementInstanced(i) is the
148    same as the effect of the command sequence
149
150        if (normal array enabled)
151            Normal3[type]v(normal array element i);
152        if (color array enabled)
153            Color[size][type]v(color array element i);
154        if (secondary color array enabled)
155            SecondaryColor3[type]v(secondary color array element i);
156        if (fog coordinate array enabled)
157            FogCoord[type]v(fog coordinate array element i);
158        for (j = 0; j < textureUnits; j++) {
159            if (texture coordinate set j array enabled)
160                MultiTexCoord[size][type]v(TEXTURE0 + j, texture coordinate set j array element i);
161        }
162        if (color index array enabled)
163            Index[type]v(color index array element i);
164        if (edge flag array enabled)
165            EdgeFlagv(edge flag array element i);
166        for (j = 1; j < genericAttributes; j++) {
167            if (generic vertex attribute j array enabled) {
168                if (VERTEX_ATTRIB_ARRAY_DIVISOR_ARB[j] > 0)
169                    k = floor(instance / VERTEX_ATTRIB_ARRAY_DIVISOR_ARB[j]);
170                else
171                    k = i;
172                if (generic vertex attribute j array normalization flag is set, and
173                    type is not FLOAT or DOUBLE)
174                    VertexAttrib[size]N[type]v(j, generic vertex attribute j array element k);
175                else
176                    VertexAttrib[size][type]v(j, generic vertex attribute j array element k);
177            }
178        }
179        if (generic attribute array 0 enabled) {
180            if (VERTEX_ATTRIB_ARRAY_DIVISOR_ARB[0] > 0)
181                k = floor(instance / VERTEX_ATTRIB_ARRAY_DIVISOR_ARB[0]);
182            else
183                k = i;
184            if (generic vertex attribute 0 array normalization flag is set, and
185                type is not FLOAT or DOUBLE)
186                VertexAttrib[size]N[type]v(0, generic vertex attribute 0 array element k);
187            else
188                VertexAttrib[size][type]v(0, generic vertex attribute 0 array element k);
189        } else if (vertex array enabled) {
190            Vertex[size][type]v(vertex array element i);
191        }
192
193    where <textureUnits> and <genericAttributes> give the number of
194    texture coordinate sets and generic vertex attributes supported by
195    the implementation, respectively.  "[size]" and "[type]"
196    correspond to the size and type of the corresponding array.  For
197    generic vertex attributes, it is assumed that a complete set of
198    vertex attribute commands exists, even though not all such
199    functions are provided by the GL.
200
201    The command
202
203        void ArrayElement( int i );
204
205    behaves identically to ArrayElementInstanced with the instance
206    set to zero; it is equivalent to calling
207
208        ArrayElementInstanced(i, 0);
209
210    Changes made to array data between the execution of Begin and the
211    corresponding execution of End may affect calls to ArrayElement
212    that are made within the same Begin/End period in non-sequential
213    ways. That is, a call to ArrayElement that precedes a change to
214    array data may access the changed data, and a call that follows a
215    change to array data may access original data.
216
217    Specifying i < 0 results in undefined behavior. Generating the
218    error INVALID VALUE is recommended in this case.
219
220    The function
221
222        void DrawArraysOneInstance( enum mode, int first, sizei count, int instance );
223
224    does not exist in the GL, but is used to describe functionality in
225    the rest of this section.  This function constructs a sequence of
226    geometric primitives using elements <first> through <first> +
227    <count> - 1 of each enabled, non-instanced array and the
228    <instance>th element of each enabled, instanced array.  <mode>
229    specifies what kind of primitives are constructed; it accepts the
230    same token values as the mode parameter of the Begin command. The
231    effect of
232
233        DrawArraysOneInstance (mode, first, count, int instance);
234
235    is the same as the effect of the command sequence
236
237        Begin(mode);
238        for (int i = 0; i < count ; i++)
239            ArrayElementInstanced(first+ i, instance);
240        End();
241
242    with one exception: the current normal coordinates, color,
243    secondary color, color index, edge flag, fog coordinate, texture
244    coordinates, and generic attributes are each indeterminate after
245    execution of DrawArraysOneInstance, if the corresponding array is
246    enabled. Current values corresponding to disabled arrays are not
247    modified by the execution of DrawArraysOneInstance.
248
249    Specifying first < 0 results in undefined behavior.  Generating
250    the error INVALID_VALUE is recommended in this case.
251
252    The command
253
254        void DrawArrays( enum mode, int first, sizei count );
255
256    behaves identically to DrawArraysOneInstance with the instance
257    set to zero; the effect of calling
258
259        DrawArrays(mode, first, count);
260
261    is equivalent to the command sequence:
262
263        if (mode or count is invalid )
264            generate appropriate error
265        else
266            DrawArraysOneInstance(mode, first, count, 0);
267
268    The command
269
270        void DrawArraysInstancedARB(enum mode, int first, sizei count,
271                sizei primcount);
272
273    behaves identically to DrawArrays except that <primcount>
274    instances of the range of elements are executed, the value of
275    <instanceID> advances for each iteration, and the instanced
276    elements advance per instance depending on the value of the divisor
277    for that vertex attribute set with VertexAttribDivisorARB.  It has the
278    same effect as:
279
280        if (mode or count is invalid)
281            generate appropriate error
282        else {
283            for (i = 0; i < primcount; i++) {
284                instanceID = i;
285                DrawArraysOneInstance(mode, first, count, i);
286            }
287            instanceID = 0;
288        }
289
290    The command
291
292        void MultiDrawArrays( enum mode, int *first,
293            sizei *count, sizei primcount );
294
295    behaves identically to DrawArraysInstancedARB except that
296    <primcount> separate ranges of elements are specified instead,
297    all elements are treated as though they are not instanced,
298    and the value of <instanceID> stays at 0.  It has the same
299    effect as:
300
301        if (mode is invalid)
302            generate appropriate error
303        else {
304            for (i = 0; i < primcount; i++) {
305                if (count[i] > 0)
306                    DrawArraysOneInstance(mode, first[i], count[i], 0);
307            }
308        }
309
310    The function
311
312        void DrawElementsOneInstance( enum mode, sizei count, enum type,
313            void *indices );
314
315    does not exist in the GL, but is used to describe functionality in
316    the rest of this section.  This function constructs a sequence of
317    geometric primitives using the <count> elements whose indices are
318    stored in indices. <type> must be one of UNSIGNED_BYTE,
319    UNSIGNED_SHORT, or UNSIGNED_INT, indicating that the values in
320    <indices> are indices of GL type ubyte, ushort, or uint
321    respectively. <mode> specifies what kind of primitives are
322    constructed; it accepts the same token values as the mode
323    parameter of the Begin command. The effect of
324
325        DrawElementsOneInstance (mode, count, type, indices);
326
327    is the same as the effect of the command sequence
328
329        Begin(mode);
330        for (int i = 0; i < count ; i++)
331            ArrayElementInstanced(indices[i], instance);
332        End();
333
334    with one exception: the current normal coordinates, color,
335    secondary color, color index, edge flag, fog coordinate, texture
336    coordinates, and generic attributes are each indeterminate after
337    execution of DrawElementsOneInstance, if the corresponding array is
338    enabled. Current values corresponding to disabled arrays are not
339    modified by the execution of DrawElementsOneInstance.
340
341    The command
342
343        void DrawElements( enum mode, sizei count, enum type,
344            void *indices );
345
346    behaves identically to DrawElementsOneInstance with the instance
347    paremeter set to zero; the effect of calling
348
349        DrawElements(mode, count, type, indices);
350
351    is equivalent to the command sequence:
352
353        if (mode, count or type is invalid )
354            generate appropriate error
355        else
356            DrawElementsOneInstance(mode, count, type, indices, 0);
357
358    The command
359
360        void DrawElementsInstancedARB(enum mode, sizei count, enum type,
361                const void *indices, sizei primcount);
362
363    behaves identically to DrawElements except that <primcount>
364    instances of the set of elements are executed, the value of
365    <instanceID> advances between each set, and the instance
366    advances between each set.  It has the same effect as:
367
368        if (mode, count, or type is invalid )
369            generate appropriate error
370        else {
371            for (int i = 0; i < primcount; i++) {
372                instanceID = i;
373                DrawElementsOneInstance(mode, count, type, indices, i);
374            }
375            instanceID = 0;
376        }
377
378    The command
379
380        void MultiDrawElements( enum mode, sizei *count,
381            enum type, void **indices, sizei primcount );
382
383    behaves identically to DrawElementsInstancedARB except that
384    <primcount> separate sets of elements are specified instead, all
385    elements are treated as though they are not instanced, and the
386    value of <instanceID> stays at 0.  It has the same effect as:
387
388        if (mode, count, or type is invalid )
389            generate appropriate error
390        else {
391            for (int i = 0; i < primcount; i++)
392                DrawElementsOneInstance(mode, count[i], type, indices[i], 0);
393        }
394
395    The command
396
397        void DrawRangeElements( enum mode, uint start,
398            uint end, sizei count, enum type, void *indices );
399
400    is a restricted form of DrawElements. ...
401
402    Modify section 2.8 (Vertex Arrays), p. 23
403
404    (remove section before final paragraph, p. 30, that was added by
405    ARB_draw_instanced and EXT_draw_instanced)
406
407    Modify section 2.8 (Vertex Arrays), p. 33
408
409    (in the list of client state required to implement vertex arrays add)
410    ... <n> integers representing vertex attribute divisors, ...
411
412    (in the list of initial state add)
413    ... the divisors are each zero, ...
414
415Additions to Chapter 5 of the OpenGL 2.1 Specification
416(Special Functions)
417
418    The error INVALID_OPERATION is generated if DrawArraysInstancedARB
419    or DrawElementsInstancedARB is called during display list
420    compilation.
421
422Additions to Chapter 6 of the OpenGL 2.1 Specification (State and State
423Requests)
424
425    In section 6.1.14, add to the list of pnames accepted by
426    GetVertexAttrib*v: VERTEX_ATTRIB_ARRAY_DIVISOR_ARB
427
428************************************************************************
429
430Additions to the AGL/EGL/GLX/WGL Specifications
431
432    None
433
434Dependencies on OpenGL 1.4
435
436    If OpenGL 1.4 is not supported, all discussion of MultiDrawArrays
437    and MultiDrawElements should be removed from section 2.8.
438
439Dependencies on ARB_draw_instanced
440
441    If neither ARB_draw_instanced nor EXT_draw_instanced is supported,
442    all references to instanceID should be removed from section 2.8.
443
444    If ARB_draw_instanced is not supported, all references to gl_InstanceIDARB
445    should be removed from section 2.8.  This extension will introduce
446    the following additional New Procedures and Functions:
447
448        void DrawArraysInstancedARB(enum mode, int first, sizei count,
449                sizei primcount);
450        void DrawElementsInstancedARB(enum mode, sizei count, enum type,
451                const void *indices, sizei primcount);
452
453Dependencies on EXT_draw_instanced
454
455    If EXT_draw_instanced is supported, then DrawArraysInstancedEXT
456    is aliased to DrawArraysInstancedARB, and DrawElementsInstancedEXT
457    is aliased to DrawElementsInstancedARB.
458
459    If neither ARB_draw_instanced nor EXT_draw_instanced is supported,
460    all references to instanceID should be removed from section 2.8.
461
462Dependencies on EXT_gpu_shader4
463
464    If EXT_gpu_shader4 is not supported, all references to gl_InstanceID
465    should be removed from section 2.8.
466
467Dependencies on EXT_direct_state_access
468
469    When EXT_direct_state_access is present, add a new entry point that takes a
470    vertex array object handle:
471
472        void VertexArrayVertexAttribDivisorEXT(uint vaobj, uint index, uint divisor);
473
474    This command behaves identically to glVertexAttribDivisorEXT
475    except it modifies the state of the vertex array object named
476    by its initial vaobj parameter (rather than the currently bound
477    vertex array object).  The vertex array object named by vaobj must
478    be generated by GenVertexArrays (and not since deleted); otherwise
479    an INVALID_OPERATION error is generated.
480
481    GetVertexArrayIntegeri_vEXT must accept VERTEX_ATTRIB_ARRAY_DIVISOR_ARB to return
482    the vertex array object's vertex attrib array divisor state.
483
484Errors
485
486    INVALID_VALUE is generated by VertexAttribDivisorARB if <index>
487    is greater than or equal to MAX_VERTEX_ATTRIBS.
488
489    INVALID_ENUM is generated by DrawElementsInstancedARB if <type> is
490    not one of UNSIGNED_BYTE, UNSIGNED_SHORT or UNSIGNED_INT.
491
492    INVALID_VALUE is generated by DrawArraysInstancedARB if <first> is
493    less than zero.
494
495New State
496
497    Changes to table 6.7, p. 268 (Vertex Array Data)
498
499                                                         Initial
500    Get Value                        Type     Get Command      Value    Description       Sec.  Attribute
501    ---------                        ----     -----------      -------  -----------       ----  ---------
502    VERTEX_ATTRIB_ARRAY_DIVISOR_ARB  16+ xZ+  GetVertexAttrib  0        Instance Divisor  2.8   vertex-array
503
504Issues
505
506    1) Should legacy arrays be supported, or only generic vertex
507       attribs?
508
509        Resolved: It is possible to render instanced objects which use
510        legacy array types but only the generic arrays may have a
511        divisor.
512
513    2) Should generic attrib zero be instance-able?
514
515        Resolved: Yes. This was added in revision 5 of the spec.
516
517        Prior to revision 5 of this spec, attempting to call
518        VertexAttribDivisorARB with attrib=0 generated INVALID_VALUE.
519        It was originally thought that this implied issuing a vertex at
520        lower frequency than the associated attribs (due to the special
521        properties of vertex attribute zero in GL 2.x and the compatibility
522        profiles).  That would be true if the immediate-mode model of
523        instancing was to make an attribute call only once every <N> vertices
524        for instanced attributes -- you wouldn't want to specify a new vertex
525        once every <N> vertices! But that's not the model -- the frequency
526        <N> is only used to translate an incoming array element <i> into an
527        attribute index <k>.  Immediate mode calls are still specified as
528        happening for every vertex. Given this definition, it is not
529        necessary to do anything differently for attribute zero.
530
531    3) How is ArrayElement affected by this extension?
532
533        Resolved: Arrays with a non-zero divisor return the first
534        element of the array, as if instanceID is fixed at zero.  This
535        allows legacy varray draw calls to give instancing behavior
536        but are still defined in terms of ArrayElement.
537
538    4) Should DrawArraysInstanced and DrawElementsInstanced be compiled
539       into display lists?
540
541        Resolved: No, calling these during display list compilation
542        generate INVALID_OPERATION.  This matches EXT_draw_instanced
543        and ARB_draw_instanced.
544
545    5) Is it useful to have instancing for the MultiDraw* functions?
546
547        Resolved: We will follow the lead of EXT_draw_instanced and
548        ARB_draw_instanced in not extending these functions.
549
550    6) This extension must elaborate on the definition of functions
551       added by ARB_draw_instanced.  How do we do this in a manner such
552       that both extensions may coexist?
553
554        Resolved: This extension is specified so that it applies on
555        top of ARB_draw_instanced and EXT_draw_instanced.  As a
556        result, some portions modified by those extensions are
557        replaced in this extension.  In the event that those
558        extensions are not supported, this extension reintroduces
559        the draw calls from ARB_draw_instanced.
560
561    7) How should EXT_direct_state_access interact with this extension?
562
563        Resolved:  Add glVertexArrayVertexAttribDivisorEXT selector-free
564        vertex array object command and glGetVertexArrayIntegeri_vEXT
565        query must accept VERTEX_ATTRIB_ARRAY_DIVISOR_ARB to return the
566        vertex array object's vertex attrib array divisor state.
567
568        The DSA interaction was added July 2013.  If implementations
569        respond to a wglGetProcAddress, etc. query for
570        "glVertexArrayVertexAttribDivisorEXT" with a NULL pointer,
571        the DSA functionality is not available.
572
573Revision History
574
575    #7 August 6, 2013 mjk
576       - Add EXT_direct_state_access interaction
577    #6 February 11, 2010 dgkoch
578       - sync language with GL3.3, add required and initial state for divisors
579    #5 January 13, 2010 dgkoch
580       - update spec so that specifying a divisor on vertex attrib 0 is legal (5796)
581       - update resolution of Issue 2 appropriately.
582    #4 January 1, 2010, Jon Leech
583       - Correct Errors section to match spec body
584    #3 July 8, 2008, jhelferty
585       - expanded Overview
586       - changed name of GLSL instance ID variable to follow naming conventions,
587         and match ARB_draw_instanced.
588       - made dependencies and interactions more explicit
589    #2 May 14 2008, jhelferty
590       - changed pname to VERTEX_ATTRIB_ARRAY_DIVISOR_ARB
591       - added dependencies on ARB_draw_instanced
592       - update to GL 2.1 language
593    #1 May 12 2008, dgkoch
594       - copied from NVX_instanced_arrays and renamed. removed original revision history
595