| Name | 
 |      | 
 |     ARB_uniform_buffer_object | 
 |  | 
 | Name Strings | 
 |  | 
 |     GL_ARB_uniform_buffer_object | 
 |  | 
 | Contact | 
 |  | 
 |     Benj Lipchak, APPLE (lipchak 'at' apple.com) | 
 |     John Rosasco, APPLE (jdr 'at' apple.com) | 
 |     Jeremy Sandmel, APPLE (jsandmel 'at' apple.com) | 
 |     Pat Brown, NVIDIA (pbrown 'at' nvidia.com) | 
 |  | 
 | Contributors | 
 |  | 
 |     Rob Barris | 
 |     Keith Bauer | 
 |     Bob Beretta | 
 |     Pat Brown | 
 |     Nick Burns | 
 |     Matt Collins | 
 |     Michael Gold | 
 |     John Kessenich | 
 |     Jon Leech | 
 |     Barthold Lichtenbelt | 
 |     Benj Lipchak | 
 |     Bruce Merry | 
 |     John Rosasco | 
 |     Jeremy Sandmel | 
 |     Geoff Stahl | 
 |  | 
 | Notice | 
 |  | 
 |     Copyright (c) 2009-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 on February 17, 2009. | 
 |  | 
 | Version | 
 |  | 
 |     Last Modified Date:     2015/06/23 | 
 |     Author revision:        68 | 
 |  | 
 | Number | 
 |  | 
 |     ARB Extension #57 | 
 |  | 
 | Dependencies | 
 |  | 
 |     The OpenGL Shading Language (GLSL) is required. OpenGL 2.0 or the | 
 |     ARB_shader_objects extension is required. | 
 |  | 
 |     OpenGL 1.5 or ARB_vertex_buffer_object is required. | 
 |  | 
 |     This extension is written against the OpenGL 2.1 specification and | 
 |     version 1.20-8 of the OpenGL Shading Language specification. | 
 |  | 
 |     This extension interacts with OpenGL 3.0, ARB_geometry_shader4, | 
 |     ARB_texture_rectangle, EXT_gpu_shader4, EXT_texture_array, | 
 |     EXT_texture_integer, and EXT_texture_buffer_object. | 
 |      | 
 | Overview | 
 |  | 
 |     This extension introduces the concept of a group of GLSL uniforms | 
 |     known as a "uniform block", and the API mechanisms to store "uniform | 
 |     blocks" in GL buffer objects. | 
 |      | 
 |     The extension also defines both a standard cross-platform layout in | 
 |     memory for uniform block data, as well as mechanisms to allow the GL | 
 |     to optimize the data layout in an implementation-defined manner. | 
 |  | 
 |     Prior to this extension, the existing interface for modification of | 
 |     uniform values allowed modification of large numbers of values using | 
 |     glUniform* calls, but only for a single uniform name (or a uniform | 
 |     array) at a time. However, updating uniforms in this manner may not | 
 |     map well to heterogenous uniform data structures defined for a GL | 
 |     application and in these cases, the application is forced to either: | 
 |  | 
 |         A) restructure their uniform data definitions into arrays | 
 |         or | 
 |         B) make an excessive number of calls through the GL interface | 
 |            to one of the Uniform* variants. | 
 |  | 
 |     These solutions have their disadvantages. Solution A imposes | 
 |     considerable development overhead on the application developer.  | 
 |     Solution B may impose considerable run-time overhead on the | 
 |     application if the number of uniforms modified in a given frame of | 
 |     rendering is sufficiently large. | 
 |  | 
 |     This extension provides a better alternative to either (A) or (B) by | 
 |     allowing buffer object backing for the storage associated with all | 
 |     uniforms of a given GLSL program. | 
 |  | 
 |     Storing uniform blocks in buffer objects enables several key use | 
 |     cases: | 
 |  | 
 |      - sharing of uniform data storage between program objects and | 
 |        between program stages | 
 |  | 
 |      - rapid swapping of sets of previously defined uniforms by storing | 
 |        sets of uniform data on the GL server | 
 |  | 
 |      - rapid updates of uniform data from both the client and the server | 
 |  | 
 |     The data storage for a uniform block can be declared to use one of | 
 |     three layouts in memory: packed, shared, or std140. | 
 |      | 
 |       - "packed" uniform blocks have an implementation-dependent data | 
 |         layout for efficiency, and unused uniforms may be eliminated by | 
 |         the compiler to save space. | 
 |      | 
 |       - "shared" uniform blocks, the default layout, have an implementation-  | 
 |         dependent data layout for efficiency, but the layout will be uniquely | 
 |         determined by the structure of the block, allowing data storage to be | 
 |         shared across programs. | 
 |      | 
 |       - "std140" uniform blocks have a standard cross-platform cross-vendor | 
 |         layout (see below). Unused uniforms will not be eliminated. | 
 |  | 
 |     Any uniforms not declared in a named uniform block are said to  | 
 |     be part of the "default uniform block". | 
 |  | 
 |     While uniforms in the default uniform block are updated with | 
 |     glUniform* entry points and can have static initializers, uniforms | 
 |     in named uniform blocks are not. Instead, uniform block data is updated | 
 |     using the routines that update buffer objects and can not use static | 
 |     initializers. | 
 |  | 
 |     Rules and Concepts Guiding this Specification: | 
 |  | 
 |     For reference, a uniform has a "uniform index" (subsequently | 
 |     referred to as "u_index) and also a "uniform location" to | 
 |     efficiently identify it in the uniform data store of the | 
 |     implementation. We subsequently refer to this uniform data store of | 
 |     the implementation as the "uniform database". | 
 |  | 
 |     A "uniform block" only has a "uniform block index" used for queries | 
 |     and connecting the "uniform block" to a buffer object. A "uniform | 
 |     block" has no "location" because "uniform blocks" are not updated | 
 |     directly. The buffer object APIs are used instead. | 
 |      | 
 |     Properties of Uniforms and uniform blocks: | 
 |      | 
 |     a) A uniform is "active" if it exists in the database and has a valid | 
 |        u_index. | 
 |     b) A "uniform block" is "active" if it exists in the database and | 
 |        has a valid ub_index. | 
 |     c) Uniforms and "uniform blocks" can be inactive because they don't | 
 |        exist in the source, or because they have been removed by dead | 
 |        code elimination. | 
 |     d) An inactive uniform has u_index == INVALID_INDEX. | 
 |     e) An inactive uniform block has ub_index == INVALID_INDEX. | 
 |     f) A u_index or ub_index of INVALID_INDEX generates the | 
 |        INVALID_VALUE error if given as a function argument. | 
 |     g) The default uniform block, which is not assigned any ub_index, uses a | 
 |        private, internal data storage, and does not have any buffer object | 
 |        associated with it. | 
 |     h) An active uniform that is a member of the default uniform block has | 
 |        location >= 0 and it has offset == stride == -1. | 
 |     i) An active uniform that is a member of a named uniform block has | 
 |        location == -1. | 
 |     j) A uniform location of -1 is silently ignored if given as a function | 
 |        argument. | 
 |     k) Uniform block declarations may not be nested | 
 |  | 
 | IP Status | 
 |  | 
 |     No known IP claims. | 
 |  | 
 | New Procedures and Functions | 
 |  | 
 |    void    GetUniformIndices(uint program, | 
 |                                 sizei uniformCount,  | 
 |                                 const char* const * uniformNames,  | 
 |                                 uint* uniformIndices); | 
 |  | 
 |    void    GetActiveUniformsiv(uint program, | 
 |                                   sizei uniformCount,  | 
 |                                   const uint* uniformIndices,  | 
 |                                   enum pname,  | 
 |                                   int* params); | 
 |  | 
 |    void    GetActiveUniformName(uint program, | 
 |                                    uint uniformIndex,  | 
 |                                    sizei bufSize,  | 
 |                                    sizei* length,  | 
 |                                    char* uniformName); | 
 |  | 
 |    uint    GetUniformBlockIndex(uint program, | 
 |                                    const char* uniformBlockName); | 
 |  | 
 |    void    GetActiveUniformBlockiv(uint program, | 
 |                                       uint uniformBlockIndex,  | 
 |                                       enum pname,  | 
 |                                       int* params); | 
 |  | 
 |    void    GetActiveUniformBlockName(uint program, | 
 |                                         uint uniformBlockIndex,  | 
 |                                         sizei bufSize,  | 
 |                                         sizei* length,  | 
 |                                         char* uniformBlockName); | 
 |  | 
 |    void    BindBufferRange(enum target,  | 
 |                            uint index,  | 
 |                            uint buffer,  | 
 |                            intptr offset, | 
 |                            sizeiptr size); | 
 |  | 
 |    void    BindBufferBase(enum target,  | 
 |                           uint index,  | 
 |                           uint buffer); | 
 |  | 
 |    void    GetIntegeri_v(enum target, uint index, int* data); | 
 |  | 
 |    void    UniformBlockBinding(uint program, | 
 |                                   uint uniformBlockIndex,  | 
 |                                   uint uniformBlockBinding); | 
 |  | 
 | New Types | 
 |  | 
 |     None. | 
 |  | 
 | New Tokens | 
 |  | 
 |     Accepted by the <target> parameters of BindBuffer, BufferData, | 
 |     BufferSubData, MapBuffer, UnmapBuffer, GetBufferSubData, and | 
 |     GetBufferPointerv: | 
 |  | 
 |         UNIFORM_BUFFER                                  0x8A11 | 
 |  | 
 |     Accepted by the <pname> parameter of GetIntegeri_v, GetBooleanv, | 
 |     GetIntegerv, GetFloatv, and GetDoublev: | 
 |  | 
 |         UNIFORM_BUFFER_BINDING                          0x8A28 | 
 |  | 
 |     Accepted by the <pname> parameter of GetIntegeri_v: | 
 |  | 
 |         UNIFORM_BUFFER_START                            0x8A29 | 
 |         UNIFORM_BUFFER_SIZE                             0x8A2A | 
 |  | 
 |     Accepted by the <pname> parameter of GetBooleanv, GetIntegerv, | 
 |     GetFloatv, and GetDoublev: | 
 |  | 
 |         MAX_VERTEX_UNIFORM_BLOCKS                       0x8A2B | 
 |         MAX_GEOMETRY_UNIFORM_BLOCKS                     0x8A2C | 
 |         MAX_FRAGMENT_UNIFORM_BLOCKS                     0x8A2D | 
 |         MAX_COMBINED_UNIFORM_BLOCKS                     0x8A2E | 
 |         MAX_UNIFORM_BUFFER_BINDINGS                     0x8A2F | 
 |         MAX_UNIFORM_BLOCK_SIZE                          0x8A30 | 
 |         MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS          0x8A31 | 
 |         MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS        0x8A32 | 
 |         MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS        0x8A33 | 
 |         UNIFORM_BUFFER_OFFSET_ALIGNMENT                 0x8A34 | 
 |  | 
 |     Accepted by the <pname> parameter of GetProgramiv: | 
 |  | 
 |         ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH            0x8A35 | 
 |         ACTIVE_UNIFORM_BLOCKS                           0x8A36 | 
 |  | 
 |     Accepted by the <pname> parameter of GetActiveUniformsiv: | 
 |  | 
 |         UNIFORM_TYPE                                    0x8A37 | 
 |         UNIFORM_SIZE                                    0x8A38 | 
 |         UNIFORM_NAME_LENGTH                             0x8A39 | 
 |         UNIFORM_BLOCK_INDEX                             0x8A3A | 
 |         UNIFORM_OFFSET                                  0x8A3B | 
 |         UNIFORM_ARRAY_STRIDE                            0x8A3C | 
 |         UNIFORM_MATRIX_STRIDE                           0x8A3D | 
 |         UNIFORM_IS_ROW_MAJOR                            0x8A3E | 
 |  | 
 |     Accepted by the <pname> parameter of GetActiveUniformBlockiv: | 
 |  | 
 |         UNIFORM_BLOCK_BINDING                           0x8A3F | 
 |         UNIFORM_BLOCK_DATA_SIZE                         0x8A40 | 
 |         UNIFORM_BLOCK_NAME_LENGTH                       0x8A41 | 
 |         UNIFORM_BLOCK_ACTIVE_UNIFORMS                   0x8A42 | 
 |         UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES            0x8A43 | 
 |         UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER       0x8A44 | 
 |         UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER     0x8A45 | 
 |         UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER     0x8A46 | 
 |          | 
 |     Returned by GetActiveUniformsiv and GetUniformBlockIndex | 
 |      | 
 |         INVALID_INDEX                                   0xFFFFFFFFu | 
 |  | 
 | 2.1 Specification Updates | 
 |  | 
 | Additions to Chapter 2 - OpenGL Operation | 
 |  | 
 |     Section 2.9 - Buffer Objects | 
 |     Add UNIFORM_BUFFER to list of buffer object targets on: | 
 |     Pg 35, 2nd pgph | 
 |     Pg 37, top of page | 
 |     Pg 38, top of page | 
 |  | 
 |     Section 2.15 - Vertex Shaders | 
 |     Pg 79, bump Uniform Variables up to a numbered section since there | 
 |     will now be hierarchy under it; replace all but first paragraph of | 
 |     Uniform Variables section on this page, through to the start of the | 
 |     first full paragraph on p. 80 (beginning "A valid <name>...") under | 
 |     the description of GetUniformLocation: | 
 |  | 
 |     Sets of uniforms can be grouped into "uniform blocks".  The values of each | 
 |     uniform in such a set are extracted from the data store of a buffer object | 
 |     corresponding to the uniform block. | 
 |     OpenGL Shading Language syntax serves to delimit named blocks of | 
 |     uniforms that can be backed by a buffer object. These are referred to as | 
 |     "named uniform blocks," and are assigned a uniform block index. Uniforms | 
 |     that are declared outside of a named uniform block are said to be part of | 
 |     the "default uniform block." Default uniform blocks have no name or uniform | 
 |     block index. Like uniforms, uniform blocks can be active or inactive. Active  | 
 |     uniform blocks are those that contain active uniforms after a program has | 
 |     been compiled and linked. | 
 |  | 
 |     The amount of storage available for uniform variables in the default uniform | 
 |     block accessed by a vertex shader is specified by the value of the | 
 |     implementation-dependent constant MAX_VERTEX_UNIFORM_COMPONENTS. The total | 
 |     amount of combined storage available for uniform variables in all uniform | 
 |     blocks accessed by a vertex shader (including the default uniform block) | 
 |     is specified by the value of the implementation-dependent | 
 |     constant MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS. These values | 
 |     represent the numbers of individual floating-point, integer, or boolean | 
 |     values that can be held in uniform variable storage for a vertex shader. | 
 |     A link error is generated if an attempt is made to utilize more than | 
 |     the space available for vertex shader uniform variables.  | 
 |  | 
 |     When a program is successfully linked, all active uniforms belonging to | 
 |     the program object's default uniform block are initialized to zero (FALSE | 
 |     for booleans). A successful link will also generate a location for each | 
 |     active uniform in the default uniform block. The values of active uniforms | 
 |     in the default uniform block can be changed using this location and the | 
 |     appropriate Uniform* command (see below). These locations are invalidated | 
 |     and new ones assigned after each successful re-link. | 
 |  | 
 |     Similarly, when a program is successfully linked, all active uniforms | 
 |     belonging to the program's named uniform blocks are assigned offsets | 
 |     (and strides for array and matrix type uniforms) within the uniform block | 
 |     according to layout rules described below. Uniform buffer objects provide | 
 |     the storage for named uniform blocks, so the values of active uniforms in | 
 |     named uniform blocks may be changed by modifying the contents of the buffer | 
 |     object using commands such as BufferData, BufferSubData, MapBuffer, and | 
 |     UnmapBuffer. Uniforms in a named uniform block are not assigned a location | 
 |     and may not be modified using the Uniform* commands. The offsets and strides  | 
 |     of all active uniforms belonging to named uniform blocks of a program object | 
 |     are invalidated and new ones assigned after each successful re-link. | 
 |  | 
 |     To find the location within a program object of an active uniform | 
 |     variable associated with the default uniform block, use the command | 
 |  | 
 |         int GetUniformLocation(uint program, const char *name); | 
 |  | 
 |     This command will return the location of uniform variable <name> if it | 
 |     is associated with the default uniform block. <name> must be a | 
 |     null-terminated string, without white space. The value -1 will be returned | 
 |     if <name> does not correspond to an active uniform variable name in | 
 |     <program>, if <name> is associated with a named uniform block, or if | 
 |     <name> starts with the reserved prefix "gl_". | 
 |  | 
 |     If <program> has not been successfully linked, the error INVALID_OPERATION | 
 |     is generated. After a program is linked, the location of a uniform | 
 |     variable will not change, unless the program is re-linked. | 
 |  | 
 |     A valid <name>... | 
 |  | 
 |     Pg 80, insert before the description of GetActiveUniform: | 
 |  | 
 |     Named uniform blocks, like uniforms, are identified by name strings.  | 
 |     Uniform block indices corresponding to uniform block names can be queried | 
 |     by calling | 
 |  | 
 |         uint GetUniformBlockIndex(uint program, | 
 |                                      const char* uniformBlockName); | 
 |  | 
 |     <program> is the name of a program object for which the command | 
 |     LinkProgram has been issued in the past. It is not | 
 |     necessary for <program> to have been linked successfully. The link | 
 |     could have failed because the number of active uniforms exceeded the | 
 |     limit. | 
 |      | 
 |     <uniformBlockName> must contain a null-terminated string specifying | 
 |     the name of a uniform block. | 
 |  | 
 |     GetUniformBlockIndex returns the uniform block index for the | 
 |     uniform block named <uniformBlockName> of <program>. If | 
 |     <uniformBlockName> does not identify an active uniform block of | 
 |     <program>, or an error occurred, then INVALID_INDEX is returned. | 
 |     The indices of the active uniform blocks of a program are assigned in | 
 |     consecutive order, beginning with zero. | 
 |      | 
 |     An active uniform block's name string can be queried from its | 
 |     uniform block index by calling | 
 |      | 
 |         void GetActiveUniformBlockName(uint program, | 
 |                                           uint uniformBlockIndex,  | 
 |                                           sizei bufSize,  | 
 |                                           sizei* length,  | 
 |                                           char* uniformBlockName); | 
 |  | 
 |     <program> is the name of a program object for which the command | 
 |     LinkProgram has been issued in the past. It is not | 
 |     necessary for <program> to have been linked successfully. The link | 
 |     could have failed because the number of active uniforms exceeded the | 
 |     limit. | 
 |  | 
 |     <uniformBlockIndex> must be an active uniform block index of | 
 |     <program>, in the range zero to the value of | 
 |     ACTIVE_UNIFORM_BLOCKS - 1. The value of | 
 |     ACTIVE_UNIFORM_BLOCKS can be queried with GetProgramiv (see | 
 |     section 6.1.14). If <uniformBlockIndex> is greater than or equal to | 
 |     the value of ACTIVE_UNIFORM_BLOCKS, the error INVALID_VALUE is | 
 |     generated. | 
 |      | 
 |     The string name of the uniform block identified by <uniformBlockIndex> | 
 |     is returned into <uniformBlockName>. The name is | 
 |     null-terminated. The actual number of characters written into | 
 |     <uniformBlockName>, excluding the null terminator, is returned in <length>. | 
 |     If <length> is NULL, no length is returned. | 
 |  | 
 |     <bufSize> contains the maximum number of characters (including the | 
 |     null terminator) that will be written back to <uniformBlockName>. | 
 |  | 
 |     If an error occurs, nothing will be written to <uniformBlockName> or | 
 |     <length>. | 
 |  | 
 |     Information about an active uniform block can be queried by calling | 
 |  | 
 |         void GetActiveUniformBlockiv(uint program, | 
 |                                         uint uniformBlockIndex,  | 
 |                                         enum pname,  | 
 |                                         int* params); | 
 |   | 
 |     <program> is the name of a program object for which the command | 
 |     LinkProgram has been issued in the past. It is not | 
 |     necessary for <program> to have been linked successfully. The link | 
 |     could have failed because the number of active uniforms exceeded the | 
 |     limit. | 
 |  | 
 |     <uniformBlockIndex> is an active uniform block index of <program>. | 
 |     If <uniformBlockIndex> is greater than or equal to the value of | 
 |     ACTIVE_UNIFORM_BLOCKS, or is not the index of an active uniform | 
 |     block in <program>, the error INVALID_VALUE is generated. | 
 |      | 
 |     If no error occurs, the uniform block parameter(s) specified by | 
 |     <pname> are returned in <params>. Otherwise, nothing will be written | 
 |     to <params>. | 
 |      | 
 |     If <pname> is UNIFORM_BLOCK_BINDING, then | 
 |     the index of the uniform buffer binding | 
 |     point last selected by the uniform block specified by <uniformBlockIndex> | 
 |     for <program> is returned. If no uniform block has been previously | 
 |     specified, zero is returned. | 
 |      | 
 |     If <pname> is UNIFORM_BLOCK_DATA_SIZE, the value returned is the | 
 |     implementation-dependent minimum total buffer object size, in | 
 |     basic machine units, required to hold all active uniforms in the | 
 |     uniform block identified by <uniformBlockIndex>. | 
 |     It is neither guaranteed nor expected that a given implementation will | 
 |     arrange uniform values as tightly packed in a buffer object. The exception | 
 |     to this is the "std140" uniform block layout, which guarantees specific | 
 |     packing behavior and does not require the application to query for offsets | 
 |     and strides. In this case, the minimum size may still be queried, even  | 
 |     though it is determined in advance based only on the uniform block | 
 |     declaration (see "Standard Uniform Block Layout" in section 2.15.3.1.2). | 
 |  | 
 |     The total amount of buffer object storage available for any given uniform | 
 |     block is subject to an implementation-dependent limit; the maximum amount | 
 |     of available space, in basic machine units, can be queried by calling | 
 |     GetIntegerv with the constant MAX_UNIFORM_BLOCK_SIZE.  If the amount | 
 |     of storage required for a uniform block exceeds this limit, a program may | 
 |     fail to link. | 
 |  | 
 |     If <pname> is UNIFORM_BLOCK_NAME_LENGTH, then the total length | 
 |     (including the null terminator) of the name of the uniform block | 
 |     identified by <uniformBlockIndex> is returned. | 
 |  | 
 |     If <pname> is UNIFORM_BLOCK_ACTIVE_UNIFORMS, then the number of | 
 |     active uniforms in the uniform block identified by | 
 |     <uniformBlockIndex> is returned. | 
 |  | 
 |     If <pname> is UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, then a list | 
 |     of the active uniform indices for the uniform block identified by | 
 |     <uniformBlockIndex> is returned. | 
 |     The number of elements that will be written to <params> is the value | 
 |     of UNIFORM_BLOCK_ACTIVE_UNIFORMS for <uniformBlockIndex>. | 
 |  | 
 |     If <pname> is UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER, | 
 |     UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER, or | 
 |     UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER, then | 
 |     a boolean value indicating whether the uniform block identified by | 
 |     <uniformBlockIndex> is referenced by the vertex, geometry, or fragment | 
 |     programming stage of <program>, respectively, is returned. | 
 |  | 
 |     Each active uniform, whether in a named uniform block or in the default | 
 |     block, is assigned an index when a program is linked.  These indices are | 
 |     assigned in consecutive order, beginning with zero.  The indices assigned | 
 |     to a set of uniforms in a program may be queried by calling | 
 |  | 
 |         void GetUniformIndices(uint program, | 
 |                                   sizei uniformCount,  | 
 |                                   const char* const * uniformNames,  | 
 |                                   uint* uniformIndices); | 
 |  | 
 |     <program> is the name of a program object for which the command | 
 |     LinkProgram has been issued in the past. It is not | 
 |     necessary for <program> to have been linked successfully. The link | 
 |     could have failed because the number of active uniforms exceeded the | 
 |     limit. | 
 |  | 
 |     <uniformCount> indicates both the number of elements in the array of | 
 |     names <uniformNames> and the number of indices that may be written to | 
 |     <uniformIndices>.  | 
 |      | 
 |     <uniformNames> contains a list of <uniformCount> name strings | 
 |     identifying the uniform names to be queried for indices.  For each name | 
 |     string in <uniformNames>, the index assigned to the active uniform of  | 
 |     that name will be written to the corresponding element of | 
 |     <uniformIndices>.  If a string in <uniformNames> is not the name of an  | 
 |     active uniform, the value INVALID_INDEX will be written to the | 
 |     corresponding element of <uniformIndices>. | 
 |  | 
 |     If an error occurs, nothing is written to <uniformIndices>. | 
 |  | 
 |     The name of an active uniform may be queried from the corresponding uniform | 
 |     index by calling | 
 |  | 
 |         void GetActiveUniformName(uint program, | 
 |                                      uint uniformIndex,  | 
 |                                      sizei bufSize,  | 
 |                                      sizei* length,  | 
 |                                      char* uniformName); | 
 |  | 
 |     <program> is the name of a program object for which the command | 
 |     LinkProgram has been issued in the past. It is not | 
 |     necessary for <program> to have been linked successfully. The link | 
 |     could have failed because the number of active uniforms exceeded the | 
 |     limit. | 
 |  | 
 |     <uniformIndex> must be an active uniform index of the program | 
 |     <program>, in the range zero to the value of ACTIVE_UNIFORMS - 1. | 
 |     The value of ACTIVE_UNIFORMS can be queried with GetProgramiv. If | 
 |     <uniformIndex> is greater than or equal to the value of | 
 |     ACTIVE_UNIFORMS, the error INVALID_VALUE is generated. | 
 |  | 
 |     The name of the uniform identified by <uniformIndex> is | 
 |     returned as a null-terminated string in <uniformName>. | 
 |     The actual number of characters written into <uniformName>, excluding the | 
 |     null terminator, is returned in <length>. If <length> is NULL, no length is | 
 |     returned. The maximum number of characters that may be written into | 
 |     <uniformName>, including the null terminator, is specified by <bufSize>. | 
 |     The returned uniform name can be the name of built-in uniform state as | 
 |     well. The complete list of built-in uniform state is described in section | 
 |     7.5 of the OpenGL Shading Language specification. The length of the | 
 |     longest uniform name in <program> is given by the value of | 
 |     ACTIVE_UNIFORM_MAX_LENGTH, which can be queried with GetProgramiv. | 
 |  | 
 |     If GetActiveUniformName is not successful, nothing is written to | 
 |     <length> or <uniformName>. | 
 |  | 
 |     Each uniform variable, declared in a shader, is broken down into one or | 
 |     more strings using the "." (dot) and "[]" operators, if necessary, to the | 
 |     point that it is legal to pass each string back into GetUniformLocation, | 
 |     for default uniform block uniform names, or GetUniformIndices, for | 
 |     named uniform block uniform names. | 
 |  | 
 |     Pg 80, replace description of GetActiveUniform | 
 |  | 
 |     Information about active uniforms can be obtained by calling either | 
 |  | 
 |         void GetActiveUniform(uint program,  | 
 |                               uint index, | 
 |                               sizei bufSize,  | 
 |                               sizei* length, | 
 |                               int* size,  | 
 |                               enum* type,  | 
 |                               char* name); | 
 |  | 
 |     or | 
 |  | 
 |         void GetActiveUniformsiv(uint program, | 
 |                                     sizei uniformCount,  | 
 |                                     const uint* uniformIndices,  | 
 |                                     enum pname,  | 
 |                                     int* params); | 
 |  | 
 |     <program> is the name of a program object for which the command | 
 |     LinkProgram has been issued in the past. It is not | 
 |     necessary for <program> to have been linked successfully. The link | 
 |     could have failed because the number of active uniforms exceeded the | 
 |     limit. | 
 |  | 
 |     These commands provide information about the uniform or uniforms selected | 
 |     by <index> or <uniformIndices>, respectively. In GetActiveUniform, an | 
 |     <index> of 0 selects the first active uniform, and an <index> of the value | 
 |     of ACTIVE_UNIFORMS - 1 selects the last active uniform. In  | 
 |     GetActiveUniformsiv, <uniformIndices> is an array of such active uniform | 
 |     indices. If any index is greater than or equal to the value of | 
 |     ACTIVE_UNIFORMS, the error INVALID_VALUE is generated. | 
 |  | 
 |     For the selected uniform, GetActiveUniform returns the uniform name as a | 
 |     null-terminated string in <name>. The actual number of | 
 |     characters written into <name>, excluding the null terminator, is returned | 
 |     in <length>. If <length> is NULL, no length is returned. The maximum | 
 |     number of characters that may be written into <name>, including the null | 
 |     terminator, is specified by <bufSize>. The returned uniform name can be the | 
 |     name of built-in uniform state as well. The complete list of built-in | 
 |     uniform state is described in section 7.5 of the OpenGL Shading Language | 
 |     specification. The length of the longest uniform name in <program> is given | 
 |     by ACTIVE_UNIFORM_MAX_LENGTH. | 
 |  | 
 |     Each uniform variable, declared in a shader, is broken down into one or | 
 |     more strings using the "." (dot) and "[]" operators, if necessary, to the | 
 |     point that it is legal to pass each string back into GetUniformLocation, | 
 |     for default uniform block uniform names, or GetUniformIndices, for | 
 |     named uniform block uniform names. | 
 |  | 
 |     For the selected uniform, GetActiveUniform returns the type of the uniform | 
 |     into <type> and the size of the uniform is into <size>. The value in | 
 |     <size> is in units of the uniform type, which can be any of the | 
 |     values in Table 2.utype. | 
 |  | 
 |     If one or more elements of an array are active, GetActiveUniform will | 
 |     return the name of the array in <name>, subject to the restrictions listed | 
 |     above. The type of the array is returned in <type>. The <size> parameter | 
 |     contains the highest array element index used, plus one. The compiler or | 
 |     linker determines the highest index used. There will be only one active | 
 |     uniform reported by the GL per uniform array. | 
 |  | 
 |     GetActiveUniform will return as much information about active uniforms as | 
 |     possible. If no information is available, <length> will be set to zero and | 
 |     <name> will be an empty string. This situation could arise if  | 
 |     GetActiveUniform is issued after a failed link. | 
 |  | 
 |     If an error occurs, nothing is written to <length>, <size>, <type>, | 
 |     or <name>. | 
 |  | 
 |  | 
 |     Type Name Token        Keyword       Type Name Token                    Keyword | 
 |     ---------------        -------       ---------------                    ------- | 
 |     FLOAT                  float         SAMPLER_1D                         sampler1D | 
 |     FLOAT_VEC2             vec2          SAMPLER_2D                         sampler2D | 
 |     FLOAT_VEC3             vec3          SAMPLER_3D                         sampler3D | 
 |     FLOAT_VEC4             vec4          SAMPLER_CUBE                       samplerCube | 
 |     INT                    int           SAMPLER_1D_SHADOW                  sampler1DShadow | 
 |     INT_VEC2               ivec2         SAMPLER_2D_SHADOW                  sampler2DShadow | 
 |     INT_VEC3               ivec3         SAMPLER_1D_ARRAY_EXT               sampler1DArray | 
 |     INT_VEC4               ivec4         SAMPLER_2D_ARRAY_EXT               sampler2DArray | 
 |     UNSIGNED_INT           unsigned int  SAMPLER_1D_ARRAY_SHADOW_EXT        sampler1DArrayShadow | 
 |     UNSIGNED_INT_VEC2_EXT  uvec2         SAMPLER_2D_ARRAY_SHADOW_EXT        sampler2DArrayShadow | 
 |     UNSIGNED_INT_VEC3_EXT  uvec3         SAMPLER_CUBE_SHADOW_EXT            samplerCubeShadow | 
 |     UNSIGNED_INT_VEC4_EXT  uvec4         SAMPLER_2D_RECT_ARB                sampler2DRect | 
 |     BOOL                   bool          SAMPLER_2D_RECT_SHADOW_ARB         sampler2DRectShadow | 
 |     BOOL_VEC2              bvec2         INT_SAMPLER_1D_EXT                 isampler1D | 
 |     BOOL_VEC3              bvec3         INT_SAMPLER_2D_EXT                 isampler2D | 
 |     BOOL_VEC4              bvec4         INT_SAMPLER_3D_EXT                 isampler3D | 
 |     FLOAT_MAT2             mat2          INT_SAMPLER_CUBE_EXT               isamplerCube | 
 |     FLOAT_MAT3             mat3          INT_SAMPLER_1D_ARRAY_EXT           isampler1DArray | 
 |     FLOAT_MAT4             mat4          INT_SAMPLER_2D_ARRAY_EXT           isampler2DArray | 
 |     FLOAT_MAT2x3           mat2x3        UNSIGNED_INT_SAMPLER_1D_EXT        usampler1D | 
 |     FLOAT_MAT2x4           mat2x4        UNSIGNED_INT_SAMPLER_2D_EXT        usampler2D | 
 |     FLOAT_MAT3x2           mat3x2        UNSIGNED_INT_SAMPLER_3D_EXT        usampler3D | 
 |     FLOAT_MAT3x4           mat3x4        UNSIGNED_INT_SAMPLER_CUBE_EXT      usamplerCube | 
 |     FLOAT_MAT4x2           mat4x2        UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT  usampler1DArray | 
 |     FLOAT_MAT4x3           mat4x3        UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT  usampler2DArray | 
 |                                          SAMPLER_BUFFER_EXT                 samplerBuffer | 
 |                                          INT_SAMPLER_BUFFER_EXT             isamplerBuffer | 
 |                                          UNSIGNED_INT_SAMPLER_BUFFER_EXT    usamplerBuffer | 
 |                                          INT_SAMPLER_2D_RECT_EXT            isampler2DRect | 
 |                                          UNSIGNED_INT_SAMPLER_2D_RECT_EXT   usampler2DRect | 
 |     ----------------------------------------------------------------------- | 
 |     Table 2.utype: OpenGL Shading Language type tokens returned by | 
 |     GetActiveUniform and GetActiveUniformsiv, and corresponding shading | 
 |     language keywords declaring each such type. | 
 |  | 
 |  | 
 |     For GetActiveUniformsiv, <uniformCount> indicates both the number of | 
 |     elements in the array of indices <uniformIndices> and the number of | 
 |     parameters written to <params> upon successful return.  <pname> identifies | 
 |     a property of each uniform in <uniformIndices> that should be written into | 
 |     the corresponding element of <params>.  If an error occurs, nothing will | 
 |     be written to <params>. | 
 |  | 
 |     If <pname> is UNIFORM_TYPE, then an array identifying the types | 
 |     of the uniforms specified by the corresponding array of | 
 |     <uniformIndices> is returned.  The returned types can be any of the  | 
 |     values in Table 2.utype. | 
 |  | 
 |     If <pname> is UNIFORM_SIZE, then an array identifying the size | 
 |     of the uniforms specified by the corresponding array of | 
 |     <uniformIndices> is returned. The sizes returned are in units of the type | 
 |     returned by a query of UNIFORM_TYPE.  For active uniforms that are | 
 |     arrays, the size is the number of active elements in the array; for  | 
 |     all other uniforms, the size is one. | 
 |  | 
 |     If <pname> is UNIFORM_NAME_LENGTH, then an array identifying the | 
 |     length, including the terminating null character, of the uniform | 
 |     name strings specified by the corresponding array of | 
 |     <uniformIndices> is returned. | 
 |  | 
 |     If <pname> is UNIFORM_BLOCK_INDEX, then an array identifying the | 
 |     uniform block index of each of the uniforms specified by the | 
 |     corresponding array of <uniformIndices> is returned. The index of a | 
 |     uniform associated with the default uniform block is -1. | 
 |  | 
 |     If <pname> is UNIFORM_OFFSET, then an array of uniform buffer offsets | 
 |     is returned.  For uniforms in a named uniform block, the returned value | 
 |     will be its offset, in basic machine units, relative to the beginning of | 
 |     the uniform block in the buffer object data store.  For uniforms in the | 
 |     default uniform block, -1 will be returned. | 
 |  | 
 |     If <pname> is UNIFORM_ARRAY_STRIDE, then an array identifying | 
 |     the stride between elements, in basic machine units, of each of the | 
 |     uniforms specified by the corresponding array of <uniformIndices> is | 
 |     returned. The stride of a uniform associated with the default | 
 |     uniform block is -1. Note that this information only makes sense for | 
 |     uniforms that are arrays. For uniforms that are not arrays, but are | 
 |     declared in a named uniform block, an array stride of zero is | 
 |     returned. | 
 |  | 
 |     If <pname> is UNIFORM_MATRIX_STRIDE, then an array identifying | 
 |     the stride between columns of a column-major matrix or rows of a | 
 |     row-major matrix, in basic machine units, of each of the uniforms | 
 |     specified by the corresponding array of <uniformIndices> is | 
 |     returned. The matrix stride of a uniform associated with the default | 
 |     uniform block is -1. Note that this information only makes sense for | 
 |     uniforms that are matrices. For uniforms that are not matrices, but | 
 |     are declared in a named uniform block, a matrix stride of zero is | 
 |     returned. | 
 |  | 
 |     If <pname> is UNIFORM_IS_ROW_MAJOR, then | 
 |     an array identifying whether each of the uniforms | 
 |     specified by the corresponding array of <uniformIndices> is a row-major | 
 |     matrix or not is returned. A value of one indicates a row-major | 
 |     matrix, and a value of zero indicates a column-major matrix, a matrix | 
 |     in the default uniform block, or a non-matrix. | 
 |  | 
 |     Pg 81, replace Uniform* description with: | 
 |  | 
 |     To load values into the uniform variables of the default uniform block of | 
 |     the program object that is currently in use, use the commands  | 
 |  | 
 |         ... | 
 |  | 
 |     The given values are loaded into the default uniform block uniform | 
 |     variable location identified by <location>. | 
 |  | 
 |   Sub-section 2.15.3.1 - Uniform Blocks | 
 |  | 
 |     The values of uniforms arranged in named uniform blocks are extracted from | 
 |     buffer object storage.  The mechanisms for placing individual uniforms in | 
 |     a buffer object and connecting a uniform block to an individual buffer | 
 |     object are described below. | 
 |      | 
 |     There is a set of implementation-dependent maximums for the number of | 
 |     active uniform blocks used by each shader (vertex, fragment, geometry). | 
 |     If the number of uniform blocks used by any shader in the program exceeds | 
 |     its corresponding limit, the program will fail to link.  The limits for | 
 |     vertex, fragment, and geometry shaders can be obtained by calling | 
 |     GetIntegerv with <pname> values of MAX_VERTEX_UNIFORM_BLOCKS, | 
 |     MAX_FRAGMENT_UNIFORM_BLOCKS, and MAX_GEOMETRY_UNIFORM_BLOCKS, | 
 |     respectively. | 
 |  | 
 |     Additionally, there is an implementation-dependent limit on the sum of the | 
 |     number of active uniform blocks used by each shader of a program.  If a | 
 |     uniform block is used by multiple shaders, each such use counts separately | 
 |     against this combined limit.  The combined uniform block use limit can be | 
 |     obtained by calling GetIntegerv with a <pname> of | 
 |     MAX_COMBINED_UNIFORM_BLOCKS. | 
 |  | 
 |     When a named uniform block is declared by multiple shaders in a program, | 
 |     it must be declared identically in each shader.  The uniforms within the | 
 |     block must be declared with the same names and types, and in the same | 
 |     order.  If a program contains multiple shaders with different declarations | 
 |     for the same named uniform block differs between shader, the program will | 
 |     fail to link. | 
 |  | 
 |   Sub-section 2.15.3.1.1 - Uniform Buffer Object Storage | 
 |  | 
 |     When stored in buffer objects associated with uniform blocks, uniforms are | 
 |     represented in memory as follows: | 
 |  | 
 |     - Members of type "bool" are extracted from a buffer object by reading a | 
 |       single uint-typed value at the specified offset. All non-zero | 
 |       values correspond to true, and zero corresponds to false. | 
 |  | 
 |     - Members of type "int" are extracted from a buffer object by reading a | 
 |       single int-typed value at the specified offset. | 
 |  | 
 |     - Members of type "uint" are extracted from a buffer object by reading a | 
 |       single uint-typed value at the specified offset. | 
 |   | 
 |     - Members of type "float" are extracted from a buffer object by reading a | 
 |       single float-typed value at the specified offset. | 
 |   | 
 |     - Vectors with <N> elements with basic data types of "bool", "int", | 
 |       "uint", or "float" are extracted as <N> values in consecutive memory | 
 |       locations beginning at the specified offset, with components stored in | 
 |       order with the first (X) component at the lowest offset. The GL data | 
 |       type used for component extraction is derived according to the rules for | 
 |       scalar members above. | 
 |   | 
 |     - Column-major matrices with <C> columns and <R> rows (using the type | 
 |       "mat<C>x<R>", or simply "mat<C>" if <C>==<R>) are treated as an array of | 
 |       <C> floating-point column vectors, each consisting of <R> components. | 
 |       The column vectors will be stored in order, with column zero at the | 
 |       lowest offset. The difference in offsets between consecutive columns of | 
 |       the matrix will be referred to as the column stride, and is constant | 
 |       across the matrix. The column stride, UNIFORM_MATRIX_STRIDE, is an | 
 |       implementation-dependent value and may be queried after a program is | 
 |       linked. | 
 |  | 
 |     - Row-major matrices with <C> columns and <R> rows (using the type | 
 |       "mat<C>x<R>", or simply "mat<C>" if <C>==<R>) are treated as an array of | 
 |       <R> floating-point row vectors, each consisting of <C> components. The | 
 |       row vectors will be stored in order, with row zero at the lowest offset. | 
 |       The difference in offsets between consecutive rows of the matrix will be | 
 |       referred to as the row stride, and is constant across the matrix. The | 
 |       row stride, UNIFORM_MATRIX_STRIDE, is an implementation-dependent | 
 |       value and may be queried after a program is linked. | 
 |  | 
 |     - Arrays of scalars, vectors, and matrices are stored in memory by element | 
 |       order, with array member zero at the lowest offset. The difference in | 
 |       offsets between each pair of elements in the array in basic machine | 
 |       units is referred to as the array stride, and is constant across the | 
 |       entire array. The array stride, UNIFORM_ARRAY_STRIDE, is an | 
 |       implementation-dependent value and may be queried after a program is | 
 |       linked. | 
 |  | 
 |   Sub-section 2.15.3.1.2 - Standard Uniform Block Layout | 
 |  | 
 |     By default, uniforms contained within a uniform block are extracted from | 
 |     buffer storage in an implementation-dependent manner. Applications may | 
 |     query the offsets assigned to uniforms inside uniform blocks with query | 
 |     functions provided by the GL. | 
 |  | 
 |     The "layout" qualifier provides shaders with control of the layout of | 
 |     uniforms within a uniform block. When the "std140" layout is specified, | 
 |     the offset of each uniform in a uniform block can be derived from the | 
 |     definition of the uniform block by applying the set of rules described | 
 |     below.  | 
 |  | 
 |     If a uniform block is declared in multiple shaders linked together into a | 
 |     single program, the link will fail unless the uniform block declaration, | 
 |     including layout qualifier, are identical in all such shaders. | 
 |  | 
 |     When using the "std140" storage layout, structures will be laid out in | 
 |     buffer storage with its members stored in monotonically increasing order | 
 |     based on their location in the declaration. A structure and each | 
 |     structure member have a base offset and a base alignment, from which an | 
 |     aligned offset is computed by rounding the base offset up to a multiple of | 
 |     the base alignment. The base offset of the first member of a structure is | 
 |     taken from the aligned offset of the structure itself. The base offset of | 
 |     all other structure members is derived by taking the offset of the last | 
 |     basic machine unit consumed by the previous member and adding one. Each | 
 |     structure member is stored in memory at its aligned offset. The members | 
 |     of a top-level uniform block are laid out in buffer storage by treating | 
 |     the uniform block as a structure with a base offset of zero. | 
 |  | 
 |       (1) If the member is a scalar consuming <N> basic machine units, the | 
 |           base alignment is <N>. | 
 |  | 
 |       (2) If the member is a two- or four-component vector with components | 
 |           consuming <N> basic machine units, the base alignment is 2<N> or | 
 |           4<N>, respectively. | 
 |  | 
 |       (3) If the member is a three-component vector with components consuming | 
 |           <N> basic machine units, the base alignment is 4<N>. | 
 |  | 
 |       (4) If the member is an array of scalars or vectors, the base alignment | 
 |           and array stride are set to match the base alignment of a single | 
 |           array element, according to rules (1), (2), and (3), and rounded up | 
 |           to the base alignment of a vec4. The array may have padding at the | 
 |           end; the base offset of the member following the array is rounded up | 
 |           to the next multiple of the base alignment. | 
 |  | 
 |       (5) If the member is a column-major matrix with <C> columns and <R> | 
 |           rows, the matrix is stored identically to an array of <C> column | 
 |           vectors with <R> components each, according to rule (4). | 
 |  | 
 |       (6) If the member is an array of <S> column-major matrices with <C> | 
 |           columns and <R> rows, the matrix is stored identically to a row of | 
 |           <S>*<C> column vectors with <R> components each, according to rule | 
 |           (4). | 
 |  | 
 |       (7) If the member is a row-major matrix with <C> columns and <R> rows, | 
 |           the matrix is stored identically to an array of <R> row vectors | 
 |           with <C> components each, according to rule (4). | 
 |  | 
 |       (8) If the member is an array of <S> row-major matrices with <C> columns | 
 |           and <R> rows, the matrix is stored identically to a row of <S>*<R> | 
 |           row vectors with <C> components each, according to rule (4). | 
 |  | 
 |       (9) If the member is a structure, the base alignment of the structure is | 
 |           <N>, where <N> is the largest base alignment value of any of its | 
 |           members, and rounded up to the base alignment of a vec4. The | 
 |           individual members of this sub-structure are then assigned offsets  | 
 |           by applying this set of rules recursively, where the base offset of | 
 |           the first member of the sub-structure is equal to the aligned offset | 
 |           of the structure. The structure may have padding at the end; the  | 
 |           base offset of the member following the sub-structure is rounded up | 
 |           to the next multiple of the base alignment of the structure. | 
 |  | 
 |       (10) If the member is an array of <S> structures, the <S> elements of | 
 |            the array are laid out in order, according to rule (9). | 
 |  | 
 |     For uniform blocks laid out according to these rules, the minimum buffer | 
 |     object size returned by the UNIFORM_BLOCK_DATA_SIZE query is derived by | 
 |     taking the offset of the last basic machine unit consumed by the last | 
 |     uniform of the uniform block (including any end-of-array or | 
 |     end-of-structure padding), adding one, and rounding up to the next | 
 |     multiple of the base alignment required for a vec4. | 
 |  | 
 |   Sub-section 2.15.3.2 - Uniform Buffer Object Bindings | 
 |  | 
 |     The value an active uniform inside a named uniform block is extracted from | 
 |     the data store of a buffer object bound to one of an array of uniform | 
 |     buffer binding points.  The number of binding points can be queried using | 
 |     GetIntegerv with the constant MAX_UNIFORM_BUFFER_BINDINGS. | 
 |  | 
 |     Buffer objects are bound to uniform block binding points by calling one of | 
 |     the commands | 
 |  | 
 |         void BindBufferRange(enum target,  | 
 |                              uint index,  | 
 |                              uint buffer,  | 
 |                              intptr offset, | 
 |                              sizeiptr size); | 
 |  | 
 |         void BindBufferBase(enum target, | 
 |                             uint index, | 
 |                             uint buffer); | 
 |  | 
 |     with <target> set to UNIFORM_BUFFER. There is an array of buffer | 
 |     object binding points with which uniform blocks can be associated via | 
 |     UniformBlockBinding, plus a single general binding point that can be | 
 |     used by other buffer object manipulation functions (e.g. BindBuffer,  | 
 |     MapBuffer). Both commands bind the buffer object named by <buffer> to the  | 
 |     general binding point, and additionally bind the buffer object to the  | 
 |     binding point in the array given by <index>. The error INVALID_VALUE is | 
 |     generated if <index> is greater than or equal to the value of | 
 |     MAX_UNIFORM_BUFFER_BINDINGS. | 
 |  | 
 |     For BindBufferRange, <offset> specifies a starting offset into the | 
 |     buffer object <buffer>, and <size> specifies the amount of data that can | 
 |     be read from the buffer object while used as the storage for a uniform | 
 |     block. Both <offset> and <size> are in basic machine units. An | 
 |     INVALID_VALUE error is generated if <size> is less than or equal to zero | 
 |     or if <offset> is not a multiple of the implementation-dependent | 
 |     required alignment (the value of UNIFORM_BUFFER_OFFSET_ALIGNMENT). | 
 |  | 
 |     BindBufferBase binds the entire buffer, even when the size of the buffer | 
 |     is changed after the binding is established. It is equivalent to calling | 
 |     BindBufferRange with <offset> zero, while <size> is determined by the | 
 |     size of the bound buffer at the time the binding is used. | 
 |  | 
 |     Regardless of the size specified with BindBufferRange, or indirectly | 
 |     with BindBufferBase, the GL will never read or write beyond the end of a | 
 |     bound buffer. This may result in visibly different behavior when a | 
 |     buffer overflow would otherwise result. | 
 |  | 
 |     Each of a program's active uniform blocks has a corresponding uniform buffer | 
 |     object binding point. This binding point can be assigned by calling: | 
 |      | 
 |          void UniformBlockBinding(uint program, | 
 |                                      uint uniformBlockIndex,  | 
 |                                      uint uniformBlockBinding); | 
 |  | 
 |     <program> is a name of a program object for which the command LinkProgram | 
 |     has been issued in the past. | 
 |  | 
 |     <uniformBlockIndex> must be an active uniform block index of the program | 
 |     <program>. Otherwise, INVALID_VALUE is generated. | 
 |  | 
 |     <uniformBlockBinding> must be less than MAX_UNIFORM_BUFFER_BINDINGS. | 
 |     Otherwise, INVALID_VALUE is generated. | 
 |  | 
 |     If successful, UniformBlockBinding specifies that | 
 |     <program> will use the data store of the buffer object bound to the | 
 |     binding point <uniformBlockBinding> to extract the values of the uniforms | 
 |     in the uniform block identified by <uniformBlockIndex>. | 
 |  | 
 |     The results of Begin or commands that perform an implicit Begin are  | 
 |     undefined when an active uniform block of the active program is assigned a  | 
 |     uniform buffer binding point where the <size> parameter to BindBufferRange  | 
 |     is less than the value of UNIFORM_BLOCK_DATA_SIZE for that uniform | 
 |     block, or when no buffer object is bound to that binding point, and may  | 
 |     result in GL interruption or termination. | 
 |  | 
 |     When executing shaders that access uniform blocks, the binding point | 
 |     corresponding to each active uniform block must be populated with a buffer | 
 |     object with a size no smaller than the minimum required size of the | 
 |     uniform block (UNIFORM_BLOCK_DATA_SIZE).  For binding points populated | 
 |     by BindBufferRange, the size in question is the value of the <size> | 
 |     parameter.  If any active uniform block is not backed by a sufficiently | 
 |     large buffer object, the results of shader execution are undefined, and | 
 |     may result in GL interruption or termination. Shaders may be executed to | 
 |     process the primitives and vertices specified between Begin and End commands | 
 |     or by Draw* or MultiDraw* commands (see section 2.8).  Shaders may also | 
 |     be executed as a result of DrawPixels, Bitmap, or RasterPos* commands. | 
 |  | 
 |     When a program object is linked or re-linked, the uniform buffer object | 
 |     binding point assigned to each of its active uniform blocks is reset to | 
 |     zero. | 
 |      | 
 | Additions to Chapter 3 - Rasterization | 
 |  | 
 |     3.11.1 Shader Variables, p. 196 | 
 |     Replace the second two sentences with: | 
 |  | 
 |     The amount of storage available for fragment shader uniform variables in | 
 |     the default uniform block is specified by the value of the implementation- | 
 |     dependent constant MAX_FRAGMENT_UNIFORM_COMPONENTS. The total amount of | 
 |     combined storage available for fragment shader uniform variables in all | 
 |     uniform blocks (including the default uniform block) is specified by the | 
 |     value of the implementation-dependent constant | 
 |     MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS. These values represent the | 
 |     numbers of individual floating-point, integer, or boolean values that can be | 
 |     held in uniform variable storage for a fragment shader.  | 
 |  | 
 | Additions to Chapter 4 - Per-Fragment Operations and the Framebuffer | 
 |  | 
 |     None | 
 |  | 
 | Additions to Chapter 5 - State and State Requests | 
 |  | 
 |     5.4 Display Lists, p. 244 | 
 |     Add the following language to the list of commands excluded from  | 
 |     display list compilation: | 
 |      | 
 |     "Buffer objects: BindBufferRange, BindBufferBase" | 
 |  | 
 |  | 
 | Additions to Chapter 6 - State and State Requests | 
 |  | 
 |     6.1.1 Simple Queries, p. 247 | 
 |     Add the following paragraph: | 
 |  | 
 |     Indexed simple state variables are queried with the command | 
 |  | 
 |         void GetIntegeri_v(enum target, uint index, int* data); | 
 |  | 
 |     <target> is the name of the indexed state and <index> is the | 
 |     index of the particular element being queried. <data> is a | 
 |     pointer to a scalar or array of the indicated type in which | 
 |     to place the returned data. An INVALID_VALUE error is generated | 
 |     if <index> is outside the valid range for the indexed state | 
 |     <target>. | 
 |  | 
 |     6.1.13 Buffer Object Queries, p. 260 | 
 |  | 
 |     Add after description of GetBufferPointerv: | 
 |  | 
 |     To query which buffer objects are bound to the array of uniform | 
 |     buffer binding points and will be used as the storage for | 
 |     active uniform blocks, call GetIntegeri_v with <param> set to | 
 |     UNIFORM_BUFFER_BINDING. <index> must be in the range | 
 |     zero to the value of MAX_UNIFORM_BUFFER_BINDINGS - 1. | 
 |     The name of the buffer object bound to <index> is returned in  | 
 |     <values>. If no buffer object is bound for <index>, zero is  | 
 |     returned in <values>. | 
 |  | 
 |     To query the starting offset or size of the range of each buffer object | 
 |     binding used for uniform buffers, call GetIntegeri_v with <param> set to | 
 |     UNIFORM_BUFFER_START or UNIFORM_BUFFER_SIZE respectively. <index> must | 
 |     be in the range zero to the value of MAX_UNIFORM_BUFFER_BINDINGS - 1. If | 
 |     the parameter (starting offset or size) was not specified when the | 
 |     buffer object was bound (e.g. if bound with BindBufferBase), or if no | 
 |     buffer object is bound to <index>, zero is returned. | 
 |  | 
 |     6.1.14 Shader and Program Queries | 
 |     Pg 261, continuation of paragraph defining "GetProgramiv" | 
 |  | 
 |     If <pname> is ACTIVE_UNIFORM_BLOCKS the number of uniform | 
 |     blocks for <program> containing active uniforms is returned. | 
 |  | 
 |     If <pname> is ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, the | 
 |     length of the longest active uniform block name, including | 
 |     the null terminator, is returned. | 
 |  | 
 |     Pg 263, replace GetUniform{f|i}v description with: | 
 |  | 
 |     ... return the value or values of the uniform at location <location> | 
 |     of the default uniform block for program object <program>... | 
 |  | 
 | GLX Protocol | 
 |  | 
 |     GLX protocol for BindBufferRange, BindBufferBase and GetIntegeri_v | 
 |     was added through NV_transform_feedback and EXT_draw_buffers2 | 
 |     protocol specs. | 
 |  | 
 |     The following rendering commands are sent to the server as part of | 
 |     a glXRender request: | 
 |  | 
 |     UniformBlockBinding | 
 |  | 
 |         2      16              rendering command length | 
 |         2      366             rendering command opcode | 
 |         4      CARD32          program | 
 |         4      CARD32          uniformBlockIndex | 
 |         4      CARD32          uniformBlockBinding | 
 |  | 
 |     The following non-rendering commands are added: | 
 |  | 
 |     GetUniformIndices | 
 |  | 
 |         1      CARD8           opcode(X assigned) | 
 |         1      215             GLX opcode | 
 |         2      4+n+(s+p)/4     request length | 
 |         4      GLX_CONTEXT_TAG context tag | 
 |         4      CARD32          program | 
 |         4      CARD32          uniformCount | 
 |         n      LISTofINT32     lengths[n], n = uniformCount, lengths[i] = strlen(uniformNames[i]) + 1, 0 <= i < n. | 
 |         s      LISTofCHAR      uniformNames, s = length[0]+...+length[n-1]. | 
 |                                array | 
 |         p                      unused, p = pad(s) | 
 |     => | 
 |         1      1               reply | 
 |         1                      unused | 
 |         2      CARD16          sequence number | 
 |         4      n               reply length | 
 |         4                      unused | 
 |         4      CARD32          n (number of uniform Indices) | 
 |  | 
 |         if (n == 1) this follows: | 
 |  | 
 |         4      CARD32          uniformIndices | 
 |         12                     unused | 
 |  | 
 |         otherwise this follows: | 
 |  | 
 |         16                     unused | 
 |         4*n    LISTofCARD32    uniformIndices | 
 |  | 
 |     GetActiveUniformsiv | 
 |  | 
 |         1      CARD8           opcode(X assigned) | 
 |         1      216             GLX opcode | 
 |         2      5+n             request length | 
 |         4      GLX_CONTEXT_TAG context tag | 
 |         4      CARD32          program | 
 |         4      INT32           uniformCount(n) | 
 |         4      ENUM            pname | 
 |         n      LISTofCARD32    uniformIndices | 
 |  | 
 |     => | 
 |         1      1               reply | 
 |         1                      unused | 
 |         2      CARD16          sequence number | 
 |         4      n               reply length | 
 |         4                      unused | 
 |  | 
 |         if (n == 1) this follows: | 
 |  | 
 |         4      INT32           params | 
 |         12                     unused | 
 |  | 
 |         otherwise this follows: | 
 |  | 
 |         16                     unused | 
 |         4*n    LISTofINT32     params | 
 |  | 
 |      GetActiveUniformName | 
 |  | 
 |         1      CARD8           opcode(X assigned) | 
 |         1      217             GLX opcode | 
 |         2      5               request length | 
 |         4      GLX_CONTEXT_TAG context tag | 
 |         4      CARD32          program | 
 |         4      CARD32          uniformIndex | 
 |         4      INT32           bufsize | 
 |     => | 
 |         1      1               reply | 
 |         1                      unused | 
 |         2      CARD16          sequence number | 
 |         4      m               reply length, m = (n+p)/4 | 
 |         4                      unused | 
 |         4      INT32           n | 
 |         16                     unused | 
 |         n      LISTofCHAR      uniformName, n = strlen(uniformName)+1 | 
 |         p                      unused, p=pad(n) | 
 |  | 
 |      GetUniformBlockIndex | 
 |  | 
 |         1      CARD8           opcode(X assigned) | 
 |         1      218             GLX opcode | 
 |         2      3+(n+p)/4       request length | 
 |         4      GLX_CONTEXT_TAG context tag | 
 |         4      CARD32          program | 
 |         n      LISTofCHAR      uniformBlockName, n = strlen(uniformBlockName)+1 | 
 |         p                      unused, p=pad(n) | 
 |     => | 
 |         1      1               reply | 
 |         1                      unused | 
 |         2      CARD16          sequence number | 
 |         4      0               reply length | 
 |         4      CARD32          return value | 
 |         20                     unused | 
 |  | 
 |     GetActiveUniformBlockiv | 
 |  | 
 |         1      CARD8           opcode(X assigned) | 
 |         1      219             GLX opcode | 
 |         2      5               request length | 
 |         4      GLX_CONTEXT_TAG context tag | 
 |         4      CARD32          program | 
 |         4      CARD32          uniformBlockIndex | 
 |         4      ENUM            pname | 
 |     => | 
 |         1      1               reply | 
 |         1                      unused | 
 |         2      CARD16          sequence number | 
 |         4      n               reply length | 
 |         4                      unused | 
 |  | 
 |         if (n == 1) this follows: | 
 |  | 
 |         4      INT32           params | 
 |         12                     unused | 
 |  | 
 |         otherwise this follows: | 
 |  | 
 |         16                     unused | 
 |         4*n    LISTofINT32     params | 
 |  | 
 |     GetActiveUniformBlockName | 
 |  | 
 |         1      CARD8           opcode(X assigned) | 
 |         1      220             GLX opcode | 
 |         2      5               request length | 
 |         4      GLX_CONTEXT_TAG context tag | 
 |         4      CARD32          program | 
 |         4      CARD32          uniformBlockIndex | 
 |         4      INT32           bufsize | 
 |     => | 
 |         1      1               reply | 
 |         1                      unused | 
 |         2      CARD16          sequence number | 
 |         4      m               reply length, m = (n+p)/4 | 
 |         4                      unused | 
 |         4      INT32           n | 
 |         16                     unused | 
 |         n      LISTofCHAR      uniformBlockName, n = strlen(uniformBlockName)+1 | 
 |         p                      unused, p=pad(n) | 
 |  | 
 | OpenGL Shading Language Spec v1.20.8 Updates | 
 |  | 
 |     Including the following line in a shader can be used to control the | 
 |     language features described in this extension: | 
 |  | 
 |     #extension GL_ARB_uniform_buffer_object : <behavior> | 
 |  | 
 |     where <behavior> is as specified in section 3.3. | 
 |  | 
 |     A new preprocessor #define is added to the OpenGL Shading | 
 |     Language: | 
 |  | 
 |     #define GL_ARB_uniform_buffer_object 1 | 
 |  | 
 |     Add two new sections: | 
 |  | 
 |     4.3.5.1 Uniform Blocks | 
 |  | 
 |     Variable declarations at global scope can be grouped into a named block to  | 
 |     provide coarser granularity for manipulation, sharing, or backing than is | 
 |     achievable with individual declarations. This is currently only allowed for | 
 |     uniform variables grouped into uniform blocks. All other uses are reserved. | 
 |   | 
 |     The application backs a uniform block with a buffer. This allows application | 
 |     access to a set of uniform variables through a single buffer. The  | 
 |     application will need to query the offsets of the variables within the  | 
 |     block or follow standard rules for block layout in order to know how to | 
 |     layout the contents of a buffer used to back the block.  | 
 |  | 
 |     A uniform block (rather than a uniform variable) is created by the uniform  | 
 |     keyword, followed by a block name, followed by an open curly brace ( { ) as | 
 |     follows: | 
 |  | 
 |         uniform-block :  | 
 |             layout-qualifieropt  uniform block-name { member-list } ;  | 
 |  | 
 |         layout-qualifier :  | 
 |             layout ( layout-qualifier-id-list )  | 
 |  | 
 |         member-list :  | 
 |             member-declaration  | 
 |             member-declaration member-list  | 
 |  | 
 |         member-declaration :  | 
 |             layout-qualifieropt  uniformopt  basic-type declarators ;  | 
 |  | 
 |     Where declarators are the same as for other uniform variable declarations,  | 
 |     except initializers are not allowed. Layout qualifiers are defined in the | 
 |     next section.  | 
 |  | 
 |     For example,  | 
 |  | 
 |         uniform Transform {  | 
 |             mat4 ModelViewMatrix;  | 
 |             mat4 ModelViewProjectionMatrix;  | 
 |             uniform mat3 NormalMatrix;      // reuse of uniform is optional  | 
 |             float Deformation;  | 
 |         };  | 
 |  | 
 |     The above establishes a uniform block named "Transform" with four uniforms | 
 |     grouped inside it.  | 
 |  | 
 |     The names declared inside the block are accessed as if they were declared | 
 |     outside the block. In no way does the shader ever access block members | 
 |     through any use of block-name.  | 
 |  | 
 |     Uniform block names and variable names declared within uniform blocks are | 
 |     scoped at the program level. Matching block names from multiple compilation | 
 |     units in the same program must match in terms of having the same number of | 
 |     declarations with the same sequence of types and the same sequence of member | 
 |     names, as well as having the same member-wise layout qualification (see next  | 
 |     section). Any mismatch will generate a link error.  | 
 |  | 
 |     Sampler types are not allowed inside of uniform blocks. All other types, | 
 |     arrays, and structures allowed for uniforms are allowed within a uniform | 
 |     block.  | 
 |  | 
 |     There is an implementation-dependent limit on the number of uniform blocks | 
 |     that can be used per stage. If this limit is exceeded, it will cause a link | 
 |     error.  | 
 |  | 
 |     4.3.5.2 Uniform Block Layout Qualifiers | 
 |  | 
 |     The layout-qualifier-id-list for uniform blocks is a comma separated list of  | 
 |     the following qualifiers:  | 
 |  | 
 |         shared        (default)  | 
 |         packed  | 
 |         std140  | 
 |         row_major  | 
 |         column_major  (default)  | 
 |  | 
 |     These qualifiers are identifiers, not keywords. None of these have any | 
 |     semantic affect at all on the usage of the variables being declared; they | 
 |     only describe how data is laid out in memory. For example, matrix semantics | 
 |     are always column-based, as described in the rest of this specification, no | 
 |     matter what layout qualifiers are being used.  | 
 |  | 
 |     Uniform block layout qualifiers can be declared at global scope, on a single | 
 |     uniform block, or on a single block member.  | 
 |  | 
 |     At global scope, it is an error to use layout qualifiers to declare a | 
 |     variable. Instead, at global scope, layout qualifiers apply just to the | 
 |     keyword uniform and establish default qualification for subsequent blocks: | 
 |  | 
 |         layout-defaults :  | 
 |             layout-qualifier uniform ;  | 
 |  | 
 |     When this is done, the previous default qualification is first inherited and  | 
 |     then overridden as per the override rules listed below for each qualifier | 
 |     listed in the declaration. The result becomes the new default qualification | 
 |     scoped to subsequent uniform block definitions. Layout defaults can only be  | 
 |     specified at global scope.  | 
 |  | 
 |     The initial state of compilation is as if the following were declared:  | 
 |  | 
 |         layout(shared, column_major) uniform;  | 
 |  | 
 |     Explicitly declaring this in a shader will return defaults back to their | 
 |     initial state.  | 
 |  | 
 |     Uniform blocks can be declared with optional layout qualifiers, and so can | 
 |     their individual member declarations. Such block layout qualification is | 
 |     scoped only to the content of the block. As with global layout declarations, | 
 |     block layout qualification first inherits from the current default  | 
 |     qualification and then overrides it. Similarly, individual member layout | 
 |     qualification is scoped just to the member declaration, and inherits from | 
 |     and overrides the block's qualification.  | 
 |  | 
 |     The shared qualifier overrides only the std140 and packed qualifiers; other | 
 |     qualifiers are inherited. The compiler/linker will ensure that multiple | 
 |     programs and programmable stages containing this definition will share the | 
 |     same memory layout for this block, as long as they also matched in their | 
 |     row_major and/or column_major qualifications. This allows use of the same | 
 |     buffer to back the same block definition across different programs.  | 
 |  | 
 |     The packed qualifier overrides only std140 and shared; other qualifiers are | 
 |     inherited. When packed is used, no shareable layout is guaranteed. The | 
 |     compiler and linker can optimize memory use based on what variables actively | 
 |     get used and on other criteria. Offsets must be queried, as there is no | 
 |     other way of guaranteeing where (and which) variables reside within the | 
 |     block. Attempts to share a packed uniform block across programs or stages | 
 |     will generally fail. However, implementations may aid application management  | 
 |     of packed blocks by using canonical layouts for packed blocks.  | 
 |  | 
 |     The std140 qualifier overrides only the packed and shared qualifiers; other | 
 |     qualifiers are inherited. The layout is explicitly determined by this, as | 
 |     described in the API specification section 2.15.3.1.2. Hence, as in shared | 
 |     above, the resulting layout is shareable across programs.  | 
 |  | 
 |     Layout qualifiers on member declarations cannot use the shared, packed, or | 
 |     std140 qualifiers. These can only be used at global scope or on a block | 
 |     declaration. | 
 |  | 
 |     The row_major qualifier overrides only the column_major qualifier; other | 
 |     qualifiers are inherited. It only affects the layout of matrices. Elements | 
 |     within a matrix row will be contiguous in memory.  | 
 |  | 
 |     The column_major qualifier overrides only the row_major qualifier; other | 
 |     qualifiers are inherited. It only affects the layout of matrices. Elements | 
 |     within a matrix column will be contiguous in memory. | 
 |  | 
 |     When multiple arguments are listed in a layout declaration, the affect will | 
 |     be the same as if they were declared one at a time, in order from left to | 
 |     right, each in turn inheriting from and overriding the result from the  | 
 |     previous qualification.  | 
 |  | 
 |     For example  | 
 |  | 
 |         layout(row_major, column_major)  | 
 |  | 
 |     results in the qualification being column_major. Other examples:  | 
 |  | 
 |         layout(shared, row_major) uniform; // default is now shared & row_major | 
 |   | 
 |         layout(std140) uniform Transform { // layout of this block is std140  | 
 |             mat4 M1;                       // row_major  | 
 |             layout(column_major) mat4 M2;  // column major  | 
 |             mat3 N1;                       // row_major  | 
 |         };  | 
 |  | 
 |         uniform T2 {  // layout of this block is shared  | 
 |             ...  | 
 |         }; | 
 |   | 
 |         layout(column_major) uniform T3 {  // shared and column_major  | 
 |             mat4 M3;                       // column_major  | 
 |             layout(row_major) mat4 m4;     // row major  | 
 |             mat3 N2;                       // column_major  | 
 |         };  | 
 |  | 
 | Interactions with OpenGL 3.0 | 
 |  | 
 |     If OpenGL 3.0 is supported, the introduction of BindBufferBase and | 
 |     BindBufferRange can be ignored, though the uniform buffer object | 
 |     language herein will need to be merged with the transform feedback | 
 |     language in GL 3.0. | 
 |  | 
 |     If OpenGL 3.0 is supported, the introduction of GetIntegeri_v | 
 |     can be ignored. | 
 |  | 
 |     If OpenGL 3.0 is supported, change: | 
 |  | 
 |     "When a program is successfully linked, all active uniforms belonging to | 
 |     the program object's default uniform block are initialized to zero (FALSE | 
 |     for booleans). A successful link will also generate a location for each | 
 |     active uniform in the default uniform block. The values of active uniforms | 
 |     in the default uniform block can be changed using this location and the | 
 |     appropriate Uniform* command (see below)." | 
 |  | 
 |         to | 
 |  | 
 |     "When a program is successfully linked, all active uniforms belonging to  | 
 |     the program object's default uniform block are initialized as defined by  | 
 |     the version of the OpenGL Shading Language used to compile the program. A | 
 |     successful link will also generate a location for each active uniform in | 
 |     the default uniform block. The values of active uniforms in the default | 
 |     uniform block can be changed using this location and the appropriate | 
 |     Uniform* command (see below)." | 
 |  | 
 |     If OpenGL 3.0 is supported, replace "Begin or commands that perform | 
 |     an implicit Begin" with "Draw* commands." | 
 |  | 
 |     If OpenGL 3.0 is supported, UNIFORM_BUFFER is a valid target for | 
 |     new buffer-related API, e.g. MapBufferRange. | 
 |  | 
 | Interactions with EXT_gpu_shader4 | 
 |  | 
 |     If EXT_gpu_shader4 is not supported, then all of the types in table | 
 |     2.utype with extension suffixes should be omitted. | 
 |  | 
 | Interactions with ARB_texture_rectangle | 
 |  | 
 |     If ARB_texture_rectangle is not available, then all of the types in | 
 |     table 2.utype with RECT in their names should be omitted. | 
 |  | 
 | Interactions with EXT_texture_array | 
 |  | 
 |     If EXT_texture_array is not available, then all of the types in | 
 |     table 2.utype with ARRAY in their names should be omitted. | 
 |  | 
 | Interactions with EXT_texture_buffer_object | 
 |  | 
 |     If EXT_texture_buffer_object is not available, then all of the types | 
 |     in table 2.utype with BUFFER in their names should be omitted. | 
 |  | 
 | Interactions with EXT_texture_integer | 
 |  | 
 |     If EXT_texture_integer is not available, then all of the types in | 
 |     table 2.utype with UNSIGNED_INT or INT_SAMPLER in their names should  | 
 |     be omitted. | 
 |  | 
 | Interactions with ARB_geometry_shader4 | 
 |  | 
 |     If ARB_geometry_shader4 is not supported, omit all mentions of the | 
 |     geometry shader stage, including MAX_GEOMETRY_UNIFORM_BUFFERS | 
 |     and UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER. The minimum | 
 |     value of MAX_COMBINED_UNIFORM_BLOCKS and | 
 |     MAX_UNIFORM_BUFFER_BINDINGS changes from 36 to 24. | 
 |  | 
 |     Language describing MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS can be found | 
 |     in the ARB_geometry_shader4 specification. | 
 |  | 
 | Errors | 
 |  | 
 |     The error INVALID_OPERATION is generated by BindBufferRange and | 
 |     BindBufferBase if <buffer> is not the name of a valid buffer object. | 
 |      | 
 |     The error INVALID_VALUE is generated by GetUniformIndices, | 
 |     GetActiveUniformsiv, GetActiveUniformName, GetUniformBlockIndex, | 
 |     GetActiveUniformBlockiv, GetActiveUniformBlockName, and | 
 |     UniformBlockBinding if <program> is not a value generated by GL. | 
 |  | 
 |     The error INVALID_VALUE is generated by GetUniformIndices and | 
 |     GetActiveUniformsiv if <uniformCount> is less than zero. | 
 |  | 
 |     The error INVALID_VALUE is generated by GetActiveUniformName and | 
 |     GetActiveUniformBlockName if <bufSize> is less than zero. | 
 |  | 
 |     The error INVALID_VALUE is generated by BindBufferRange if <size> is less | 
 |     than zero. | 
 |  | 
 |     The error INVALID_VALUE is generated by GetActiveUniformName if | 
 |     <uniformIndex> is greater than or equal to ACTIVE_UNIFORMS. | 
 |  | 
 |     The error INVALID_VALUE is generated by GetActiveUniformsiv if any of | 
 |     the indices in <uniformIndices> is greater than or equal to ACTIVE_UNIFORMS. | 
 |  | 
 |     The error INVALID_VALUE is generated by GetActiveUniformBlockiv, | 
 |     GetActiveUniformBlockName, and UniformBlockBinding if | 
 |     <uniformBlockIndex> is greater than or equal to ACTIVE_UNIFORM_BLOCKS. | 
 |  | 
 |     The error INVALID_VALUE is generated by UniformBlockBinding if | 
 |     <uniformBlockBinding> is greater than or equal to  | 
 |     MAX_UNIFORM_BUFFER_BINDINGS. | 
 |  | 
 |     The error INVALID_VALUE is generated by BindBufferRange and BindBufferBase | 
 |     if <index> is greater than or equal to MAX_UNIFORM_BUFFER_BINDINGS. | 
 |  | 
 |     The error INVALID_VALUE is generated by BindBufferRange if <offset> is not | 
 |     a multiple of UNIFORM_BUFFER_OFFSET_ALIGNMENT basic machine units. | 
 |  | 
 |     The error INVALID_ENUM is generated by GetActiveUniformsiv and | 
 |     GetActiveUniformBlockiv if <pname> is not one of the accepted values. | 
 |  | 
 |     The error INVALID_ENUM is generated by BindBufferRange and BindBufferBase | 
 |     if <target> is not an accepted indexable buffer object target. | 
 |  | 
 |  | 
 | New State | 
 |                                                                     Initial | 
 |     Get Value                          Type  Get Command            Value     Description                Sec    Attribute | 
 |     --------------------------         ----  -----------            -----     -------------------------  -----  --------- | 
 |     UNIFORM_BUFFER_BINDING             Z+    GetIntegerv              0       Uniform buffer object      2.15.3 - | 
 |                                                                               bound to the context for | 
 |                                                                               buffer object manipulation. | 
 |  | 
 |     UNIFORM_BUFFER_BINDING             nxZ+  GetIntegeri_v            0       Uniform buffer object      2.15.3 - | 
 |                                                                               bound to the specified | 
 |                                                                               context binding point | 
 |                                                                                | 
 |     ACTIVE_UNIFORM_BLOCKS              Z+    GetProgramiv             0       Number of active           2.15.3 - | 
 |                                                                               uniform blocks in a  | 
 |                                                                               program | 
 |  | 
 |     ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH | 
 |                                        Z+    GetProgramiv             0       Length of longest active   2.15.3 - | 
 |                                                                               uniform block name | 
 |  | 
 |     UNIFORM_TYPE                    0*xZ_27  GetActiveUniformsiv      -       Type of active uniform     2.15.3 - | 
 |  | 
 |     UNIFORM_SIZE                       0*xZ+ GetActiveUniformsiv      -       Size of active uniform     2.15.3 - | 
 |      | 
 |     UNIFORM_NAME_LENGTH                0*xZ+ GetActiveUniformsiv      -       Uniform name length        2.15.3 - | 
 |  | 
 |     UNIFORM_BLOCK_INDEX                0*xZ  GetActiveUniformsiv      -       Uniform block index        2.15.3 - | 
 |          | 
 |     UNIFORM_OFFSET                     0*xZ  GetActiveUniformsiv      -       Uniform buffer offset      2.15.3 - | 
 |      | 
 |     UNIFORM_ARRAY_STRIDE               0*xZ  GetActiveUniformsiv      -       Uniform buffer array       2.15.3 - | 
 |                                                                               stride | 
 |  | 
 |     UNIFORM_MATRIX_STRIDE              0*xZ  GetActiveUniformsiv      -       Uniform buffer intra-      2.15.3 - | 
 |                                                                               matrix stride | 
 |  | 
 |     UNIFORM_IS_ROW_MAJOR               0*xZ+ GetActiveUniformsiv      -       Whether uniform is a       2.15.3 - | 
 |                                                                               row-major matrix | 
 |  | 
 |     UNIFORM_BLOCK_BINDING              0*xZ+ GetActiveUniformBlockiv  0       Uniform buffer binding     2.15.3 - | 
 |                                                                               points associated with the | 
 |                                                                               specified uniform block | 
 |  | 
 |  | 
 |     UNIFORM_BLOCK_DATA_SIZE            0*xZ+ GetActiveUniformBlockiv  -       Size of the storage        2.15.3 - | 
 |                                                                               needed to hold this | 
 |                                                                               uniform block's data | 
 |  | 
 |  | 
 |     UNIFORM_BLOCK_ACTIVE_UNIFORMS      0*xZ+ GetActiveUniformBlockiv  -       Count of active            2.15.3 - | 
 |                                                                               uniforms in  | 
 |                                                                               the specified  | 
 |                                                                               uniform block | 
 |  | 
 |     UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES | 
 |                                     0*xnxZ+  GetActiveUniformBlockiv  -       Array of active            2.15.3 - | 
 |                                                                               uniform indices of | 
 |                                                                               the specified  | 
 |                                                                               uniform block | 
 |  | 
 |     UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER | 
 |                                        0*xB  GetActiveUniformBlockiv  0       TRUE if uniform block      2.15.3 - | 
 |                                                                               is actively  | 
 |                                                                               referenced by the  | 
 |                                                                               vertex shader | 
 |  | 
 |     UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER | 
 |                                        0*xB  GetActiveUniformBlockiv  0       TRUE if uniform block      2.15.3 - | 
 |                                                                               is actively  | 
 |                                                                               referenced by the  | 
 |                                                                               geometry shader | 
 |  | 
 |     UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER | 
 |                                        0*xB  GetActiveUniformBlockiv  0       TRUE if uniform block      2.15.3 - | 
 |                                                                               is actively  | 
 |                                                                               referenced by the  | 
 |                                                                               fragment shader | 
 |  | 
 | New Implementation Dependent State | 
 |  | 
 |                                                                        Minimum | 
 |     Get Value                                       Type  Get Command  Value    Description                  Sec     Attribute | 
 |     --------------------------------                --    -----------  -----    -------------------------    -----   ---------- | 
 |     MAX_VERTEX_UNIFORM_BLOCKS                       Z+    GetIntegerv   12      Maximum number of vertex     2.15.3  - | 
 |                                                                                 uniform buffers per  | 
 |                                                                                 program | 
 |  | 
 |     MAX_FRAGMENT_UNIFORM_BLOCKS                     Z+    GetIntegerv   12      Maximum number of fragment   2.15.3  - | 
 |                                                                                 uniform buffers per  | 
 |                                                                                 program | 
 |  | 
 |     MAX_GEOMETRY_UNIFORM_BLOCKS                     Z+    GetIntegerv   12      Maximum number of geometry   2.15.3  - | 
 |                                                                                 uniform buffers per  | 
 |                                                                                 program | 
 |  | 
 |     MAX_COMBINED_UNIFORM_BLOCKS                     Z+    GetIntegerv   36      Maximum number of uniform    2.15.3  - | 
 |                                                                                 buffers per program | 
 |  | 
 |     MAX_UNIFORM_BUFFER_BINDINGS                     Z+    GetIntegerv   36      Maximum number of uniform    2.15.3  - | 
 |                                                                                 buffer binding points | 
 |                                                                                 on the context | 
 |  | 
 |     MAX_UNIFORM_BLOCK_SIZE                          Z+    GetIntegerv   16384   Max size in basic machine    2.15.3  - | 
 |                                                                                 units of a uniform block | 
 |  | 
 |     MAX_VERTEX_UNIFORM_COMPONENTS                   Z+    GetIntegerv   *       Number of words for vertex   2.15.3  - | 
 |                                                                                 shader uniform variables | 
 |                                                                                 in default uniform block | 
 |  | 
 |     MAX_FRAGMENT_UNIFORM_COMPONENTS                 Z+    GetIntegerv   *       Number of words for fragment 2.15.3  - | 
 |                                                                                 shader uniform variables | 
 |                                                                                 in default uniform block | 
 |  | 
 |     MAX_GEOMETRY_UNIFORM_COMPONENTS                 Z+    GetIntegerv   *       Number of words for geometry 2.15.3  - | 
 |                                                                                 shader uniform variables | 
 |                                                                                 in default uniform block | 
 |  | 
 |     MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS          Z+    GetIntegerv   *       Number of words for vertex   2.15.3  - | 
 |                                                                                 shader uniform variables | 
 |                                                                                 in all uniform blocks | 
 |                                                                                 (including default) | 
 |  | 
 |     MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS        Z+    GetIntegerv   *       Number of words for fragment 2.15.3  - | 
 |                                                                                 shader uniform variables | 
 |                                                                                 in all uniform blocks | 
 |                                                                                 (including default) | 
 |  | 
 |     MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS        Z+    GetIntegerv   *       Number of words for geometry 2.15.3  - | 
 |                                                                                 shader uniform variables | 
 |                                                                                 in all uniform blocks | 
 |                                                                                 (including default) | 
 |  | 
 |     UNIFORM_BUFFER_OFFSET_ALIGNMENT                 Z+    GetIntegerv   1       Minimum required alignment   2.15.3  - | 
 |                                                                                 for uniform buffer sizes | 
 |                                                                                 and offsets | 
 |  | 
 |     * Minimum value for OpenGL 3.1 is (MAX_<stage>_UNIFORM_BLOCKS * | 
 |       MAX_UNIFORM_BLOCK_SIZE) + MAX_<stage>_UNIFORM_COMPONENTS. Minimum | 
 |       value prior to OpenGL 3.1 is MAX_<stage>_UNIFORM_COMPONENTS. | 
 |  | 
 | Sample Code | 
 |  | 
 |     //////////////////////////////////////////////////////////////////////////// | 
 |     Example: Full code of a simple use case: updating a group of variables | 
 |     in a real shader. | 
 |     //////////////////////////////////////////////////////////////////////////// | 
 |  | 
 |     //Platform-specific includes go here | 
 |  | 
 |     #define glError() { \ | 
 |     GLenum err = glGetError(); \ | 
 |     while (err != GL_NO_ERROR) { \ | 
 |     printf("glError: %s caught at %s:%u", \ | 
 |            (char*)gluErrorString(err), __FILE__, __LINE__); \ | 
 |     err = glGetError(); \ | 
 |     exit(-1); \ | 
 |     } \ | 
 |     } | 
 |  | 
 |     // globals | 
 |     int initialized = 0; | 
 |  | 
 |     int width=640; | 
 |     int height=480; | 
 |  | 
 |     GLfloat wf,hf; | 
 |     //uniform names | 
 |     GLchar* names[] = | 
 |     { | 
 |         "SurfaceColor", | 
 |         "WarmColor", | 
 |         "CoolColor", | 
 |         "DiffuseWarm", | 
 |         "DiffuseCool" | 
 |     }; | 
 |     GLuint buffer_id, uniformBlockIndex, index, vshad_id, fshad_id, prog_id; | 
 |     GLsizei uniformBlockSize; | 
 |     GLint singleSize, offset; | 
 |  | 
 |     GLfloat colors[] =  | 
 |     { | 
 |         0.45,0.45,1,1, | 
 |         0.45,0.45,1,1, | 
 |         0.75,0.75,0.75,1, | 
 |         0.0,0.0,1.0,1, | 
 |         0.0,1.0,0.0,1, | 
 |     }; | 
 |  | 
 |     void reshape(int w, int h) { | 
 |         width = w; height = h; | 
 |         wf = (GLfloat) width; | 
 |         hf = (GLfloat) height; | 
 |         glMatrixMode(GL_PROJECTION); | 
 |         glLoadIdentity(); | 
 |         gluPerspective(60.0, wf/hf, 0.1, 100.0);     | 
 |     } | 
 |  | 
 |     void init_opengl() | 
 |     {     | 
 |         reshape(width, height); | 
 |         //load_shader and link_program are utility functions omitted here | 
 |         vshad_id = load_shader(GL_VERTEX_SHADER, "gooch.vs"); | 
 |         fshad_id = load_shader(GL_FRAGMENT_SHADER, "gooch.fs"); | 
 |         prog_id = glCreateProgram(); | 
 |         glAttachShader(prog_id, vshad_id); | 
 |         glAttachShader(prog_id, fshad_id); | 
 |         link_program(prog_id); | 
 |          | 
 |         //Update the uniforms using ARB_uniform_buffer_object | 
 |         glGenBuffers(1, &buffer_id); | 
 |  | 
 |         //There's only one uniform block here, the 'colors0' uniform block.  | 
 |         //It contains the color info for the gooch shader. | 
 |         uniformBlockIndex = glGetUniformBlockIndex(prog_id, "colors0"); | 
 |          | 
 |         //We need to get the uniform block's size in order to back it with the | 
 |         //appropriate buffer | 
 |         glGetActiveUniformBlockiv(prog_id, uniformBlockIndex, | 
 |                                      GL_UNIFORM_BLOCK_DATA_SIZE, | 
 |                                      &uniformBlockSize); | 
 |         glError(); | 
 |          | 
 |         //Create UBO. | 
 |         glBindBuffer(GL_UNIFORM_BUFFER, buffer_id); | 
 |         glBufferData(GL_UNIFORM_BUFFER, uniformBlockSize, | 
 |                      NULL, GL_DYNAMIC_DRAW); | 
 |  | 
 |         //Now we attach the buffer to UBO binding point 0... | 
 |         glBindBufferBase(GL_UNIFORM_BUFFER, 0, buffer_id); | 
 |         //And associate the uniform block to this binding point. | 
 |         glUniformBlockBinding(prog_id, uniformBlockIndex, 0); | 
 |         glError(); | 
 |  | 
 |         //To update a single uniform in a uniform block, we need to get its | 
 |         //offset into the buffer. | 
 |         glGetUniformIndices(prog_id, 1, &names[2], &index); | 
 |         glGetActiveUniformsiv(prog_id, 1, &index, | 
 |                                  GL_UNIFORM_OFFSET, &offset); | 
 |          | 
 |         glGetActiveUniformsiv(prog_id, 1, &index, | 
 |                                  GL_UNIFORM_SIZE, &singleSize); | 
 |         glError(); | 
 |          | 
 |         glViewport(0, 0, width, height); | 
 |     } | 
 |  | 
 |     void render() | 
 |     { | 
 |         glClearColor(0.0, 0.0, 0.0, 0.0); | 
 |         glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT); | 
 |          | 
 |         glUseProgram(prog_id); | 
 |  | 
 |         glEnable(GL_DEPTH_TEST); | 
 |         glMatrixMode(GL_MODELVIEW); | 
 |         glLoadIdentity(); | 
 |         glTranslatef(0, 0, -4); | 
 |         glColor3f(1.0, 1.0, 1.0); | 
 |         glBindBuffer(GL_UNIFORM_BUFFER, buffer_id); | 
 |         //We can use BufferData to upload our data to the shader, | 
 |         //since we know it's in the std140 layout | 
 |         glBufferData(GL_UNIFORM_BUFFER, 80, colors, GL_DYNAMIC_DRAW); | 
 |         //With a non-standard layout, we'd use BufferSubData for each uniform. | 
 |         glBufferSubData(GL_UNIFORM_BUFFER, offset, singleSize, &colors[8]); | 
 |         //the teapot winds backwards | 
 |         glFrontFace(GL_CW); | 
 |         glutSolidTeapot(1.33); | 
 |         glFrontFace(GL_CCW); | 
 |         glutSwapBuffers(); | 
 |     } | 
 |  | 
 |     void display() | 
 |     { | 
 |         if(!initialized) | 
 |         { | 
 |             init_opengl(); | 
 |             initialized = 1; | 
 |         } | 
 |          | 
 |         render(); | 
 |     } | 
 |  | 
 |     int main (int argc, const char** argv) { | 
 |         //GLUT initialization goes here | 
 |     } | 
 |  | 
 |     // Vertex shader for Gooch shading | 
 |     // Author: Randi Rost | 
 |     // Copyright (c) 2002-2006 3Dlabs Inc. Ltd. | 
 |     // See 3Dlabs-License.txt for license information | 
 |  | 
 |     vec3 LightPosition = vec3(0.0, 10.0, 4.0);  | 
 |  | 
 |     varying float NdotL; | 
 |     varying vec3  ReflectVec; | 
 |     varying vec3  ViewVec; | 
 |  | 
 |     void main(void) | 
 |     { | 
 |         vec3 ecPos      = vec3 (gl_ModelViewMatrix * gl_Vertex); | 
 |         vec3 tnorm      = normalize(gl_NormalMatrix * gl_Normal); | 
 |         vec3 lightVec   = normalize(LightPosition - ecPos); | 
 |         ReflectVec      = normalize(reflect(-lightVec, tnorm)); | 
 |         ViewVec         = normalize(-ecPos); | 
 |         NdotL           = (dot(lightVec, tnorm) + 1.0) * 0.5; | 
 |         gl_Position     = ftransform(); | 
 |     } | 
 |  | 
 |     // Fragment shader for Gooch shading, adapted for ARB_uniform_buffer_object | 
 |  | 
 |     #extension GL_ARB_uniform_buffer_object : enable | 
 |  | 
 |     layout(std140) uniform colors0 | 
 |     { | 
 |         float DiffuseCool; | 
 |         float DiffuseWarm; | 
 |         vec3  SurfaceColor; | 
 |         vec3  WarmColor; | 
 |         vec3  CoolColor; | 
 |     }; | 
 |  | 
 |     varying float NdotL; | 
 |     varying vec3  ReflectVec; | 
 |     varying vec3  ViewVec; | 
 |  | 
 |     void main (void) | 
 |     { | 
 |         vec3 kcool    = min(CoolColor + DiffuseCool * SurfaceColor, 1.0); | 
 |         vec3 kwarm    = min(WarmColor + DiffuseWarm * SurfaceColor, 1.0);  | 
 |         vec3 kfinal   = mix(kcool, kwarm, NdotL); | 
 |  | 
 |         vec3 nreflect = normalize(ReflectVec); | 
 |         vec3 nview    = normalize(ViewVec); | 
 |  | 
 |         float spec    = max(dot(nreflect, nview), 0.0); | 
 |         spec          = pow(spec, 32.0); | 
 |  | 
 |         gl_FragColor = vec4 (min(kfinal + spec, 1.0), 1.0); | 
 |     } | 
 |  | 
 | Examples | 
 |  | 
 |     The following example illustrates the rules specified by the "std140" | 
 |     layout. | 
 |  | 
 |       layout(std140) uniform Example { | 
 |  | 
 |                       // Base types below consume 4 basic machine units | 
 |                       // | 
 |                       //       base   base  align | 
 |                       // rule  align  off.  off.  bytes used | 
 |                       // ----  ------ ----  ----  ----------------------- | 
 |         float a;      //  1       4     0    0    0..3 | 
 |         vec2 b;       //  2       8     4    8    8..15 | 
 |         vec3 c;       //  3      16    16   16    16..27 | 
 |         struct {      //  9      16    28   32    (align begin) | 
 |           int d;      //  1       4    32   32    32..35 | 
 |           bvec2 e;    //  2       8    36   40    40..47 | 
 |         } f;          //  9      16    48   48    (pad end) | 
 |         float g;      //  1       4    48   48    48..51 | 
 |         float h[2];   //  4      16    52   64    64..67 (h[0]) | 
 |                       //                    80    80..83 (h[1]) | 
 |                       //  4      16    84   96    (pad end of h) | 
 |         mat2x3 i;     // 5/4     16    96   96    96..107 (i, column 0) | 
 |                       //                   112    112..123 (i, column 1) | 
 |                       // 5/4     16   124  128    (pad end of i) | 
 |         struct {      //  10     16   128  128    (align begin) | 
 |           uvec3 j;    //  3      16   128  128    128..139 (o[0].j) | 
 |           vec2 k;     //  2       8   140  144    144..151 (o[0].k) | 
 |           float l[2]; //  4      16   152  160    160..163 (o[0].l[0]) | 
 |                       //                   176    176..179 (o[0].l[1]) | 
 |                       //  4      16   180  192    (pad end of o[0].l) | 
 |           vec2 m;     //  2       8   192  192    192..199 (o[0].m) | 
 |           mat3 n[2];  // 6/4     16   200  208    208..219 (o[0].n[0], column 0) | 
 |                       //                   224    224..235 (o[0].n[0], column 1) | 
 |                       //                   240    240..251 (o[0].n[0], column 2) | 
 |                       //                   256    256..267 (o[0].n[1], column 0) | 
 |                       //                   272    272..283 (o[0].n[1], column 1) | 
 |                       //                   288    288..299 (o[0].n[1], column 2) | 
 |                       // 6/4     16   300  304    (pad end of o[0].n) | 
 |                       //  9      16   304  304    (pad end of o[0]) | 
 |                       //  3      16   304  304    304..315 (o[1].j) | 
 |                       //  2       8   316  320    320..327 (o[1].k) | 
 |                       //  4      16   328  336    336..347 (o[1].l[0]) | 
 |                       //                   352    352..355 (o[1].l[1]) | 
 |                       //  4      16   356  368    (pad end of o[1].l) | 
 |                       //  2       8   368  368    368..375 (o[1].m) | 
 |                       // 6/4     16   376  384    384..395 (o[1].n[0], column 0) | 
 |                       //                   400    400..411 (o[1].n[0], column 1) | 
 |                       //                   416    416..427 (o[1].n[0], column 2) | 
 |                       //                   432    432..443 (o[1].n[1], column 0) | 
 |                       //                   448    448..459 (o[1].n[1], column 1) | 
 |                       //                   464    464..475 (o[1].n[1], column 2) | 
 |                       // 6/4     16   476  480    (pad end of o[1].n) | 
 |                       //  9      16   480  480    (pad end of o[1]) | 
 |         } o[2]; | 
 |       }; | 
 |  | 
 |  | 
 | Issues | 
 |  | 
 |     (1) How are offsets to elements in a uniform buffer correlated to  | 
 |     uniform locations? | 
 |  | 
 |         Resolved: Traditional uniform locations were used in the glUniform | 
 |         API to access the private uniform storage.  This API does not allow | 
 |         the use of glUniform to update uniforms stored in uniform blocks. | 
 |         Instead it uses the various means to update buffer objects, and | 
 |         exposes the byte offsets of the uniforms in the buffer object. So, | 
 |         in short, uniform locations and uniform offsets are similar concepts | 
 |         but unrelated. | 
 |  | 
 |     (2) Should uniforms declared bindable be excluded from a uniform | 
 |     buffer? | 
 |  | 
 |         Resolved:  No, however, if a bindable uniform is declared inside | 
 |         a named uniform uniform block, the bindable declaration and all | 
 |         associated behavior of the bindable uniform extension will be | 
 |         superceded by the mechanisms defined in this extension to obtain | 
 |         information about the location of uniforms and to update the values | 
 |         of those uniforms. | 
 |  | 
 |         In other words, if the bindable modifier is used on a uniform declared | 
 |         within a named uniform block, it will be ignored. | 
 |  | 
 |     (3) Are there restrictions on the data types or the order in which uniforms | 
 |     are declared that are to be included as part of the uniform buffer? | 
 |  | 
 |         Resolved:  The only restriction is that sampler uniforms can not be | 
 |         stored in a uniform buffer object. All other uniform types can be | 
 |         stored in a uniform block. | 
 |  | 
 |     (4) Should a uniform buffer be split into multiple uniform buffers | 
 |     on a per data type basis to simplify the buffer offset interface ? | 
 |  | 
 |         Resolved: No.  This violates the intended "generic data store"  | 
 |         convention of buffer objects.  Users of this extension are free | 
 |         to group their uniform definitions on a per data-type basis in | 
 |         this manner and, indeed, it may, on some implementations, result | 
 |         in a more efficient uniform update model. | 
 |  | 
 |     (5) Should uniform buffers be scoped per shader (program | 
 |     stage) rather than per program (as in GLSL) ? | 
 |  | 
 |         Resolved:  No, this extension does not change the per-program | 
 |         scope of uniforms.  Uniforms in a uniform block, like traditional | 
 |         GLSL uniforms, are global to a program object. | 
 |          | 
 |         It's tricky because allowing uniforms to have per-stage scope | 
 |         exposes both a feature and the possibility for an application | 
 |         programming error. | 
 |          | 
 |         feature:  an application that wants to use a uniform "foo" in two | 
 |                   stages and wants uniform "foo" has different layouts | 
 |                   and/or values in each stage (or possibly simply does not | 
 |                   care if they do) | 
 |         vs. | 
 |          | 
 |         error: an application that wants to use a uniform "foo" in two | 
 |                stages and does not want them to have different values, but | 
 |                *accidentally* defines "foo" in each stage differently or | 
 |                binds different uniform buffers to each stage. | 
 |      | 
 |         Rather than enable this feature (and simultaneously add possibility | 
 |         for error) in this extension, we defer the choice to a future | 
 |         extension. | 
 |      | 
 |         Note however, some of the motivation for a per-stage scope for | 
 |         uniform names comes from a broader desire to augment the GLSL API | 
 |         with a set of per-stage program objects that do not need to be | 
 |         linked at all.  This is possibly a valuable addition to the GL API, | 
 |         but is left to be defined by an additional extension.  Such a future | 
 |         extension could, if desired, add syntax to the GLSL to allow any | 
 |         uniform (uniform block or default) to be defined with "per-stage" scope | 
 |         in a more comprehensive way. | 
 |      | 
 |  | 
 |     (6) Should AttachUniformBuffer take a <program> argument? | 
 |  | 
 |         This issue is moot.  Earlier versions of this extension included | 
 |         the additional ability to attach a uniform buffer object directly | 
 |         to a progam's uniform blocks instead of going through the per-context | 
 |         uniform buffer binding points. | 
 |          | 
 |         This feature has been deferred, possibly to be added in a future | 
 |         extension. | 
 |          | 
 |         If this routine were to be added and does not take a program | 
 |         argument, then it should work on the currently bound program | 
 |         object, and its name should be changed to | 
 |         ProgramUniformBuffer, to conform to precedent set by | 
 |         FramebufferTexture, et. all. | 
 |      | 
 |         Alternately, if AttachUniformBuffer requires a program | 
 |         argument, it would be for consistency with existing C API to | 
 |         GLSL (i.e., those that attach shaders to program objects and | 
 |         query program objects for information). | 
 |  | 
 |         RESOLUTION: RESOLVED, moot. | 
 |  | 
 |  | 
 |     (7) Should uniforms in a uniform block be identified by location or | 
 |     string? | 
 |  | 
 |         Resolved: By string and also by index (but not location).  Name | 
 |         strings will be used to identify uniforms much as they are | 
 |         today.  Uniform indices were available before for referring to | 
 |         uniforms because they provide a more efficient update mechanism | 
 |         to specify uniforms.  Uniform block indices have been used in | 
 |         this extension for the same reason. | 
 |          | 
 |         The location API not used by this extension and is only relevant for | 
 |         the glUniform* API. | 
 |      | 
 |         RESOLUTION: RESOLVED, moot. | 
 |  | 
 |  | 
 |     (8) What is the order of operations under which a uniform buffer | 
 |     association is made with a program (or shader)? | 
 |      | 
 |         It is known that at very least, that the uniform buffer | 
 |         offsets and strides will be known at link time.  Does the  | 
 |         uniform buffer need to be attached to the program prior to linking in  | 
 |         order to keep these offsets constant or can a uniform buffer be  | 
 |         bound to a program at any time post-link effectively acting as  | 
 |         substitute storage for the uniform data? | 
 |      | 
 |         RESOLVED:  Uniform buffer objects are bound to the context's | 
 |         uniform buffer binding points, and this can happen at any time.  | 
 |         However, the association of a program's uniform block to the context's | 
 |         uniform buffer binding points can only happen after linking because only | 
 |         then are uniform block indices known. | 
 |  | 
 |  | 
 |     (9) Can the existing Uniform API be used to update values in a  | 
 |     uniform buffer? | 
 |  | 
 |         Resolved: No.  The Uniform* API won't update values in a uniform buffer, | 
 |         which is reinforced by the fact that uniform block uniforms do not have | 
 |         a location. | 
 |  | 
 |  | 
 |     (10) When is the size of a uniform block's storage known? | 
 |      | 
 |         Resolved:  Only after linking. | 
 |          | 
 |         Once a program is linked, the storage needed for a given uniform | 
 |         block can be determined by querying for | 
 |         UNIFORM_BLOCK_DATA_SIZE. | 
 |  | 
 |         If a uniform block needs more storage than the buffer object | 
 |         bound to the associated uniform buffer binding point can provide, | 
 |         results are undefined.  This is no different than fetching off the end | 
 |         of an array. | 
 |          | 
 |  | 
 |     (11) Is it an error to call AttachUniformBuffer prior to | 
 |     linking the program designated by <program>? | 
 |  | 
 |         Resolved.  This issue is moot because the | 
 |         AttachUniformBuffer was removed/deferred to a future | 
 |         extension. | 
 |  | 
 |         But if this API were added, then yes. INVALID_VALUE is generated | 
 |         if AttachUniformBuffer is used to attach a buffer to an | 
 |         invalid uniform block index.  Prior to linking, there are no | 
 |         uniform block indices. | 
 |  | 
 |  | 
 |     (12) Some hardware does not support some of the GLSL data types  | 
 |     natively (bools or ints perhaps). What limitations do we have in  | 
 |     exposing the raw uniform data storage via the buffer object API ? | 
 |  | 
 |         Resolved:  None, but note that some implementations without | 
 |         native support for these data types may have to copy the data | 
 |         in these data types into some more native data types. | 
 |  | 
 |         Also, queries are provided to expose the layout of the buffer | 
 |         objects to allow the buffers to be packed properly. | 
 |   | 
 |  | 
 |     (13) Are there expected limitations for dead uniform elimination | 
 |     using this extension? | 
 |  | 
 |         Resolved:  yes. | 
 |  | 
 |         For starters, when using the "std140" layout, an implementation | 
 |         may not alter the storage layout in any way.  This limitation | 
 |         includes dead uniform elimination.  The standard layout must | 
 |         remain unchanged because an application will depend on it | 
 |         rather than querying for uniform offsets/strides. | 
 |  | 
 |         When using the "shared" layout, dead uniform elimination is again | 
 |         excluded because different uniforms could be eliminated based on | 
 |         different shaders' uniform usage.  In order to preserve shareability | 
 |         of the uniform blocks, the full contingent of uniforms must remain. | 
 |  | 
 |         For the "packed" layout, an implementation may take the liberty of | 
 |         eliminating uniforms and uniform blocks that are not used by the paired | 
 |         shaders.  Here, limitations exist only for arrays.  Dead elements may be | 
 |         stripped from the end of an array that is never dynamically | 
 |         dereferenced.  An application must query UNIFORM_SIZE before | 
 |         loading array data into the uniform buffer to ensure that trailing | 
 |         elements exist. | 
 |  | 
 |         Issue (24) deals with stripping leading elements from an array, and | 
 |         issue (25) deals with stripping arbitrary elements from an array, | 
 |         both of which are currently disallowed. | 
 |  | 
 |         Note that the default uniform block always exists even if it is empty. | 
 |  | 
 |  | 
 |     (14) Is it necessary to provide array uniform element offsets into | 
 |     a uniform buffer object?  If so, this suggests string parsing | 
 |     of things such as "myuniform[12]".  If not, this assumes array | 
 |     strides be guaranteed based on array data type for all hw platforms? | 
 |  | 
 |         Resolved: No.  The stride is provided explictly by querying | 
 |         UNIFORM_ARRAY_STRIDE with GetActiveUniformsiv. | 
 |  | 
 |  | 
 |     (15) How are the values from static initializer values propagated  | 
 |     to a buffer object once it is attached? | 
 |  | 
 |         Resolved:  Static initialization values declared in a shader mapped | 
 |         to a uniform buffer are disallowed by the grammar and must be | 
 |         established through writes to the uniform buffer. | 
 |  | 
 |      | 
 |     (16) Is GetUniformBlockIndex needed?  This information can be | 
 |     obtained (in reverse mapping) from GetActiveUniformBlock. | 
 |  | 
 |         Resolved: Yes.  GetUniformBlockIndex allows the uniform | 
 |         block database to be queried in the most natural manner: step 1) | 
 |         do the expensive conversion from a uniform block name to a | 
 |         uniform block index, step 2) use the uniform block index to | 
 |         obtain all other uniform block data, which is a simple array | 
 |         dereference, not a search. | 
 |  | 
 |  | 
 |     (17) is GetUniformIndex needed?  This information can be obtained (in | 
 |     reverse mapping) from GetActiveUniform. | 
 |  | 
 |         Resolved: Yes.  See issue (16). | 
 |  | 
 |  | 
 |     (18) Should we add a separate function GetActiveUniformBlockBufferSize | 
 |     instead of using GetActiveUniformBlock to return everything. | 
 |  | 
 |         Resolved: No.  This issue became moot when the more general function | 
 |         GetActiveUniformBlockiv was added. | 
 |  | 
 |  | 
 |     (19) Should we provide a mechanism for iterating over the uniforms in a | 
 |     particular uniform block? | 
 |  | 
 |         Resolved: Yes.  This is provided by querying | 
 |         UNIFORM_BLOCK_ACTIVE_UNIFORMS with GetActiveUniformBlockiv. | 
 |  | 
 |  | 
 |     (20) Should we provide a means for the application to query the desired | 
 |     storage format for integers, booleans, and matrices, or should we specify | 
 |     a format and force non-conforming implementations to do a conversion? | 
 |  | 
 |         RESOLUTION: No queries will be introduced. Implementations that cannot | 
 |         handle the prescribed storage formats must convert as necessary. | 
 |          | 
 |         See also issue (48) | 
 |  | 
 |  | 
 |     (21) Should we delete the integer and boolean storage types in favor of | 
 |     implementation repacking of the data when the hardware doesn't support it? | 
 |  | 
 |         RESOLUTION: RESOLVED, no. | 
 |  | 
 |         Hardware that doesn't support the types must repack the uniform data | 
 |         if needed.  This is true for all layout options. | 
 |  | 
 |  | 
 |     (22) How does the program notice new changes to the uniform buffer object? | 
 |      | 
 |         Should we add a new "UpdateUniforms()" call or use | 
 |         AttachUniformBuffer(), or UseProgram() to realize changes. | 
 |  | 
 |         RESOLUTION: Following the "standard" way in which object changes are | 
 |         noticed, the buffer object in question must be re-bound or | 
 |         re-attached if the changes to the buffer object come from another | 
 |         context. | 
 |          | 
 |         If the changes come from this context, then the intent is to | 
 |         follow the general object model decision here that governs how | 
 |         child/container object state changes are made. | 
 |          | 
 |         [Currently, this means that changes by this context will be | 
 |         noticed at next draw time, at the latest]. | 
 |      | 
 |  | 
 |     (23) The naming convention choosen for GetActiveUniformsiv and | 
 |     GetActivePartitionsiv is not a simple matter. | 
 |  | 
 |         First, considering that the list of uniforms passed into these | 
 |         routines must be active uniform indices, and is an error if not, | 
 |         suggests that the name "Active" in these function calls is | 
 |         redundant.  GLSL established a precedent of using "Active" in | 
 |         the names of functions that require their uniform parameters to | 
 |         consist solely of active uniforms.  For these routines, it is an | 
 |         error to include an inactive uniform as one of their input | 
 |         parameters.  Consistency with this GLSL precedent is the reason | 
 |         we've choosen to include "Active" in these routine names. | 
 |  | 
 |         Second, note that GetActiveUniformsiv does not "get active | 
 |         uniforms" and GetActiveUniformBlocksiv does not "get active | 
 |         uniform blocks".  There is a compelling argument therefore that | 
 |         these names are counterintuitive. In reality, these routines | 
 |         return parameters of active uniforms and active uniform blocks | 
 |         rather than the uniforms or uniform blocks themselves.  Again, | 
 |         looking back at GLSL precedent note the conventions used for | 
 |         both GetProgramiv and GetShaderiv.  Both of these routines have | 
 |         a <pname> argument and both of these routines are in fact | 
 |         returning parameters of programs and shaders respectively | 
 |         however "Parameters" was not included in the name. | 
 |  | 
 |         Further challenging this second point are two other | 
 |         considerations. First, the GL spec prior to GLSL does in fact | 
 |         use "Parameters" in the name of functions that match this | 
 |         pattern.  Second, this spec itself includes the name of the | 
 |         output parameter in the name (specifically calls to get Indices | 
 |         and Names). | 
 |  | 
 |         In the end, because this specification has to work within the | 
 |         GLSL framework, it was decided that this precendent should | 
 |         prevail over all others.  Therefore, these routines will not | 
 |         include "Parameters" in their names. | 
 |  | 
 |         Resolved: See above. | 
 |  | 
 |  | 
 |     (24) Do we need to be able to query UNIFORM_START to get the index of | 
 |     the first active element of an array? | 
 |  | 
 |         An application must query UNIFORM_SIZE to find the extent of an | 
 |         array at runtime because the GLSL compiler may have eliminated elements | 
 |         from the end of a static array during dead code elimination.  If the | 
 |         application is not required to similarly query UNIFORM_START, the | 
 |         compiler must be prevented from eliminating elements from the start of | 
 |         an array. | 
 |      | 
 |         For example, if an application declares "uniform float myFloat[10];" and | 
 |         accesses only the single element myFloat[7] in the shader text, the | 
 |         compiler may eliminate elements 8-9 only.  Querying UNIFORM_SIZE | 
 |         will give 8, and UNIFORM_OFFSET will give the offset of element 0. | 
 |      | 
 |         If we add UNIFORM_START, in this example, querying | 
 |         UNIFORM_SIZE will give 1, UNIFORM_START will give 7, and | 
 |         UNIFORM_OFFSET will give the offset of element 7 in the uniform | 
 |         buffer. | 
 |      | 
 |         Purely for symmetry, it seems that the compiler should be as free to | 
 |         strip leading elements as it is to strip trailing elements. | 
 |          | 
 |         After additional discussions, however, the working group decided | 
 |         not to introduce this complexity.  This feature could be layered | 
 |         as an additional extension if desired. | 
 |      | 
 |         RESOLUTION: RESOLVED | 
 |  | 
 |  | 
 |     (25) Following issue (24), should we provide a mechanism to allow the | 
 |     compiler to strip *any* dead elements from a uniform array without | 
 |     restriction, not just leading and trailing elements? | 
 |  | 
 |         Resolved: No.  Too cumbersome for the application to use. | 
 |  | 
 |  | 
 |     (26) Should we make any guarantees about the ordering of uniforms in the | 
 |     active uniform array, relative to their uniform block number? | 
 |      | 
 |         It might be useful to guarantee that the ordering of the | 
 |         uniforms in the active uniform array is such that all uniforms | 
 |         in a single uniform block form a contiguous subrange of the | 
 |         active uniform array. | 
 |      | 
 |         On the other hand, just knowing the order is probably not enough | 
 |         since you need to know offsets/strides, packing, etc. | 
 |      | 
 |         This extension provides uniform block-based uniform updates.  | 
 |         This level of organization is efficient and requires no further | 
 |         augmentation as this issue suggests. | 
 |  | 
 |         RESOLUTION: RESOLVED, no | 
 |      | 
 |  | 
 |     (27) What is the difference between | 
 |     MAX_LOGICAL_UNIFORM_BUFFERS and | 
 |     MAX_COMBINED_UNIFORM_BUFFERS? | 
 |  | 
 |         MAX_LOGICAL_UNIFORM_BUFFERS is the maximum number of | 
 |         uniform buffer binding points on the context. | 
 |         MAX_COMBINED_UNIFORM_BUFFERS is the maximum number of | 
 |         uniform buffers that any one program can use at one time. | 
 |  | 
 |         Note, see issue (46) for a related issue with textures. | 
 |  | 
 |         RESOLUTION: RESOLVED | 
 |  | 
 |  | 
 |     (28) Should we have versions of GetActiveUniforms and GetActiveUniformBlocks | 
 |     that return intptr types so a cast is not required. | 
 |  | 
 |         No.  Another extension can add them, and they have no real | 
 |         utility at this time except causing the app to allocate twice as much | 
 |         storage to store values that can't exceed 32 bits. | 
 |  | 
 |         RESOLUTION: RESOLVED, No. | 
 |  | 
 |  | 
 |     (29) Transform feedback writes primitive information to a buffer object | 
 |     tightly arranged and in accordance with the size of the attributes | 
 |     designated for transform feedback (or varyings thereof).  If uniform | 
 |     buffers are to leverage data supplied from the transform feedback | 
 |     operation, yet uniforms are not guaranteed to be tightly packed, how | 
 |     can one reasonably use transform feedback to populate uniform | 
 |     buffers? | 
 |      | 
 |         DISCUSSION:  As it stands, existing implementations pack uniform | 
 |         definitions on 16 byte boundaries, 4 byte boundaries or are tightly | 
 |         packed.  If this is known for a given implementation, uniform | 
 |         declarations could of course be made such that they lined up on these | 
 |         boundaries. However, without a dedicated queryable interface in the GL | 
 |         C API, there is no way to guarantee the portability of this logic. | 
 |      | 
 |         RESOLUTION: resolved, compatibility with XFB output is only guaranteed | 
 |         for vec4 types in a "std140" layout uniform block: | 
 |          | 
 |         In order to facilitate the read-only nature of uniform and | 
 |         transform feedback data formatting, we've added to this | 
 |         specification a uniform buffer "std140" layout qualifier guarantee of | 
 |         vec4 types being tightly packed.  This layout guarantee will provide | 
 |         portability of applications that wish to use transform feedback in | 
 |         conjunction with uniform buffers as they can simply rely on this | 
 |         data arrangement, declaring their uniforms accordingly, to allow | 
 |         ARB_uniform_buffer_object and EXT_transform_feedback to | 
 |         interoperate. | 
 |      | 
 |  | 
 |     (30) Should the "active" keyword in shader text be declared per uniform or | 
 |     per uniform block ? | 
 |  | 
 |         Note, this issue is mostly moot, as we've decided to use a | 
 |         different syntax in the GLSL.  Earlier versions of this spec | 
 |         leveraged the concept of 'active' uniforms from GLSL that were | 
 |         defined with the initial GLSL API. | 
 |          | 
 |         The discussion that follows pertains to a feature where the user can | 
 |         declare uniforms and uniform blocks as active explicitly. | 
 |  | 
 |         DISCUSSION:  Declaring a uniform active has the advantages of simplicity | 
 |         and little additional spec language to describe behavior.  When a  | 
 |         uniform is declared active, all of its members are considered active | 
 |         (for structs and arrays) and therefore the arrangement of the data in | 
 |         that uniform can be guaranteed to be consistent.  Consistency of this | 
 |         uniform data arrangement can be used to share the uniform across muliple  | 
 |         programs without worrying about dead code elimination changing the | 
 |         offsets and strides of uniform data. | 
 |      | 
 |         Declaring uniform blocks active has some of the advantages that were | 
 |         primary motivating factors for this specficiation being written.   | 
 |         Namely, that uniforms did not have to be aggregated into structures in | 
 |         order to update them efficiently.  In this case, uniforms don't have to | 
 |         be aggregated into structs in order to share them easily.  Another | 
 |         advantage is the logical distinction of a group of shared uniforms that | 
 |         is analogous to how the uniform buffer object, also a shared entity, | 
 |         that backs them. | 
 |      | 
 |         If a uniform uniform block is declared active, all uniforms therein are | 
 |         considered active.  It is presumed under this model, that an advisable | 
 |         usage pattern would be to gather the declaration of shared uniforms of | 
 |         multiple shaders into an atomic shader source call.  Then each | 
 |         individual shader would carry declarations of uniforms unique to | 
 |         themselves.   | 
 |      | 
 |         GLSL allows piecewise declaration of uniforms in multiple modules in a | 
 |         program.  Piecewise declaration of shared uniform blocks carries with it | 
 |         some difficulties because missing pieces can change the layout of the | 
 |         uniform block. | 
 |      | 
 |             A) Should we disallow piecewise construction of uniform blocks  | 
 |             declared active by setting a compile time error if this is | 
 |             attempted ? | 
 |      | 
 |             RESOLVED: Yes, piecewise construction of uniform blocks will be | 
 |             allowed. | 
 |      | 
 |         Proposal for active uniform block demarcation:   | 
 |      | 
 |         Active uniform blocks are declared as followed: | 
 |      | 
 |         active uniform block foo; | 
 |      | 
 |         uniform <type> a; | 
 |         uniform <type> b; | 
 |         uniform <type> c; | 
 |      | 
 |         uniform block; | 
 |      | 
 |         The first uniform block delimiter names the uniform block.  The second | 
 |         uniform block, with no name argument, terminates the "foo" uniform block  | 
 |         and indicates that any subsequent uniform definition will be part of the | 
 |         default uniform block. | 
 |      | 
 |         Subsequent declarations referring to uniform block "foo" augment the | 
 |         contents of the uniform block.  These subsequent declarations, of  | 
 |         course, can appear within the same shader or within other shader sources  | 
 |         in the same program. | 
 |      | 
 |         This aggregation mechanism, and the use of piece-wise definitions of | 
 |         uniform blocks, has sharing implications. | 
 |      | 
 |         Considering the following example: | 
 |      | 
 |         ***************************** | 
 |         PROGRAM A Text: | 
 |      | 
 |         active uniform block foo; | 
 |      | 
 |         uniform <type> a; | 
 |         uniform <type> b; | 
 |      | 
 |         uniform block; | 
 |      | 
 |      | 
 |         ***************************** | 
 |         PROGRAM B Text: | 
 |      | 
 |         active uniform block foo; | 
 |      | 
 |         uniform <type> b; | 
 |         uniform <type> a; | 
 |      | 
 |         uniform block; | 
 |      | 
 |         ... some place later in the program text | 
 |      | 
 |         active uniform block foo; | 
 |      | 
 |         uniform <type> e; | 
 |         uniform <type> d; | 
 |      | 
 |         uniform block; | 
 |         ***************************** | 
 |      | 
 |         Both the order and the number of uniforms in the aggregate definition of | 
 |         'foo' in program B must be considered for sharing the uniform buffer | 
 |         backing A & B corresponding to uniform block 'foo'. | 
 |      | 
 |         First, order.  To avoid potential confusion with order of declarations | 
 |         of uniforms, all uniforms declared in a uniform block will be sorted in | 
 |         an implementation defined manner.  By doing so, the implementation will | 
 |         allow sharing of uniform buffers with identical uniform declarations by | 
 |         name, type and number, but arranged in different orders. | 
 |      | 
 |         Second, mismatches in declarations of uniforms within 'foo' between two | 
 |         different programs.  Because uniforms are sorted, partial matches of | 
 |         uniform declarations within uniform blocks are not guaranteed to have | 
 |         the same offsets when the buffer is bound to different programs.  In our  | 
 |         example, there are no guarantees that the offset of uniform 'a' and the | 
 |         offset of uniform 'b' would be the same in uniform block foo of program | 
 |         'A' when compared to program 'B'.  Applications must therefore use care | 
 |         when attempting to share uniform buffers between multiple programs | 
 |         because any mismatch in uniform name or type or the number of uniforms | 
 |         themselves between uniform block declarations will result in offsets | 
 |         without correlation and application errors should be expected if any | 
 |         assumptions about these offsets is made otherwise. | 
 |      | 
 |         This sharing behavior if of particular significance when defining | 
 |         shaders as it suggests that the shaders themselves, if they choose to | 
 |         define uniform blocks piecewise across given program text.  This sharing | 
 |         model suggests defining all uniform uniform blocks that are expected to | 
 |         be shared as standalone shader text definitions to logically segragate | 
 |         them from uniform block declarations that can be changed in a piecewise | 
 |         fashion.  In this manner, the logically separated shared uniform uniform | 
 |         block can be handled as a distinct ShaderSource call and effectively act | 
 |         as a header file where the uniform block definition is guaranteed to be | 
 |         the same when used in multiple programs thus allowing sharing and | 
 |         consistent offsets. | 
 |      | 
 |         RESOLUTION: RESOLVED | 
 |      | 
 |         Partitions, uniforms, and varyings can all have the "active" keyword | 
 |         applied to them.  See rules q - t in the rules and concepts list | 
 |         following the opening summary to this spec. | 
 |      | 
 |         The resolution of issue (34) to use struct-like syntax for uniform block  | 
 |         definition closes the issue on piecewise definition of uniform blocks | 
 |         discussed above. | 
 |  | 
 |  | 
 |     (31) ActiveVaryingNV() uses the GL C API to declare a varying active in  | 
 |     contrast to declaring uniforms/uniform uniform blocks active as suggested in | 
 |     this specification.  Is this inconsistency a concern ? | 
 |  | 
 |         RESOLUTION: RESOLVED, moot. | 
 |  | 
 |         Earlier versions of this spec declared uniforms and uniform blocks | 
 |         as active, and optionally extended this to varyings as well. | 
 |          | 
 |         Later versions of this spec deferred this concept out of the extension. | 
 |      | 
 |         The declaring a varying as active via function call requires | 
 |         that this call is made prior to link time and that it identifies | 
 |         the varying using a name string.  It is more efficient to manage | 
 |         program resources using indices and is better in terms of | 
 |         locality of reference to make 'active' declarations in program | 
 |         text.  We should consider whether we might want to add this back | 
 |         in in a future extension. | 
 |  | 
 |  | 
 |     (32) GetVaryingLocationNV() returns -1 if the designated name doesn't | 
 |     exist.  Should we return -1 rather than a special purposed token if a | 
 |     uniform name doesn't exist to follow this precedent ? | 
 |  | 
 |         RESOLUTION: RESOLVED | 
 |      | 
 |         This specification uses indices which are unsigned integers and | 
 |         therefore our unsigned value of 0xFFFFFFFF is not called "-1" | 
 |         but acts effectively the same on platforms where GLint is | 
 |         32-bit twos-complement. | 
 |          | 
 |         Also note, uniform (and varying locations) are signed which | 
 |         allows them to use -1 as a signifier, but uniform (and uniform | 
 |         block) indices are unsigned because they are used to iterate | 
 |         through uniforms (and uniform blocks). | 
 |  | 
 |  | 
 |     (33) Which uniform buffer object commands must be excluded from display | 
 |     lists? | 
 |  | 
 |         RESOLUTION:  Resolved | 
 |  | 
 |         When used with 3.1 (where display lists have been removed | 
 |         altogether) obviously, this question is moot. | 
 |          | 
 |         For GL 2.0/3.0, this should be resolved with the following | 
 |         precedents: | 
 |          | 
 |         BindUniformBlock should follow the precedent of BindBufferRange, | 
 |         which does not get included in display lists. | 
 |  | 
 |         UniformBlockBinding should follow the precedent of glUniform (for | 
 |         setting samplers) which *does* get included in display lists. | 
 |          | 
 |         Note, the GL 2.1 spec says (p.244, section 5.4) that "GL | 
 |         commands that source data from buffer objects dereference the | 
 |         buffer object data in question at display list compile time, | 
 |         rather than encoding the buffer ID and buffer offset into the | 
 |         display list. Only GL commands that are executed immediately, | 
 |         rather than being compiled into a display list, are permitted to | 
 |         use a buffer object as a data sink." | 
 |          | 
 |         The same rules would affect uniform blocks sourcing data from | 
 |         buffer objects. | 
 |          | 
 |         So this basically means that only BindUniformBlock is excluded, | 
 |         (since all queries are already excluded), however see issue (55). | 
 |          | 
 |         Since we use the BindBufferRange API introduced by OpenGL 3.0, and | 
 |         those routines are already excluded, there's no additions to the | 
 |         display list exclusion list needed. | 
 |  | 
 |  | 
 |     (34) What should the syntax of uniform block demarcation be ? | 
 |  | 
 |         DISCUSSION: The two following syntaxes were considered: | 
 |      | 
 |         uniform block foo; | 
 |      | 
 |         uniform <type> a; | 
 |         uniform <type> b; | 
 |      | 
 |         uniform block; | 
 |      | 
 |         In this example, the "uniform block" keyword both opens and closes the | 
 |         uniform block. | 
 |      | 
 |         Second, a struct-like syntax: | 
 |          | 
 |             uniform myUniformBlock | 
 |             { | 
 |                 int a; | 
 |                 vec4 b; | 
 |             };   | 
 |          | 
 |         and | 
 |          | 
 |             packed uniform myUniformBlock | 
 |             { | 
 |                 int a; | 
 |                 vec4 b; | 
 |             };   | 
 |         | 
 |         where "packed" means that the uniform block might be optimized by the | 
 |         compiler to eliminate/re-order uniforms. | 
 |          | 
 |         This is functionally equivalent to the current uniform block | 
 |         syntax in this spec. | 
 |      | 
 |         RESOLUTION:  RESOLVED, using the "struct-like" syntax above. | 
 |  | 
 |  | 
 |     (35) Should UBOs be bound to context binding points rather than to | 
 |     programs themselves ? | 
 |  | 
 |         DISCUSSION: | 
 |      | 
 |         Attaching UBOs to programs versus the context has the following | 
 |         advantages: | 
 |      | 
 |             UBOs and programs have natural encapsulation boundaries that | 
 |             fit with the conventions of object-oriented design | 
 |             programming. | 
 |      | 
 |         Alternately, binding UBOs to the context has the following advantages: | 
 |      | 
 |             Migration to the possible program environment object design | 
 |             expected in future versions of OpenGL will be handled more | 
 |             easily and won't require a semantics change because these | 
 |             context bindings will all be moved collectively to the PEO | 
 |             and UBO attachments will not have to be handled as a | 
 |             "special case" item. | 
 |          | 
 |         If we support per-context per-stage bindings, then we'll need the | 
 |         following additions to this extension: | 
 |          | 
 |             - a set number of binding points on the context for each stage | 
 |               (vertex/fragment/geometry) | 
 |                 VERTEX_SHADER_BINDING_0..n | 
 |                 GEOMETRY_SHADER_BINDING_0..n | 
 |                 FRAGMENT_SHADER_BINDING_0..n | 
 |                  | 
 |               or alternately, a unified set of per context bindings  | 
 |                 SHADER_BINDING_0..n | 
 |  | 
 |             - a new routine to bind a UBO to a per-stage context binding point | 
 |                 BindUniformBuffer(enum target, uint uniformBlockIndex, | 
 |                                      uint buffer); | 
 |      | 
 |             - a new routine that defines the mapping of a uniform block name | 
 |             string to a per-stage binding point index | 
 |                 void UniformBlockBinding(uint program, uint unit, | 
 |                     const char* name); | 
 |  | 
 |  | 
 |         RESOLUTION: RESOLVED,  | 
 |          | 
 |         Note per-context and per-program bindings serve two distinct use cases. | 
 |          | 
 |         Per-context:  assumes that there is generally many to one mapping | 
 |         between programs and given set of uniform buffers. | 
 |      | 
 |         Per-program:  assumes that there is a one to one mapping between | 
 |         programs and a given set of uniform buffers. | 
 |      | 
 |         The original ARB "assembly-language" programming extensions serviced | 
 |         both use cases (with "program locals" and "program environment" | 
 |         parameters). | 
 |      | 
 |         The GLSL programming API dropped the "program environment" / | 
 |         per-context storage of uniforms in favor of per-program only storage | 
 |         for uniforms. | 
 |      | 
 |         This API currently supports only the context binding model, but | 
 |         a future extension could add the per-program-object bindings if | 
 |         desired. | 
 |         | 
 |  | 
 |     (36) How is the query for MAX_{FRAGMENT|VERTEX}_UNIFORM_COMPONENTS | 
 |     affected by UBOs? | 
 |      | 
 |         DISCUSSION:  MAX_{FRAGMENT|VERTEX}_UNIFORM_COMPONENTS traditionally | 
 |         referred to the limited amount of dedicated (often register based, | 
 |         sometimes per-stage) uniform storage.  For implementations that | 
 |         support directly reading uniforms from arbitrary memory, the limit | 
 |         on uniform storage is generally not quantified by a single number of | 
 |         uniforms.  Instead it is quantified by two numbers: the number of | 
 |         separate buffers that can be read at one time (per stage), and the | 
 |         sizes of one of those buffers. | 
 |      | 
 |         On the other hand for implementations that wish to support this | 
 |         extension but that still have this limited amount of dedicated | 
 |         uniform storage this single MAX_{FRAGMENT|VERTEX}_UNIFORM_COMPONENTS | 
 |         value is still valid. | 
 |      | 
 |         RESOLUTION: Resolved, as follows: | 
 |  | 
 |         We added a new set of integer implementation-dependent queries, named | 
 |         MAX_COMBINED_{VERTEX|GEOMETRY|FRAGMENT}_UNIFORM_COMPONENTS. These | 
 |         would indicate the maximum total number of uniforms available between | 
 |         the default uniform block and all uniform blocks. For this ARB version | 
 |         of the extension, the minimum maximum would be  | 
 |         MAX_{VERTEX|GEOMETRY|FRAGMENT}_UNIFORM_COMPONENTS. For the 3.1 core | 
 |         version, the minimum maximum would be larger: | 
 |         MAX_{VERTEX|GEOMETRY|FRAGMENT}_UNIFORM_BLOCKS * MAX_UNIFORM_BLOCK_SIZE + | 
 |         MAX_{VERTEX|GEOMETRY|FRAGMENT}_UNIFORM_COMPONENTS. | 
 |  | 
 |          | 
 |     (37) Do we need  MAX_{VERTEX|GEOMETRY|FRAGMENT}_UNIFORM_BUFFERS | 
 |     or can we merge these into a single value MAX_UNIFORM_BUFFERS that | 
 |     is the same for the 3 stages? | 
 |      | 
 |         DISCUSSION: | 
 |          | 
 |         3 separate queries is needed only if we think implementations would have | 
 |         different values for each stage. | 
 |      | 
 |         RESOLUTION: currently 3 queries, plus a "combined" query. | 
 |          | 
 |  | 
 |     (38) What's the deal with UniformBlockBinding()?  How does it | 
 |     work?  What is it for? | 
 |  | 
 |         DISCUSSION: | 
 |          | 
 |         UniformBlockBinding can be defined in two different ways, depending on | 
 |         the precedent we'd like to use. | 
 |          | 
 |         It can either be similar to a uniform sampler (i.e., an indirection | 
 |         table that can choose a particular buffer to use after linking), or | 
 |         an attribute location (i.e., an indirection table that can choose a | 
 |         particular buffer to use PRIOR to linking). | 
 |      | 
 |         The current API chooses the former precedent (i.e., uniform | 
 |         samplers), and as a result, UniformBlockBinding can be called (in | 
 |         fact, must be called) after linking the program. | 
 |      | 
 |         If we desired to change this behavior, we'd need to modify | 
 |         UniformBlockBinding to take a uniform block *name* intead of *index*, | 
 |         because a uniform block index is only defined post-link. | 
 |      | 
 |         This is workable, but slightly less flexible for the developer, at | 
 |         the cost of an indirection. | 
 |          | 
 |         RESOLUTION: Use the "sampler" precedent, UniformBlockBinding is | 
 |         called post link. | 
 |  | 
 |  | 
 |     (39) Does the matrix packing need to be "per program" state or "per | 
 |     implementation" state? | 
 |      | 
 |         DISCUSSION: | 
 |          | 
 |         Is the choice of matrix packing really "per program"?  If not, | 
 |         should we just use the per-context queries for this information? The | 
 |         former might be useful if we intend to expose some kind of | 
 |         per-program packing control in the shading language or API. If we | 
 |         don't, then the latter might be simpler. | 
 |          | 
 |         Or do we think we might go further and make this per-uniform state | 
 |         in the future? if so, then the current per-program query is also | 
 |         insufficient. | 
 |          | 
 |         After discussion with the working group, queries for | 
 |         matrix (and all other uniform layout) will be per-uniform, not | 
 |         per program, so these routines have been removed. | 
 |  | 
 |         RESOLUTION: Resolved, this issue is moot.   | 
 |  | 
 |  | 
 |     (40) Are uniform block indices assumed to be "tightly packed"? | 
 |      | 
 |         Yes, an implementation will assign consecutive indices to  | 
 |         active uniform blocks, starting with zero.  | 
 |  | 
 |         Note that there is no prescribed ordering in which indices must be | 
 |         assigned. In other words, which uniform block indices are assigned to | 
 |         which uniform blocks is an implementation choice. An application must | 
 |         call GetUniformBlockIndex to find the mapping. | 
 |          | 
 |         RESOLUTION: Resolved, yes. | 
 |  | 
 |  | 
 |     (41) Is "uniform block" the right name? | 
 |  | 
 |         The GLSL group considered many names here:  "uniform blocks", | 
 |         "commons", "uniform groups", etc.  Regardless of what the GLSL | 
 |         calls these groupings, we need *some name* that we can describe | 
 |         in the API spec and in the API names.  Currently we use "uniform | 
 |         block" for this, and the API seems to make sense, but could | 
 |         change if someone has a better name. | 
 |      | 
 |         RESOLUTION: RESOLVED, yes. | 
 |      | 
 |  | 
 |     (42) Should there be an "offset" for the base of the ubo so that an | 
 |     application can use collections uniforms within a buffer object? | 
 |      | 
 |         DISCUSSION: | 
 |          | 
 |         If we do this, we'd need an additional/augmented version of | 
 |         BindUniformBuffer that takes an offset, and a queriable required | 
 |         alignment for the offset.  See also issue 55. | 
 |  | 
 |         Currently, we do now support this offset (via BindBufferRange) and an | 
 |         alignment query (UNIFORM_BUFFER_OFFSET_ALIGNMENT).  The offset | 
 |         is per-context binding point state.  We probably want to pick up | 
 |         UNIFORM_BUFFER_START and UNIFORM_BUFFER_SIZE queries, too.  See issue | 
 |         (65) to track whether we add these. | 
 |  | 
 |         RESOLUTION: Resolved, there should be an offset for the base of a | 
 |         uniform block within a UBO.  If an implementation can not support | 
 |         non-zero offsets, they can set UNIFORM_BUFFER_OFFSET_ALIGNMENT | 
 |         to a sufficiently large value. | 
 |  | 
 |  | 
 |     (43) Do we need the versions of the uniform queries that query the | 
 |     GL for the properties/names of multiple uniforms at one time?  Or | 
 |     can we simplify those apis to only query for the property/name of | 
 |     one uniform at a time? | 
 |      | 
 |         DISCUSSION:  The multiquery apis are useful for getting lists of | 
 |         uniform data at once, but are more complicated (require arrays of | 
 |         pointers to output values). | 
 |      | 
 |         Do we need these? | 
 |      | 
 |         RESOLUTION: Resolved, we'll replace GetActiveUniformNames with | 
 |         GetActiveUniformName, but keep the rest which have solid use | 
 |         cases. | 
 |  | 
 |  | 
 |     (44) What is the default value for UNIFORM_BLOCK_BINDING? | 
 |  | 
 |         Having the default values be set equal to the uniform block index at | 
 |         link time would be convenient.  This would make it unnecessary | 
 |         for apps to call glUniformBlockBinding unless they wanted a | 
 |         non-default mapping. | 
 |  | 
 |         After some discussion, using texture samplers as precedent, then | 
 |         the default value should be zero. | 
 |  | 
 |         RESOLUTION.  Resolved, default value is zero. | 
 |  | 
 |  | 
 |     (45) What is the default value of UNIFORM_BLOCK_BUFFER_BINDING? | 
 |      | 
 |         This is moot without the AttachUniformBuffer API. This was the | 
 |         query for the uniform buffer object bound directly to a uniform | 
 |         block in the program object. | 
 |          | 
 |         If we add this API in a future extension, it seems it should be | 
 |         zero. We would need for the spec to state the precedence of | 
 |         program attachments over context attachments.  I.e., if the | 
 |         value of UNIFORM_BLOCK_BUFFER_BINDING is non-zero, then | 
 |         the backing for that uniform block comes from the specified | 
 |         uniform block uniform buffer binding, otherwise it comes from | 
 |         the  unit binding, and hence from the context that is currently | 
 |         using the program. | 
 |      | 
 |         RESOLUTION.  RESOLVED, moot. | 
 |  | 
 |  | 
 |     (46) How do the logical/combined maximums for UBOs and textures | 
 |          relate to each other? | 
 |      | 
 |         Textures have these queries: | 
 |          | 
 |             MAX_TEXTURE_IMAGE_UNITS | 
 |                 maximum textures that can be used by the fragment stage. | 
 |  | 
 |             MAX_COMBINED_TEXTURE_IMAGE_UNITS | 
 |                 maximum textures that can be used by all program stages | 
 |                 at once. | 
 |              | 
 |         Ideally, MAX_TEXTURE_IMAGE_UNITS would be called | 
 |         "MAX_FRAGMENT_TEXTURE_IMAGE_UNITS" | 
 |  | 
 |         Also, most implementations use MAX_TEXTURE_IMAGE_UNITS to define | 
 |         the number of per-context binding points for textures, though | 
 |         technically, there's no requirement that the number of context | 
 |         binding points is equal to the number of fragment textures. | 
 |  | 
 |         For instance, if an implementation had the ability to use more | 
 |         vertex or geometry textures than fragment textures, then this | 
 |         scheme would break down because there would not be enough | 
 |         context binding points for these other stages. | 
 |  | 
 |         This spec tries to avoid this problem with the following queries: | 
 |          | 
 |             MAX_VERTEX_UNIFORM_BLOCKS | 
 |             MAX_GEOMETRY_UNIFORM_BLOCKS | 
 |             MAX_FRAGMENT_UNIFORM_BLOCKS | 
 |             MAX_COMBINED_UNIFORM_BLOCKS  (much like "combined" for textures) | 
 |             MAX_UNIFORM_BUFFER_BINDINGS  (# UBO binding points on context) | 
 |              | 
 |         For symmetry, we'd recommend that we make a similar update to textures | 
 |         in the 3.1 spec: | 
 |  | 
 |             MAX_FRAGMENT_SAMPLERS      (= old MAX_TEXTURE_IMAGE_UNITS) | 
 |             MAX_GEOMETRY_SAMPLERS      (= old MAX_GEOMETRY_TEXTURE_IMAGE_UNITS) | 
 |             MAX_VERTEX_SAMPLERS        (= old MAX_VERTEX_TEXTURE_IMAGE_UNITS) | 
 |             MAX_COMBINED_SAMPLERS      (= old MAX_COMBINED_TEXTURE_IMAGE_UNITS) | 
 |             MAX_TEXTURE_IMAGE_BINDINGS (# texture binding points on context) | 
 |  | 
 |         RESOLUTION: Resolved.  The texture token name changes should be made | 
 |         in the 3.1 API spec, deprecating the old names. | 
 |  | 
 |  | 
 |     (47)  Is using a keyword to specify packed/shared/std140 the best way  | 
 |     to manage uniform block packing?  What do they mean anyway? | 
 |      | 
 |         DISCUSSION: | 
 |          | 
 |         There are 3 use cases of interest: | 
 |          | 
 |         "packed" | 
 |  | 
 |             - implementation may optimize the layout to remove inactive | 
 |               uniforms and otherwise restructure the layout for | 
 |               efficiency. | 
 |  | 
 |             - application must query the GL for the uniform block layout | 
 |          | 
 |         "shared" | 
 |  | 
 |             - implementation may optimize the layout but must use the same | 
 |               layout across shaders so that the resulting layout can be shared | 
 |               by multiple shaders | 
 |  | 
 |             - application must query the GL for the uniform block layout | 
 |              | 
 |          | 
 |         "std140": | 
 |             - implementation must use a pre-determined layout, defined | 
 |               in this specification. | 
 |             - application need not query the implementation for layout | 
 |               information as it can be determined by reading the shader | 
 |               and the specification | 
 |          | 
 |          | 
 |         Other options considered included: | 
 |             - an API in the GL | 
 |             - a #pragma in the GLSL | 
 |             - gcc style __attribute__ tokens | 
 |             - others? | 
 |  | 
 |         RESOLUTION: resolved, we use a layout qualifier construct which | 
 |         includes identifiers for "packed", "std140", and "shared" which is the | 
 |         intial default.  These qualifiers can be used either within a uniform | 
 |         block declaration, or at global scope causing subsequent uniform blocks | 
 |         with unspecified layouts to adopt a new default layout. | 
 |          | 
 |  | 
 |     (48)  What is the "std140" packing layout? | 
 |  | 
 |         This extension is supposed to define a standard packing layout | 
 |         that applications can choose to use and know the uniform block | 
 |         data layout within the uniform buffer without querying the | 
 |         implementation. | 
 |  | 
 |         The user would need to opt-in to this layout. | 
 |  | 
 |         We need to define what this layout looks like. | 
 |          | 
 |         See also issue (20). | 
 |  | 
 |         RESOLUTION: resolved, standard layout is now in 2.15.3.1.2. | 
 |  | 
 |  | 
 |     (49)  Will storage of int/ivec*/uint/uvec*/float/vec* be guaranteed | 
 |     to match the GLint, GLuint, and GLfloat types of the CPU's | 
 |     implementation? What if the CPU and GPU differ?  What about indirect | 
 |     renderers? | 
 |  | 
 |         See also issues (20) and (48) | 
 |  | 
 |         RESOLVED:  We've never figured out how to properly handle other buffer | 
 |         object extensions (e.g., VBO) in conjunction with indirect rendering | 
 |         with data type differences.  This feature should continue that fine (?) | 
 |         tradition. | 
 |  | 
 |         Ignoring indirect rendering, if the native data types of the GLSL | 
 |         executable's processor differs from the client's representation, data | 
 |         should still be extracted from buffer objects using the client's | 
 |         representation.  Mechanisms that could be used to accomplish this | 
 |         include: | 
 |  | 
 |         * having the driver making a copy of the buffer object for internal use, | 
 |           doing conversion during the copy; | 
 |  | 
 |         * having the GLSL executable's processor automatically convert data | 
 |           types as they are fetched; or | 
 |  | 
 |         * generating code to be executed by the GLSL executable's processor to | 
 |           manually perform data type conversions. | 
 |  | 
 |         If dealing with data type mismatches turns out to be a problem on some | 
 |         implementations, it might be possible to provide an extension where | 
 |         applications to avoid conversion overhead by storing data using the | 
 |         native data type of the GPU, instead of the CPU. | 
 |  | 
 |  | 
 |     (50) This extension needs to be sanitized to be written against | 
 |     the 2.1 and 3.0 core specs.  What are the differences? | 
 |      | 
 |         Aside from the sanity checking for using the right | 
 |         section numbers and such, there are two other changes: | 
 |          | 
 |         1) GetIntegeri_v doesn't exist in 2.0 so needs to be | 
 |         added by this extension for the 2.0 version | 
 |          | 
 |         2) The "max components" query needs different behavior | 
 |         for a 2.1 vs. a 3.0/3.1 implementation.  See issue (36) | 
 |          | 
 |          | 
 |         RESOLUTION: Resolved, interactions section added which | 
 |         details the differences when OpenGL 3.0 is supported. | 
 |         Spec is written against OpenGL 2.1, so that's where the | 
 |         section numbers come from. | 
 |  | 
 |  | 
 |     (51) Do we need to name the default uniform block with index 0 and | 
 |     name ""? | 
 |      | 
 |         This is done for symmetry and to allow iterating through  | 
 |         all uniform blocks, including the default, and treat them | 
 |         similarly. | 
 |          | 
 |         On the other hand, it's a little weird since the default | 
 |         partition can not be used with a buffer object.  On the third hand,  | 
 |         maybe some day we will allow that. | 
 |          | 
 |         As a side note, if we go with a name, should it be "", or | 
 |         perhaps "gl_DefaultUniformBlock" or something like that. | 
 |  | 
 |         RESOLUTION: Resolved, do not reserve block number 0 for the default | 
 |         uniform block.  The default uniform block no longer needs a name. | 
 |         If the uniform block index is queried for a uniform that is associated | 
 |         with the default uniform block, -1 is returned. | 
 |          | 
 |  | 
 |     (52) The current extension spec seems to specify "uint" indices, but | 
 |     the values in the queries such as GetActiveUniformBlockiv are | 
 |     returned as "int" values. Should we fix this? | 
 |  | 
 |         Need to double check the APIs to see if we'd have to duplicate | 
 |         some or all of the queries to make them type safe for signed vs. | 
 |         unsigned ints. | 
 |          | 
 |         RESOLUTION: resolved, No.  There are a few other places in the GL | 
 |         query APIs that already suffer from this problem. | 
 |  | 
 |  | 
 |     (53) What are the UNIFORM_BLOCK_REFERENCED_BY_*_SHADER queries used | 
 |     for? | 
 |      | 
 |         The total number of uniform blocks in each stage may be subject | 
 |         to a per-stage limit on some implementations. These queries | 
 |         allow the user to query the program's uniform blocks to see | 
 |         which are used for each stage. | 
 |  | 
 |         RESOLUTION: resolved | 
 |          | 
 |     (54) How do the APIs that use uniform locations relate to the | 
 |     uniforms in named uniform blocks?  And how do the APIs | 
 |     introduced by this extension relate to uniforms in the default | 
 |     uniform block? | 
 |  | 
 |         Basically, locations can't be used with uniforms in a uniform | 
 |         block, so that rules out any queries that require locations. | 
 |  | 
 |         However, the query APIs introduced by this extension can be used | 
 |         with all uniforms, including those in a default uniform block. | 
 |          | 
 |         RESOLUTION: resolved  | 
 |  | 
 |     (55) Should we use the BindBufferBase/BindBufferRange APIs that were | 
 |     introduced in GL 3.0 instead of BindUniformBuffer? | 
 |      | 
 |         As defined, they'd work fine. | 
 |          | 
 |         One side issue:  should the "offset" be part of the context binding? | 
 |         or should the uniform blocks get to each select their own | 
 |         offset within a single context binding? | 
 |          | 
 |         If implementations can support the latter, it may allow | 
 |         applications to get by with fewer context bindings. | 
 |          | 
 |         If not, then we should replace BindUniformBuffer with | 
 |         these routines, but for the 2.0 extension version we'd still | 
 |         need to add those routines and duplicate their spec language | 
 |         in this spec. | 
 |  | 
 |         See issue 42 for the resolution of this side issue. | 
 |  | 
 |         RESOLUTION: resolved, yes we should use BindBufferBase/Range. | 
 |  | 
 |  | 
 |     (56) Can a mapping from uniform block to uniform buffer object be | 
 |     queried? | 
 |      | 
 |         On one hand, it seems like GetActiveUniformBlock could handle | 
 |         it. | 
 |  | 
 |         On the other hand, this linking is indirect: a uniform block | 
 |         selects a binding point, and a binding point binds a UBO. The GL  | 
 |         *could* do the indirect lookup for you, but the data would only be  | 
 |         valid until you changed the unit binding, so it's a little fragile  | 
 |         for the implementation to provide this query. | 
 |          | 
 |         RESOLUTION:  Resolved, not needed, the user can do this. | 
 |  | 
 |  | 
 |     (57) Should we have MAX_UNIFORM_BUFFER_SIZE or a max size on | 
 |     uniform block data instead? | 
 |          | 
 |         The uniform buffer could be larger than the amount of uniform | 
 |         block(s) data inside it. | 
 |          | 
 |         Also see issue (36). | 
 |      | 
 |         RESOLUTION: Resolved, name is MAX_UNIFORM_BLOCK_SIZE. | 
 |          | 
 |      | 
 |     (58) Is there any expectation that uniforms stay in the order | 
 |     declared for the packed/shared layouts? | 
 |  | 
 |         This might make sharing easier, but is not clear if it's  | 
 |         worth it / overly constraining. | 
 |          | 
 |         RESOLUTION: resolved, yes, names/types must retain declaration order | 
 |          | 
 |  | 
 |     (59) Do we need the glsl syntax for declaring arrays of uniform | 
 |     blocks? | 
 |      | 
 |         Deferred this feature to a future extension. | 
 |  | 
 |         RESOLUTION, resolved | 
 |  | 
 |  | 
 |     (60) When using this extension with OpenGL 2.1/3.0, do we require | 
 |     that uniform buffer object names must be generated with glGenBuffers | 
 |     to be used with these new entry points? | 
 |      | 
 |         For OpenGL 3.1 core, there is a blanket requirement to call glGen | 
 |         for object names. | 
 |          | 
 |         For OpenGL 2.x, there is not a requirement to call glGen but in | 
 |         3.0, user-generated names have been deprecated. | 
 |          | 
 |         For 3.0, we added two new object types (FBO/VAO) that | 
 |         required the user to call glGen, but existing object types | 
 |         (textures/renderbuffers/buffer objects) could be used | 
 |         without calling glGen. | 
 |          | 
 |         We need to decide what to do with this when exporting | 
 |         this extension on 2.1 and 3.0. | 
 |  | 
 |         RESOLUTION: Resolved, this extension does not govern the creation of | 
 |         buffer objects.  That's done by BindBuffer, which is not altered | 
 |         by this spec, so on 2.1 and 3.0 you'd be able to use any name,  | 
 |         whereas on 3.1 you'd be required to call GenBuffers. | 
 |  | 
 |  | 
 |     (61) Do we need "instance name" syntax? | 
 |  | 
 |         RESOLUTION: resolved, deferred for now | 
 |  | 
 |  | 
 |     (62) Why don't the new tokens and entry points in this extension have | 
 |          "ARB" suffixes like other ARB extensions? | 
 |  | 
 |         RESOLVED: Unlike a normal ARB extension, this is a strict subset | 
 |         of functionality already approved in OpenGL 3.1. This extension | 
 |         exists only to support that functionality on older hardware that | 
 |         cannot implement a full OpenGL 3.1 driver. Since there are no | 
 |         possible behavior changes between the ARB extension and core | 
 |         features, source code compatibility is improved by not using | 
 |         suffixes on the extension. | 
 |  | 
 |  | 
 |     (63) Should we introduce a query of a program's longest uniform name length, | 
 |     similar to the ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH query of a | 
 |     program's longest uniform block name? | 
 |  | 
 |         RESOLUTION: Resolved, no.  ACTIVE_UNIFORM_MAX_LENGTH serves this purpose | 
 |         well enough.  No great need for a per uniform block query of the same. | 
 |  | 
 |  | 
 |     (64) What should the UNIFORM_OFFSET query return for uniforms that | 
 |     are associated with the default uniform block?  Same for strides? | 
 |  | 
 |         RESOLUTION: Resolved, spec'd to return -1 in these cases. | 
 |  | 
 |  | 
 |     (65) Should we add queries for the base offset and size of the uniform | 
 |     buffer bound to a binding point?  What should the names be? | 
 |  | 
 |         DISCUSSION: This would be analogous to the similar transform feedback | 
 |         queries.  Names could be UNIFORM_BUFFER_START and UNIFORM_BUFFER_SIZE. | 
 |  | 
 |         RESOLUTION: Resolved, yes. | 
 |  | 
 |  | 
 |     (66) Should we provide some mechanism allow applications to annotate their | 
 |     uniform declarations to specify an offset by hand?  Direct3D 10 does.  An | 
 |     example of the D3D syntax: | 
 |  | 
 |         cbuffer D3DExample { | 
 |           float4 a : packoffset(c0);    // bytes 0-15 | 
 |           float3 b : packoffset(c16);   // bytes 256-267 (c0-c15 are all vec4s) | 
 |           float1 c : packoffset(c1.y);  // bytes 20-23 | 
 |         } | 
 |  | 
 |         If so, how would we handle a mixed declaration that includes some | 
 |         uniforms with annotations and others without? | 
 |  | 
 |         RESOLVED:  An annotation mechanism would be useful for fine-grained | 
 |         application control, but we will defer this. | 
 |  | 
 |  | 
 |     (67) Should we provide a mechanism to expose both row-major and column-major | 
 |     storage of matrices? | 
 |  | 
 |         If no controls are provided in GLSL 1.40, the default resolution for the | 
 |         UBO layout documentation would be to treat all matrices as column-major.   | 
 |         We will also need to pick a default orientation for matrices with that | 
 |         use no GLSL language mechanism to declare orientation. | 
 |  | 
 |         Either way, the UBO GL API should provide a GetActiveUniform query to | 
 |         determine if an active matrix is stored in row- or column-major order. | 
 |  | 
 |         RECOMMENDATION:  Provide a should have a type modifier for matrix | 
 |         declarations, for example: | 
 |  | 
 |         row_major mat4 matrix1; | 
 |         column_major mat4 matrix2; | 
 |  | 
 |         It may be desirable to have a global control (e.g., a #pragma) to | 
 |         specify that all matrices are row- or column-major. | 
 |  | 
 |         RESOLVED:  Yes, we should provide this control.  It is now available | 
 |         in the form of uniform block layout qualifiers.  The identifiers | 
 |         "row_major" and "column_major" are allowed, with the latter serving as | 
 |         the initial default.  These qualifiers can be specified on a per- | 
 |         matrix basis, a per-uniform block basis (affecting all matrices within | 
 |         the uniform block that have unspecified orders), or globally.  In the | 
 |         latter case, all subsequent matrices with unspecified order will adopt | 
 |         a new default order. | 
 |  | 
 |  | 
 |     (68) Should the buffer layout be expressed in terms of standard GL types? | 
 |     For example, should the storage for a "vec3" be equivalent to "GLfloat [3]"? | 
 |  | 
 |         RESOLVED:  Yes.  One other alternative would be to specify exact type | 
 |         (e.g., "32-bit floats using IEEE 754 encoding", "32-bit two's complement | 
 |         integers", etc...).  These choices will be roughly equivalent in | 
 |         practice, and it's probably better to use standard GL types. | 
 |  | 
 |  | 
 |     (69) Do we need to pad the end of structures and/or arrays using the | 
 |     standard packing rules?  Or should we be able to squeeze data types with | 
 |     small alignment requirements in the "holes" left at the end of structures or  | 
 |     arrays with larger alignment requirements? | 
 |  | 
 |         uniform ExamplePad { | 
 |                             // with     without | 
 |                             // padding  padding   comments | 
 |                             // -------  -------   ------------------------ | 
 |           struct {          // | 
 |             vec3 a;         // 0..11    0..11 | 
 |           } b;              //                    add 4B of padding? | 
 |           float c;          // 16..19   12..15 | 
 |           vec3 d[2];        // 32..43   16..27    align to 16B due to vec3 | 
 |                             // 48..59   32..43    add 4B of padding? | 
 |           float e;          // 64..67   44..47 | 
 |           struct {          //                    align to 16B due to <f> | 
 |             vec4 f;         // 80..95   48..63 | 
 |             ivec2 g;        // 96..103  64..71 | 
 |           } h;              //                    add 8B of padding? | 
 |           uint i;           // 112..115 72..75 | 
 |         } | 
 |  | 
 |       The strongest argument against padding is compactness. | 
 |  | 
 |       The strongest argument in favor of padding is to have a structure | 
 |       definition that can be matched with a similar structure definition in | 
 |       application code. For example, consider the following GLSL code: | 
 |  | 
 |       uniform Example { | 
 |         vec3 a[10]; | 
 |         float b; | 
 |       }; | 
 |  | 
 |       The standard layout rules suggest that the vec3 members of "a" are | 
 |       effectively padded out to vec4's in the array; so the natural C structure | 
 |       would look like: | 
 |  | 
 |       typedef struct { float x, y, z, pad; } vec3InArray; | 
 |         struct Example { | 
 |         vec3InArray a[10]; | 
 |         float b; | 
 |       } | 
 |  | 
 |       The problem is that without padding the end of arrays, the uniform "b" | 
 |       will be stored immediately after the last float in a[9], but with the C | 
 |       structure, that word will be consumed by a[9].pad, and "b" will be stored | 
 |       one word following. | 
 |  | 
 |       A similar issue arises with structures; common C compilers seem to pad the | 
 |       end of structures to the largest alignment of the atomic types used in the | 
 |       structure.  For example, if you have: | 
 |  | 
 |       struct {  | 
 |         double a; | 
 |         char b; | 
 |       } c; | 
 |  | 
 |       common compilers will generate code where sizeof(c)==16.  We are | 
 |       effectively treating vectors and matrices as atomic types, so it seems to | 
 |       make sense that for GLSL code like: | 
 |  | 
 |       struct { | 
 |         vec4 a; | 
 |         float b; | 
 |       } c; | 
 |  | 
 |       it would follow that sizeof(c)==32. | 
 |  | 
 |       RESOLVED: Yes, we need to pad in support of the reasons above. | 
 |  | 
 |  | 
 |     (70) Should "bool" data types be represented as 8-bit quantities (a la | 
 |     GLboolean in most gl.h versions) or 32-bit? | 
 |  | 
 |         RESOLVED:  Use 32-bit integers.   | 
 |  | 
 |         Using GLboolean (8-bit) would be the closest match to the API types, but | 
 |         some implementations of this standard may prefer 32-bit integers at this | 
 |         point.  We don't expect uniform blocks to contain enough bool-typed data | 
 |         where the wasted storage matters significantly. | 
 |  | 
 |         One other option considered was to have an implementation-dependent | 
 |         representation, which could be queried, but requiring applications to | 
 |         query and handle multiple basic data types seemed cumbersome.  Even if | 
 |         we did this, we would still want to have a single representation for a | 
 |         fully-defined "std140" packing, at least. | 
 |  | 
 |  | 
 |     (71) What happens we are using indirect rendering where the data types used | 
 |     by the client and server differ, due to endianness or some other issues  | 
 |     related to basic data type?  What happens if the processor running the GLSL | 
 |     executable uses different data type representations than the application? | 
 |  | 
 |         DUPLICATE of issue (49) | 
 |  | 
 |  | 
 |     (72) What parameters should we provide for querying the layout of matrices  | 
 |     (and arrays of matrices) in memory? | 
 |  | 
 |         RESOLVED:  We expect that matrices will be stored as an array of column | 
 |         vectors or row vectors.  There are two possibly independent strides: | 
 |  | 
 |           - bytes between columns/rows within a single matrix | 
 |           - bytes between matrices within an array of matrices | 
 |  | 
 |         The GetActiveUniform*() API for UBO will provide queries for both | 
 |         strides. | 
 |  | 
 |         For single matrices, the stride between columns/rows is the only | 
 |         parameter.  Some implementations may provide tightly packed matrices,  | 
 |         where a 3x3 column-major matrix might be represented with 9 consecutive | 
 |         floats with a 12-byte (3-float) stride between columns.  Others, such as | 
 |         the "std140" packing above represents such a matrix as an array of 3 | 
 |         column or row vectors, but pads each row/column for a 16-byte (4-float) | 
 |         stride. | 
 |  | 
 |         For arrays of matrices, two queries would be needed for maximum  | 
 |         flexibility.  For example, a hypothetical implementation might pack 3x3 | 
 |         arrays tightly as 9 floats, but require that each array in the matrix be | 
 |         aligned on a 16-byte boundary.  This would have a column stride of 12B, | 
 |         but would require a matrix stride of 48B, not 3*12=36B.  If we didn't | 
 |         care about such implementations, an alternate approach would be to | 
 |         treat an array of N column-major matrices with C columns as though it | 
 |         were an array of N*C column vectors, as in the std140 layout.  The | 
 |         stride between matrices would be derived from the stride between | 
 |         columns. | 
 |  | 
 |         Providing multiple queries seems like the safest choice, and doesn't | 
 |         have any significant down-side. The first stride query, between major | 
 |         vectors of a matrix, is UNIFORM_MATRIX_STRIDE. The latter query is | 
 |         actually the same UNIFORM_ARRAY_STRIDE query used for any type of | 
 |         array element. | 
 |  | 
 |  | 
 |     (73) Should GetActiveUniform allow you to query if a matrix is column- or | 
 |     row-major, so an app can determine the layout without knowing how the | 
 |     matrix is declared in the shader? | 
 |  | 
 |         RESOLVED:  Yes, UNIFORM_IS_ROW_MAJOR. | 
 |  | 
 |  | 
 |     (74) What's language mechanism should be used for opting into standard | 
 |     layout? | 
 |  | 
 |         At the January 2009 F2F, it was recommended to specify a per-uniform | 
 |         block layout via a language mechanism such as: | 
 |  | 
 |         layout(<identifier>) uniform { | 
 |           ... | 
 |         }; | 
 |  | 
 |         where <identifier> must be "std140" in the current standard.  Future | 
 |         extensions and core versions could define additional identifiers (such | 
 |         as "std140novec4").  The mechanism could be further extended to | 
 |         include an identifier list if there is ever a need for very fine-grained | 
 |         control. | 
 |  | 
 |         There appears to be a strong desire for a global mechanism that doesn't | 
 |         require individually annotating each and every uniform block.  Options | 
 |         considered include the #pragma described above and a GL API call that | 
 |         might set a "compiler flag" such as: | 
 |  | 
 |         glProgramParameteri(program, GL_UNIFORM_BLOCK_LAYOUT, GL_LAYOUT_STD140); | 
 |  | 
 |         It was noted that the GL API call, since implementations are permitted | 
 |         to do some or most code generation during glCompileShader(), where a | 
 |         program parameter would not be available.  A similar shader parameter | 
 |         call could conceivably be provided. | 
 |  | 
 |         RESOLVED: We've adopted a layout qualifier construct which can be used | 
 |         to specify the "std140" standard layout either within a uniform block | 
 |         declaration or at global scope, affecting all subsequently declared | 
 |         uniform blocks with unspecified layout. | 
 |  | 
 |     (75) What is the story behind the "std140" packing, and the possible | 
 |     "std140vec4" alternative? | 
 |  | 
 |         RESOLVED:  The "std140" packing is intended to provide a common | 
 |         device-independent layout for uniform blocks that can be supported by  | 
 |         all OpenGL 3.1-capable GPUs.  Applications using this packing do not | 
 |         need to query the offsets and strides of all its uniforms and can rely | 
 |         on the same packing being used on all OpenGL 3.1 implementations. | 
 |  | 
 |         While some implementations may be able to support a more space-efficient | 
 |         packing, "std140" does not attempt to provide any features not available  | 
 |         on all platforms.  Some of the limitations baked into this packing | 
 |         include: | 
 |  | 
 |           * scalars need to be size-aligned; | 
 |  | 
 |           * vectors are treated as atomic units, and need to be vector-size- | 
 |             aligned; | 
 |  | 
 |           * array elements and structures are aligned/padded to 16-byte | 
 |             boundaries | 
 |  | 
 |         The array/structure restriction is because some implementations treat | 
 |         uniform buffers as arrays of four-component vectors and may not be able | 
 |         to efficiently perform indexed array access with strides less than 16  | 
 |         bytes. | 
 |  | 
 |         The "std140novec4" alternate packing illustrates an alternate approach | 
 |         without required 16-byte alignment that might be exposed as a future | 
 |         vendor extension. | 
 |  | 
 |         Future versions of OpenGL/GLSL may choose to provide additional sets of | 
 |         canonical packing rules that may end up being more compact. | 
 |  | 
 |     (76) When using the standard layout, how is UNIFORM_BLOCK_DATA_SIZE | 
 |     determined? | 
 |  | 
 |       RESOLVED:  The data size returned by the query is derived by taking the | 
 |       next free byte after all uniform block members (including any specified | 
 |       end-of-array or end-of-structure padding) and rounding up to the next | 
 |       vec4 boundary.  It would be equivalent to the offset of a hypothetical | 
 |       vec4 member added to the end of the uniform block. | 
 |  | 
 |       There is no implementation-dependent padding of the uniform block data | 
 |       size when using the standard layout. | 
 |  | 
 |  | 
 | Revision History | 
 |  | 
 |     (v68, 2015-06-23, srahman) | 
 |         - Add GLX protocol specification. | 
 |  | 
 |     (v67, 2013-08-17, jon) | 
 |         - Add extra 'const' qualifier for GetUniformIndices <uniformNames> | 
 |           argument (Bug 10703). | 
 |  | 
 |     (v66, 2012-09-17, jon) | 
 |         - Remove _EXT suffix from GL_UNIFORM_BUFFER_EXT in sample code (Bug | 
 |           7948). | 
 |  | 
 |     (v65, 2012-06-28, jon) | 
 |         - Remove INVALID_VALUE error for BindBufferRange when specifying a | 
 |           range beyond the current end of buffer. Define BindBufferBase as | 
 |           specifying a range as large as the actual buffer size at time of | 
 |           use, and return zero when querying the buffer size as a sentinel | 
 |           value for the buffer size indicating this behavior. Specify that | 
 |           the GL will never read from or write to beyond the end of a bound | 
 |           buffer (Bugs 7318 and 7329, matching OpenGL 4.2 core spec | 
 |           behavior). Remove dangling references to nonexistent | 
 |           BindBufferOffset. | 
 |  | 
 |     (v64, 2011-01-27, jon) | 
 |         - Change return value for start/size queries when no buffer | 
 |           bound from -1 to zero, to match state tables (Bug 7318). | 
 |  | 
 |     (v63, 2011-01-21, pbrown) | 
 |         - Add interaction with ARB_geometry_shader4 to indicate that | 
 |           MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS is defined there. | 
 |  | 
 |     (v62, 2009-03-26, jon) | 
 |         - Remove ARB suffixes for consistency with other extensions | 
 |           simultaneously introduced with new GL core features, intended | 
 |           to enable those features in older drivers. | 
 |  | 
 |     (v61, 2009-02-16, benj) | 
 |         - pickup latest changes to GLSL language | 
 |  | 
 |     (v60, 2009-02-12, benj) | 
 |         - revert the change to silently ignore INVALID_INDEX_ARB within | 
 |           <uniformIndices> passed to GetActiveUniformsivARB | 
 |         - picked up a few proposed language changes from Pat | 
 |         - updated table 2.utype to include types from extensions | 
 |         - added interactions for these extension types | 
 |         - fixed issue (40) resolution | 
 |  | 
 |     (v59, 2009-02-12, benj) | 
 |         - remove INVALID_OPERATION error when <program> has not been linked, | 
 |           and instead just behave appropriately for the case where there are | 
 |           no active uniforms or uniform blocks | 
 |         - added GL 3.0 interaction regarding description of uniform | 
 |           initialization, which is limited to uniforms in the default block | 
 |  | 
 |     (v58, 2009-02-11, jon) | 
 |         - Add some more comments. | 
 |  | 
 |     (v57, 2009-02-11, benj) | 
 |         - restore 80-column width | 
 |         - change _STAGE to _SHADER in UNIFORM_BLOCK_REFERENCED_BY token names | 
 |         - silently ignore INVALID_INDEX_ARB in GetActiveUniformsivARB | 
 |         - clarify that matrices in the default uniform block return 0 for | 
 |           UNIFORM_IS_ROW_MAJOR | 
 |         - Replace Draw* with Begin or commands that perform an implicit Begin | 
 |           since the extension is written against GL 2.1 | 
 |  | 
 |     (v56, 2009-02-11, jon) | 
 |         - Accept some of Pat's edits and remove associated notes/comments. | 
 |           Add my comments on some others. | 
 |  | 
 |     (v55, 2009-02-11, pbrown) | 
 |         - Many edits attempting to make the spec read more clearly. | 
 |         - Added a number of notes and issues in the spec for additional edits. | 
 |  | 
 |     (v54, 2009-02-11, jon) | 
 |         - Note that uniform binding limits change when geometry | 
 |           shaders not supported, and update uniform state variable | 
 |           types. | 
 |  | 
 |     (v53, 2009-02-09, jon) | 
 |         - Restore an error accidentally removed from GetUniformLocation | 
 |           (at least, I think it was accidentaly). | 
 |  | 
 |     (v52, 2009-02-09, jon) | 
 |         - Resolve some issues as recommended by Bruce and leave his | 
 |           comments in for others Benj should look at. | 
 |         - Allow undefined behavior including termination if no buffer is | 
 |           bound backing a uniform block. | 
 |  | 
 |     (v51, 2009-02-08, jon) | 
 |         - Cleanup before core spec integration: | 
 |         - Change definition of INVALID_INDEX_ARB to avoid signed/unsigned | 
 |           conversion questions by making it an unsigned literal (would | 
 |           like to change the name too, it looks too much like an error). | 
 |         - Rephrase some query language for greater consistency with core | 
 |           spec. Duplicated <program> error conditions in each affected | 
 |           call to avoid more state-dependent reading. | 
 |  | 
 |     (v50, 2009-02-08, benj) | 
 |         - resolve last four issues (47), (67), (74), (76) | 
 |         - update the GLSL changes for uniform blocks | 
 |         - update API descriptions to refer to packed/shared/std140 layouts | 
 |         - update the buffer overrun language courtesy of Bruce | 
 |         - rename APPLE to ARB in the issues list | 
 |         - misc. other cleanups | 
 |  | 
 |     (v49, 2009-02-05, benj) | 
 |         - change UBO overrun language to say "undefined behavior that may lead | 
 |           to GL interruption or termination" instead of just "undefined values" | 
 |         - flesh out Errors section | 
 |  | 
 |     (v48, 2009-02-04, benj) | 
 |         - add query for whether a matrix uniform is row- or column-major | 
 |         - add query for the stride between a matrix uniform's major vectors | 
 |         - apply one description of <program> to all uniform query commands | 
 |         - update example code | 
 |  | 
 |     (v47, 2009-02-03, benj) | 
 |         - update packing rules and examples | 
 |         - standardize on "named" uniform block instead of "user-defined" | 
 |         - refactor UBO spec language so it is blended with old uniform language | 
 |  | 
 |     (v46, 2009-02-03, benj) | 
 |         - update token MAX token names re: issue (46) | 
 |         - rename "uniform block unit" to "uniform buffer binding point" | 
 |         - updated uniform block binding and uniform buffer binding overview | 
 |         - add queries for uniform buffer start and size re: issue (65) | 
 |         - resolved issues (46), (65), (69) | 
 |         - incorporated many more misc. suggestions from Bruce | 
 |  | 
 |     (v45, 2009-02-02, benj) | 
 |         - rename from APPLE to ARB | 
 |         - assigned token values | 
 |         - misc. suggestions from Bruce, more to come | 
 |         - pull issues over from Pat's packing doc | 
 |         - resolved issues (57), (60), (62), (63), (64), (65) | 
 |  | 
 |     (v44, 2009-01-30, benj) | 
 |         - resolved issues (20), (29), (42) | 
 |         - added MAX_COMBINED_{VERTEX|GEOMETRY|FRAGMENT}_UNIFORM_COMPONENTS | 
 |           queries with different minimum maxima for before and after GL 3.1, | 
 |           resolving issue (36) | 
 |         - replaced GetActiveUniformNamesAPPLE with GetActiveUniformNameAPPLE, | 
 |           resolving issue (43) | 
 |         - stop reserving uniform block index 0 for the default uniform block, | 
 |           resolving issue (51) | 
 |         - remove language saying uniform buffer range size must be aligned to | 
 |           UNIFORM_BUFFER_OFFSET_ALIGNMENT | 
 |         - make consistent use of "uniform block unit" instead of "uniform | 
 |           buffer unit" | 
 |  | 
 |     (v43, 2009-01-29, benj) | 
 |         - UNIFORM_BLOCK_NAME_LENGTH changed from 0 to 1 for the default | 
 |           uniform block, since "" still has a null terminator | 
 |         - UNIFORM_BLOCK_DATA_SIZE description updated to reflect how | 
 |           offset/stride queries are unnecessary for "standard" layout | 
 |         - Add language to GetUniformLocation to say that uniforms in | 
 |           named uniform blocks return -1, and that Uniform* are for | 
 |           loading uniforms of the default uniform block | 
 |         - update discussion of issues (13), (15), (21), (34) to align with | 
 |           current spec | 
 |         - sanitize uniform query descriptions (both pre-existing and | 
 |           new in this extension) to clarify handling of uniforms from | 
 |           default uniform blocks vs. named uniform blocks, | 
 |           resolving issue (54) | 
 |         - rename MAX_UNIFORM_BUFFER_SIZE to MAX_UNIFORM_BLOCK_SIZE per | 
 |           issue (57) | 
 |         - introduce language guaranteeing order of member offsets will match | 
 |           order within declaration per issue (58) | 
 |         - update some section #s | 
 |  | 
 |     (v42, 2009-01-28, benj) | 
 |         - introduce Pat's packing rules, including standard layout, | 
 |           resolving issues (48), (49) | 
 |         - add interactions with extensions and GL 3.0, resolving | 
 |           issue (50) | 
 |         - change names of MAX query names for uniform block | 
 |           per-stage, combined, and binding point limits | 
 |         - introduce BindBufferRange/BindBufferBase in place of | 
 |           BindUniformBufferAPPLE, resolving issue (55) | 
 |         - add missing query language in Chapter 6 | 
 |         - add missing UNIFORM_BUFFER_OFFSET_ALIGNMENT_APPLE from  | 
 |           state tables | 
 |         - separate new state from implementation state in state tables | 
 |         - remove instance-name language and arrays of uniform blocks per | 
 |           resolution to issues (59), (61) | 
 |         - fix minor typos and cosmetic issues | 
 |         - reformat some lines to fit in 80 columns | 
 |         - replace tabs with spaces | 
 |          | 
 |     (v41, 2009-01-25, jsandmel) | 
 |         - incorporated resolutions/feedback from Portland F2F | 
 |         - resolved issues (33), (39), (44), (52), (55), (56), (58), (59) | 
 |         - added issue (61) | 
 |          | 
 |     (v40, 2009-01-25, jsandmel) | 
 |         - fixed a few typos noticed by Barthold Lichtenbelt | 
 |         - fixed up some white space in issues list | 
 |  | 
 |     (v39, 2009-01-21, jsandmel) | 
 |         - fixed a few typos noticed by Daniel Koch | 
 |         - added issue (60) | 
 |  | 
 |  | 
 |     (v38, 2009-01-21, jsandmel) | 
 |         - integrated feedback and questions from Bruce Merry | 
 |         - fixed typo in GetUniformIndices (missing const char**) | 
 |         - added length (output) parameter to GetActiveUniformBlockNameAPPLE | 
 |           for symmetry with GetActiveUniform | 
 |         - removed stale matrix packing queries (to be handled more generally | 
 |           with rest of packing language) | 
 |         - fixed wrong error language when validating <program> arguments | 
 |           to be consistent with generic error language already in | 
 |           GL spec | 
 |         - make GetActiveUniformNamesAPPLE not write NULL to names entries | 
 |           for invalid indices | 
 |         - made <bufSize> validation the same as GetActiveUniform | 
 |         - added issues (57), (58), (59) | 
 |  | 
 |  | 
 |     (v37, 2009-01-19, jsandmel) | 
 |         - incorporated feedback from Pat Brown | 
 |         - added issues (47) - (56) | 
 |         - added note to interactions section | 
 |         - clarified layouts in overview section | 
 |         - fixed wrong error code in GetActiveUniformBlockivAPPLE | 
 |         - added additional description to parameters in | 
 |           GetActiveUniformNamesAPPLE | 
 |         - added note to GetActiveUniformsivAPPLE to make it more | 
 |           similar to GetActiveUniform wrt to program linking and | 
 |           type/size queries. | 
 |         - added todo for UniformBlockBindingAPPLE to clarify over better | 
 |           based on feedback from pat | 
 |         - increased MAX_UNIFORM_BUFFER_SIZE_APPLE from 64 to 16k | 
 |         - unresolved issue (33) re: display lists | 
 |  | 
 |  | 
 |     (v36, 2009-01-14, jsandmel) | 
 |         - added issue (48) requesting the standard layout and referred | 
 |           to this in various places | 
 |         - added missing UNIFORM_BLOCK_NAME_LENGTH_APPLE state variable | 
 |         - corrected references of GetIndexedIntegerv with GetIntegeri_v | 
 |         - fixed typo in description of UNIFORM_BLOCK_INDEX_APPLE | 
 |         - clarified UNIFORM_OFFSET_APPLE description further | 
 |         - clarified that several constantscan be queried with GetIntegerv | 
 |         - fixed a set of stale references to "partitions" | 
 |  | 
 |     (v35, 2009-01-14, jdr) | 
 |         - improved readability of a few areas | 
 |         - fixed a data type typo | 
 |  | 
 |     (v34, 2009-01-12, jsandmel)  | 
 |         - added issue (47) and preliminary keyword support for packed, | 
 |           sharable, standard layouts | 
 |  | 
 |     (v33, 2009-01-11, jsandmel)  | 
 |         - switched terminology from "partition" to "uniform block" | 
 |         - switched syntax from 'active' to 'packed', and changed default | 
 |           behavior | 
 |         - changed lots of function names to account for the above | 
 |         - cleaned up overview  | 
 |         - dropped language talking about "binding" for the uniform block -> | 
 |           uniform block unit association, since it's not an object binding | 
 |           operation | 
 |         - added concept of "combined"/"logical" binding point max queries | 
 |         - incorporated most recent GLSL syntax from the GLSL working group for  | 
 |           uniform blocks | 
 |         - removed the AttachUniformBufferAPPLE for per-program bindings of UBOs | 
 |  | 
 |     (v32, 2008-12-08, jsandmel)  | 
 |         - added UNIFORM_BUFFER_OFFSET_ALIGNMENT_APPLE | 
 |  | 
 |     (v31, 2008-12-08, jsandmel)  | 
 |         - minor updates to overview (this could still use more editing). | 
 |  | 
 |     (v30, 2008-12-08, jsandmel)  | 
 |         - cleaned up function argument names for clarity | 
 |         - reformatted new procedures/tokens section | 
 |         - added concept of uniformBlockBinding (for context bindings) to | 
 |           distinguish from uniformBlockIndex | 
 |         - renamed MAX_VERTEX_UNIFORM_BUFFERS_APPLE -> | 
 |           MAX_VERTEX_UNIFORM_BUFFERS_APPLE and friends. | 
 |         - removed/simplified the unneeded per-stage quries for active | 
 |           partitions (under assumption that partition names are global per | 
 |           program) | 
 |         - de-assigned apple enums for most tokens while we work out the enums | 
 |         - added UNIFORM_BLOCK_REFERENCED_BY_VERTEX_STAGE_APPLE and friends | 
 |           to queries of each partition | 
 |         - clarified/cleaned up overview of uniform partitions | 
 |         - added more detail to each of the function descriptions to clarify | 
 |           how each of the arguments was to be handled | 
 |         - temporarily deleted the Errors section since it was partially stale | 
 |           need to add this back later | 
 |         - removed stale query for UNIFORM_LOCATION_APPLE from state table | 
 |         - cleaned up (most of) issues list with API changes | 
 |         - removed some AMD/NV'isms from the issues language | 
 |   | 
 |     (v29, 2008-11-24, jsandmel)  | 
 |         - Added <stage> argument to query routines to indicate | 
 |           vtx/geom/fragment. | 
 |         - Still need to update sample code for this proposal. | 
 |         - Also need to still specify how uniform scoping works (cross | 
 |           stage or per stage). | 
 |         - Eliminated special "INVALID_INDEX_APPLE" value since the rest | 
 |           of the GLSL API uses "-1" to mean invalid index, so we use | 
 |           that here too. | 
 |  | 
 |     (v28, 2008-10-08, jsandmel) | 
 |         - Added more discussion to issue (35) regarding context vs. | 
 |           program bindings of UBOs. | 
 |         - Added prototypes for BindUniformBuffer API. | 
 |         - Added issue (36) about maximum uniform component API. | 
 |         - Integrated the proposed API for per-context bindings into | 
 |           issue (35) from NVIDIA's NV_ubo proposal. | 
 |         - Added issue (37) about if we need 3 values for | 
 |           MAX_{VERTEX|GEOMETRY|FRAGMENT}_UNIFORM_BUFFERS_APPLE. | 
 |  | 
 |     (2008-10-08, jdr) Grammar additions.  Re-instated piece-wise partition | 
 |     definitions. Elaboration of issue 35.  Addition of 36.  Readability | 
 |     improvements. | 
 |  | 
 |     (2008-10-07, jdr) 18 in previous check-in -> not true.  18 *is* in this | 
 |     one.  Skeltal issue for NV suggested context binding points. | 
 |  | 
 |     (2008-10-06, jdr) Incorporated Nick's and Matt's changes 2, 3, 4, 5, | 
 |     6, 8, 12, 14, 16, 17, and 18. | 
 |  | 
 |     (2008-08-27, jdr) Additions to contributer list. | 
 |  | 
 |     (2008-07-22, jdr) Changed buffer minimums and contributor list per | 
 |     discussion with NVidia. | 
 |  | 
 |     (2008-06-19, jdr) Added issue 34 and language describing the decision | 
 |     to use struct-like syntax for partition definitions.  Added explicit | 
 |     mention that AttachUniformBufferObjectAPPLE() was required after a  | 
 |     uniform buffer object has been modified.  Fixed examples. | 
 |  | 
 |     (2008-03-18, jdr) Provide resolution and spec language for "active" and | 
 |     "partition" resolving related issues.  Appended "_object" to spec name. | 
 |     Added required GLSL v1.20.8 spec language. | 
 |  | 
 |     (2008-03-17, jdr) Removed issue 30 as it was a misread spec.  Added | 
 |     resolutions for 29, 31, and 32 - made spec changes accordingly.  Added | 
 |     proposal for active partition demarcation and sharing rules. | 
 |  | 
 |     (2008-03-14, jdr) Added issues 29-34 for transform feedback, scoping the | 
 |     "active" keyword, and following precedents. | 
 |  | 
 |     (2008-03-13, bb) Fixed incorrect error returns. | 
 |  | 
 |     (2008-03-13, bb) Changed the return value of GetUniformBlockIndexAPPLE to | 
 |     uint.  Added INVALID_INDEX.  Fixed Example code 2.  Cleaned up line breaks. | 
 |     Cleaned up issues.  Added issues 24-26. | 
 |  | 
 |     (2008-03-12, jdr) Added state tables and state retrieval segment. | 
 |  | 
 |     (2008-03-12, jdr) Rewrote advanced source example.  Made a few minor fixes | 
 |     and additions that writing the example illuminated. | 
 |  | 
 |     (2008-03-11, jdr) After considerable dialog with BB around handling of bulk | 
 |     extraction of uniform meta-data, conclusions of dialog required sweeping | 
 |     changes to spec.  Rewrote specification updates section.  Added new | 
 |     tokens.  Changed New Functions segment.  Updated Errors segment. | 
 |     Added issue 23. | 
 |  | 
 |     (2008-03-04, jdr) Rewrote specification updates section.  Rewrote error | 
 |     section. | 
 |  | 
 |     (2008-03-03, jdr) Rewrote overview to reflect partitioning.  Re-arranged | 
 |     for spec worthiness.  Cleaned up new procedures functions and defined  | 
 |     aggregate layout function. Revised issues list to reflect partitioning, | 
 |     include more recent discussions, and used current accepted vernacular. | 
 |  | 
 |     (2008-03-03, bb) Resolved issue 19.  Changed the return value of | 
 |     GetActivePartitionUniformInfoAPPLE to a void because it does not return | 
 |     locations. | 
 |  | 
 |     (2008-03-03, jdr) Changed to namespace to partitions.  Added issues 21 & | 
 |     22. Added aggregate uniform info query per partition.   | 
 |  | 
 |     (2008-03-03, bb) Added separate partition support.  Changed extension name | 
 |     to APPLE_uniform_buffer. | 
 |  | 
 |     (2008-02-27, jdr)  Dumped program arguments. Changed "types" output array | 
 |     to "sizes" output array.  Added expected scatter/gather logic in the | 
 |     example to advocate efficient schlepping of uniform data into the buffer. | 
 |  | 
 |     (2008-02-26, jdr)  Changes to accomodate relative offsets.  Revised | 
 |     example source. Error additions. Removed contact information for | 
 |     contributors list. | 
 |      | 
 |     (2008-02-25, jdr)  Added source example. | 
 |  | 
 |     (2008-02-21, jdr)  Added to issues list, resolutions of all issues | 
 |     excepting 16.  Changes per meeting.  Additions to procedures and | 
 |     explanations.  2.1 spec integration.  Implementation Dependent State. | 
 |  | 
 |     (2008-02-19, jdr)  Added to issues list, additions to procedures and | 
 |     explanations, errors. | 
 |  | 
 |     (2008-02-18, jdr)  Added to issues list, modifications to procedures and | 
 |     explanations. | 
 |  | 
 |     (2008-02-16, jdr)  Added to issues list and procedures. | 
 |  | 
 |     (2008-02-15, jdr)  Initial revision, overview. |