This repository has been archived by the owner on Jun 16, 2018. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Trac #18156 git-svn-id: http://angleproject.googlecode.com/svn/trunk@967 736b8ea6-26fd-11df-bfd4-992fa37f6226
- Loading branch information
daniel@transgaming.com
committed
Jan 27, 2012
1 parent
61d1122
commit 2c1370b
Showing
1 changed file
with
355 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,355 @@ | ||
Name | ||
|
||
ANGLE_instanced_arrays | ||
|
||
Name Strings | ||
|
||
GL_ANGLE_instanced_arrays | ||
|
||
Contributors | ||
|
||
Contributors to ARB_instanced_arrays | ||
Nicolas Capens, TransGaming Inc. | ||
James Helferty, TransGaming Inc. | ||
Kenneth Russell, Google Inc. | ||
Vangelis Kokkevis, Google Inc. | ||
|
||
Contact | ||
|
||
Daniel Koch, TransGaming Inc. (daniel 'at' transgaming.com) | ||
|
||
Status | ||
|
||
Draft | ||
|
||
Version | ||
|
||
Last Modified Date: January 24, 2012 | ||
Author Revision: 2 | ||
|
||
Number | ||
|
||
OpenGL ES Extension #?? | ||
|
||
Dependencies | ||
|
||
OpenGL ES 2.0 is required. | ||
|
||
This extension is written against the OpenGL ES 2.0 Specification. | ||
|
||
Overview | ||
|
||
A common use case in GL for some applications is to be able to | ||
draw the same object, or groups of similar objects that share | ||
vertex data, primitive count and type, multiple times. This | ||
extension provides a means of accelerating such use cases while | ||
restricting the number of API calls, and keeping the amount of | ||
duplicate data to a minimum. | ||
|
||
This extension introduces an array "divisor" for generic | ||
vertex array attributes, which when non-zero specifies that the | ||
attribute is "instanced." An instanced attribute does not | ||
advance per-vertex as usual, but rather after every <divisor> | ||
conceptual draw calls. | ||
|
||
(Attributes which aren't instanced are repeated in their entirety | ||
for every conceptual draw call.) | ||
|
||
By specifying transform data in an instanced attribute or series | ||
of instanced attributes, vertex shaders can, in concert with the | ||
instancing draw calls, draw multiple instances of an object with | ||
one draw call. | ||
|
||
IP Status | ||
|
||
No known IP claims. | ||
|
||
New Tokens | ||
|
||
Accepted by the <pname> parameters of GetVertexAttribfv and | ||
GetVertexAttribiv: | ||
|
||
VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 0x88FE | ||
|
||
New Procedures and Functions | ||
|
||
void DrawArraysInstancedANGLE(enum mode, int first, sizei count, | ||
sizei primcount); | ||
|
||
void DrawElementsInstancedANGLE(enum mode, sizei count, enum type, | ||
const void *indices, sizei primcount); | ||
|
||
void VertexAttribDivisorANGLE(uint index, uint divisor); | ||
|
||
Additions to Chapter 2 of the OpenGL ES 2.0 Specification | ||
(OpenGL ES Operation) | ||
|
||
Modify section 2.8 (Vertex Arrays), p. 21 | ||
|
||
After description of EnableVertexAttribArray / DisableVertexAttribArray | ||
add the following: | ||
|
||
"The command | ||
|
||
void VertexAttribDivisorANGLE(uint index, uint divisor); | ||
|
||
modifies the rate at which generic vertex attributes advance when | ||
rendering multiple instances of primitives in a single draw call | ||
(see DrawArraysInstancedANGLE and DrawElementsInstancedANGLE below). | ||
If <divisor> is zero, the attribute at slot <index> advances once | ||
per vertex. If <divisor> is non-zero, the attribute advances once | ||
per <divisor> instances of the primitives being rendered. | ||
An attribute is referred to as "instanced" if its <divisor> value is | ||
non-zero." | ||
|
||
Replace the text describing DrawArrays and DrawElements in the | ||
"Transferring Array Elements" subsection of 2.8, from the second paragraph | ||
through the end of the section with the following: | ||
|
||
"The command | ||
|
||
void DrawArraysOneInstance( enum mode, int first, sizei count, int instance ); | ||
|
||
does not exist in the GL, but is used to describe functionality in | ||
the rest of this section. This function constructs a sequence of | ||
geometric primitives by transferring elements <first> through <first> + | ||
<count> - 1 of each enabled non-instanced array to the GL. <mode> | ||
specifies what kind of primitives are constructed, as defined in section | ||
2.6.1. | ||
|
||
If an enabled vertex attribute array is instanced (it has a non-zero | ||
attribute <divisor> as specified by VertexAttribDivisorANGLE), the element | ||
that is transferred to the GL is given by: | ||
|
||
floor( <instance> / <divisor> ). | ||
|
||
If an array corresponding to a generic attribute required by a vertex shader | ||
is not enabled, then the corresponding element is taken from the current | ||
generic attribute state (see section 2.7). | ||
|
||
If an array corresponding to a generic attribute required by a vertex shader | ||
is enabled, the corresponding current generic attribute value is unaffected | ||
by the execution of DrawArraysOneInstance. | ||
|
||
Specifying <first> < 0 results in undefined behavior. Generating the error | ||
INVALID_VALUE is recommended in this case. | ||
|
||
The command | ||
|
||
void DrawArrays( enum mode, int first, sizei count ); | ||
|
||
is equivalent to the command sequence | ||
|
||
DrawArraysOneInstance(mode, first, count, 0); | ||
|
||
The command | ||
|
||
void DrawArraysInstancedANGLE(enum mode, int first, sizei count, | ||
sizei primcount); | ||
|
||
behaves identically to DrawArrays except that <primcount> | ||
instances of the range of elements are executed, and the | ||
<instance> advances for each iteration. Instanced attributes that | ||
have <divisor> N, (where N > 0, as specified by | ||
VertexAttribDivisorANGLE) advance once every N instances. | ||
|
||
It has the same effect as: | ||
|
||
if (mode, count, or primcount is invalid) | ||
generate appropriate error | ||
else { | ||
for (i = 0; i < primcount; i++) { | ||
DrawArraysOneInstance(mode, first, count, i); | ||
} | ||
} | ||
|
||
The command | ||
|
||
void DrawElementsOneInstance( enum mode, sizei count, enum type, | ||
void *indices, int instance ); | ||
|
||
does not exist in the GL, but is used to describe functionality in | ||
the rest of this section. This command constructs a sequence of | ||
geometric primitives by successively transferring the <count> elements | ||
whose indices are stored in the currently bound element array buffer | ||
(see section 2.9.2) at the offset defined by <indices> to the GL. | ||
The <i>-th element transferred by DrawElementsOneInstance will be taken | ||
from element <indices>[i] of each enabled non-instanced array. | ||
<type> must be one of UNSIGNED_BYTE, UNSIGNED_SHORT, or UNSIGNED_INT, | ||
indicating that the index values are of GL type ubyte, ushort, or uint | ||
respectively. <mode> specifies what kind of primitives are constructed, | ||
as defined in section 2.6.1. | ||
|
||
If an enabled vertex attribute array is instanced (it has a non-zero | ||
attribute <divisor> as specified by VertexAttribDivisorANGLE), the element | ||
that is transferred to the GL is given by: | ||
|
||
floor( <instance> / <divisor> ); | ||
|
||
If an array corresponding to a generic attribute required by a vertex | ||
shader is not enabled, then the corresponding element is taken from the | ||
current generic attribute state (see section 2.7). Otherwise, if an array | ||
is enabled, the corresponding current generic attribute value is | ||
unaffected by the execution of DrawElementsOneInstance. | ||
|
||
The command | ||
|
||
void DrawElements( enum mode, sizei count, enum type, | ||
const void *indices); | ||
|
||
behaves identically to DrawElementsOneInstance with the <instance> | ||
parameter set to zero; the effect of calling | ||
|
||
DrawElements(mode, count, type, indices); | ||
|
||
is equivalent to the command sequence: | ||
|
||
if (mode, count or type is invalid ) | ||
generate appropriate error | ||
else | ||
DrawElementsOneInstance(mode, count, type, indices, 0); | ||
|
||
The command | ||
|
||
void DrawElementsInstancedANGLE(enum mode, sizei count, enum type, | ||
const void *indices, sizei primcount); | ||
|
||
behaves identically to DrawElements except that <primcount> | ||
instances of the set of elements are executed and the instance | ||
advances between each set. Instanced attributes are advanced as they do | ||
during the execution of DrawArraysInstancedANGLE. It has the same effect as: | ||
|
||
if (mode, count, primcount, or type is invalid ) | ||
generate appropriate error | ||
else { | ||
for (int i = 0; i < primcount; i++) { | ||
DrawElementsOneInstance(mode, count, type, indices, i); | ||
} | ||
} | ||
|
||
If the number of supported generic vertex attributes (the value of | ||
MAX_VERTEX_ATTRIBS) is <n>, then the client state required to implement | ||
vertex arrays consists of <n> boolean values, <n> memory pointers, <n> | ||
integer stride values, <n> symbolic constants representing array types, | ||
<n> integers representing values per element, <n> boolean values | ||
indicating normalization, and <n> integers representing vertex attribute | ||
divisors. | ||
|
||
In the initial state, the boolean values are each false, the memory | ||
pointers are each NULL, the strides are each zero, the array types are | ||
each FLOAT, the integers representing values per element are each four, | ||
and the divisors are each zero." | ||
|
||
Additions to Chapter 3 of the OpenGL ES 2.0 Specification (Rasterization) | ||
|
||
None | ||
|
||
Additions to Chapter 4 of the OpenGL ES 2.0 Specification (Per-Fragment | ||
Operations and the Framebuffer) | ||
|
||
None | ||
|
||
Additions to Chapter 5 of the OpenGL ES 2.0 Specification (Special Functions) | ||
|
||
None | ||
|
||
Additions to Chapter 6 of the OpenGL ES 2.0 Specification (State and State | ||
Requests) | ||
|
||
In section 6.1.8, add VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE to the list of | ||
pnames accepted by GetVertexAttribfv and GetVertexAttribiv. | ||
|
||
Additions to the AGL/EGL/GLX/WGL Specifications | ||
|
||
None | ||
|
||
Dependencies on OES_element_index_uint | ||
|
||
If OES_element_index_uint is not supported, removed all references | ||
to UNSIGNED_INT indices and the associated GL data type uint in | ||
the description of DrawElementsOneInstance. | ||
|
||
Errors | ||
|
||
INVALID_VALUE is generated by VertexAttribDivisorANGLE if <index> | ||
is greater than or equal to MAX_VERTEX_ATTRIBS. | ||
|
||
INVALID_ENUM is generated by DrawElementsInstancedANGLE if <type> is | ||
not one of UNSIGNED_BYTE, UNSIGNED_SHORT or UNSIGNED_INT. | ||
|
||
INVALID_VALUE is generated by DrawArraysInstancedANGLE if <first>, | ||
<count>, or <primcount> is less than zero. | ||
|
||
INVALID_ENUM is generated by DrawArraysInstancedANGLE or | ||
DrawElementsInstancedANGLE if <mode> is not one of the modes described in | ||
section 2.6.1. | ||
|
||
INVALID_VALUE is generated by DrawElementsInstancedANGLE if <count> or | ||
<primcount> is less than zero. | ||
|
||
INVALID_OPERATION is generated by DrawArraysInstancedANGLE or | ||
DrawElementsInstancedANGLE if there is not at least one enabled | ||
vertex attribute that has a <divisor> of zero. | ||
|
||
New State | ||
|
||
Changes to table 6.7, p. 268 (Vertex Array Data) | ||
|
||
Initial | ||
Get Value Type Get Command Value Description Sec. | ||
--------- ----- ----------- ------- ----------- ---- | ||
VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 8*xZ+ GetVertexAttrib 0 Instance Divisor 2.8 | ||
|
||
Issues | ||
|
||
1) Should vertex attribute zero be instance-able? | ||
|
||
Resolved: Yes. | ||
Discussion: In Direct3D 9 stream 0 must be specified as indexed data | ||
and it cannot be instanced. In ANGLE we can work around this by | ||
remapping any other stream that does have indexed data (ie a zero | ||
attribute divisor) to stream 0 in D3D9. This works because the HLSL | ||
vertex shader matches attributes against the stream by using the | ||
shader semantic index. | ||
|
||
2) Can all vertex attributes be instanced simultaneously? | ||
|
||
Resolved: No | ||
Discussion: In rare cases it is possible for no attribute to have a | ||
divisor of 0, meaning that all attributes are instanced and none of | ||
them are regularly indexed. This in turn means each instance can only | ||
have a single position element, and so it only actually renders | ||
something when rendering point primitives. This is not a very | ||
meaningful way of using instancing (which is likely why D3D restricts | ||
stream 0 to be indexed regularly for position data in the first place). | ||
We could implement it by drawing these points one at a time (essentially | ||
emulating instancing), but it would not be very efficient and there | ||
seems to be little-to-no value in doing so. | ||
|
||
If all of the enabled attributes have a non-zero divisor, the draw | ||
call should return INVALID_OPERATION. | ||
|
||
3) Direct3D 9 only supports instancing for DrawIndexedPrimitive which | ||
corresponds to DrawElementsInstanced. Should we support | ||
DrawArraysInstanced? | ||
|
||
Resolved: Yes | ||
Discussion: This can be supported easily enough by simply manufacturing | ||
a linear index buffer of sufficient size and using that to do indexed | ||
D3D9 drawing. | ||
|
||
4) How much data is needed in a buffer for an instanced attribute? | ||
|
||
Resolved: Where stride is the value passed to VertexAttribPointer: | ||
|
||
if stride > 0 | ||
size = stride * ceil(primcount / divisor); | ||
else | ||
size = elementsize * ceil(primcount / divisor); | ||
|
||
Revision History | ||
|
||
#2 January 24, 2012 dgkoch | ||
- fix typos, add clarifications, and more errors | ||
#1 January 17, 2012 dgkoch | ||
- initial GLES2 version from ARB_instanced_arrays |