| Name |
| |
| AMD_interleaved_elements |
| |
| Name Strings |
| |
| GL_AMD_interleaved_elements |
| |
| Contact |
| |
| Graham Sellers (graham.sellers 'at' amd.com) |
| |
| Contributors |
| |
| Sergey Leontyev, AMD |
| |
| Status |
| |
| Shipping |
| |
| Version |
| |
| Last Modified Date: 2 May 2013 |
| Revision: 3 |
| |
| Number |
| |
| 431 |
| |
| Dependencies |
| |
| This extension is written against version 4.3 of the Core Profile OpenGL |
| Specification, dated August 6, 2012. |
| |
| Overview |
| |
| The glDrawElements function and its variants (instanced and indirect, |
| for example) allow OpenGL to draw indexed arrays of vertices. Since its |
| inception, OpenGL has supported unsigned bytes, unsigned shorts and |
| unsigned integers as index types. However, all enabled vertex arrays may |
| be represented by at most one shared index. |
| |
| A common scenario in graphics rendering is that several faces share |
| a vertex where, for each face some properties of a vertex (position and |
| texture coordinates, for example) should be common but others must be |
| unique (colors, normals, and so on). Consider a mesh of a cube with |
| per-face normals, for example. There are 8 vertices and 6 normals, and 12 |
| triangles (where each face of the cube is represented as two triangles). |
| To render this cube, we must compute the 24 unique permutations of |
| position and normal and build a new element list to index into it. In |
| fact, any advantage of indexed draw is lost here as the number of required |
| permutations is equal to the final vertex count required to draw the |
| object. |
| |
| This extension allows OpenGL to process multi-component packed element |
| data. The maximum size of a vertex's index data is not increased, but the |
| facility to store 2 16-bit or 2 or 4 8-bit indices per vertex is introduced. |
| Each vertex attribute is given a swizzle property to allow its index to |
| be sourced from one of up to 4 channels of index data. This effectively |
| allows an application to supply multiple interleaved streams of index data |
| to OpenGL. Each vertex attribute is given a 'channel selector' to select |
| one of the up to 4 channels of vertex index information presented to |
| OpenGL. This enables the use-case described above and many more. |
| The swizzle parameter is also applied to vertex indices passed to shaders, |
| and updates to the definition of base vertex parameters and primitive |
| restart are applied. |
| |
| New Procedures and Functions |
| |
| void VertexAttribParameteriAMD(uint index, enum pname, int param); |
| |
| New Tokens |
| |
| Accepted by the <pname> parameter of VertexAttribParameteriAMD and |
| GetVertexAttrib{iv|dv|fv|Iiv|Iuiv|Ldv}: |
| |
| VERTEX_ELEMENT_SWIZZLE_AMD 0x91A4 |
| |
| Selected by the <pname> parameter of ProgramParameteri and GetProgramiv: |
| |
| VERTEX_ID_SWIZZLE_AMD 0x91A5 |
| |
| Accepted by the <param> parameter of VertexAttribParameteriAMD: |
| |
| RED 0x1903 |
| GREEN 0x1904 |
| BLUE 0x1905 |
| ALPHA 0x1906 |
| |
| Accepted by the <type> parameter of DrawElements, DrawElementsInstanced, |
| DrawElementsInstancedBaseInstance and DrawElementsIndirect: |
| |
| RG8UI 0x8238 |
| RG16UI 0x823A |
| RGBA8UI 0x8D7C |
| |
| IP Status |
| |
| None. |
| |
| Additions to Chapter 7 of the OpenGL Core Profile Specification, Version 4.3, |
| "Programs and Shaders" |
| |
| Add to the parameters accepted by ProgramParameteri, p.82: |
| |
| If <pname> is VERTEX_ID_SWIZZLE_AMD, <value> should be set to |
| RED, GREEN, BLUE or ALPHA to indicate that the first, second, third |
| or fourth component of the vertex element vector be propagated to the |
| gl_VertexID vertex shader input as described in subsection 11.1.3.9. |
| The initial value of VERTEX_ID_SWIZZLE_AMD is RED. |
| |
| Additions to Chapter 10 of the OpenGL Core Profile Specification, Version 4.3, |
| "Vertex Specification and Drawing Commands" |
| |
| Insert Subsection 10.3.2, "Vertex Attribute Parameters", renumber |
| subsequent sections: |
| |
| Each vertex attribute possesses a set of parameters that control |
| its behavior. Parameters for a vertex attribute may be set by calling: |
| |
| void VertexAttribParameteriAMD(uint index, |
| enum pname, |
| int param); |
| |
| where <index> identifies the generic vertex attribute array whose parameter |
| to modify. If <pname> is VERTEX_ELEMENT_SWIZZLE_AMD, then <param> |
| specifies the component of the vertex element that is to be used to |
| source the vertex indices for the selected vertex attribute. Its value |
| may be RED, GREEN, BLUE or ALPHA to select the first, second, third or |
| fourth component of the vertex element. |
| |
| In section 10.3.2, "Primitive Restart", modify the language describing |
| how the restart index is compared to the vertex element index, p.302 |
| as follows: |
| |
| When one of the Draw* commands transfers a set of generic attribute |
| array elements to the GL, if all present index channels in the passed |
| element index are equal to the primitive restart index, then the GL |
| does not process those elements as a vertex. Instead ... *include |
| remainder of section verbatim.* |
| |
| In the description of DrawElementsOneInstance (p. 311), replace the |
| sentence beginning "The ith element transferred by..." with: |
| |
| For each enabled vertex attribute, the ith element transferred by |
| DrawElementsOneInstance will be taken from that attribute's selected |
| channel of the element whose values are stored currently bound element |
| array buffer at offset indices + i. |
| |
| Replace the paragraph explaining the <type> parameter to |
| DrawElementsOneIntance (p. 311): |
| |
| <type> may be UNSIGNED_BYTE, UNSIGNED_SHORT or UNSIGNED_INT, |
| indicating that the index values are of GL type ubyte, ushort or uint, |
| respectively, RG8UI or RG16UI, indicating that the index values are pairs |
| of GL type ubyte or ushort, respectively, or RGBA8UI, indicating that |
| index values are quadruplets of GL type ubyte. ... |
| |
| Modify the language describing the DrawElements*BaseVertex* functions |
| on p.314 as follows: |
| |
| ... are equivalent to the commands with the same base name (without |
| the BaseVertex suffix), except that the ith element transferred by |
| the corresponding draw call will be taken from the selected channel |
| of the element vector indices[i] + <basevertex>. That is, the value of |
| <basevertex> is added to the vertex index after channel selection. |
| ... *include remainder of description verbatim.* |
| |
| Add to the list of accepted values for the <pname> parameter to |
| GetVertexAttrib* in Section 10.6, "Vertex Array and Vertex Array Object |
| Queries", p. 317: |
| |
| ... VERTEX_ELEMENT_SWIZZLE_AMD. |
| |
| Additions to Chapter 11 of the OpenGL Core Profile Specification, Version 4.3, |
| "Programmable Vertex Processing" |
| |
| In Subsection 11.1.3.9, "Shader Inputs", p.338, modify the description |
| of gl_VertexID as follows: |
| |
| gl_VertexID holds the integer index i stored in the selected component |
| of the element implicitly passed by DrawArrays or one of the other drawing |
| commands defined in section 10.5. The component of the element data |
| stored in gl_VertexID may be specified by calling ProgramParameteri with |
| <pname> set to VERTEX_ID_SWIZZLE_AMD as specified in section 7.3. |
| |
| New State |
| |
| Append to Table 23.4, "Vertex Array Object State (cont.)": |
| |
| +------------------------------+----------+---------------------+----------------+---------------------------------------------+----------+ |
| | Get Value | Type | Get Command | Initial Value | Description | Sec | |
| +------------------------------+----------+---------------------+----------------+---------------------------------------------+----------+ |
| | VERTEX_ELEMENT_SWIZZLE_AMD | 16 * x E | GetVertexAttribiv | RED | Channel selector for vertex attribute index | 10.3.2 | |
| +------------------------------+----------+---------------------+----------------+---------------------------------------------+----------+ |
| |
| Append to Table 23.39, "Program Object State (cont.)": |
| |
| +------------------------+-------+---------------+----------------+------------------------------------+----------+ |
| | Get Value | Type | Get Command | Initial Value | Description | Sec | |
| +------------------------+-------+---------------+----------------+------------------------------------+----------+ |
| | VERTEX_ID_SWIZZLE_AMD | E | GetProgramiv | RED | Channel selector for gl_VertexID | 11.1.3.9 | |
| +------------------------+-------+---------------+----------------+------------------------------------+----------+ |
| |
| New Implementation Dependent State |
| |
| None. |
| |
| Errors |
| |
| INVALID_ENUM is generated by VertexAttribParameteri if <pname> is not an |
| accepted token. |
| |
| INVALID_VALUE is generated by VertexAttribParameteri if <value> is not an |
| acceptable value for the specified value of <pname>. |
| |
| Examples |
| |
| // Basic per-face normals |
| |
| // Normal data |
| static const float normals[] = |
| { |
| 0.0f, 0.0f, 1.0f, // Positive Z |
| 0.0f, 0.0f, -1.0f, // Negative Z |
| 0.0f, 1.0f, 0.0f, // Positive Y |
| 0.0f, -1.0f, 0.0f, // Negative Y |
| 1.0f, 0.0f, 0.0f, // Positive X |
| -1.0f, 0.0f, 0.0f, // Negative X |
| }; |
| |
| // Position data |
| static const float positions[] = |
| { |
| -1.0f, -1.0f, -1.0f, |
| // <More data here> |
| 1.0f, 1.0f, 1.0f |
| }; |
| |
| // Put the above data into a buffer and bind them as separate vertex |
| // attributes. |
| GLuint vertex_buffer; |
| glGenBuffers(1, &vertex_buffer); |
| glBindBuffer(GL_ARRAY_BUFFER, sizeof(positions) + sizeof(normals), |
| NULL, GL_STATIC_DRAW); |
| glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(positions), positions); |
| glBufferSubData(GL_ARRAY_BUFFER, sizeof(positions), |
| sizeof(normals), normals); |
| // ... etc. Set up vertex attributes. |
| |
| // Index data |
| static const unsigned short indices[] = |
| { |
| 0, 0, // vertex 0: position index, normal index |
| 1, 0, // vertex 1: position index, normal index |
| 2, 0, // vertex 2: position index, normal index |
| 1, 0, // vertex 3: position index, normal index |
| 2, 0, // ... six vertices, forming |
| 3, 0, // ... two complete triangles, all using normals[0] |
| 0, 1, |
| 2, 1, |
| 3, 1, |
| 3, 1, |
| 4, 1, // ... six more vertices, forming |
| 2, 1, // ... two more triangles, all using normals[1] |
| // etc... |
| }; |
| |
| GLuint index_buffer; |
| glGenBuffers(1, &index_buffer); |
| glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer); |
| glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), |
| indices, GL_STATIC_DRAW); |
| |
| // Okay... here's the new code. Set up vertex attribute 0 (position) to |
| // consume the RED channel of the vertex index and attribute 1 (normal) |
| // to consume the GREEN (second) channel of the vertex index. Then |
| // draw with GL_RG16UI (two channel, 16-bit unsigned int) as the index |
| // type. |
| glVertexAttribParameteriAMD(0, GL_VERTEX_ELEMENT_SWIZZLE_AMD, GL_RED); |
| glVertexAttribParameteriAMD(1, GL_VERTEX_ELEMENT_SWIZZLE_AMD, GL_GREEN); |
| |
| glDrawElements(GL_TRIANGLES, |
| sizeof(indices) / (2 * sizeof(unsigned short)), |
| GL_RG16UI, |
| NULL); |
| |
| Issues |
| |
| 1) What is the effect of multi-channel vertex indices on gl_VertexID? |
| |
| RESOLVED: The VERTEX_ID_SWIZZLE_AMD program parameter selects the |
| channel of vector element types to be passed to gl_VertexID. By |
| default, this is RED, which is backwards compatible with single-channel |
| types. |
| |
| 2) How does this interact with primitive-restart indices? |
| |
| RESOLVED: If all present channels of the vertex index vector match the |
| restart index, then the element index is considered to match. |
| |
| 3) How does baseVertex affect this? |
| |
| RESOLVED: The same base vertex value is added to each each vertex |
| element component after channel selection for each of the enabled |
| vertex attributes. This choice is primarily motivated by the behavior |
| of base vertex elements encoded in indirect draw commands. |
| |
| 4) Does this feature disable potential optimizations such as vertex |
| reuse? |
| |
| RESOVLED: No, vertex reuse should continue to function correctly. |
| Each unique vector of indices should produce a unique set of vertex |
| shader outputs (modulo side effects) and will hit a naive vertex |
| reuse cache. Nothing precludes more advanced optimization strategies |
| from being implemented, however. |
| |
| 5) Is it possible to get at all two or four channels of the vertex index |
| using a built-in input to the vertex shader? |
| |
| RESOLVED: No. A single channel selection is provided. Providing more |
| data could be implemented by introducing a new built-in integer vector |
| input to the shader, but we have chosen not to do at this time. |
| |
| 6) What is the value of missing channels? For example, if we render with |
| GL_RG16UI indices but set certain attributes to GL_BLUE or GL_ALPHA |
| swizzle, what index value is used for those channels? |
| |
| RESOLVED: Zero. |
| |
| 7) Are the traditional GL_RED, GL_GREEN, GL_BLUE, and GL_ALPHA terms |
| appropriate for this use? |
| |
| RESOLVED: Not really, but are they appropriate for normals? g-buffers? |
| Any other arbitrary data that might be in a buffer or texture? |
| It's not worth introducing new enumerants just for this - we'll use |
| R, G, B, A. |
| |
| Revision History |
| |
| Rev. Date Author Changes |
| ---- -------- -------- ----------------------------------------- |
| |
| 3 05/02/2013 gsellers Shipping. Finalize spec ready for posting. |
| 2 01/25/2013 gsellers Resolve issues 1, 2, 3. Polish spec. |
| 1 01/17/2013 gsellers Initial draft |
| |