• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1Name
2
3    ANGLE_instanced_arrays
4
5Name Strings
6
7    GL_ANGLE_instanced_arrays
8
9Contributors
10
11    Contributors to ARB_instanced_arrays
12    Nicolas Capens, TransGaming Inc.
13    James Helferty, TransGaming Inc.
14    Kenneth Russell, Google Inc.
15    Vangelis Kokkevis, Google Inc.
16
17Contact
18
19    Daniel Koch, TransGaming Inc. (daniel 'at' transgaming.com)
20
21Status
22
23    Implemented in ANGLE r976.
24
25Version
26
27    Last Modified Date: February 3, 2017
28    Author Revision: 4
29
30Number
31
32    OpenGL ES Extension #109
33
34Dependencies
35
36    OpenGL ES 2.0 is required.
37
38    This extension is written against the OpenGL ES 2.0 Specification.
39
40Overview
41
42    A common use case in GL for some applications is to be able to
43    draw the same object, or groups of similar objects that share
44    vertex data, primitive count and type, multiple times.  This
45    extension provides a means of accelerating such use cases while
46    restricting the number of API calls, and keeping the amount of
47    duplicate data to a minimum.
48
49    This extension introduces an array "divisor" for generic
50    vertex array attributes, which when non-zero specifies that the
51    attribute is "instanced."  An instanced attribute does not
52    advance per-vertex as usual, but rather after every <divisor>
53    conceptual draw calls.
54
55    (Attributes which aren't instanced are repeated in their entirety
56    for every conceptual draw call.)
57
58    By specifying transform data in an instanced attribute or series
59    of instanced attributes, vertex shaders can, in concert with the
60    instancing draw calls, draw multiple instances of an object with
61    one draw call.
62
63IP Status
64
65    No known IP claims.
66
67New Tokens
68
69    Accepted by the <pname> parameters of GetVertexAttribfv and
70    GetVertexAttribiv:
71
72        VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE               0x88FE
73
74New Procedures and Functions
75
76    void DrawArraysInstancedANGLE(enum mode, int first, sizei count,
77            sizei primcount);
78
79    void DrawElementsInstancedANGLE(enum mode, sizei count, enum type,
80            const void *indices, sizei primcount);
81
82    void VertexAttribDivisorANGLE(uint index, uint divisor);
83
84Additions to Chapter 2 of the OpenGL ES 2.0 Specification
85(OpenGL ES Operation)
86
87    Modify section 2.8 (Vertex Arrays), p. 21
88
89    After description of EnableVertexAttribArray / DisableVertexAttribArray
90    add the following:
91
92    "The command
93
94        void VertexAttribDivisorANGLE(uint index, uint divisor);
95
96    modifies the rate at which generic vertex attributes advance when
97    rendering multiple instances of primitives in a single draw call
98    (see DrawArraysInstancedANGLE and DrawElementsInstancedANGLE below).
99    If <divisor> is zero, the attribute at slot <index> advances once
100    per vertex.  If <divisor> is non-zero, the attribute advances once
101    per <divisor> instances of the primitives being rendered.
102    An attribute is referred to as "instanced" if its <divisor> value is
103    non-zero."
104
105    Replace the text describing DrawArrays and DrawElements in the
106    "Transferring Array Elements" subsection of 2.8, from the second paragraph
107    through the end of the section with the following:
108
109    "The command
110
111        void DrawArraysOneInstance( enum mode, int first, sizei count, int instance );
112
113    does not exist in the GL, but is used to describe functionality in
114    the rest of this section.  This function constructs a sequence of
115    geometric primitives by transferring elements <first> through <first> +
116    <count> - 1 of each enabled non-instanced array to the GL. <mode>
117    specifies what kind of primitives are constructed, as defined in section
118    2.6.1.
119
120    If an enabled vertex attribute array is instanced (it has a non-zero
121    attribute <divisor> as specified by VertexAttribDivisorANGLE), the element
122    that is transferred to the GL is given by:
123
124        floor( <instance> / <divisor> ).
125
126    If an array corresponding to a generic attribute required by a vertex shader
127    is not enabled, then the corresponding element is taken from the current
128    generic attribute state (see section 2.7).
129
130    If an array corresponding to a generic attribute required by a vertex shader
131    is enabled, the corresponding current generic attribute value is unaffected
132    by the execution of DrawArraysOneInstance.
133
134    Specifying <first> < 0 results in undefined behavior. Generating the error
135    INVALID_VALUE is recommended in this case.
136
137    The command
138
139        void DrawArrays( enum mode, int first, sizei count );
140
141    is equivalent to the command sequence
142
143        DrawArraysOneInstance(mode, first, count, 0);
144
145    The command
146
147        void DrawArraysInstancedANGLE(enum mode, int first, sizei count,
148                sizei primcount);
149
150    behaves identically to DrawArrays except that <primcount>
151    instances of the range of elements are executed, and the
152    <instance> advances for each iteration. Instanced attributes that
153    have <divisor> N, (where N > 0, as specified by
154    VertexAttribDivisorANGLE) advance once every N instances.
155
156    It has the same effect as:
157
158        if (mode, count, or primcount is invalid)
159            generate appropriate error
160        else {
161            for (i = 0; i < primcount; i++) {
162                DrawArraysOneInstance(mode, first, count, i);
163            }
164        }
165
166    The command
167
168       void DrawElementsOneInstance( enum mode, sizei count, enum type,
169            void *indices, int instance );
170
171    does not exist in the GL, but is used to describe functionality in
172    the rest of this section.  This command constructs a sequence of
173    geometric primitives by successively transferring the <count> elements
174    whose indices are stored in the currently bound element array buffer
175    (see section 2.9.2) at the offset defined by <indices> to the GL.
176    The <i>-th element transferred by DrawElementsOneInstance will be taken
177    from element <indices>[i] of each enabled non-instanced array.
178    <type> must be one of UNSIGNED_BYTE, UNSIGNED_SHORT, or UNSIGNED_INT,
179    indicating that the index values are of GL type ubyte, ushort, or uint
180    respectively. <mode> specifies what kind of primitives are constructed,
181    as defined in section 2.6.1.
182
183    If an enabled vertex attribute array is instanced (it has a non-zero
184    attribute <divisor> as specified by VertexAttribDivisorANGLE), the element
185    that is transferred to the GL is given by:
186
187        floor( <instance> / <divisor> );
188
189    If an array corresponding to a generic attribute required by a vertex
190    shader is not enabled, then the corresponding element is taken from the
191    current generic attribute state (see section 2.7). Otherwise, if an array
192    is enabled, the corresponding current generic attribute value is
193    unaffected by the execution of DrawElementsOneInstance.
194
195    The command
196
197        void DrawElements( enum mode, sizei count, enum type,
198             const void *indices);
199
200    behaves identically to DrawElementsOneInstance with the <instance>
201    parameter set to zero; the effect of calling
202
203        DrawElements(mode, count, type, indices);
204
205    is equivalent to the command sequence:
206
207       if (mode, count or type is invalid )
208            generate appropriate error
209        else
210            DrawElementsOneInstance(mode, count, type, indices, 0);
211
212    The command
213
214        void DrawElementsInstancedANGLE(enum mode, sizei count, enum type,
215                const void *indices, sizei primcount);
216
217    behaves identically to DrawElements except that <primcount>
218    instances of the set of elements are executed and the instance
219    advances between each set. Instanced attributes are advanced as they do
220    during the execution of DrawArraysInstancedANGLE. It has the same effect as:
221
222        if (mode, count, primcount, or type is invalid )
223            generate appropriate error
224        else {
225            for (int i = 0; i < primcount; i++) {
226                DrawElementsOneInstance(mode, count, type, indices, i);
227            }
228        }
229
230    If the number of supported generic vertex attributes (the value of
231    MAX_VERTEX_ATTRIBS) is <n>, then the client state required to implement
232    vertex arrays consists of <n> boolean values, <n> memory pointers, <n>
233    integer stride values, <n> symbolic constants representing array types,
234    <n> integers representing values per element, <n> boolean values
235    indicating normalization, and <n> integers representing vertex attribute
236    divisors.
237
238    In the initial state, the boolean values are each false, the memory
239    pointers are each NULL, the strides are each zero, the array types are
240    each FLOAT, the integers representing values per element are each four,
241    and the divisors are each zero."
242
243Additions to Chapter 3 of the OpenGL ES 2.0 Specification (Rasterization)
244
245    None
246
247Additions to Chapter 4 of the OpenGL ES 2.0 Specification (Per-Fragment
248Operations and the Framebuffer)
249
250    None
251
252Additions to Chapter 5 of the OpenGL ES 2.0 Specification (Special Functions)
253
254    None
255
256Additions to Chapter 6 of the OpenGL ES 2.0 Specification (State and State
257Requests)
258
259    In section 6.1.8, add VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE to the list of
260    pnames accepted by GetVertexAttribfv and GetVertexAttribiv.
261
262Additions to the AGL/EGL/GLX/WGL Specifications
263
264    None
265
266Dependencies on OES_element_index_uint
267
268    If OES_element_index_uint is not supported, removed all references
269    to UNSIGNED_INT indices and the associated GL data type uint in
270    the description of DrawElementsOneInstance.
271
272Errors
273
274    INVALID_VALUE is generated by VertexAttribDivisorANGLE if <index>
275    is greater than or equal to MAX_VERTEX_ATTRIBS.
276
277    INVALID_ENUM is generated by DrawElementsInstancedANGLE if <type> is
278    not one of UNSIGNED_BYTE, UNSIGNED_SHORT or UNSIGNED_INT.
279
280    INVALID_VALUE is generated by DrawArraysInstancedANGLE if <first>,
281    <count>, or <primcount> is less than zero.
282
283    INVALID_ENUM is generated by DrawArraysInstancedANGLE or
284    DrawElementsInstancedANGLE if <mode> is not one of the modes described in
285    section 2.6.1.
286
287    INVALID_VALUE is generated by DrawElementsInstancedANGLE if <count> or
288    <primcount> is less than zero.
289
290    INVALID_OPERATION is generated by DrawArraysInstancedANGLE or
291    DrawElementsInstancedANGLE if there is not at least one enabled
292    vertex attribute array that has a <divisor> of zero and is bound to an
293    active generic attribute value in the program used for the draw command.
294
295New State
296
297    Changes to table 6.2, p. 136 (Vertex Array Data)
298
299                                                               Initial
300    Get Value                          Type   Get Command      Value    Description       Sec.
301    ---------                          -----  -----------      -------  -----------       ----
302    VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE  8*xZ+  GetVertexAttrib  0        Instance Divisor  2.8
303
304Issues
305
306    1) Should vertex attribute zero be instance-able?
307
308       Resolved: Yes.
309       Discussion: In Direct3D 9 stream 0 must be specified as indexed data
310       and it cannot be instanced. In ANGLE we can work around this by
311       remapping any other stream that does have indexed data (ie a zero
312       attribute divisor) to stream 0 in D3D9. This works because the HLSL
313       vertex shader matches attributes against the stream by using the
314       shader semantic index.
315
316    2) Can all vertex attributes be instanced simultaneously?
317
318       Resolved: No
319       Discussion: In rare cases it is possible for no attribute to have a
320       divisor of 0, meaning that all attributes are instanced and none of
321       them are regularly indexed. This in turn means each instance can only
322       have a single position element, and so it only actually renders
323       something when rendering point primitives. This is not a very
324       meaningful way of using instancing (which is likely why D3D restricts
325       stream 0 to be indexed regularly for position data in the first place).
326       We could implement it by drawing these points one at a time (essentially
327       emulating instancing), but it would not be very efficient and there
328       seems to be little-to-no value in doing so.
329
330       If all of the enabled vertex attribute arrays that are bound to active
331       generic attributes in the program have a non-zero divisor, the draw
332       call should return INVALID_OPERATION.
333
334    3) Direct3D 9 only supports instancing for DrawIndexedPrimitive which
335       corresponds to DrawElementsInstanced.  Should we support
336       DrawArraysInstanced?
337
338       Resolved: Yes
339       Discussion: This can be supported easily enough by simply manufacturing
340       a linear index buffer of sufficient size and using that to do indexed
341       D3D9 drawing.
342
343    4) How much data is needed in a buffer for an instanced attribute?
344
345       Resolved: Where stride is the value passed to VertexAttribPointer:
346
347       if stride > 0
348         size = stride * ceil(primcount / divisor);
349       else
350         size = elementsize * ceil(primcount / divisor);
351
352Revision History
353
354    #4 February 3, 2017 Jon Leech
355       - Correct reference to ES 2.0 state table from 6.7 to 6.2 (public bug
356         1390)
357    #3 February 8, 2012 dgkoch
358       - clarify Issue 3 and the error condition for no indexed attributes
359    #2 January 24, 2012 dgkoch
360       - fix typos, add clarifications, and more errors
361    #1 January 17, 2012 dgkoch
362       - initial GLES2 version from ARB_instanced_arrays
363