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.
