Path: blob/main_old/extensions/ANGLE_instanced_arrays.txt
1693 views
Name12ANGLE_instanced_arrays34Name Strings56GL_ANGLE_instanced_arrays78Contributors910Contributors to ARB_instanced_arrays11Nicolas Capens, TransGaming Inc.12James Helferty, TransGaming Inc.13Kenneth Russell, Google Inc.14Vangelis Kokkevis, Google Inc.1516Contact1718Daniel Koch, TransGaming Inc. (daniel 'at' transgaming.com)1920Status2122Implemented in ANGLE r976.2324Version2526Last Modified Date: February 8, 201227Author Revision: 32829Number3031OpenGL ES Extension #1093233Dependencies3435OpenGL ES 2.0 is required.3637This extension is written against the OpenGL ES 2.0 Specification.3839Overview4041A common use case in GL for some applications is to be able to42draw the same object, or groups of similar objects that share43vertex data, primitive count and type, multiple times. This44extension provides a means of accelerating such use cases while45restricting the number of API calls, and keeping the amount of46duplicate data to a minimum.4748This extension introduces an array "divisor" for generic49vertex array attributes, which when non-zero specifies that the50attribute is "instanced." An instanced attribute does not51advance per-vertex as usual, but rather after every <divisor>52conceptual draw calls.5354(Attributes which aren't instanced are repeated in their entirety55for every conceptual draw call.)5657By specifying transform data in an instanced attribute or series58of instanced attributes, vertex shaders can, in concert with the59instancing draw calls, draw multiple instances of an object with60one draw call.6162IP Status6364No known IP claims.6566New Tokens6768Accepted by the <pname> parameters of GetVertexAttribfv and69GetVertexAttribiv:7071VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 0x88FE7273New Procedures and Functions7475void DrawArraysInstancedANGLE(enum mode, int first, sizei count,76sizei primcount);7778void DrawElementsInstancedANGLE(enum mode, sizei count, enum type,79const void *indices, sizei primcount);8081void VertexAttribDivisorANGLE(uint index, uint divisor);8283Additions to Chapter 2 of the OpenGL ES 2.0 Specification84(OpenGL ES Operation)8586Modify section 2.8 (Vertex Arrays), p. 218788After description of EnableVertexAttribArray / DisableVertexAttribArray89add the following:9091"The command9293void VertexAttribDivisorANGLE(uint index, uint divisor);9495modifies the rate at which generic vertex attributes advance when96rendering multiple instances of primitives in a single draw call97(see DrawArraysInstancedANGLE and DrawElementsInstancedANGLE below).98If <divisor> is zero, the attribute at slot <index> advances once99per vertex. If <divisor> is non-zero, the attribute advances once100per <divisor> instances of the primitives being rendered.101An attribute is referred to as "instanced" if its <divisor> value is102non-zero."103104Replace the text describing DrawArrays and DrawElements in the105"Transferring Array Elements" subsection of 2.8, from the second paragraph106through the end of the section with the following:107108"The command109110void DrawArraysOneInstance( enum mode, int first, sizei count, int instance );111112does not exist in the GL, but is used to describe functionality in113the rest of this section. This function constructs a sequence of114geometric primitives by transferring elements <first> through <first> +115<count> - 1 of each enabled non-instanced array to the GL. <mode>116specifies what kind of primitives are constructed, as defined in section1172.6.1.118119If an enabled vertex attribute array is instanced (it has a non-zero120attribute <divisor> as specified by VertexAttribDivisorANGLE), the element121that is transferred to the GL is given by:122123floor( <instance> / <divisor> ).124125If an array corresponding to a generic attribute required by a vertex shader126is not enabled, then the corresponding element is taken from the current127generic attribute state (see section 2.7).128129If an array corresponding to a generic attribute required by a vertex shader130is enabled, the corresponding current generic attribute value is unaffected131by the execution of DrawArraysOneInstance.132133Specifying <first> < 0 results in undefined behavior. Generating the error134INVALID_VALUE is recommended in this case.135136The command137138void DrawArrays( enum mode, int first, sizei count );139140is equivalent to the command sequence141142DrawArraysOneInstance(mode, first, count, 0);143144The command145146void DrawArraysInstancedANGLE(enum mode, int first, sizei count,147sizei primcount);148149behaves identically to DrawArrays except that <primcount>150instances of the range of elements are executed, and the151<instance> advances for each iteration. Instanced attributes that152have <divisor> N, (where N > 0, as specified by153VertexAttribDivisorANGLE) advance once every N instances.154155It has the same effect as:156157if (mode, count, or primcount is invalid)158generate appropriate error159else {160for (i = 0; i < primcount; i++) {161DrawArraysOneInstance(mode, first, count, i);162}163}164165The command166167void DrawElementsOneInstance( enum mode, sizei count, enum type,168void *indices, int instance );169170does not exist in the GL, but is used to describe functionality in171the rest of this section. This command constructs a sequence of172geometric primitives by successively transferring the <count> elements173whose indices are stored in the currently bound element array buffer174(see section 2.9.2) at the offset defined by <indices> to the GL.175The <i>-th element transferred by DrawElementsOneInstance will be taken176from element <indices>[i] of each enabled non-instanced array.177<type> must be one of UNSIGNED_BYTE, UNSIGNED_SHORT, or UNSIGNED_INT,178indicating that the index values are of GL type ubyte, ushort, or uint179respectively. <mode> specifies what kind of primitives are constructed,180as defined in section 2.6.1.181182If an enabled vertex attribute array is instanced (it has a non-zero183attribute <divisor> as specified by VertexAttribDivisorANGLE), the element184that is transferred to the GL is given by:185186floor( <instance> / <divisor> );187188If an array corresponding to a generic attribute required by a vertex189shader is not enabled, then the corresponding element is taken from the190current generic attribute state (see section 2.7). Otherwise, if an array191is enabled, the corresponding current generic attribute value is192unaffected by the execution of DrawElementsOneInstance.193194The command195196void DrawElements( enum mode, sizei count, enum type,197const void *indices);198199behaves identically to DrawElementsOneInstance with the <instance>200parameter set to zero; the effect of calling201202DrawElements(mode, count, type, indices);203204is equivalent to the command sequence:205206if (mode, count or type is invalid )207generate appropriate error208else209DrawElementsOneInstance(mode, count, type, indices, 0);210211The command212213void DrawElementsInstancedANGLE(enum mode, sizei count, enum type,214const void *indices, sizei primcount);215216behaves identically to DrawElements except that <primcount>217instances of the set of elements are executed and the instance218advances between each set. Instanced attributes are advanced as they do219during the execution of DrawArraysInstancedANGLE. It has the same effect as:220221if (mode, count, primcount, or type is invalid )222generate appropriate error223else {224for (int i = 0; i < primcount; i++) {225DrawElementsOneInstance(mode, count, type, indices, i);226}227}228229If the number of supported generic vertex attributes (the value of230MAX_VERTEX_ATTRIBS) is <n>, then the client state required to implement231vertex arrays consists of <n> boolean values, <n> memory pointers, <n>232integer stride values, <n> symbolic constants representing array types,233<n> integers representing values per element, <n> boolean values234indicating normalization, and <n> integers representing vertex attribute235divisors.236237In the initial state, the boolean values are each false, the memory238pointers are each NULL, the strides are each zero, the array types are239each FLOAT, the integers representing values per element are each four,240and the divisors are each zero."241242Additions to Chapter 3 of the OpenGL ES 2.0 Specification (Rasterization)243244None245246Additions to Chapter 4 of the OpenGL ES 2.0 Specification (Per-Fragment247Operations and the Framebuffer)248249None250251Additions to Chapter 5 of the OpenGL ES 2.0 Specification (Special Functions)252253None254255Additions to Chapter 6 of the OpenGL ES 2.0 Specification (State and State256Requests)257258In section 6.1.8, add VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE to the list of259pnames accepted by GetVertexAttribfv and GetVertexAttribiv.260261Additions to the AGL/EGL/GLX/WGL Specifications262263None264265Dependencies on OES_element_index_uint266267If OES_element_index_uint is not supported, removed all references268to UNSIGNED_INT indices and the associated GL data type uint in269the description of DrawElementsOneInstance.270271Errors272273INVALID_VALUE is generated by VertexAttribDivisorANGLE if <index>274is greater than or equal to MAX_VERTEX_ATTRIBS.275276INVALID_ENUM is generated by DrawElementsInstancedANGLE if <type> is277not one of UNSIGNED_BYTE, UNSIGNED_SHORT or UNSIGNED_INT.278279INVALID_VALUE is generated by DrawArraysInstancedANGLE if <first>,280<count>, or <primcount> is less than zero.281282INVALID_ENUM is generated by DrawArraysInstancedANGLE or283DrawElementsInstancedANGLE if <mode> is not one of the modes described in284section 2.6.1.285286INVALID_VALUE is generated by DrawElementsInstancedANGLE if <count> or287<primcount> is less than zero.288289INVALID_OPERATION is generated by DrawArraysInstancedANGLE or290DrawElementsInstancedANGLE if there is not at least one enabled291vertex attribute array that has a <divisor> of zero and is bound to an292active generic attribute value in the program used for the draw command.293294New State295296Changes to table 6.7, p. 268 (Vertex Array Data)297298Initial299Get Value Type Get Command Value Description Sec.300--------- ----- ----------- ------- ----------- ----301VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 8*xZ+ GetVertexAttrib 0 Instance Divisor 2.8302303Issues3043051) Should vertex attribute zero be instance-able?306307Resolved: Yes.308Discussion: In Direct3D 9 stream 0 must be specified as indexed data309and it cannot be instanced. In ANGLE we can work around this by310remapping any other stream that does have indexed data (ie a zero311attribute divisor) to stream 0 in D3D9. This works because the HLSL312vertex shader matches attributes against the stream by using the313shader semantic index.3143152) Can all vertex attributes be instanced simultaneously?316317Resolved: No318Discussion: In rare cases it is possible for no attribute to have a319divisor of 0, meaning that all attributes are instanced and none of320them are regularly indexed. This in turn means each instance can only321have a single position element, and so it only actually renders322something when rendering point primitives. This is not a very323meaningful way of using instancing (which is likely why D3D restricts324stream 0 to be indexed regularly for position data in the first place).325We could implement it by drawing these points one at a time (essentially326emulating instancing), but it would not be very efficient and there327seems to be little-to-no value in doing so.328329If all of the enabled vertex attribute arrays that are bound to active330generic attributes in the program have a non-zero divisor, the draw331call should return INVALID_OPERATION.3323333) Direct3D 9 only supports instancing for DrawIndexedPrimitive which334corresponds to DrawElementsInstanced. Should we support335DrawArraysInstanced?336337Resolved: Yes338Discussion: This can be supported easily enough by simply manufacturing339a linear index buffer of sufficient size and using that to do indexed340D3D9 drawing.3413424) How much data is needed in a buffer for an instanced attribute?343344Resolved: Where stride is the value passed to VertexAttribPointer:345346if stride > 0347size = stride * ceil(primcount / divisor);348else349size = elementsize * ceil(primcount / divisor);350351Revision History352353#3 February 8, 2012 dgkoch354- clarify Issue 3 and the error condition for no indexed attributes355#2 January 24, 2012 dgkoch356- fix typos, add clarifications, and more errors357#1 January 17, 2012 dgkoch358- initial GLES2 version from ARB_instanced_arrays359360361