gfx/angle/extensions/ANGLE_instanced_arrays.txt

changeset 0
6474c204b198
     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

mercurial