Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | Name |
michael@0 | 2 | |
michael@0 | 3 | ANGLE_instanced_arrays |
michael@0 | 4 | |
michael@0 | 5 | Name Strings |
michael@0 | 6 | |
michael@0 | 7 | GL_ANGLE_instanced_arrays |
michael@0 | 8 | |
michael@0 | 9 | Contributors |
michael@0 | 10 | |
michael@0 | 11 | Contributors to ARB_instanced_arrays |
michael@0 | 12 | Nicolas Capens, TransGaming Inc. |
michael@0 | 13 | James Helferty, TransGaming Inc. |
michael@0 | 14 | Kenneth Russell, Google Inc. |
michael@0 | 15 | Vangelis Kokkevis, Google Inc. |
michael@0 | 16 | |
michael@0 | 17 | Contact |
michael@0 | 18 | |
michael@0 | 19 | Daniel Koch, TransGaming Inc. (daniel 'at' transgaming.com) |
michael@0 | 20 | |
michael@0 | 21 | Status |
michael@0 | 22 | |
michael@0 | 23 | Implemented in ANGLE r976. |
michael@0 | 24 | |
michael@0 | 25 | Version |
michael@0 | 26 | |
michael@0 | 27 | Last Modified Date: February 8, 2012 |
michael@0 | 28 | Author Revision: 3 |
michael@0 | 29 | |
michael@0 | 30 | Number |
michael@0 | 31 | |
michael@0 | 32 | OpenGL ES Extension #109 |
michael@0 | 33 | |
michael@0 | 34 | Dependencies |
michael@0 | 35 | |
michael@0 | 36 | OpenGL ES 2.0 is required. |
michael@0 | 37 | |
michael@0 | 38 | This extension is written against the OpenGL ES 2.0 Specification. |
michael@0 | 39 | |
michael@0 | 40 | Overview |
michael@0 | 41 | |
michael@0 | 42 | A common use case in GL for some applications is to be able to |
michael@0 | 43 | draw the same object, or groups of similar objects that share |
michael@0 | 44 | vertex data, primitive count and type, multiple times. This |
michael@0 | 45 | extension provides a means of accelerating such use cases while |
michael@0 | 46 | restricting the number of API calls, and keeping the amount of |
michael@0 | 47 | duplicate data to a minimum. |
michael@0 | 48 | |
michael@0 | 49 | This extension introduces an array "divisor" for generic |
michael@0 | 50 | vertex array attributes, which when non-zero specifies that the |
michael@0 | 51 | attribute is "instanced." An instanced attribute does not |
michael@0 | 52 | advance per-vertex as usual, but rather after every <divisor> |
michael@0 | 53 | conceptual draw calls. |
michael@0 | 54 | |
michael@0 | 55 | (Attributes which aren't instanced are repeated in their entirety |
michael@0 | 56 | for every conceptual draw call.) |
michael@0 | 57 | |
michael@0 | 58 | By specifying transform data in an instanced attribute or series |
michael@0 | 59 | of instanced attributes, vertex shaders can, in concert with the |
michael@0 | 60 | instancing draw calls, draw multiple instances of an object with |
michael@0 | 61 | one draw call. |
michael@0 | 62 | |
michael@0 | 63 | IP Status |
michael@0 | 64 | |
michael@0 | 65 | No known IP claims. |
michael@0 | 66 | |
michael@0 | 67 | New Tokens |
michael@0 | 68 | |
michael@0 | 69 | Accepted by the <pname> parameters of GetVertexAttribfv and |
michael@0 | 70 | GetVertexAttribiv: |
michael@0 | 71 | |
michael@0 | 72 | VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 0x88FE |
michael@0 | 73 | |
michael@0 | 74 | New Procedures and Functions |
michael@0 | 75 | |
michael@0 | 76 | void DrawArraysInstancedANGLE(enum mode, int first, sizei count, |
michael@0 | 77 | sizei primcount); |
michael@0 | 78 | |
michael@0 | 79 | void DrawElementsInstancedANGLE(enum mode, sizei count, enum type, |
michael@0 | 80 | const void *indices, sizei primcount); |
michael@0 | 81 | |
michael@0 | 82 | void VertexAttribDivisorANGLE(uint index, uint divisor); |
michael@0 | 83 | |
michael@0 | 84 | Additions to Chapter 2 of the OpenGL ES 2.0 Specification |
michael@0 | 85 | (OpenGL ES Operation) |
michael@0 | 86 | |
michael@0 | 87 | Modify section 2.8 (Vertex Arrays), p. 21 |
michael@0 | 88 | |
michael@0 | 89 | After description of EnableVertexAttribArray / DisableVertexAttribArray |
michael@0 | 90 | add the following: |
michael@0 | 91 | |
michael@0 | 92 | "The command |
michael@0 | 93 | |
michael@0 | 94 | void VertexAttribDivisorANGLE(uint index, uint divisor); |
michael@0 | 95 | |
michael@0 | 96 | modifies the rate at which generic vertex attributes advance when |
michael@0 | 97 | rendering multiple instances of primitives in a single draw call |
michael@0 | 98 | (see DrawArraysInstancedANGLE and DrawElementsInstancedANGLE below). |
michael@0 | 99 | If <divisor> is zero, the attribute at slot <index> advances once |
michael@0 | 100 | per vertex. If <divisor> is non-zero, the attribute advances once |
michael@0 | 101 | per <divisor> instances of the primitives being rendered. |
michael@0 | 102 | An attribute is referred to as "instanced" if its <divisor> value is |
michael@0 | 103 | non-zero." |
michael@0 | 104 | |
michael@0 | 105 | Replace the text describing DrawArrays and DrawElements in the |
michael@0 | 106 | "Transferring Array Elements" subsection of 2.8, from the second paragraph |
michael@0 | 107 | through the end of the section with the following: |
michael@0 | 108 | |
michael@0 | 109 | "The command |
michael@0 | 110 | |
michael@0 | 111 | void DrawArraysOneInstance( enum mode, int first, sizei count, int instance ); |
michael@0 | 112 | |
michael@0 | 113 | does not exist in the GL, but is used to describe functionality in |
michael@0 | 114 | the rest of this section. This function constructs a sequence of |
michael@0 | 115 | geometric primitives by transferring elements <first> through <first> + |
michael@0 | 116 | <count> - 1 of each enabled non-instanced array to the GL. <mode> |
michael@0 | 117 | specifies what kind of primitives are constructed, as defined in section |
michael@0 | 118 | 2.6.1. |
michael@0 | 119 | |
michael@0 | 120 | If an enabled vertex attribute array is instanced (it has a non-zero |
michael@0 | 121 | attribute <divisor> as specified by VertexAttribDivisorANGLE), the element |
michael@0 | 122 | that is transferred to the GL is given by: |
michael@0 | 123 | |
michael@0 | 124 | floor( <instance> / <divisor> ). |
michael@0 | 125 | |
michael@0 | 126 | If an array corresponding to a generic attribute required by a vertex shader |
michael@0 | 127 | is not enabled, then the corresponding element is taken from the current |
michael@0 | 128 | generic attribute state (see section 2.7). |
michael@0 | 129 | |
michael@0 | 130 | If an array corresponding to a generic attribute required by a vertex shader |
michael@0 | 131 | is enabled, the corresponding current generic attribute value is unaffected |
michael@0 | 132 | by the execution of DrawArraysOneInstance. |
michael@0 | 133 | |
michael@0 | 134 | Specifying <first> < 0 results in undefined behavior. Generating the error |
michael@0 | 135 | INVALID_VALUE is recommended in this case. |
michael@0 | 136 | |
michael@0 | 137 | The command |
michael@0 | 138 | |
michael@0 | 139 | void DrawArrays( enum mode, int first, sizei count ); |
michael@0 | 140 | |
michael@0 | 141 | is equivalent to the command sequence |
michael@0 | 142 | |
michael@0 | 143 | DrawArraysOneInstance(mode, first, count, 0); |
michael@0 | 144 | |
michael@0 | 145 | The command |
michael@0 | 146 | |
michael@0 | 147 | void DrawArraysInstancedANGLE(enum mode, int first, sizei count, |
michael@0 | 148 | sizei primcount); |
michael@0 | 149 | |
michael@0 | 150 | behaves identically to DrawArrays except that <primcount> |
michael@0 | 151 | instances of the range of elements are executed, and the |
michael@0 | 152 | <instance> advances for each iteration. Instanced attributes that |
michael@0 | 153 | have <divisor> N, (where N > 0, as specified by |
michael@0 | 154 | VertexAttribDivisorANGLE) advance once every N instances. |
michael@0 | 155 | |
michael@0 | 156 | It has the same effect as: |
michael@0 | 157 | |
michael@0 | 158 | if (mode, count, or primcount is invalid) |
michael@0 | 159 | generate appropriate error |
michael@0 | 160 | else { |
michael@0 | 161 | for (i = 0; i < primcount; i++) { |
michael@0 | 162 | DrawArraysOneInstance(mode, first, count, i); |
michael@0 | 163 | } |
michael@0 | 164 | } |
michael@0 | 165 | |
michael@0 | 166 | The command |
michael@0 | 167 | |
michael@0 | 168 | void DrawElementsOneInstance( enum mode, sizei count, enum type, |
michael@0 | 169 | void *indices, int instance ); |
michael@0 | 170 | |
michael@0 | 171 | does not exist in the GL, but is used to describe functionality in |
michael@0 | 172 | the rest of this section. This command constructs a sequence of |
michael@0 | 173 | geometric primitives by successively transferring the <count> elements |
michael@0 | 174 | whose indices are stored in the currently bound element array buffer |
michael@0 | 175 | (see section 2.9.2) at the offset defined by <indices> to the GL. |
michael@0 | 176 | The <i>-th element transferred by DrawElementsOneInstance will be taken |
michael@0 | 177 | from element <indices>[i] of each enabled non-instanced array. |
michael@0 | 178 | <type> must be one of UNSIGNED_BYTE, UNSIGNED_SHORT, or UNSIGNED_INT, |
michael@0 | 179 | indicating that the index values are of GL type ubyte, ushort, or uint |
michael@0 | 180 | respectively. <mode> specifies what kind of primitives are constructed, |
michael@0 | 181 | as defined in section 2.6.1. |
michael@0 | 182 | |
michael@0 | 183 | If an enabled vertex attribute array is instanced (it has a non-zero |
michael@0 | 184 | attribute <divisor> as specified by VertexAttribDivisorANGLE), the element |
michael@0 | 185 | that is transferred to the GL is given by: |
michael@0 | 186 | |
michael@0 | 187 | floor( <instance> / <divisor> ); |
michael@0 | 188 | |
michael@0 | 189 | If an array corresponding to a generic attribute required by a vertex |
michael@0 | 190 | shader is not enabled, then the corresponding element is taken from the |
michael@0 | 191 | current generic attribute state (see section 2.7). Otherwise, if an array |
michael@0 | 192 | is enabled, the corresponding current generic attribute value is |
michael@0 | 193 | unaffected by the execution of DrawElementsOneInstance. |
michael@0 | 194 | |
michael@0 | 195 | The command |
michael@0 | 196 | |
michael@0 | 197 | void DrawElements( enum mode, sizei count, enum type, |
michael@0 | 198 | const void *indices); |
michael@0 | 199 | |
michael@0 | 200 | behaves identically to DrawElementsOneInstance with the <instance> |
michael@0 | 201 | parameter set to zero; the effect of calling |
michael@0 | 202 | |
michael@0 | 203 | DrawElements(mode, count, type, indices); |
michael@0 | 204 | |
michael@0 | 205 | is equivalent to the command sequence: |
michael@0 | 206 | |
michael@0 | 207 | if (mode, count or type is invalid ) |
michael@0 | 208 | generate appropriate error |
michael@0 | 209 | else |
michael@0 | 210 | DrawElementsOneInstance(mode, count, type, indices, 0); |
michael@0 | 211 | |
michael@0 | 212 | The command |
michael@0 | 213 | |
michael@0 | 214 | void DrawElementsInstancedANGLE(enum mode, sizei count, enum type, |
michael@0 | 215 | const void *indices, sizei primcount); |
michael@0 | 216 | |
michael@0 | 217 | behaves identically to DrawElements except that <primcount> |
michael@0 | 218 | instances of the set of elements are executed and the instance |
michael@0 | 219 | advances between each set. Instanced attributes are advanced as they do |
michael@0 | 220 | during the execution of DrawArraysInstancedANGLE. It has the same effect as: |
michael@0 | 221 | |
michael@0 | 222 | if (mode, count, primcount, or type is invalid ) |
michael@0 | 223 | generate appropriate error |
michael@0 | 224 | else { |
michael@0 | 225 | for (int i = 0; i < primcount; i++) { |
michael@0 | 226 | DrawElementsOneInstance(mode, count, type, indices, i); |
michael@0 | 227 | } |
michael@0 | 228 | } |
michael@0 | 229 | |
michael@0 | 230 | If the number of supported generic vertex attributes (the value of |
michael@0 | 231 | MAX_VERTEX_ATTRIBS) is <n>, then the client state required to implement |
michael@0 | 232 | vertex arrays consists of <n> boolean values, <n> memory pointers, <n> |
michael@0 | 233 | integer stride values, <n> symbolic constants representing array types, |
michael@0 | 234 | <n> integers representing values per element, <n> boolean values |
michael@0 | 235 | indicating normalization, and <n> integers representing vertex attribute |
michael@0 | 236 | divisors. |
michael@0 | 237 | |
michael@0 | 238 | In the initial state, the boolean values are each false, the memory |
michael@0 | 239 | pointers are each NULL, the strides are each zero, the array types are |
michael@0 | 240 | each FLOAT, the integers representing values per element are each four, |
michael@0 | 241 | and the divisors are each zero." |
michael@0 | 242 | |
michael@0 | 243 | Additions to Chapter 3 of the OpenGL ES 2.0 Specification (Rasterization) |
michael@0 | 244 | |
michael@0 | 245 | None |
michael@0 | 246 | |
michael@0 | 247 | Additions to Chapter 4 of the OpenGL ES 2.0 Specification (Per-Fragment |
michael@0 | 248 | Operations and the Framebuffer) |
michael@0 | 249 | |
michael@0 | 250 | None |
michael@0 | 251 | |
michael@0 | 252 | Additions to Chapter 5 of the OpenGL ES 2.0 Specification (Special Functions) |
michael@0 | 253 | |
michael@0 | 254 | None |
michael@0 | 255 | |
michael@0 | 256 | Additions to Chapter 6 of the OpenGL ES 2.0 Specification (State and State |
michael@0 | 257 | Requests) |
michael@0 | 258 | |
michael@0 | 259 | In section 6.1.8, add VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE to the list of |
michael@0 | 260 | pnames accepted by GetVertexAttribfv and GetVertexAttribiv. |
michael@0 | 261 | |
michael@0 | 262 | Additions to the AGL/EGL/GLX/WGL Specifications |
michael@0 | 263 | |
michael@0 | 264 | None |
michael@0 | 265 | |
michael@0 | 266 | Dependencies on OES_element_index_uint |
michael@0 | 267 | |
michael@0 | 268 | If OES_element_index_uint is not supported, removed all references |
michael@0 | 269 | to UNSIGNED_INT indices and the associated GL data type uint in |
michael@0 | 270 | the description of DrawElementsOneInstance. |
michael@0 | 271 | |
michael@0 | 272 | Errors |
michael@0 | 273 | |
michael@0 | 274 | INVALID_VALUE is generated by VertexAttribDivisorANGLE if <index> |
michael@0 | 275 | is greater than or equal to MAX_VERTEX_ATTRIBS. |
michael@0 | 276 | |
michael@0 | 277 | INVALID_ENUM is generated by DrawElementsInstancedANGLE if <type> is |
michael@0 | 278 | not one of UNSIGNED_BYTE, UNSIGNED_SHORT or UNSIGNED_INT. |
michael@0 | 279 | |
michael@0 | 280 | INVALID_VALUE is generated by DrawArraysInstancedANGLE if <first>, |
michael@0 | 281 | <count>, or <primcount> is less than zero. |
michael@0 | 282 | |
michael@0 | 283 | INVALID_ENUM is generated by DrawArraysInstancedANGLE or |
michael@0 | 284 | DrawElementsInstancedANGLE if <mode> is not one of the modes described in |
michael@0 | 285 | section 2.6.1. |
michael@0 | 286 | |
michael@0 | 287 | INVALID_VALUE is generated by DrawElementsInstancedANGLE if <count> or |
michael@0 | 288 | <primcount> is less than zero. |
michael@0 | 289 | |
michael@0 | 290 | INVALID_OPERATION is generated by DrawArraysInstancedANGLE or |
michael@0 | 291 | DrawElementsInstancedANGLE if there is not at least one enabled |
michael@0 | 292 | vertex attribute array that has a <divisor> of zero and is bound to an |
michael@0 | 293 | active generic attribute value in the program used for the draw command. |
michael@0 | 294 | |
michael@0 | 295 | New State |
michael@0 | 296 | |
michael@0 | 297 | Changes to table 6.7, p. 268 (Vertex Array Data) |
michael@0 | 298 | |
michael@0 | 299 | Initial |
michael@0 | 300 | Get Value Type Get Command Value Description Sec. |
michael@0 | 301 | --------- ----- ----------- ------- ----------- ---- |
michael@0 | 302 | VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 8*xZ+ GetVertexAttrib 0 Instance Divisor 2.8 |
michael@0 | 303 | |
michael@0 | 304 | Issues |
michael@0 | 305 | |
michael@0 | 306 | 1) Should vertex attribute zero be instance-able? |
michael@0 | 307 | |
michael@0 | 308 | Resolved: Yes. |
michael@0 | 309 | Discussion: In Direct3D 9 stream 0 must be specified as indexed data |
michael@0 | 310 | and it cannot be instanced. In ANGLE we can work around this by |
michael@0 | 311 | remapping any other stream that does have indexed data (ie a zero |
michael@0 | 312 | attribute divisor) to stream 0 in D3D9. This works because the HLSL |
michael@0 | 313 | vertex shader matches attributes against the stream by using the |
michael@0 | 314 | shader semantic index. |
michael@0 | 315 | |
michael@0 | 316 | 2) Can all vertex attributes be instanced simultaneously? |
michael@0 | 317 | |
michael@0 | 318 | Resolved: No |
michael@0 | 319 | Discussion: In rare cases it is possible for no attribute to have a |
michael@0 | 320 | divisor of 0, meaning that all attributes are instanced and none of |
michael@0 | 321 | them are regularly indexed. This in turn means each instance can only |
michael@0 | 322 | have a single position element, and so it only actually renders |
michael@0 | 323 | something when rendering point primitives. This is not a very |
michael@0 | 324 | meaningful way of using instancing (which is likely why D3D restricts |
michael@0 | 325 | stream 0 to be indexed regularly for position data in the first place). |
michael@0 | 326 | We could implement it by drawing these points one at a time (essentially |
michael@0 | 327 | emulating instancing), but it would not be very efficient and there |
michael@0 | 328 | seems to be little-to-no value in doing so. |
michael@0 | 329 | |
michael@0 | 330 | If all of the enabled vertex attribute arrays that are bound to active |
michael@0 | 331 | generic attributes in the program have a non-zero divisor, the draw |
michael@0 | 332 | call should return INVALID_OPERATION. |
michael@0 | 333 | |
michael@0 | 334 | 3) Direct3D 9 only supports instancing for DrawIndexedPrimitive which |
michael@0 | 335 | corresponds to DrawElementsInstanced. Should we support |
michael@0 | 336 | DrawArraysInstanced? |
michael@0 | 337 | |
michael@0 | 338 | Resolved: Yes |
michael@0 | 339 | Discussion: This can be supported easily enough by simply manufacturing |
michael@0 | 340 | a linear index buffer of sufficient size and using that to do indexed |
michael@0 | 341 | D3D9 drawing. |
michael@0 | 342 | |
michael@0 | 343 | 4) How much data is needed in a buffer for an instanced attribute? |
michael@0 | 344 | |
michael@0 | 345 | Resolved: Where stride is the value passed to VertexAttribPointer: |
michael@0 | 346 | |
michael@0 | 347 | if stride > 0 |
michael@0 | 348 | size = stride * ceil(primcount / divisor); |
michael@0 | 349 | else |
michael@0 | 350 | size = elementsize * ceil(primcount / divisor); |
michael@0 | 351 | |
michael@0 | 352 | Revision History |
michael@0 | 353 | |
michael@0 | 354 | #3 February 8, 2012 dgkoch |
michael@0 | 355 | - clarify Issue 3 and the error condition for no indexed attributes |
michael@0 | 356 | #2 January 24, 2012 dgkoch |
michael@0 | 357 | - fix typos, add clarifications, and more errors |
michael@0 | 358 | #1 January 17, 2012 dgkoch |
michael@0 | 359 | - initial GLES2 version from ARB_instanced_arrays |