• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1Name
2
3    NV_instanced_arrays
4
5Name Strings
6
7    GL_NV_instanced_arrays
8
9Contributors
10
11    Contributors to ARB_instanced_arrays and ANGLE_instanced_arrays
12    Mathias Heyer, NVIDIA
13    Greg Roth, NVIDIA
14
15Contact
16
17    Greg Roth, NVIDIA (groth 'at' nvidia 'dot' com)
18
19Status
20
21    Complete
22
23Version
24
25    Last Modified Date:  Aug 28, 2012
26    Author Revision: 4
27
28Number
29
30    OpenGL ES Extension #145
31
32Dependencies
33
34    OpenGL ES 2.0 is required.
35
36    This extension is written against the OpenGL ES 2.0.25
37    Specification.
38
39    NV_draw_instanced affects the definition of this extension.
40
41    OES_element_index_uint affects the definition of this extension.
42
43    OES_vertex_array_object affects the definition of this extension.
44
45Overview
46
47    A common use case in GL for some applications is to be able to
48    draw the same object, or groups of similar objects that share
49    vertex data, primitive count and type, multiple times.  This
50    extension provides a means of accelerating such use cases while
51    limiting the number of required API calls, and keeping the amount
52    of duplicate data to a minimum.
53
54    In particular, this extension specifies an alternative to the
55    read-only shader variable introduced by NV_draw_instanced.  It
56    uses the same draw calls introduced by that extension, but
57    redefines them so that a vertex shader can instead use vertex
58    array attributes as a source of instance data.
59
60    This extension introduces an array "divisor" for generic
61    vertex array attributes, which when non-zero specifies that the
62    attribute is "instanced."  An instanced attribute does not
63    advance per-vertex as usual, but rather after every <divisor>
64    conceptual draw calls.
65
66    (Attributes which aren't instanced are repeated in their entirety
67    for every conceptual draw call.)
68
69    By specifying transform data in an instanced attribute or series
70    of instanced attributes, vertex shaders can, in concert with the
71    instancing draw calls, draw multiple instances of an object with
72    one draw call.
73
74New Procedures and Functions
75
76    void VertexAttribDivisorNV(uint index, uint divisor);
77
78New Tokens
79
80    Accepted by the <pname> parameters of GetVertexAttribfv, and
81    GetVertexAttribiv:
82
83        VERTEX_ATTRIB_ARRAY_DIVISOR_NV                  0x88FE
84
85Additions to Chapter 2 of the OpenGL ES 2.0.25 Specification
86(OpenGL ES Operation)
87
88    Modify section 2.8 (Vertex Arrays)
89
90    After description of EnableVertexAttribArray /
91    DisableVertexAttribArray add the following:
92
93    The internal counter <instanceID> is a 32-bit integer value which
94    may be read by a vertex shader as <gl_InstanceIDNV>, as
95    described in section 2.10.5.2.  The value of this counter is
96    always zero, except as noted below.
97
98    The command
99
100        void VertexAttribDivisorNV(uint index, uint divisor);
101
102    modifies the rate at which generic vertex attributes advance when
103    rendering multiple instances of primitives in a single draw call.
104    If <divisor> is zero, the attribute at slot <index> advances once
105    per vertex.  If <divisor> is non-zero, the attribute advances once
106    per <divisor> instances of the set(s) of vertices being rendered.
107    An attribute is referred to as "instanced" if its <divisor> value is
108    non-zero.
109
110    Replace the text describing DrawArrays and DrawElements in the
111    "Transferring Array Elements" subsection of 2.8, from the second paragraph
112    through the end of the section with the following:
113
114    The function
115
116        void DrawArraysOneInstance( enum mode, int first, sizei count, int instance );
117
118    does not exist in the GL, but is used to describe functionality in
119    the rest of this section.  This function constructs a sequence of
120    geometric primitives using the indicated elements of enabled arrays.
121    <mode> specifies what kind of primitives are constructed, as defined
122    in section 2.6.1. Elements <first> through <first> + <count> - 1 of
123    enabled non-instanced arrays are transferred to the GL.
124    If an enabled vertex attribute array is instanced (it has a non-zero
125    attribute <divisor> as specified by VertexAttribDivisorNV), the
126    element that is transferred to the GL is given by:
127
128        floor( <instance> / <divisor> ).
129
130    If an array corresponding to a generic attribute required by a
131    vertex shader is not enabled, then the corresponding element is
132    taken from the current generic attribute state (see section 2.7).
133
134    If an array corresponding to a attribute required by a vertex
135    shader is enabled, the corresponding current generic attribute value
136    is unaffected by the execution of DrawArraysOneInstance.
137
138    Specifying <first> < 0 results in undefined behavior.  Generating
139    the error INVALID_VALUE is recommended in this case.
140
141    The command
142
143        void DrawArrays( enum mode, int first, sizei count );
144
145    behaves identically to DrawArraysOneInstance with the instance
146    set to zero; the effect of calling
147
148        DrawArrays(mode, first, count);
149
150    is equivalent to the command sequence:
151
152        if (mode or count is invalid )
153            generate appropriate error
154        else
155            DrawArraysOneInstance(mode, first, count, 0);
156
157    The command
158
159        void DrawArraysInstancedNV(enum mode, int first, sizei count,
160                sizei primcount);
161
162    behaves identically to DrawArrays except that <primcount>
163    instances of the range of elements are executed, the value of
164    <instanceID> advances for each iteration, and the instance advances
165    between each set. Instanced attributes that have <divisor> N, (where
166    N > 0, as specified by VertexAttribDivisorNV advance once every N
167    instances.
168
169    It has the same effect as:
170
171        if (mode, count, or primcount is invalid)
172            generate appropriate error
173        else {
174            for (i = 0; i < primcount; i++) {
175                instanceID = i;
176                DrawArraysOneInstance(mode, first, count, i);
177            }
178            instanceID = 0;
179        }
180
181    The function
182
183        void DrawElementsOneInstance( enum mode, sizei count, enum type,
184            void *indices, int instance );
185
186    does not exist in the GL, but is used to describe functionality in
187    the rest of this section.  This function constructs a sequence of
188    geometric primitives by successively transferring the <count>
189    elements whose indices are stored in <indices>. <type> must be one
190    of UNSIGNED_BYTE, UNSIGNED_SHORT, or UNSIGNED_INT, indicating that
191    the values in <indices> are indices of GL type ubyte, ushort, or
192    uint respectively. <mode> specifies what kind of primitives are
193    constructed, as defined in section 2.6.1.
194
195    If an enabled vertex attribute array is instanced (it has a non-zero
196    attribute <divisor> as specified by VertexAttribDivisorNV), the
197    element that is transferred to the GL is given by:
198
199        floor( <instance> / <divisor> );
200
201    If an array corresponding to a generic attribute required by a
202    vertex shader is not enabled, then the corresponding element is
203    taken from the current generic attribute state (see section 2.7).
204    Otherwise, if an array is enabled, the corresponding current
205    generic attribute value is unaffected by the execution of
206    DrawElementsOneInstance.
207
208    The command
209
210        void DrawElements( enum mode, sizei count, enum type,
211            void *indices );
212
213    behaves identically to DrawElementsOneInstance with <instance> set
214    to zero; the effect of calling
215
216        DrawElements(mode, count, type, indices);
217
218    is equivalent to the command sequence:
219
220        if (mode, count or type is invalid )
221            generate appropriate error
222        else
223            DrawElementsOneInstance(mode, count, type, indices, 0);
224
225    The command
226
227        void DrawElementsInstancedNV(enum mode, sizei count, enum type,
228                const void *indices, sizei primcount);
229
230    behaves identically to DrawElements except that <primcount>
231    instances of the set of elements are executed, the value of
232    <instanceID> advances for each iteration, and the instance
233    advances between each set. Instanced attributes are advanced as
234    they do during the execution of DrawArraysInstancedNV. It has the
235    same effect as:
236
237        if (mode, count, primcount, or type is invalid )
238            generate appropriate error
239        else {
240            for (int i = 0; i < primcount; i++) {
241                instanceID = i;
242                DrawElementsOneInstance(mode, count, type, indices, i);
243            }
244            instanceID = 0;
245        }
246
247    If the number of supported generic vertex attributes (the value of
248    MAX_VERTEX_ATTRIBS) is <n>, then the client state required to
249    implement vertex arrays consists of <n> boolean values, <n> memory
250    pointers, <n> integer stride values, <n> symbolic constants
251    representing array types, <n> integers representing values per
252    element, <n> boolean values indicating normalization, and <n>
253    integers representing vertex attribute divisors.
254
255    In the initial state, the boolean values are each false, the memory
256    pointers are each NULL, the strides are each zero, the array types
257    are each FLOAT, the integers representing values per element are
258    each four, and the divisors are each zero.
259
260    Modify section 2.10, "Vertex Array Objects" (Added by OES_vertex_array_object)
261
262    Add VERTEX_ATTRIB_ARRAY_DIVISOR_NV to the list of state included in
263    the vertex array object type vector.
264
265Additions to Chapter 6 of the OpenGL ES 2.0.25 Specification (State and
266State Requests)
267
268    In section 6.1.8, add VERTEX_ATTRIB_ARRAY_DIVISOR_NV to the list of
269    pnames accepted by GetVertexAttribfv and GetVertexAttribiv:
270
271Dependencies on OES_element_index_uint
272
273    If OES_element_index_uint is not supported, removed all references
274    to UNSIGNED_INT indices and the associated GL data type uint in
275    the description of DrawElementsOneInstance.
276
277Dependencies on NV_draw_instanced
278
279    If NV_draw_instanced is not supported, all references to
280    instanceID should be removed from section 2.8. This extension
281    will introduce the following additional New Procedures and
282    Functions:
283
284        void DrawArraysInstancedNV(enum mode, int first, sizei count,
285                sizei primcount);
286        void DrawElementsInstancedNV(enum mode, sizei count, enum type,
287                const void *indices, sizei primcount);
288
289Dependencies on OES_vertex_array_object
290
291    If OES_vertex_array_object is not supported, ignore all edits to
292    section 2.10, "Vertex Array Objects".
293
294Errors
295
296    INVALID_VALUE is generated by VertexAttribDivisorNV if <index>
297    is greater than or equal to MAX_VERTEX_ATTRIBS.
298
299    INVALID_ENUM is generated by DrawElementsInstancedNV if <type> is
300    not one of UNSIGNED_BYTE, UNSIGNED_SHORT or UNSIGNED_INT.
301
302    INVALID_VALUE is generated by DrawArraysInstancedNV if <first>,
303    <count>, or <primcount> is less than zero.
304
305    INVALID_ENUM is generated by DrawArraysInstancedNV or
306    DrawElementsInstancedNV if <mode> is not one of the modes described in
307    section 2.6.1.
308
309    INVALID_VALUE is generated by DrawElementsInstancedNV if <count> or
310    <primcount> is less than zero.
311
312New State
313
314    Changes to table 6.2 (Vertex Array Data)
315
316                                                               Initial
317    Get Value                       Type     Get Command       Value    Description       Sec.  Attribute
318    ---------                       ----    ---------------    -------  -----------       ----  ---------
319    VERTEX_ATTRIB_ARRAY_DIVISOR_NV  8xZ+    GetVertexAttrib    0        Instance Divisor  2.8   vertex-array
320
321Issues
322
323
324    1) Should generic attrib zero be instance-able?
325
326        Resolved: Yes. Attribute zero does not necessarily contain
327        position information.
328
329    2) This extension must elaborate on the definition of functions
330       added by NV_draw_instanced.  How do we do this in a manner such
331       that both extensions may coexist?
332
333        Resolved: This extension is specified so that it applies on
334        top of NV_draw_instanced.  As a result, some portions modified
335        by that extension are replaced in this extension.  In the
336        event that NV_draw_instanced is not supported, this extension
337        reintroduces the draw calls from NV_draw_instanced.
338
339    3) Should current generic attributes be affected by the execution of
340       DrawArraysOneInstance?
341
342       Resolved: No. ANGLE says no. ARB says maybe. Defined behavior is
343       always better. The wishy washy ARB language is likely to permit
344       a software implementation without excessive state resetting. This
345       Is not terribly useful if implemented in software.
346
347
348    4) Can all vertex attributes be instanced simultaneously?
349
350       Resolved: No. In rare cases it is possible for no attribute to
351       have a divisor of 0, meaning that all attributes are instanced
352       and none of them are regularly indexed. This in turn means each
353       instance can only have a single position element, and so it only
354       actually renders something when rendering point primitives. This
355       is not a very meaningful way of using instancing (which is likely
356       why D3D restricts stream 0 to be indexed regularly for position
357       data in the first place).
358
359Revision History
360
361    Rev.    Date        Author      Changes
362    ----  ------------- ---------   ----------------------------------------
363     4    28 Aug 2012    groth      Various spelling corrections and minor clarifications
364     3    20 Aug 2012    groth      Add interaction with VAOs
365     2    19 Aug 2012    groth      Correct section number
366     1    12 Aug 2012    groth      Initial GLES2 version from ARB_instanced_arrays
367                                    with inspiration from ANGLE_instanced_arrays
368