|
1 Name |
|
2 |
|
3 ANGLE_instanced_arrays |
|
4 |
|
5 Name Strings |
|
6 |
|
7 GL_ANGLE_instanced_arrays |
|
8 |
|
9 Contributors |
|
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 |
|
17 Contact |
|
18 |
|
19 Daniel Koch, TransGaming Inc. (daniel 'at' transgaming.com) |
|
20 |
|
21 Status |
|
22 |
|
23 Implemented in ANGLE r976. |
|
24 |
|
25 Version |
|
26 |
|
27 Last Modified Date: February 8, 2012 |
|
28 Author Revision: 3 |
|
29 |
|
30 Number |
|
31 |
|
32 OpenGL ES Extension #109 |
|
33 |
|
34 Dependencies |
|
35 |
|
36 OpenGL ES 2.0 is required. |
|
37 |
|
38 This extension is written against the OpenGL ES 2.0 Specification. |
|
39 |
|
40 Overview |
|
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 |
|
63 IP Status |
|
64 |
|
65 No known IP claims. |
|
66 |
|
67 New Tokens |
|
68 |
|
69 Accepted by the <pname> parameters of GetVertexAttribfv and |
|
70 GetVertexAttribiv: |
|
71 |
|
72 VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 0x88FE |
|
73 |
|
74 New 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 |
|
84 Additions 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 |
|
243 Additions to Chapter 3 of the OpenGL ES 2.0 Specification (Rasterization) |
|
244 |
|
245 None |
|
246 |
|
247 Additions to Chapter 4 of the OpenGL ES 2.0 Specification (Per-Fragment |
|
248 Operations and the Framebuffer) |
|
249 |
|
250 None |
|
251 |
|
252 Additions to Chapter 5 of the OpenGL ES 2.0 Specification (Special Functions) |
|
253 |
|
254 None |
|
255 |
|
256 Additions to Chapter 6 of the OpenGL ES 2.0 Specification (State and State |
|
257 Requests) |
|
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 |
|
262 Additions to the AGL/EGL/GLX/WGL Specifications |
|
263 |
|
264 None |
|
265 |
|
266 Dependencies 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 |
|
272 Errors |
|
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 |
|
295 New State |
|
296 |
|
297 Changes to table 6.7, p. 268 (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 |
|
304 Issues |
|
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 |
|
352 Revision History |
|
353 |
|
354 #3 February 8, 2012 dgkoch |
|
355 - clarify Issue 3 and the error condition for no indexed attributes |
|
356 #2 January 24, 2012 dgkoch |
|
357 - fix typos, add clarifications, and more errors |
|
358 #1 January 17, 2012 dgkoch |
|
359 - initial GLES2 version from ARB_instanced_arrays |