• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1Name
2
3    AMD_interleaved_elements
4
5Name Strings
6
7    GL_AMD_interleaved_elements
8
9Contact
10
11    Graham Sellers (graham.sellers 'at' amd.com)
12
13Contributors
14
15    Sergey Leontyev, AMD
16
17Status
18
19    Shipping
20
21Version
22
23    Last Modified Date: 2 May 2013
24    Revision: 3
25
26Number
27
28    431
29
30Dependencies
31
32    This extension is written against version 4.3 of the Core Profile OpenGL
33    Specification, dated August 6, 2012.
34
35Overview
36
37        The glDrawElements function and its variants (instanced and indirect,
38    for example) allow OpenGL to draw indexed arrays of vertices. Since its
39    inception, OpenGL has supported unsigned bytes, unsigned shorts and
40    unsigned integers as index types. However, all enabled vertex arrays may
41    be represented by at most one shared index.
42
43        A common scenario in graphics rendering is that several faces share
44    a vertex where, for each face some properties of a vertex (position and
45    texture coordinates, for example) should be common but others must be
46    unique (colors, normals, and so on). Consider a mesh of a cube with
47    per-face normals, for example. There are 8 vertices and 6 normals, and 12
48    triangles (where each face of the cube is represented as two triangles).
49    To render this cube, we must compute the 24 unique permutations of
50    position and normal and build a new element list to index into it. In
51    fact, any advantage of indexed draw is lost here as the number of required
52    permutations is equal to the final vertex count required to draw the
53    object.
54
55        This extension allows OpenGL to process multi-component packed element
56    data. The maximum size of a vertex's index data is not increased, but the
57    facility to store 2 16-bit or 2 or 4 8-bit indices per vertex is introduced.
58    Each vertex attribute is given a swizzle property to allow its index to
59    be sourced from one of up to 4 channels of index data. This effectively
60    allows an application to supply multiple interleaved streams of index data
61    to OpenGL. Each vertex attribute is given a 'channel selector' to select
62    one of the up to 4 channels of vertex index information presented to
63    OpenGL. This enables the use-case described above and many more.
64    The swizzle parameter is also applied to vertex indices passed to shaders,
65    and updates to the definition of base vertex parameters and primitive
66    restart are applied.
67
68New Procedures and Functions
69
70    void VertexAttribParameteriAMD(uint index, enum pname, int param);
71
72New Tokens
73
74    Accepted by the <pname> parameter of VertexAttribParameteriAMD and
75    GetVertexAttrib{iv|dv|fv|Iiv|Iuiv|Ldv}:
76
77        VERTEX_ELEMENT_SWIZZLE_AMD                          0x91A4
78
79    Selected by the <pname> parameter of ProgramParameteri and GetProgramiv:
80
81        VERTEX_ID_SWIZZLE_AMD                               0x91A5
82
83    Accepted by the <param> parameter of VertexAttribParameteriAMD:
84
85        RED                                                 0x1903
86        GREEN                                               0x1904
87        BLUE                                                0x1905
88        ALPHA                                               0x1906
89
90    Accepted by the <type> parameter of DrawElements, DrawElementsInstanced,
91    DrawElementsInstancedBaseInstance and DrawElementsIndirect:
92
93        RG8UI                                               0x8238
94        RG16UI                                              0x823A
95        RGBA8UI                                             0x8D7C
96
97IP Status
98
99    None.
100
101Additions to Chapter 7 of the OpenGL Core Profile Specification, Version 4.3,
102"Programs and Shaders"
103
104    Add to the parameters accepted by ProgramParameteri, p.82:
105
106        If <pname> is VERTEX_ID_SWIZZLE_AMD, <value> should be set to
107    RED, GREEN, BLUE or ALPHA to indicate that the first, second, third
108    or fourth component of the vertex element vector be propagated to the
109    gl_VertexID vertex shader input as described in subsection 11.1.3.9.
110    The initial value of VERTEX_ID_SWIZZLE_AMD is RED.
111
112Additions to Chapter 10 of the OpenGL Core Profile Specification, Version 4.3,
113"Vertex Specification and Drawing Commands"
114
115    Insert Subsection 10.3.2, "Vertex Attribute Parameters", renumber
116    subsequent sections:
117
118        Each vertex attribute possesses a set of parameters that control
119    its behavior. Parameters for a vertex attribute may be set by calling:
120
121        void VertexAttribParameteriAMD(uint index,
122                                       enum pname,
123                                       int param);
124
125    where <index> identifies the generic vertex attribute array whose parameter
126    to modify. If <pname> is VERTEX_ELEMENT_SWIZZLE_AMD, then <param>
127    specifies the component of the vertex element that is to be used to
128    source the vertex indices for the selected vertex attribute. Its value
129    may be RED, GREEN, BLUE or ALPHA to select the first, second, third or
130    fourth component of the vertex element.
131
132    In section 10.3.2, "Primitive Restart", modify the language describing
133    how the restart index is compared to the vertex element index, p.302
134    as follows:
135
136        When one of the Draw* commands transfers a set of generic attribute
137    array elements to the GL, if all present index channels in the passed
138    element index are equal to the primitive restart index, then the GL
139    does not process those elements as a vertex. Instead ... *include
140    remainder of section verbatim.*
141
142    In the description of DrawElementsOneInstance (p. 311), replace the
143    sentence beginning "The ith element transferred by..." with:
144
145    For each enabled vertex attribute, the ith element transferred by
146    DrawElementsOneInstance will be taken from that attribute's selected
147    channel of the element whose values are stored currently bound element
148    array buffer at offset indices + i.
149
150    Replace the paragraph explaining the <type> parameter to
151    DrawElementsOneIntance (p. 311):
152
153        <type> may be UNSIGNED_BYTE, UNSIGNED_SHORT or UNSIGNED_INT,
154    indicating that the index values are of GL type ubyte, ushort or uint,
155    respectively, RG8UI or RG16UI, indicating that the index values are pairs
156    of GL type ubyte or ushort, respectively, or RGBA8UI, indicating that
157    index values are quadruplets of GL type ubyte. ...
158
159    Modify the language describing the DrawElements*BaseVertex* functions
160    on p.314 as follows:
161
162        ... are equivalent to the commands with the same base name (without
163    the BaseVertex suffix), except that the ith element transferred by
164    the corresponding draw call will be taken from the selected channel
165    of the element vector indices[i] + <basevertex>. That is, the value of
166    <basevertex> is added to the vertex index after channel selection.
167    ... *include remainder of description verbatim.*
168
169    Add to the list of accepted values for the <pname> parameter to
170    GetVertexAttrib* in Section 10.6, "Vertex Array and Vertex Array Object
171    Queries", p. 317:
172
173        ... VERTEX_ELEMENT_SWIZZLE_AMD.
174
175Additions to Chapter 11 of the OpenGL Core Profile Specification, Version 4.3,
176"Programmable Vertex Processing"
177
178    In Subsection 11.1.3.9, "Shader Inputs", p.338, modify the description
179    of gl_VertexID as follows:
180
181        gl_VertexID holds the integer index i stored in the selected component
182    of the element implicitly passed by DrawArrays or one of the other drawing
183    commands defined in section 10.5. The component of the element data
184    stored in gl_VertexID may be specified by calling ProgramParameteri with
185    <pname> set to VERTEX_ID_SWIZZLE_AMD as specified in section 7.3.
186
187New State
188
189    Append to Table 23.4, "Vertex Array Object State (cont.)":
190
191    +------------------------------+----------+---------------------+----------------+---------------------------------------------+----------+
192    | Get Value                    | Type     | Get Command         | Initial Value  | Description                                 | Sec      |
193    +------------------------------+----------+---------------------+----------------+---------------------------------------------+----------+
194    | VERTEX_ELEMENT_SWIZZLE_AMD   | 16 * x E | GetVertexAttribiv   | RED            | Channel selector for vertex attribute index | 10.3.2   |
195    +------------------------------+----------+---------------------+----------------+---------------------------------------------+----------+
196
197    Append to Table 23.39, "Program Object State (cont.)":
198
199    +------------------------+-------+---------------+----------------+------------------------------------+----------+
200    | Get Value              | Type  | Get Command   | Initial Value  | Description                        | Sec      |
201    +------------------------+-------+---------------+----------------+------------------------------------+----------+
202    | VERTEX_ID_SWIZZLE_AMD  | E     | GetProgramiv  | RED            | Channel selector for gl_VertexID   | 11.1.3.9 |
203    +------------------------+-------+---------------+----------------+------------------------------------+----------+
204
205New Implementation Dependent State
206
207    None.
208
209Errors
210
211    INVALID_ENUM is generated by VertexAttribParameteri if <pname> is not an
212    accepted token.
213
214    INVALID_VALUE is generated by VertexAttribParameteri if <value> is not an
215    acceptable value for the specified value of <pname>.
216
217Examples
218
219    // Basic per-face normals
220
221    // Normal data
222    static const float normals[] =
223    {
224        0.0f, 0.0f, 1.0f,   // Positive Z
225        0.0f, 0.0f, -1.0f,  // Negative Z
226        0.0f, 1.0f, 0.0f,   // Positive Y
227        0.0f, -1.0f, 0.0f,  // Negative Y
228        1.0f, 0.0f, 0.0f,   // Positive X
229        -1.0f, 0.0f, 0.0f,  // Negative X
230    };
231
232    // Position data
233    static const float positions[] =
234    {
235        -1.0f, -1.0f, -1.0f,
236        // <More data here>
237        1.0f, 1.0f, 1.0f
238    };
239
240    // Put the above data into a buffer and bind them as separate vertex
241    // attributes.
242    GLuint vertex_buffer;
243    glGenBuffers(1, &vertex_buffer);
244    glBindBuffer(GL_ARRAY_BUFFER, sizeof(positions) + sizeof(normals),
245                 NULL, GL_STATIC_DRAW);
246    glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(positions), positions);
247    glBufferSubData(GL_ARRAY_BUFFER, sizeof(positions),
248                    sizeof(normals), normals);
249    // ... etc. Set up vertex attributes.
250
251    // Index data
252    static const unsigned short indices[] =
253    {
254        0, 0,       // vertex 0: position index, normal index
255        1, 0,       // vertex 1: position index, normal index
256        2, 0,       // vertex 2: position index, normal index
257        1, 0,       // vertex 3: position index, normal index
258        2, 0,       // ... six vertices, forming
259        3, 0,       // ... two complete triangles, all using normals[0]
260        0, 1,
261        2, 1,
262        3, 1,
263        3, 1,
264        4, 1,       // ... six more vertices, forming
265        2, 1,       // ... two more triangles, all using normals[1]
266        // etc...
267    };
268
269    GLuint index_buffer;
270    glGenBuffers(1, &index_buffer);
271    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
272    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices),
273                 indices, GL_STATIC_DRAW);
274
275    // Okay... here's the new code. Set up vertex attribute 0 (position) to
276    // consume the RED channel of the vertex index and attribute 1 (normal)
277    // to consume the GREEN (second) channel of the vertex index. Then
278    // draw with GL_RG16UI (two channel, 16-bit unsigned int) as the index
279    // type.
280    glVertexAttribParameteriAMD(0, GL_VERTEX_ELEMENT_SWIZZLE_AMD, GL_RED);
281    glVertexAttribParameteriAMD(1, GL_VERTEX_ELEMENT_SWIZZLE_AMD, GL_GREEN);
282
283    glDrawElements(GL_TRIANGLES,
284                   sizeof(indices) / (2 * sizeof(unsigned short)),
285                   GL_RG16UI,
286                   NULL);
287
288Issues
289
290    1) What is the effect of multi-channel vertex indices on gl_VertexID?
291
292       RESOLVED: The VERTEX_ID_SWIZZLE_AMD program parameter selects the
293       channel of vector element types to be passed to gl_VertexID. By
294       default, this is RED, which is backwards compatible with single-channel
295       types.
296
297    2) How does this interact with primitive-restart indices?
298
299       RESOLVED: If all present channels of the vertex index vector match the
300       restart index, then the element index is considered to match.
301
302    3) How does baseVertex affect this?
303
304       RESOLVED: The same base vertex value is added to each each vertex
305       element component after channel selection for each of the enabled
306       vertex attributes. This choice is primarily motivated by the behavior
307       of base vertex elements encoded in indirect draw commands.
308
309    4) Does this feature disable potential optimizations such as vertex
310       reuse?
311
312       RESOVLED: No, vertex reuse should continue to function correctly.
313       Each unique vector of indices should produce a unique set of vertex
314       shader outputs (modulo side effects) and will hit a naive vertex
315       reuse cache. Nothing precludes more advanced optimization strategies
316       from being implemented, however.
317
318    5) Is it possible to get at all two or four channels of the vertex index
319       using a built-in input to the vertex shader?
320
321       RESOLVED: No. A single channel selection is provided. Providing more
322       data could be implemented by introducing a new built-in integer vector
323       input to the shader, but we have chosen not to do at this time.
324
325    6) What is the value of missing channels? For example, if we render with
326       GL_RG16UI indices but set certain attributes to GL_BLUE or GL_ALPHA
327       swizzle, what index value is used for those channels?
328
329       RESOLVED: Zero.
330
331    7) Are the traditional GL_RED, GL_GREEN, GL_BLUE, and GL_ALPHA terms
332       appropriate for this use?
333
334       RESOLVED: Not really, but are they appropriate for normals? g-buffers?
335       Any other arbitrary data that might be in a buffer or texture?
336       It's not worth introducing new enumerants just for this - we'll use
337       R, G, B, A.
338
339Revision History
340
341    Rev.    Date      Author    Changes
342    ----  --------    --------  -----------------------------------------
343
344     3    05/02/2013  gsellers  Shipping. Finalize spec ready for posting.
345     2    01/25/2013  gsellers  Resolve issues 1, 2, 3. Polish spec.
346     1    01/17/2013  gsellers  Initial draft
347
348