1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/angle/extensions/ANGLE_instanced_arrays.txt Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,359 @@ 1.4 +Name 1.5 + 1.6 + ANGLE_instanced_arrays 1.7 + 1.8 +Name Strings 1.9 + 1.10 + GL_ANGLE_instanced_arrays 1.11 + 1.12 +Contributors 1.13 + 1.14 + Contributors to ARB_instanced_arrays 1.15 + Nicolas Capens, TransGaming Inc. 1.16 + James Helferty, TransGaming Inc. 1.17 + Kenneth Russell, Google Inc. 1.18 + Vangelis Kokkevis, Google Inc. 1.19 + 1.20 +Contact 1.21 + 1.22 + Daniel Koch, TransGaming Inc. (daniel 'at' transgaming.com) 1.23 + 1.24 +Status 1.25 + 1.26 + Implemented in ANGLE r976. 1.27 + 1.28 +Version 1.29 + 1.30 + Last Modified Date: February 8, 2012 1.31 + Author Revision: 3 1.32 + 1.33 +Number 1.34 + 1.35 + OpenGL ES Extension #109 1.36 + 1.37 +Dependencies 1.38 + 1.39 + OpenGL ES 2.0 is required. 1.40 + 1.41 + This extension is written against the OpenGL ES 2.0 Specification. 1.42 + 1.43 +Overview 1.44 + 1.45 + A common use case in GL for some applications is to be able to 1.46 + draw the same object, or groups of similar objects that share 1.47 + vertex data, primitive count and type, multiple times. This 1.48 + extension provides a means of accelerating such use cases while 1.49 + restricting the number of API calls, and keeping the amount of 1.50 + duplicate data to a minimum. 1.51 + 1.52 + This extension introduces an array "divisor" for generic 1.53 + vertex array attributes, which when non-zero specifies that the 1.54 + attribute is "instanced." An instanced attribute does not 1.55 + advance per-vertex as usual, but rather after every <divisor> 1.56 + conceptual draw calls. 1.57 + 1.58 + (Attributes which aren't instanced are repeated in their entirety 1.59 + for every conceptual draw call.) 1.60 + 1.61 + By specifying transform data in an instanced attribute or series 1.62 + of instanced attributes, vertex shaders can, in concert with the 1.63 + instancing draw calls, draw multiple instances of an object with 1.64 + one draw call. 1.65 + 1.66 +IP Status 1.67 + 1.68 + No known IP claims. 1.69 + 1.70 +New Tokens 1.71 + 1.72 + Accepted by the <pname> parameters of GetVertexAttribfv and 1.73 + GetVertexAttribiv: 1.74 + 1.75 + VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 0x88FE 1.76 + 1.77 +New Procedures and Functions 1.78 + 1.79 + void DrawArraysInstancedANGLE(enum mode, int first, sizei count, 1.80 + sizei primcount); 1.81 + 1.82 + void DrawElementsInstancedANGLE(enum mode, sizei count, enum type, 1.83 + const void *indices, sizei primcount); 1.84 + 1.85 + void VertexAttribDivisorANGLE(uint index, uint divisor); 1.86 + 1.87 +Additions to Chapter 2 of the OpenGL ES 2.0 Specification 1.88 +(OpenGL ES Operation) 1.89 + 1.90 + Modify section 2.8 (Vertex Arrays), p. 21 1.91 + 1.92 + After description of EnableVertexAttribArray / DisableVertexAttribArray 1.93 + add the following: 1.94 + 1.95 + "The command 1.96 + 1.97 + void VertexAttribDivisorANGLE(uint index, uint divisor); 1.98 + 1.99 + modifies the rate at which generic vertex attributes advance when 1.100 + rendering multiple instances of primitives in a single draw call 1.101 + (see DrawArraysInstancedANGLE and DrawElementsInstancedANGLE below). 1.102 + If <divisor> is zero, the attribute at slot <index> advances once 1.103 + per vertex. If <divisor> is non-zero, the attribute advances once 1.104 + per <divisor> instances of the primitives being rendered. 1.105 + An attribute is referred to as "instanced" if its <divisor> value is 1.106 + non-zero." 1.107 + 1.108 + Replace the text describing DrawArrays and DrawElements in the 1.109 + "Transferring Array Elements" subsection of 2.8, from the second paragraph 1.110 + through the end of the section with the following: 1.111 + 1.112 + "The command 1.113 + 1.114 + void DrawArraysOneInstance( enum mode, int first, sizei count, int instance ); 1.115 + 1.116 + does not exist in the GL, but is used to describe functionality in 1.117 + the rest of this section. This function constructs a sequence of 1.118 + geometric primitives by transferring elements <first> through <first> + 1.119 + <count> - 1 of each enabled non-instanced array to the GL. <mode> 1.120 + specifies what kind of primitives are constructed, as defined in section 1.121 + 2.6.1. 1.122 + 1.123 + If an enabled vertex attribute array is instanced (it has a non-zero 1.124 + attribute <divisor> as specified by VertexAttribDivisorANGLE), the element 1.125 + that is transferred to the GL is given by: 1.126 + 1.127 + floor( <instance> / <divisor> ). 1.128 + 1.129 + If an array corresponding to a generic attribute required by a vertex shader 1.130 + is not enabled, then the corresponding element is taken from the current 1.131 + generic attribute state (see section 2.7). 1.132 + 1.133 + If an array corresponding to a generic attribute required by a vertex shader 1.134 + is enabled, the corresponding current generic attribute value is unaffected 1.135 + by the execution of DrawArraysOneInstance. 1.136 + 1.137 + Specifying <first> < 0 results in undefined behavior. Generating the error 1.138 + INVALID_VALUE is recommended in this case. 1.139 + 1.140 + The command 1.141 + 1.142 + void DrawArrays( enum mode, int first, sizei count ); 1.143 + 1.144 + is equivalent to the command sequence 1.145 + 1.146 + DrawArraysOneInstance(mode, first, count, 0); 1.147 + 1.148 + The command 1.149 + 1.150 + void DrawArraysInstancedANGLE(enum mode, int first, sizei count, 1.151 + sizei primcount); 1.152 + 1.153 + behaves identically to DrawArrays except that <primcount> 1.154 + instances of the range of elements are executed, and the 1.155 + <instance> advances for each iteration. Instanced attributes that 1.156 + have <divisor> N, (where N > 0, as specified by 1.157 + VertexAttribDivisorANGLE) advance once every N instances. 1.158 + 1.159 + It has the same effect as: 1.160 + 1.161 + if (mode, count, or primcount is invalid) 1.162 + generate appropriate error 1.163 + else { 1.164 + for (i = 0; i < primcount; i++) { 1.165 + DrawArraysOneInstance(mode, first, count, i); 1.166 + } 1.167 + } 1.168 + 1.169 + The command 1.170 + 1.171 + void DrawElementsOneInstance( enum mode, sizei count, enum type, 1.172 + void *indices, int instance ); 1.173 + 1.174 + does not exist in the GL, but is used to describe functionality in 1.175 + the rest of this section. This command constructs a sequence of 1.176 + geometric primitives by successively transferring the <count> elements 1.177 + whose indices are stored in the currently bound element array buffer 1.178 + (see section 2.9.2) at the offset defined by <indices> to the GL. 1.179 + The <i>-th element transferred by DrawElementsOneInstance will be taken 1.180 + from element <indices>[i] of each enabled non-instanced array. 1.181 + <type> must be one of UNSIGNED_BYTE, UNSIGNED_SHORT, or UNSIGNED_INT, 1.182 + indicating that the index values are of GL type ubyte, ushort, or uint 1.183 + respectively. <mode> specifies what kind of primitives are constructed, 1.184 + as defined in section 2.6.1. 1.185 + 1.186 + If an enabled vertex attribute array is instanced (it has a non-zero 1.187 + attribute <divisor> as specified by VertexAttribDivisorANGLE), the element 1.188 + that is transferred to the GL is given by: 1.189 + 1.190 + floor( <instance> / <divisor> ); 1.191 + 1.192 + If an array corresponding to a generic attribute required by a vertex 1.193 + shader is not enabled, then the corresponding element is taken from the 1.194 + current generic attribute state (see section 2.7). Otherwise, if an array 1.195 + is enabled, the corresponding current generic attribute value is 1.196 + unaffected by the execution of DrawElementsOneInstance. 1.197 + 1.198 + The command 1.199 + 1.200 + void DrawElements( enum mode, sizei count, enum type, 1.201 + const void *indices); 1.202 + 1.203 + behaves identically to DrawElementsOneInstance with the <instance> 1.204 + parameter set to zero; the effect of calling 1.205 + 1.206 + DrawElements(mode, count, type, indices); 1.207 + 1.208 + is equivalent to the command sequence: 1.209 + 1.210 + if (mode, count or type is invalid ) 1.211 + generate appropriate error 1.212 + else 1.213 + DrawElementsOneInstance(mode, count, type, indices, 0); 1.214 + 1.215 + The command 1.216 + 1.217 + void DrawElementsInstancedANGLE(enum mode, sizei count, enum type, 1.218 + const void *indices, sizei primcount); 1.219 + 1.220 + behaves identically to DrawElements except that <primcount> 1.221 + instances of the set of elements are executed and the instance 1.222 + advances between each set. Instanced attributes are advanced as they do 1.223 + during the execution of DrawArraysInstancedANGLE. It has the same effect as: 1.224 + 1.225 + if (mode, count, primcount, or type is invalid ) 1.226 + generate appropriate error 1.227 + else { 1.228 + for (int i = 0; i < primcount; i++) { 1.229 + DrawElementsOneInstance(mode, count, type, indices, i); 1.230 + } 1.231 + } 1.232 + 1.233 + If the number of supported generic vertex attributes (the value of 1.234 + MAX_VERTEX_ATTRIBS) is <n>, then the client state required to implement 1.235 + vertex arrays consists of <n> boolean values, <n> memory pointers, <n> 1.236 + integer stride values, <n> symbolic constants representing array types, 1.237 + <n> integers representing values per element, <n> boolean values 1.238 + indicating normalization, and <n> integers representing vertex attribute 1.239 + divisors. 1.240 + 1.241 + In the initial state, the boolean values are each false, the memory 1.242 + pointers are each NULL, the strides are each zero, the array types are 1.243 + each FLOAT, the integers representing values per element are each four, 1.244 + and the divisors are each zero." 1.245 + 1.246 +Additions to Chapter 3 of the OpenGL ES 2.0 Specification (Rasterization) 1.247 + 1.248 + None 1.249 + 1.250 +Additions to Chapter 4 of the OpenGL ES 2.0 Specification (Per-Fragment 1.251 +Operations and the Framebuffer) 1.252 + 1.253 + None 1.254 + 1.255 +Additions to Chapter 5 of the OpenGL ES 2.0 Specification (Special Functions) 1.256 + 1.257 + None 1.258 + 1.259 +Additions to Chapter 6 of the OpenGL ES 2.0 Specification (State and State 1.260 +Requests) 1.261 + 1.262 + In section 6.1.8, add VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE to the list of 1.263 + pnames accepted by GetVertexAttribfv and GetVertexAttribiv. 1.264 + 1.265 +Additions to the AGL/EGL/GLX/WGL Specifications 1.266 + 1.267 + None 1.268 + 1.269 +Dependencies on OES_element_index_uint 1.270 + 1.271 + If OES_element_index_uint is not supported, removed all references 1.272 + to UNSIGNED_INT indices and the associated GL data type uint in 1.273 + the description of DrawElementsOneInstance. 1.274 + 1.275 +Errors 1.276 + 1.277 + INVALID_VALUE is generated by VertexAttribDivisorANGLE if <index> 1.278 + is greater than or equal to MAX_VERTEX_ATTRIBS. 1.279 + 1.280 + INVALID_ENUM is generated by DrawElementsInstancedANGLE if <type> is 1.281 + not one of UNSIGNED_BYTE, UNSIGNED_SHORT or UNSIGNED_INT. 1.282 + 1.283 + INVALID_VALUE is generated by DrawArraysInstancedANGLE if <first>, 1.284 + <count>, or <primcount> is less than zero. 1.285 + 1.286 + INVALID_ENUM is generated by DrawArraysInstancedANGLE or 1.287 + DrawElementsInstancedANGLE if <mode> is not one of the modes described in 1.288 + section 2.6.1. 1.289 + 1.290 + INVALID_VALUE is generated by DrawElementsInstancedANGLE if <count> or 1.291 + <primcount> is less than zero. 1.292 + 1.293 + INVALID_OPERATION is generated by DrawArraysInstancedANGLE or 1.294 + DrawElementsInstancedANGLE if there is not at least one enabled 1.295 + vertex attribute array that has a <divisor> of zero and is bound to an 1.296 + active generic attribute value in the program used for the draw command. 1.297 + 1.298 +New State 1.299 + 1.300 + Changes to table 6.7, p. 268 (Vertex Array Data) 1.301 + 1.302 + Initial 1.303 + Get Value Type Get Command Value Description Sec. 1.304 + --------- ----- ----------- ------- ----------- ---- 1.305 + VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 8*xZ+ GetVertexAttrib 0 Instance Divisor 2.8 1.306 + 1.307 +Issues 1.308 + 1.309 + 1) Should vertex attribute zero be instance-able? 1.310 + 1.311 + Resolved: Yes. 1.312 + Discussion: In Direct3D 9 stream 0 must be specified as indexed data 1.313 + and it cannot be instanced. In ANGLE we can work around this by 1.314 + remapping any other stream that does have indexed data (ie a zero 1.315 + attribute divisor) to stream 0 in D3D9. This works because the HLSL 1.316 + vertex shader matches attributes against the stream by using the 1.317 + shader semantic index. 1.318 + 1.319 + 2) Can all vertex attributes be instanced simultaneously? 1.320 + 1.321 + Resolved: No 1.322 + Discussion: In rare cases it is possible for no attribute to have a 1.323 + divisor of 0, meaning that all attributes are instanced and none of 1.324 + them are regularly indexed. This in turn means each instance can only 1.325 + have a single position element, and so it only actually renders 1.326 + something when rendering point primitives. This is not a very 1.327 + meaningful way of using instancing (which is likely why D3D restricts 1.328 + stream 0 to be indexed regularly for position data in the first place). 1.329 + We could implement it by drawing these points one at a time (essentially 1.330 + emulating instancing), but it would not be very efficient and there 1.331 + seems to be little-to-no value in doing so. 1.332 + 1.333 + If all of the enabled vertex attribute arrays that are bound to active 1.334 + generic attributes in the program have a non-zero divisor, the draw 1.335 + call should return INVALID_OPERATION. 1.336 + 1.337 + 3) Direct3D 9 only supports instancing for DrawIndexedPrimitive which 1.338 + corresponds to DrawElementsInstanced. Should we support 1.339 + DrawArraysInstanced? 1.340 + 1.341 + Resolved: Yes 1.342 + Discussion: This can be supported easily enough by simply manufacturing 1.343 + a linear index buffer of sufficient size and using that to do indexed 1.344 + D3D9 drawing. 1.345 + 1.346 + 4) How much data is needed in a buffer for an instanced attribute? 1.347 + 1.348 + Resolved: Where stride is the value passed to VertexAttribPointer: 1.349 + 1.350 + if stride > 0 1.351 + size = stride * ceil(primcount / divisor); 1.352 + else 1.353 + size = elementsize * ceil(primcount / divisor); 1.354 + 1.355 +Revision History 1.356 + 1.357 + #3 February 8, 2012 dgkoch 1.358 + - clarify Issue 3 and the error condition for no indexed attributes 1.359 + #2 January 24, 2012 dgkoch 1.360 + - fix typos, add clarifications, and more errors 1.361 + #1 January 17, 2012 dgkoch 1.362 + - initial GLES2 version from ARB_instanced_arrays