• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1Name
2
3    ARB_base_instance
4
5Name Strings
6
7    GL_ARB_base_instance
8
9Contact
10
11    Graham Sellers, AMD (graham.sellers 'at' amd.com)
12
13Contributors
14
15    Daniel Koch, NVIDIA
16
17Notice
18
19    Copyright (c) 2011-2013 The Khronos Group Inc. Copyright terms at
20        http://www.khronos.org/registry/speccopyright.html
21
22Specification Update Policy
23
24    Khronos-approved extension specifications are updated in response to
25    issues and bugs prioritized by the Khronos OpenGL Working Group. For
26    extensions which have been promoted to a core Specification, fixes will
27    first appear in the latest version of that core Specification, and will
28    eventually be backported to the extension document. This policy is
29    described in more detail at
30        https://www.khronos.org/registry/OpenGL/docs/update_policy.php
31
32Status
33
34    Complete. Approved by the ARB on 2011/06/20.
35    Approved by the Khronos Promoters on 2011/07/29.
36
37Version
38
39    Last Modified Date:         June 13, 2014
40    Author Revision:            7
41
42Number
43
44    ARB Extension #107
45
46Dependencies
47
48    This extension is written against the OpenGL Specification, Version 4.1
49    (Core Profile).
50
51    OpenGL 3.1 or ARB_draw_instanced is required.
52
53Overview
54
55    This extension allows the offset within buffer objects used for instanced
56    rendering to be specified. This is congruent with the <first> parameter
57    in glDrawArrays and the <basevertex> parameter in glDrawElements. When
58    instanced rendering is performed (for example, through
59    glDrawArraysInstanced), instanced vertex attributes whose vertex attribute
60    divisors are non-zero are fetched from enabled vertex arrays per-instance
61    rather than per-vertex. However, in unextended OpenGL, there is no way to
62    define the offset into those arrays from which the attributes are fetched.
63    This extension adds that offset in the form of a <baseinstance> parameter
64    to several new procedures.
65
66    The <baseinstance> parameter is added to the index of the array element,
67    after division by the vertex attribute divisor. This allows several sets of
68    instanced vertex attribute data to be stored in a single vertex array, and
69    the base offset of that data to be specified for each draw. Further, this
70    extension exposes the <baseinstance> parameter as the final and previously
71    undefined structure member of the draw-indirect data structure.
72
73IP Status
74
75    None.
76
77New Procedures and Functions
78
79        void DrawArraysInstancedBaseInstance(enum mode,
80                                             int first,
81                                             sizei count,
82                                             sizei primcount,
83                                             uint baseinstance);
84
85        void DrawElementsInstancedBaseInstance(enum mode,
86                                               sizei count,
87                                               enum type,
88                                               const void *indices,
89                                               sizei primcount,
90                                               uint baseinstance);
91
92        void DrawElementsInstancedBaseVertexBaseInstance(enum mode,
93                                                         sizei count,
94                                                         enum type,
95                                                         const void *indices,
96                                                         sizei primcount,
97                                                         int basevertex,
98                                                         uint baseinstance);
99
100New Tokens
101
102    None.
103
104Modifications to Chapter 2 of the the OpenGL 4.1 (Core Profile) Specification
105(OpenGL Operation)
106
107    Modification to Section 2.8.3, "Drawing Commands"
108
109    Modify the definition of DrawArraysOneInstance on p.33.
110
111    The command
112
113        void DrawArraysOneInstance(enum mode,
114                                   int first,
115                                   sizei count,
116                                   int instance,
117                                   uint baseinstance);
118
119    does not exist in the GL, but is used to describe functionality in the rest
120    of this section. This command constructs a sequence of geometric primitives
121    by transferring elements <first> through <first> + <count> - 1 of each
122    enabled array to the GL. <mode> specifies what kind of primitives are
123    constructed, as defined in section 2.6.1. If <mode> is not a valid primitive
124    type, an INVALID_ENUM error is generated. If <count> is negative, an
125    INVALID_VALUE error is generated.
126
127    For any vertex attribute whose divisor is non-zero as set by
128    VertexAttribDivisor, the value <baseinstance> is used to determine the element
129    of the enabled instanced attribute arrays that will be transferred for all
130    vertices transferred by this function.
131
132    If an array corresponding to a generic attribute required by a vertex
133    shader is not enabled, then the corresponding element is taken from the
134    current generic attribute state (see section 2.7).
135
136    If an array corresponding to a generic attribute required by a vertex
137    shader is enabled, the corresponding current generic attribute value is
138    unaffected by the execution of DrawArraysOneInstance.
139
140    Specifying <first> < 0 results in undefined behavior. Generating the
141    error INVALID_VALUE is recommended in this case.
142
143    The command
144
145        void DrawArrays( enum mode, int first, sizei count );
146
147    is equivalent to the command sequence
148
149        DrawArraysOneInstance(mode, first, count, 0, 0);
150
151    Replace the description of DrawArraysInstanced with the following (p.35):
152
153    The command
154
155        void DrawArraysInstancedBaseInstance(enum mode,
156                                             int first,
157                                             sizei count,
158                                             sizei primcount,
159                                             uint baseinstance);
160
161    behaves identically to DrawArrays, except that <primcount> instances of the
162    range of elements are executed and the value of <instanceID> advances for
163    each iteration. Those attributes that have divisor N where N is other than
164    zero (as specified by VertexAttribDivisor) advance once every N instances.
165    Additionally, the first element within those instanced vertex attributes
166    is specified in <baseinstance>. Thus, the element transferred from instanced
167    vertex attributes is given by:
168
169        (<instanceID> / <divisor>) + <baseinstance>
170
171    DrawArraysInstancedBaseInstance has the same effect as:
172
173        if (<mode> or <count> is invalid)
174            generate  appropriate  error
175        else {
176            for  (i = 0; i < <primcount>; i++) {
177                instanceID  =  i;
178                DrawArraysOneInstance(<mode>, <first>, <count>, i, <baseinstance>);
179            }
180            instanceID  =  0;
181        }
182
183    The command
184
185            void DrawArraysInstanced(enum mode,
186                                     int first,
187                                     sizei count,
188                                     sizei primcount);
189
190    Is equivalent to calling DrawArraysInstancedBaseInstance with <baseinstance>
191    set to zero.
192
193    Update the definition of DrawArraysIndirect as follows (p.35):
194
195    The command
196
197            void  DrawArraysIndirect(enum mode,
198                                     const void *indirect);
199
200    has the same effect as:
201
202            typedef  struct {
203                uint  count;
204                uint  primCount;
205                uint  first;
206                uint  baseInstance;
207        } DrawArraysIndirectCommand;
208
209        const DrawArraysIndirectCommand  *cmd  =
210            (const DrawArraysIndirectCommand *)indirect;
211
212        DrawArraysInstancedBaseInstance(mode,
213                                        cmd->first,
214                                        cmd->count,
215                                        cmd->primCount,
216                                        cmd->baseInstance);
217
218    Remove the sentence "Results are undefined if reservedMustBeZero is non-
219    zero, but must not lead to GL interruption or termination."
220
221    Update the definition of DrawElementsOneInstance, p.36:
222
223    The command
224
225        void DrawElementsOneInstance(enum mode,
226                                     sizei count,
227                                     enum type,
228                                     const void *indices,
229                                     int instance,
230                                     uint baseinstance);
231
232    does not exist in the GL ... <retain the remainder of the description>
233
234    If an enabled vertex attribute array is instanced (it has a non-zero
235    attribute divisor as specified by VertexAttribDivisor), the element that is
236    transferred to the GL is given by:
237
238        floor(<instance> / <divisor>) + <baseinstance>
239
240    Update the text describing DrawElements:
241
242    The command
243
244        void DrawElements(enum mode,
245                          sizei count,
246                          enum type,
247                          const  void *indices);
248
249    behaves identically to DrawElementsOneInstance with the <instance> and
250    <baseinstance> parameters set to zero; the effect of calling
251
252        DrawElements(mode, count, type, indices);
253
254    is equivalent to the command sequence:
255
256        if (<mode>, <count> or <type> is invalid)
257            generate appropriate error
258        else
259            DrawElementsOneInstance(mode, count, type, indices, 0, 0);
260
261    Replace the description of DrawElementsInstanced with the following (p.37)
262
263    The command
264
265            void DrawElementsInstancedBaseInstance(enum mode,
266                                                   sizei count,
267                                                   enum type,
268                                                   const void *indices,
269                                                   sizei primcount,
270                                                   uint baseinstance);
271
272    behaves identically to DrawElements except that <primcount> instances of the
273    set of elements are executed, the value of instanceID advances between each
274    set, and the instance advances between each set. Instanced attributes
275    are advanced as they do during execution of DrawArraysInstancedBaseInstace,
276    and <baseinstance> has the same effect. It has the same effect as:
277
278        if  (<mode>, <count>, <type> or <primcount> is invalid)
279            generate  appropriate  error
280        else {
281            for (int i = 0; i < <primcount>;  i++) {
282                instanceID  =  i;
283                DrawElementsOneInstance(<mode>,
284                                        <count>,
285                                        <type>,
286                                        <indices>,
287                                        i,
288                                        <baseinstance>);
289            }
290            instanceID  =  0;
291        }
292
293    Add to the list of functions which include DrawElementsBaseVertex,
294    DrawRangeElementsBaseVertex, and DrawElementsInstancedBaseVertex (p.39):
295
296        void DrawElementsInstancedBaseVertexBaseInstance(enum mode,
297                                                         sizei count,
298                                                         enum type,
299                                                         const void *indices,
300                                                         sizei primcount,
301                                                         int basevertex,
302                                                         uint baseinstance);
303
304    Append to the paragraph describing DrawElementsBaseVertex,
305    DrawRangeElementsBaseVertex, and DrawElementsInstancedBaseVertex (p.40):
306
307    For DrawElementsInstancedBaseVertexBaseInstance, <baseinstance> is
308    used to offset the element from which instanced vertex attributes (those
309    with a non-zero divisor as specified by VertexAttribDivisor) are taken.
310
311    Update the definition of DrawElementsIndirect as follows (p.39):
312
313    The command
314
315        void  DrawElementsIndirect(enum mode,
316                                   enum type,
317                                   const void *indirect );
318
319    has the same effect as:
320
321        typedef  struct {
322            uint  count;
323            uint  primCount;
324            uint  firstIndex;
325            int   baseVertex;
326            uint  baseInstance;
327        } DrawElementsIndirectCommand;
328
329        if  (no element array buffer is bound) {
330            generate appropriate error
331        } else {
332            const DrawElementsIndirectCommand  *cmd  =
333                (const DrawElementsIndirectCommand  *)indirect;
334
335            DrawElementsInstancedBaseVertexBaseInstance(
336                                                mode,
337                                                cmd->count,
338                                                type,
339                                                cmd->firstIndex * size-of-type,
340                                                cmd->primCount,
341                                                cmd->baseVertex,
342                                                cmd->baseInstance);
343        }
344
345    Remove the sentence "Results are undefined if reservedMustBeZero is non-
346    zero, but must not lead to GL interruption or termination."
347
348Modifications to Chapter 3 of the the OpenGL 4.1 (Core Profile) Specification
349(Rasterization)
350
351    None.
352
353Modifications to Chapter 4 of the the OpenGL 4.1 (Core Profile) Specification
354(Per-Fragment Operations and the Framebuffer)
355
356    None.
357
358Modifications to Chapter 5 of the the OpenGL 4.1 (Core Profile) Specification
359(Special Functions)
360
361    None.
362
363Modifications to Chapter 6 of the the OpenGL 4.1 (Core Profile) Specification
364(State and State Requests)
365
366    None.
367
368Additions to the AGL/GLX/WGL Specifications
369
370    None.
371
372GLX Protocol
373
374    None.
375
376Errors
377
378    None.
379
380New State
381
382    None.
383
384New Implementation Dependent State
385
386    None.
387
388Conformance Testing
389
390    TBD.
391
392Issues
393
394    1) Does <baseinstance> offset gl_InstanceID?
395
396    RESOLVED: No. gl_InstanceID always starts from zero and counts up by one
397    for each instance rendered. If the shader author requires the actual value
398    of the instance index, including the base instance, they must pass the
399    base instance as a uniform. In OpenGL, the vertex attribute divisors are
400    not passed implicitly to the shader anyway, so the shader writer will need
401    to take care of this regardless.
402
403    2) Is <baseinstance> per-attribute, or global?
404
405    RESOLVED: It is global. The same base is used for all instanced attribute
406    arrays.
407
408    3) Do we need any more entry points?
409
410    DISCUSSION: Maybe. Technically, we could specify a base vertex to any
411    drawing command and any instanced vertex attributes would be taken from
412    that offset within their respective buffers. OpenGL already has enough
413    entry points. Another possibility is to actually make <baseinstance> OpenGL
414    state. The application would set it before any draw call (even non-
415    instanced ones) and this would affect the base used for any instanced vertex
416    attributes. However, this would introduce performance overhead and would not
417    work well with Draw{Arrays|Elements}Indirect.
418
419    4) DrawElementsInstancedBaseVertexBaseInstance? Really? The length of entry
420    point names is starting to get silly. Can we clean this up?
421
422    RESOLVED: Yes, we can, but not here.
423
424    5) What happens if baseInstance is > 2^31-1 (i.e., negative as a signed
425    integer)?
426
427    Need to check with hardware vendors.
428
429Revision History
430
431    Rev.    Date      Author    Changes
432    ----  ----------  --------  -----------------------------------------
433    7     06/13/2014  dkoch     fix <baseinstance> typos in overview.
434    6     01/18/2011  Jon Leech Use floor() in computing element transferred
435                                to the GL to match change in core spec.
436    5     01/10/2011  gsellers  Address bugzilla 7185. Make baseinstance API
437                                parameter unsigned to match structure member.
438                                Add issue 5.
439    4     01/05/2011  Jon Leech Fix typos from Bug 7202.
440    3     11/09/2010  gsellers  Address bugzilla 7011. Elaborate in overview
441                                and issues. Add placeholder for conformance test
442                                plan.
443    2     11/08/2010  gsellers  Did some TODOs. Check in to SVN.
444    1     11/04/2010  gsellers  Initial revision.
445