diff -r 000000000000 -r 6474c204b198 gfx/angle/extensions/ANGLE_instanced_arrays.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gfx/angle/extensions/ANGLE_instanced_arrays.txt Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,359 @@ +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 + + Implemented in ANGLE r976. + +Version + + Last Modified Date: February 8, 2012 + Author Revision: 3 + +Number + + OpenGL ES Extension #109 + +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 + 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 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 is zero, the attribute at slot advances once + per vertex. If is non-zero, the attribute advances once + per instances of the primitives being rendered. + An attribute is referred to as "instanced" if its 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 through + + - 1 of each enabled non-instanced array to the GL. + 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 as specified by VertexAttribDivisorANGLE), the element + that is transferred to the GL is given by: + + floor( / ). + + 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 < 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 + instances of the range of elements are executed, and the + advances for each iteration. Instanced attributes that + have 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 elements + whose indices are stored in the currently bound element array buffer + (see section 2.9.2) at the offset defined by to the GL. + The -th element transferred by DrawElementsOneInstance will be taken + from element [i] of each enabled non-instanced array. + 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. 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 as specified by VertexAttribDivisorANGLE), the element + that is transferred to the GL is given by: + + floor( / ); + + 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 + 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 + 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 , then the client state required to implement + vertex arrays consists of boolean values, memory pointers, + integer stride values, symbolic constants representing array types, + integers representing values per element, boolean values + indicating normalization, and 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 + is greater than or equal to MAX_VERTEX_ATTRIBS. + + INVALID_ENUM is generated by DrawElementsInstancedANGLE if is + not one of UNSIGNED_BYTE, UNSIGNED_SHORT or UNSIGNED_INT. + + INVALID_VALUE is generated by DrawArraysInstancedANGLE if , + , or is less than zero. + + INVALID_ENUM is generated by DrawArraysInstancedANGLE or + DrawElementsInstancedANGLE if is not one of the modes described in + section 2.6.1. + + INVALID_VALUE is generated by DrawElementsInstancedANGLE if or + is less than zero. + + INVALID_OPERATION is generated by DrawArraysInstancedANGLE or + DrawElementsInstancedANGLE if there is not at least one enabled + vertex attribute array that has a of zero and is bound to an + active generic attribute value in the program used for the draw command. + +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 vertex attribute arrays that are bound to active + generic attributes in the program 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 + + #3 February 8, 2012 dgkoch + - clarify Issue 3 and the error condition for no indexed attributes + #2 January 24, 2012 dgkoch + - fix typos, add clarifications, and more errors + #1 January 17, 2012 dgkoch + - initial GLES2 version from ARB_instanced_arrays