1Name
2
3    EXT_instanced_arrays
4
5Name Strings
6
7    GL_EXT_instanced_arrays
8
9Contributors
10
11    Contributors to ARB_instanced_arrays desktop OpenGL extension 
12        from which this extension borrows heavily
13    Abhijit Bhelande, Apple
14    Benj Lipchak, Apple
15
16Contact
17
18    Benj Lipchak, Apple (lipchak 'at' apple.com)
19
20Status
21
22    Complete
23
24Version
25
26    Last Modified Date:     June 26, 2013
27    Revision:               2
28
29Number
30
31    OpenGL ES Extension #156
32
33Dependencies
34
35    OpenGL ES 2.0 is required.
36
37    This extension is written against the OpenGL ES 2.0 Specification.
38    
39    OES_element_index_uint affects the definition of this extension.
40
41Overview
42
43    A common use case in GL for some applications is to be able to
44    draw the same object, or groups of similar objects that share
45    vertex data, primitive count and type, multiple times.  This 
46    extension provides a means of accelerating such use cases while 
47    reducing the number of API calls, and keeping the amount of 
48    duplicate data to a minimum.
49    
50    This extension introduces an array "divisor" for generic
51    vertex array attributes, which when non-zero specifies that the
52    attribute is "instanced."  An instanced attribute does not
53    advance per-vertex as usual, but rather after every <divisor>
54    conceptual draw calls.
55    
56    (Attributes which aren't instanced are repeated in their entirety
57    for every conceptual draw call.)
58    
59    By specifying transform data in an instanced attribute or series
60    of instanced attributes, vertex shaders can, in concert with the 
61    instancing draw calls, draw multiple instances of an object with 
62    one draw call.
63
64IP Status
65
66    No known IP claims.
67
68New Tokens
69
70    Accepted by the <pname> parameters of GetVertexAttribfv and 
71    GetVertexAttribiv:
72
73        VERTEX_ATTRIB_ARRAY_DIVISOR_EXT                 0x88FE
74
75New Procedures and Functions
76
77    void VertexAttribDivisorEXT(uint index, uint divisor);
78    void DrawArraysInstancedEXT(enum mode, int first, sizei count,
79            sizei instanceCount);
80    void DrawElementsInstancedEXT(enum mode, sizei count, enum type,
81            const void *indices, sizei instanceCount);
82
83Additions to Chapter 2 of the OpenGL ES 2.0 Specification
84
85    Modify section 2.8 (Vertex Arrays), p. 21
86
87    (insert before section Transferring Array Elements, p. 21)
88
89    "The command
90        
91        void VertexAttribDivisorEXT(uint index, uint divisor);
92
93    modifies the rate at which generic vertex attributes advance, which is 
94    useful when rendering multiple instances of primitives in a single draw call
95    (see DrawArraysInstancedEXT and DrawElementsInstancedEXT below). If 
96    <divisor> is zero, the attribute at slot <index> advances once per vertex. 
97    If <divisor> is non-zero, the attribute advances once per <divisor> 
98    instances of the primitives being rendered. An attribute is referred to as 
99    instanced if its <divisor> value is non-zero.
100    
101    An INVALID_VALUE error is generated if <index> is greater than or equal to 
102    the value of MAX_VERTEX_ATTRIBS."
103
104    (replace all occurrences of "DrawArrays or DrawElements" with "DrawArrays, 
105    DrawElements, or the other Draw* commands", for example the first sentence 
106    of Transferring Array Elements, p. 21)
107    
108    "When an array element i is transferred to the GL by DrawArrays, 
109    DrawElements, or the other Draw* commands described below, each generic 
110    attribute is expanded to four components."
111    
112    (replace second through fourth paragraphs of Transferring Array Elements)
113    
114    "The command
115
116        void DrawArraysOneInstance(enum mode, int first, sizei count, 
117                int instance);
118
119    does not exist in the GL, but is used to describe functionality in the rest 
120    of this section. This command constructs a sequence of geometric primitives
121    by successively transferring elements for <count> vertices. Elements <first> 
122    through <first> + <count> − 1 of each enabled non-instanced array are 
123    transferred to the GL. <mode> specifies what kind of primitives are 
124    constructed, as defined in section 2.6.1.
125    
126    If an enabled vertex attribute array is instanced (it has a non-zero 
127    <divisor> as specified by VertexAttribDivisorEXT), the element that is 
128    transferred to the GL, for all vertices, is given by:
129    
130         floor(instance / divisor)
131
132    If an array corresponding to a generic attribute is not enabled, then the 
133    corresponding element is taken from the current generic attribute state (see
134    section 2.7). Otherwise, if an array is enabled, the corresponding current 
135    generic attribute value is unaffected by the execution of 
136    DrawArraysOneInstance.
137
138    Specifying <first> < 0 results in undefined behavior. Generating the error 
139    INVALID_VALUE is recommended in this case.
140    
141    The command
142
143        void DrawArrays(enum mode, int first, sizei count);
144
145    is equivalent to the command sequence
146
147        DrawArraysOneInstance(mode, first, count, 0); 
148
149    The command
150        
151        void DrawArraysInstancedEXT(enum mode, int first, sizei count, 
152                sizei instanceCount);
153
154    behaves identically to DrawArrays except that <instanceCount> instances of 
155    the range of elements are executed and the value of <instance> advances 
156    for each iteration. Those attributes that have non-zero values for 
157    <divisor>, as specified by VertexAttribDivisorEXT, advance once every 
158    <divisor> instances. It has the same effect as:
159    
160        if (mode, count, or instanceCount is invalid) 
161            generate appropriate error
162        else {
163            for (i = 0; i < instanceCount; i++) {
164                DrawArraysOneInstance(mode, first, count, i); 
165            }
166        }
167            
168    The command
169        
170        void DrawElementsOneInstance(enum mode, sizei count, enum type, 
171                const void *indices, int instance);
172            
173    does not exist in the GL, but is used to describe functionality in the rest 
174    of this section. This command constructs a sequence of geometric primitives 
175    by successively transferring elements for <count> vertices. The ith element 
176    transferred by DrawElementsOneInstance will be taken from element 
177    <indices>[i] of each enabled non-instanced array, where <indices> specifies 
178    the location in memory of the first index of the element array being 
179    specified. <type> must be one of UNSIGNED_BYTE, UNSIGNED_SHORT, or 
180    UNSIGNED_INT indicating that the index values are of GL type ubyte, ushort,
181    or uint respectively. <mode> specifies what kind of primitives are 
182    constructed, as defined in section 2.6.1.
183    
184    If an enabled vertex attribute array is instanced (it has a non-zero 
185    <divisor> as specified by VertexAttribDivisorEXT), the element that is 
186    transferred to the GL, for all vertices, is given by:
187    
188    floor(instance / divisor)
189
190    If an array corresponding to a generic attribute is not enabled, then the 
191    corresponding element is taken from the current generic attribute state (see
192    section 2.7). Otherwise, if an array is enabled, the corresponding current 
193    generic attribute value is unaffected by the execution of 
194    DrawElementsOneInstance.
195
196    The command
197    
198        void DrawElements(enum mode, sizei count, enum type, 
199                const void *indices);
200    
201    behaves identically to DrawElementsOneInstance with the <instance> 
202    parameter set to zero; the effect of calling
203    
204        DrawElements(mode, count, type, indices); 
205    
206    is equivalent to the command sequence:
207        
208        if (mode, count or type is invalid) 
209            generate appropriate error
210        else
211            DrawElementsOneInstance(mode, count, type, indices, 0);
212            
213    The command
214            
215        void DrawElementsInstancedEXT(enum mode, sizei count, enum type, 
216                const void *indices, sizei instanceCount);
217            
218    behaves identically to DrawElements except that <instanceCount> instances of
219    the set of elements are executed and the value of <instance> advances 
220    between each set. Instanced attributes are advanced as they do during 
221    execution of DrawArraysInstancedEXT. It has the same effect as:
222            
223        if (mode, count, instanceCount, or type is invalid) 
224            generate appropriate error
225        else {
226            for (int i = 0; i < instanceCount; i++) {
227                DrawElementsOneInstance(mode, count, type, indices, i); 
228            }
229        }
230        
231    (append to first sentence of last paragraph of Transferring Array Elements)
232    
233    "..., and n integers representing vertex attribute divisors."
234
235    (append to last sentence of last paragraph of Transferring Array Elements)
236    
237    "..., the divisors are each zero."
238
239Additions to Chapter 6 of the OpenGL ES 2.0 Specification (State and State
240Requests)
241
242    In section 6.1.8, add to the list of pnames accepted by GetVertexAttrib*v: 
243    VERTEX_ATTRIB_ARRAY_DIVISOR_EXT
244
245Dependencies on OES_element_index_uint
246    
247    If OES_element_index_uint is not supported, remove references to
248    UNSIGNED_INT as a valid <type> for DrawElements*.
249    
250Errors
251
252    INVALID_VALUE is generated by VertexAttribDivisorEXT if <index>
253    is greater than or equal to MAX_VERTEX_ATTRIBS.
254
255    INVALID_ENUM is generated by DrawElementsInstancedEXT if <type> is
256    not one of UNSIGNED_BYTE, UNSIGNED_SHORT or UNSIGNED_INT.
257
258    INVALID_VALUE is generated by DrawArraysInstancedEXT if <first>,
259    <count>, or <instanceCount> is less than zero.
260
261    INVALID_VALUE is generated by DrawElementsInstancedEXT if <count> or
262    <instanceCount> is less than zero.
263
264    INVALID_ENUM is generated by DrawArraysInstancedEXT or
265    DrawElementsInstancedEXT if <mode> is not one of the kinds of primitives
266    accepted by DrawArrays and DrawElements.
267
268
269New State
270
271    Changes to table 6.2, p. 136 (Vertex Array Data)
272                                                                    Initial
273    Get Value                          Type      Get Command        Value    Description          Sec.
274    ---------                          ----      -----------        -------  -----------          ----
275    VERTEX_ATTRIB_ARRAY_DIVISOR_EXT    16* x Z+  GetVertexAttribiv  0        Vertex attrib array  2.8
276                                                                             instance divisor
277Issues
278
279    None
280    
281Revision History
282
283    #1 November 11 2012, Abhijit Bhelande and Benj Lipchak
284        - initial conversion from ARB to APPLE for ES2
285    #2 June 26 2013, Benj Lipchak
286        - promotion from APPLE to EXT
287