Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/extensions/ANGLE_instanced_arrays.txt
1693 views
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
360
361