gfx/angle/extensions/ANGLE_instanced_arrays.txt

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:697c11dcc7d8
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

mercurial