Name ARB_vertex_type_2_10_10_10_rev Name Strings GL_ARB_vertex_type_2_10_10_10_rev Contact Graham Sellers (graham.sellers 'at' amd.com) Contributors Daniel Koch, TransGaming Graham Sellers, AMD Jeff Bolz, NVIDIA Jon Leech Contributors to the OES_vertex_type_10_10_10_2 extension Notice Copyright (c) 2010-2013 The Khronos Group Inc. Copyright terms at http://www.khronos.org/registry/speccopyright.html Specification Update Policy Khronos-approved extension specifications are updated in response to issues and bugs prioritized by the Khronos OpenGL Working Group. For extensions which have been promoted to a core Specification, fixes will first appear in the latest version of that core Specification, and will eventually be backported to the extension document. This policy is described in more detail at https://www.khronos.org/registry/OpenGL/docs/update_policy.php Status Complete. Approved by the ARB at the 2010/01/22 F2F meeting. Approved by the Khronos Board of Promoters on March 10, 2010. Version Last Modified Date: March 8, 2010 Author Revision: 14 Number ARB Extension #86 Dependencies This extension is written against the OpenGL 3.2 specification, compatibility profile. OpenGL 1.1 is required. The OpenGL 3.2, core profile specification affects the definition of this extension. This extension trivially interacts with the OES_vertex_type_10_10_10_2 extension. This extension interacts with the EXT_vertex_array_bgra extension. Overview This extension adds the following data formats: Two new vertex attribute data formats: a signed 2.10.10.10 and an unsigned 2.10.10.10 vertex data format. These vertex data formats describe a 4 component stream which can be used to store normals or other attributes in a quantized form. Normals, tangents, binormals and other vertex attributes can often be specified at reduced precision without introducing noticeable artifacts, reducing the amount of memory and memory bandwidth they consume. IP Status No known IP claims. New Procedures and Functions void VertexP2ui(enum type, uint value); void VertexP3ui(enum type, uint value); void VertexP4ui(enum type, uint value); void VertexP2uiv(enum type, const uint *value); void VertexP3uiv(enum type, const uint *value); void VertexP4uiv(enum type, const uint *value); void TexCoordP1ui(enum type, uint coords); void TexCoordP2ui(enum type, uint coords); void TexCoordP3ui(enum type, uint coords); void TexCoordP4ui(enum type, uint coords); void TexCoordP1uiv(enum type, const uint *coords); void TexCoordP2uiv(enum type, const uint *coords); void TexCoordP3uiv(enum type, const uint *coords); void TexCoordP4uiv(enum type, const uint *coords); void MultiTexCoordP1ui(enum texture, enum type, uint coords); void MultiTexCoordP2ui(enum texture, enum type, uint coords); void MultiTexCoordP3ui(enum texture, enum type, uint coords); void MultiTexCoordP4ui(enum texture, enum type, uint coords); void MultiTexCoordP1uiv(enum texture, enum type, const uint *coords); void MultiTexCoordP2uiv(enum texture, enum type, const uint *coords); void MultiTexCoordP3uiv(enum texture, enum type, const uint *coords); void MultiTexCoordP4uiv(enum texture, enum type, const uint *coords); void NormalP3ui(enum type, uint coords); void NormalP3uiv(enum type, const uint *coords); void ColorP3ui(enum type, uint color); void ColorP4ui(enum type, uint color); void ColorP3uiv(enum type, const uint *color); void ColorP4uiv(enum type, const uint *color); void SecondaryColorP3ui(enum type, uint color); void SecondaryColorP3uiv(enum type, const uint *color); void VertexAttribP1ui(uint index, enum type, boolean normalized, uint value); void VertexAttribP2ui(uint index, enum type, boolean normalized, uint value); void VertexAttribP3ui(uint index, enum type, boolean normalized, uint value); void VertexAttribP4ui(uint index, enum type, boolean normalized, uint value); void VertexAttribP1uiv(uint index, enum type, boolean normalized, const uint *value); void VertexAttribP2uiv(uint index, enum type, boolean normalized, const uint *value); void VertexAttribP3uiv(uint index, enum type, boolean normalized, const uint *value); void VertexAttribP4uiv(uint index, enum type, boolean normalized, const uint *value); New Tokens Accepted by the parameter of VertexAttribPointer, VertexPointer, NormalPointer, ColorPointer, SecondaryColorPointer, TexCoordPointer, VertexAttribP{1234}ui, VertexP*, TexCoordP*, MultiTexCoordP*, NormalP3ui, ColorP*, SecondaryColorP* and VertexAttribP* UNSIGNED_INT_2_10_10_10_REV 0x8368 (existing core enum) INT_2_10_10_10_REV 0x8D9F Additions to Chapter 2 of the OpenGL 3.2 Specification (Compatibility Profile) (OpenGL Operation) Modifications to Section 2.7 (Vertex Specification) Add the following after the discussion of Vertex* on p.30 Vertex coordinates may be stored as packed components within a larger natural type. Such data may be specified using void VertexP{234}ui(enum type, uint coords); void VertexP{234}uiv(enum type, uint *coords); These commands specify up to four coordinates as described above, packed into a single natural type as described in Section 2.8.1. The parameter must be INT_2_10_10_10_REV or UNSIGNED_INT_2_10_10_10_REV, specifying signed or unsigned data respectively. The first two (x,y), three (x,y,z) or four (x,y,z,w) components of the packed data are consumed by VertexP2ui, VertexP3ui, and VertexP4ui, respectively. Note that in the case of VertexP{234}uiv, contains the address of a single uint containing the packed coordinate components. Add the following after the discussion of TexCoord* on p.30 Texture coordinates may be stored as packed components within a larger natural type. Such data may be specified using void TexCoordP{1234}ui(enum type, uint coords); void TexCoordP{1234}uiv(enum type, uint *coords); This command specifies up to four components as described above, packed into a single natural type as described in Section 2.8.1. The parameter must be INT_2_10_10_10_REV or UNSIGNED_INT_2_10_10_10_REV, specifying signed or unsigned data, respectively. The first one (x), two (x,y), three (x,y,z) or four (x,y,z,w) components of the packed data are consumed by TexCoordP1ui{v}, TexCoordP2ui{v}, TexCoordP3ui{v}, and TexCoordP4ui{v}, respectively. Note that in the case TexCoordP{1234}uiv, contains the address of a single uint containing the packed texture coordinate components. Add the following function to the list of prototypes defining MultiTexCoord* void MultiTexCoordP{1234}ui(enum texture, enum type, uint coords); void MultiTexCoordP{1234}uiv(enum texture, enum type, uint *coords); Add the following after the discussion of Normal3* on p.31 Normals may be stored as packed components within a larger natural type. Such data may be specified using void NormalP3ui(enum type, uint normal); void NormalP3uiv(enum type, uint *normal); This specifies a three component normal, packed into the first three (x,y,z) components of the natural type as described in Section 2.8.1. must be INT_2_10_10_10_REV or UNSIGNED_INT_2_10_10_10_REV, specifying signed or unsigned data, respectively. Individual components are converted to floating-point values according to equations 2.1 and 2.2. Note that in the case of NormalP3uiv, contains the address of a single uint containing the packed normal components. Add the following after the discussion of Color* and SecondaryColor* on p.32 RGBA colors may be stored as packed components within a larger natural type. Such data may be specified using void ColorP{34}ui(enum type, uint coords); void ColorP{34}uiv(enum type, uint *coords); void SecondaryColorP3ui(enum type, uint coords); void SecondaryColorP3uiv(enum type, uint *coords); The ColorP* command sets the primary color similarly to Color*, above. The SecondaryColorP* command sets the secondary color similarly to SecondaryColor*. must be INT_2_10_10_10_REV or UNSIGNED_INT_2_10_10_10_REV, specifying signed or unsigned data, respectively. Colors are packed into a single natural type as described in Section 2.8.1. The first three (x,y,z) or four (x,y,z,w) components of the packed data are consumed by *ColorP3ui* and *ColorP4ui*, respectively. Individual components are converted to floating-point values according to equations 2.1 and 2.2. Note that in the case of ColorP{34}uiv and SecondaryColorP3uiv, contains the address of a single uint containing the packed color components. Add the following after the discussion of VertexAttribI* on p.33 Vertex data may be stored as packed components within a larger natural type. Such data may be specified using void VertexAttribP{1234}ui(uint index, enum type, boolean normalized, uint value); void VertexAttribP{1234}uiv(uint index, enum type, boolean normalized, uint *value); This command accepts packed data in a single natural type and places it in the generic attribute at slot . The parameter must be INT_2_10_10_10_REV or UNSIGNED_INT_2_10_10_10_REV, specifying signed or unsigned data respectively. The first one (x), two (x,y), three (x,y,z), or four (x,y,z,w) components of the packed data are consumed by VertexAttribP1ui, VertexAttribP2ui, VertexAttribP3ui, and VertexAttribP4ui, respectively. Data specified by VertexAttribP* will be converted to floating point by normalizing if is TRUE, and converted directly to floating point otherwise. Note that in the case of VertexAttribP{1234}uiv, contains the address of a single uint containing the packed attribute components. The error INVALID_VALUE is generated if is greater or equal to the value of MAX_VERTEX_ATTRIBS. The error INVALID_ENUM is generated if is not INT_2_10_10_10_REV or UNSIGNED_INT_2_10_10_10_REV. Modifications to Section 2.8 (Vertex Arrays) Add INT_2_10_10_10_REV and UNSIGNED_INT_2_10_10_10_REV as a valid value in Table 2.5 on p.36 for VertexPointer, NormalPointer, ColorPointer, SecondaryColorPointer, TexCoordPointer and VertexAttribPointer Modify the pseudo-code explaining ArrayElement as follows (p.38) if (normal array enabled) { if (normal array contains packed data) NormalP3uiv(type of data in normal array, normal array element i); else Normal3[type]v(normal array element i); } if (color array enabled) { if (color array contains packed data) ColorP[size]uiv(type of data in color array, color array element i); else Color[size][type]v(color array element i); } if (secondary color array enabled) { if (secondary color array contains packed data) SecondaryColorP3uiv(type of data in secondary color array, secondary color array element i); else SecondaryColor3[type]v(secondary color array element i); } if (fog coordinate array enabled) FogCoord[type]v(fog coordinate array element i); for (j = 0; j < textureUnits; j++) { if (texture coordinate set j array enabled) { if (texture coordinate set j contains packed data) MultiTexCoordP[size]uiv(TEXTURE0 + j, type of data in texture coordinate set j array element i, texture coordinate set j array element i); else MultiTexCoord[size][type]v(TEXTURE0 + j, texture coordinate set j array element i); } } if (color index array enabled) Index[type]v(color index array element i); if (edge flag array enabled) EdgeFlagv(edge flag array element i); for (j = 1; j < genericAttributes; j++) { if (generic vertex attribute j array enabled) { if (generic vertex attribute j array is a pure integer array) VertexAttribI[size][type]v(j, generic vertex attribute j array element i); else if (generic vertex attribute j array normalization flag is set, and type is not FLOAT or DOUBLE) { if (generic vertex attribute j contains packed data) VertexAttribP[size]uiv(j, type of data in generic vertex attribute j, TRUE, generic vertex attribute j array element i); else VertexAttrib[size]N[type]v(j, generic vertex attribute j array element i); } else if (generic vertex attribute j contains packed data) VertexAttribP[size]uiv(j, type of data in generic vertex attribute j, FALSE, generic vertex attribute j array element i); else VertexAttrib[size][type]v(j, generic vertex attribute j array element i); } } if (generic vertex attribute array 0 enabled) { if (generic vertex attribute 0 array is a pure integer array) VertexAttribI[size][type]v(0, generic vertex attribute 0 array element i); else if (generic vertex attribute 0 array normalization flag is set, and type is not FLOAT or DOUBLE) { if (generic vertex attribute 0 contains packed data) VertexAttribP[size]uiv(0, type of data in generic vertex attribute 0, TRUE, generic vertex attribute 0 array element i); else VertexAttrib[size]N[type]v(0, generic vertex attribute 0 array element i); } else VertexAttrib[size][type]v(0, generic vertex attribute 0 array element i); } else if (vertex array enabled) { if (generic vertex attribute 0 contains packed data) VertexAttribP[size]uiv(0, type of data in generic vertex attribute 0, FALSE, generic vertex attribute 0 array element i); else VertexAttrib[size]N[type]v(0, generic vertex attribute 0 array element i); } Add a new section 2.8.1 - Packed Vertex Data Formats, renumber subsequent sections UNSIGNED_INT_2_10_10_10_REV and INT_2_10_10_10_REV vertex data formats describe packed, 4 component formats stored in a single 32-bit word. For the UNSIGNED_INT_2_10_10_10_REV vertex data format, the first (x), second (y), and third (z) components are represented as a 10-bit unsigned integer value, and the fourth (w) component is represented as a 2-bit unsigned integer value. For the INT_2_10_10_10_REV vertex data format, the x, y and z components are represented as a 10-bit signed two's complement integer value and the w component is represented as a 2-bit signed two's complement integer value. The value is used to indicate whether to normalize the data to [0,1] (for unsigned type) or [-1,1] (for signed type). During normalization, the conversion rules specified in equations 2.1 and 2.2 are followed. The following figure describes how these components are laid out in a 32-bit word. 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 ----------------------------------------------------------------------------------------------- | w | z | y | x | ----------------------------------------------------------------------------------------------- If is BGRA, the components are instead laid out as in the following figure 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 ----------------------------------------------------------------------------------------------- | w | x | y | z | ----------------------------------------------------------------------------------------------- Calls to VertexAttribPointer, VertexPointer, ColorPointer, SecondaryColorPointer or TexCoordPointer with of INT_2_10_10_10_REV and UNSIGNED_INT_2_10_10_10_REV can only be made with = 4 or BGRA. values other than 4 or BGRA will generate an INVALID_OPERATION error. Additions to Appendix A of the OpenGL 3.2 (Compatibility Profile) Specification (Invariance) None. Additions to the AGL/GLX/WGL Specifications None. Dependencies on OES_vertex_type_10_10_10_2 The OpenGL ES extension OES_vertex_type_10_10_10_2 defines the UNSIGNED_INT_10_10_10_2_OES and INT_10_10_10_2_OES types for vertices (although it uses different values for the former than the core GL equivalent token). However, the OES extension did not define a method for specifying individual attributes, which this extension attempts to address through the addition of the VertexAttribP* procedure; the OES extension allows to be 3 in many of the functions where must be either four or BGRA in this extension; and most importantly, uses a different component packing (1010102 vs. 2101010REV) than this extension, reflecting different underlying hardware capabilities. Therefore while the purpose of the two extensions is similar, they are not functionally, source-level, or data-level compatible. Dependencies with EXT_vertex_array_bgra If EXT_vertex_array_bgra is not supported, remove references to BGRA as an allowed parameter for in VertexAttrib. Interaction with OpenGL 3.2, Core Profile When using a core profile of OpenGL 3.2, remove references to VertexPointer, NormalPointer, ColorPointer, SecondaryColorPointer, and TexCoordPointer. Also, remove references to VertexP*, NormalP3ui, TexCoordP*, ColorP*, and SecondaryColorP*. Errors The error INVALID_ENUM is generated by VertexP*, NormalP*, TexCoordP*, MultiTexCoordP*, ColorP*, or SecondaryColorP if is not UNSIGNED_INT_2_10_10_10_REV or INT_2_10_10_10_REV. The error INVALID_OPERATION is generated if VertexAttribPointer is called with = UNSIGNED_INT_2_10_10_10_REV or INT_2_10_10_10_REV, and the parameter is not 4 or BGRA. The error INVALID_OPERATION is generated if VertexPointer, ColorPointer, SecondaryColorPointer or TexCoordPointer is called with = UNSIGNED_INT_2_10_10_10_REV or INT_2_10_10_10_REV, and the parameter is not 4 or BGRA. New State None. New Implementation Dependent State None. Issues 1. Is it possible to pass unnormalized packed integer data into a shader, for example through an ivec4 input attribute? RESOLVED: No, not directly. One solution is to pass a uint input attribute and use shifting and masking in the shader to access the individual components. 2. What is the value in allowing 1 and 2 component parameters? DISCUSSION: While it's unlikely to find much use, it doesn't produce an ambiguous condition. However, only a four component type is defined here, and the additional data may be thrown out by a shader. Further extensions could add support for types that contain only two or three components packed into 32-bit words, such as UNSIGNED_SHORT_5_6_5 or UNSIGNED_INT_24_8. Such an extension could allow the use of 2 or 3 as a parameter. 3. What about packed 16-bit formats such as UNSIGNED_SHORT_5_6_6? How do those get passed to the GL? RESOLVED: This extension does not add support for any 16-bit types. As a future extension would be required to add such support, that extension could also define the new procedure. 4. Do we need 'v' versions of the immediate entry-points (i.e. those that take a pointer, such as VertexAttribP4uiv)? RESOLVED: They are included for consistency. 5. What component packing should be used? Desktop hardware conventions use 2_10_10_10_REV packing (e.g. xyzw / zyxw packed in reverse order with w occupying the high two bits of a uint) in opposition to OpenGL ES hardware which uses 10_10_10_2 packing (with w occupying the low two bits of a uint). Since the intent of this extension is compatibility with existing hardware and performance, we follow the desktop convention despite the incompatibility with the OES extension that results. 6. SecondaryColorPointer accepts 3 and 4 as parameters with non packed types. Should this extension accept 3 as a size parameter to SecondaryColorPointer for packed types? UNRESOLVED: Maybe. It doesn't, though. 7. This extension provides immediate mode and vertex array APIs to specify fixed-function vertex attributes using packed components. How are the components interpreted? RESOLVED: For VertexP*, TexCoordP*, and MultiTexCoordP*, components should be converted directly to floating-point values. For NormalP*, ColorP*, and SecondaryColorP*, they should produce normalized [0,1] or [-1,1] values, as appropriate. For VertexAttribP*, conversion or normalization is controlled by the argument. Note that this extension does not provide any mechanisms to specify vertex attributes that remain as integers, as can be done using the VertexAttribI* APIs. Revision History Rev. Date Author Changes ---- ------------ -------- ------------------------------------------------------ 14 Mar 8, 2010 pbrown Added language clarifying that NormalP*, ColorP*, and SecondaryColorP* are always normalized. Also added issue 7. 13 Mar 5, 2010 pbrown Expand the list of new functions to enumerate each function individually. 12 Feb 12, 2010 Jon Leech Change errors for invalid combinations of otherwise legal parameters to INVALID_OPERATION (bug 6014). Correct 'VertexPointerP*' to 'VertexP*' in Errors section. 11 Feb 11, 2010 gsellers Remove SecondaryColorP4*. Add error for non (4 or BGRA) size parameters to VertexPointer etc. Add issue 6. 10 Feb 10, 2010 Jon Leech Add const attribute to commands taking arrays. 9 Jan 26, 2010 pbrown Assign enum for INT_2_10_10_10_REV. 8 Jan 20, 2010 Jon Leech Update spec to make component ordering match desktop hardware. Justify paragraphs. 7 Dec 10, 2009 dgkoch de-ARBed new tokens 6 Nov 12, 2009 gsellers Rename to ARB 5 Oct 22, 2009 gsellers Add 'v' versions of new entry points. Resolve issue 4. Update pseudo-code on p.38. 4 Oct 9, 2009 gsellers Add issue 4. Upate dependency on OES_vertex_type_10_10_10_2. 3 Oct 6, 2009 gsellers Add ColorP, SecondaryColorP, NormalP. Disallow sizes other than 4 or BGRA. Remove duplicate dependency on EXT_vertex_array_bgra. 2 Oct 5, 2009 gsellers Minor cleanup. Add support for VertexPointer, NormalPointer, ColorPointer, SecondaryColorPointer, and TexCoordPointer. Specify interaction with BGRA vertex formats. 1 Sep 28, 2009 gsellers Initial version based on GL_OES_vertex_type_10_10_10_2