Name

    ARB_enhanced_layouts

Name Strings

    GL_ARB_enhanced_layouts

Contact

    John Kessenich (cepheus 'at' frii.com)

Contributors

    Pat Brown, NVIDIA (pbrown 'at' nvidia.com)
    Christophe Riccio, AMD
        
Notice

    Copyright (c) 2013 The Khronos Group Inc. Copyright terms at
        http://www.khronos.org/registry/speccopyright.html

Status

    Complete. Approved by the ARB on June 3, 2013.
    Ratified by the Khronos Board of Promoters on July 19, 2013.

Version

    Last Modified Date: June 13, 2014
    Revision: 27

Number

    ARB Extension #146

Dependencies

    This extension is written against the OpenGL 4.3 (Compatibility Profile)
    Specification, dated February 14, 2013.

    This extension is written against the GLSL 4.30 Specification.

    OpenGL 3.1 and GLSL 1.40 or later are required.

    This extension interacts with OpenGL 3.3 and ARB_explicit_attrib_location.

    This extension interacts with OpenGL 4.0 and ARB_vertex_attrib_64bit.

    This extension interacts with OpenGL 4.0 and ARB_transform_feedback3.

    This extension interacts with OpenGL 4.1 and ARB_separate_shader_objects.

    This extension interacts with OpenGL 4.3 and
    ARB_shader_storage_buffer_object.

    This extension interacts with OpenGL 4.3 and ARB_program_interface_query.

Overview

    This extension adds the following functionality to layout qualifiers,
    including broadening the API where this functionality is reflected.

    The following are added:

    1) Use compile-time constant expressions. E.g.,

          const int start = 6;
          layout(location = start + 2) int vec4 v;

    2) Specify explicit byte offsets within a uniform or shader storage block. 
       For example, if you want two vec4 variables "batman" and "robin" to
       appear at byte offsets 0 and 64 in your block, you can say:

          uniform Block {
            layout(offset = 0) vec4 batman;
            layout(offset = 64) vec4 robin;
          };

    3) Force alignment within a uniform or shader storage block.  The previous
       example could also be expressed:

          uniform Block {
            vec4 batman;
            layout(align = 64) vec4 robin;
          };

       This says the member 'robin' must start at the next address that is a 
       multiple of 64.  It allows constructing the same layout in C and in GLSL
       without inventing explicit offsets.

       Explicit offsets and aligned offsets can be combined:

          uniform Block {
            vec4 batman;
            layout(offset = 44, align = 8) vec4 robin;
          };

       would make 'robin' be at the first 8-byte aligned address, starting at
       44, which is 48.  This is more useful when using the *align* at
       the block level, which will apply to all members.

    4) Specify component numbers to more fully utilize the vec4-slot interfaces
       between shader outputs and shader inputs.
      
       For example, you could fit the following

          - an array of 32 vec3
          - a single float

       into the space of 32 vec4 slots using the following code:

          // consume X/Y/Z components of 32 vectors
          layout(location = 0) in vec3 batman[32];

          // consumes W component of first vector
          layout(location = 0, component = 3) in float robin;

       Further, an array of vec3 and an array of float can be stored 
       interleaved, using the following.

          // consumes W component of 32 vectors
          layout(location = 0, component = 3) in float robin[32];

          // consume X/Y/Z components of 32 vectors
          layout(location = 0) in vec3 batman[32];

    5) Specify transform/feedback buffers, locations, and widths. For example:

           layout(xfb_buffer = 0, xfb_offset = 0)  out vec3 var1;
           layout(xfb_buffer = 0, xfb_offset = 24) out vec3 var2;
           layout(xfb_buffer = 1, xfb_offset = 0)  out vec4 var3;

       The second line above says to write var2 out to byte offset 24 of 
       transform/feedback buffer 0.  (When doing this, output are only 
       captured when xfb_offset is used.)

       To specify the total number of bytes per entry in a buffer:

           layout(xfb_buffer = 1, xfb_stride = 32) out;
       
       This is necessary if, say, var3 above, which uses bytes 0-11,
       does not fully fill the buffer, which in this case takes 32 bytes.

       Use of this feature effectively eliminates the need to use previously 
       existing API commands to describe the transform feedback layout.

    6) Allow locations on input and output blocks for SSO interface matching.
       
       For example:

          layout(location = 4) in block {
              vec4 batman;   // gets location 4
              vec4 robin;    // gets location 5
              layout(location = 7) vec4 joker;  // gets location 7
              vec4 riddler;  // location 8
          };

IP Status

    No known IP claims.

New Procedures and Functions

    None.

New Tokens

    Accepted in the <props> array of GetProgramResourceiv:

        LOCATION_COMPONENT                              0x934A
        TRANSFORM_FEEDBACK_BUFFER_INDEX                 0x934B
        TRANSFORM_FEEDBACK_BUFFER_STRIDE                0x934C

    Accepted by the <programInterface> parameter of GetProgramInterfaceiv,
    GetProgramResourceIndex, GetProgramResourceName, and
    GetProgramResourceiv:

        TRANSFORM_FEEDBACK_BUFFER                       // reuse from core

Modifications to the OpenGL 4.3 (Compatibility Profile) Specification

    Modify Section 7.3.1, Program Interfaces, p. 84

    (insert after the TRANSFORM_FEEDBACK_VARYING bullet, p. 86)

      * TRANSFORM_FEEDBACK_BUFFER corresponds to the set of active buffer
        binding points to which output variables in the
        TRANSFORM_FEEDBACK_VARYING interface are written.

    (modify next-to-last paragraph, p. 87, to indicate that variables in the
     TRANSFORM_FEEDBACK_VARYING interface need not be sorted if specified via
     layout qualifiers)

    The order of the active resource list is implementation-dependent for all
    interfaces except for TRANSFORM_FEEDBACK_VARYING.  If variables in the
    TRANSFORM_FEEDBACK_VARYING interface were specified using the
    TransformFeedbackVaryings command, the active resource list will be
    arranged in the variable order specified in the most recent call to
    TransformFeedbackVaryings before the last call to LinkProgram.  If
    variables in the TRANSFORM_FEEDBACK_VARYING interface were specified using
    layout qualifiers in shader code, the order of the active resource list is
    implementation-dependent.

    (insert after the first paragraph, p. 88)

    For the TRANSFORM_FEEDBACK_BUFFER interface, the list of active buffer
    binding points is built by identifying each unique binding point to which
    one or more active output variables will be written in transform feedback
    mode.  Active transform feedback buffers do not have an associated name
    string.

    (modify "Errors" section at the bottom of p. 89, for
     GetProgramInterfaceiv, handling the new TRANSFORM_FEEDBACK_BUFFER
     interface)

     An INVALID_OPERATION error is generated if pname is MAX_NAME_LENGTH and
     <programInterface> is ATOMIC_COUNTER_BUFFER or TRANSFORM_FEEDBACK_BUFFER,
     since active atomic counter and transform feedback buffer resources are
     not assigned name strings.

     An INVALID_OPERATION error is generated if pname is
     MAX_NUM_ACTIVE_VARIABLES and programInterface is not UNIFORM_BLOCK,
     SHADER_STORAGE_BLOCK, ATOMIC_COUNTER_BUFFER, or
     TRANSFORM_FEEDBACK_BUFFER.

     (modify the "Errors" section in the middle of p. 90, for
      GetProgramResourceIndex, handling the new TRANSFORM_FEEDBACK_BUFFER
      interface)

     An INVALID_ENUM error is generated if <programInterface> is
     ATOMIC_COUNTER_BUFFER or TRANSFORM_FEEDBACK_BUFFER, since active atomic
     counter and transform feedback buffer resources are not assigned name
     strings.

     (modify the "Errors" section in the middle of p. 90, for
      GetProgramResourceName, handling the new TRANSFORM_FEEDBACK_BUFFER
      interface)

     An INVALID_ENUM error is generated if <programInterface> is
     ATOMIC_COUNTER_BUFFER or TRANSFORM_FEEDBACK_BUFFER, since active atomic
     counter and transform feedback buffer resources are not assigned name
     strings.

    (modify existing entries in table 7.2, "GetProgramResourceiv properties
     and supported interfaces", pp. 92-93)

      Property                  Supported Interfaces
      -------------------       ----------------------------------------
      NAME_LENGTH               all but ATOMIC_COUNTER_BUFFER and
                                TRANSFORM_FEEDBACK_BUFFER

      OFFSET                    UNIFORM, BUFFER_VARIABLE, 
                                TRANSFORM_FEEDBACK_VARYING

      BLOCK_INDEX,              UNIFORM, BUFFER_VARIABLE
      ARRAY_STRIDE,
      MATRIX_STRIDE,
      IS_ROW_MAJOR

      BUFFER_BINDING            UNIFORM_BLOCK, ATOMIC_COUNTER_BUFFER,
      NUM_ACTIVE_VARIABLES,     SHADER_STORAGE_BLOCK, 
      ACTIVE_VARIABLES          TRANSFORM_FEEDBACK_BUFFER

      BUFFER_DATA_SIZE          UNIFORM_BLOCK, ATOMIC_COUNTER_BUFFER,
                                SHADER_STORAGE_BLOCK

    (add to table 7.2, "GetProgramResourceiv properties and supported
     interfaces", pp. 92-93)

      Property                  Supported Interfaces
      -------------------       ----------------------------------------
      LOCATION_COMPONENT        PROGRAM_INPUT, PROGRAM_OUTPUT

      TRANSFORM_FEEDBACK_       TRANSFORM_FEEDBACK_VARYING
        BUFFER_INDEX

      TRANSFORM_FEEDBACK_       TRANSFORM_FEEDBACK_BUFFER
        BUFFER_STRIDE

    (modify the third paragraph, p. 98)

    For the property OFFSET, a single integer identifying the offset of an
    active variable is written to <params>.  For variables in the UNIFORM and
    BUFFER_VARIABLE interfaces that are backed by a buffer object, the value
    written is the offset of that variable relative to the base of the buffer
    range holding its value.  For variables in the TRANSFORM_FEEDBACK_VARYING
    interface, the value written is the offset in the transform feedback
    buffer storage assigned to each vertex captured in transform feedback mode
    where the value of the variable will be stored.  Such offsets are
    specified via the /xfb_offset/ layout qualifier or assigned according to
    the variables position in the list of strings passed to
    TransformFeedbackVaryings.  Offsets are expressed in basic machine units.
    For all variables not recorded in transform feedback mode, including the
    special names "gl_NextBuffer", "gl_SkipComponents1", "gl_SkipComponents2",
    "gl_SkipComponents3", and "gl_SkipComponents4", -1 is written to <params>.

    (modify the next-to-last paragraph, p. 98)

    For the property BUFFER_BINDING, the index of the buffer binding point
    associated with the active uniform block, shader storage block, atomic
    counter buffer, or transform feedback buffer is written to <params>.

    (modify the second and third paragraphs, p. 99)

    For the property NUM_ACTIVE_VARIABLES, the number of active variables
    associated with an active uniform block, shader storage block, atomic
    counter buffer, or transform feedback buffer is written to <params>.

    For the property ACTIVE_VARIABLES, an array of active variable indices
    associated with an active uniform block, shader storage block, atomic
    counter buffer, or transform feedback buffer is written to <params>.  The
    number of values written to params for an active resource is given by the
    value of the property NUM_ACTIVE_VARIABLES for the resource.

    (insert after the first paragraph, p. 100)

    For the property LOCATION_COMPONENT, a single integer indicating the first
    component of the location assigned to an active input or output variable
    is written to <params>.  For input and output variables with a component
    specified by a <layout> qualifier, the specified component is written.
    For all other input and output variables, the value zero is written.

    (insert after the second paragraph, p. 100)

    For the property TRANSFORM_FEEDBACK_BUFFER_INDEX, a single integer
    identifying the index of the active transform feedback buffer associated
    with an active variable is written to <params>.  For variables
    corresponding to the special names "gl_NextBuffer", "gl_SkipComponents1",
    "gl_SkipComponents2", "gl_SkipComponents3", and "gl_SkipComponents4", -1
    is written to <params>.

    For the property TRANSFORM_FEEDBACK_BUFFER_STRIDE, a single integer
    identifying the stride, in basic machine units, between consecutive
    vertices written to the transform feedback buffer is written to <params>.


    Modify Section 7.4.1, Shader Interface Matching, p. 105

    (modify the last bullet of "An output variable is considered to match",
    adding the 

      - the two variables are declared with the same location and component
        layout qualifiers and match in type and qualification

    (insert a new sentence to the beginning of the last paragraph, p. 105)

    For the purposes of interface matching, variables declared with a location
    layout qualifier but without a component layout qualifier are considered
    to have declared a component layout qualifier of zero.  Variables or block
    members declared as structures...


    Modify Section 11.1.1, Vertex Attributes, p. 377

    (replace the first two paragraphs, p. 378)

    When an attribute variable declared using one of the scalar or vector data
    types enumerated in table 11.1 is bound to a generic attribute index <i>,
    its value(s) are taken from the components of generic attribute <i>.  The
    generic attribute components used depend on the type of the variable and
    value of the "component" layout qualifier (if any) specified in the
    variable declaration, as identified in table X.1.  An attribute variable
    declared using a combination of data type and "component" layout qualifier
    not listed in this table is not supported and will result in shader
    compilation errors.

                                "component"
      Data type                 layout qualifier        Components used
      ----------------------    ----------------        ---------------
      scalar                    0 or unspecified        x
      scalar                    1                       y
      scalar                    2                       z
      scalar                    3                       w
      two-component vector      0 or unspecified        (x,y)
      two-component vector      1                       (y,z)
      two-component vector      2                       (z,w)
      three-component vector    0 or unspecified        (x,y,z)
      three-component vector    1                       (y,z,w)
      four-component vector     0 or unspecified        (x,y,z,w)
      
      Table X.1:  Generic attribute components accessed by attribute variables

    When an attribute variable declared using a matrix type is bound to a
    generic attribute index <i>, its values are taken from consecutive generic
    attributes beginning with generic attribute <i>.  Such matrices are
    treated as an array of column vectors with values taken from the generic
    attributes identified in table X.2.  Individual column vectors are taken
    from generic attribute components according table X.1, using the vector
    type from Table X.2 and the "component" layout qualifier (if any)
    specified in the variable declaration.

      Data type             Column vector type        Generic attributes used
      ---------------       --------------------      ------------------------
      mat2    dmat2         two-component vector      i, i+1
      mat2x3  dmat2x3       three-component vector    i, i+1
      mat2x4  dmat2x4       four-component vector     i, i+1
      mat3x2  dmat3x2       two-component vector      i, i+1, i+2
      mat3    dmat3         three-component vector    i, i+1, i+2
      mat3x4  dmat3x4       four-component vector     i, i+1, i+2
      mat4x2  dmat4x2       two-component vector      i, i+1, i+2, i+3
      mat4x3  dmat4x3       three-component vector    i, i+1, i+2, i+3
      mat4    dmat4         four-component vector     i, i+1, i+2, i+3

      Table X.2:  Generic attributes and vector types used by column vectors
      of matrix variables bound to generic attribute index <i>.

    When an attribute variable declared using an array type is bound to
    generic attribute index <i>, the active array elements are assigned to
    consecutive generic attributes beginning with generic attribute <i>.  The
    number of attributes and components assigned to each element are
    determined according to the data type of array elements and "component"
    layout qualifier (if any) specified in the declaration of the array, as
    described above.


    Modify Section 11.1.2.1, Output Variables (Vertex Shaders), p. 383

    (insert before the third paragraph, p. 384)

    The set of variables to record can be specified in shader text using the
    "xfb_buffer", "xfb_offset", or "xfb_stride" layout qualifiers.  When
    recording output variables of each vertex in transform feedback mode, a
    fixed amount of memory is reserved in the buffer bound to each transform
    feedback buffer binding point.  Each output variable recorded is
    associated with a binding point, specified by the "xfb_buffer" layout
    qualifier.  Each output variable is written to its associated transform
    feedback binding point at an offset specified by the "xfb_offset" layout
    qualifier, in basic machine units, relative to the base of the memory
    reserved for its vertex.  The amount of memory reserved in each transform
    feedback binding point for a single vertex can be specified using the
    "xfb_stride" layout qualifier.  If no "xfb_stride" qualifier is specified
    for a binding point, the stride is derived by identifying the variable
    associated with the binding point having the largest offset, and then
    adding the offset and the size of the variable, in basic machine units.
    If any variable associated with the binding point contains
    double-precision floating-point components, the derived stride is aligned
    to the next multiple of eight basic machine units.  If a binding point has
    no "xfb_stride" qualifier and no associated output variables, its stride
    is zero.

    (modify third paragraph, p. 384)

    When no "xfb_buffer", "xfb_offset", or "xfb_stride" layout qualifiers are
    specified, the set of variables to record is specified with the command

      void TransformFeedbackVaryings(uint program, ...

    (replace last paragraph, p. 384)

    The variables in <varyings> are assigned binding points and offsets
    sequentially, as though each were specified using the "xfb_buffer" and
    "xfb_offset" layout qualifiers.  The strides associated with each binding
    point are derived by adding the offset and size of the last variable
    associated with that binding point.  The first variable in <varyings> is
    assigned a binding point and offset of zero.  When <bufferMode> is
    INTERLEAVED_ATTRIBS, each subsequent variable is assigned to the same
    binding point as the previous variable and an offset equal to the sum of
    the offset and size of of the previous variable.  When <bufferMode> is
    SEPARATE_ATTRIBS, each subsequent variable is assigned to the binding
    point following the binding point of the previous variable with an offset
    of zero.

    Several special identifiers are supported when <bufferMode> is
    INTERLEAVED_ATTRIBS.  These identifiers do not identify output variables
    captured in transform feedback mode, but can be used to modify the binding
    point and offsets assigned to subsequent variables.  If a string in
    <varyings> is "gl_NextBuffer", the next variable in <varyings> will be
    assigned to the next binding point, with an offset of zero.  If a string
    in <varyings> is "gl_SkipComponents1", "gl_SkipComponents2",
    "gl_SkipComponents3", or "gl_SkipComponents4", the variable is treated as
    as specifying a one- to four-component floating-point output variable with
    undefined values.  No data will be recorded for such strings, but the
    offset assigned to the next variable in <varyings> and the stride of the
    assigned binding point will be affected.

    (modify first paragraph after the errors section, p. 385)

    The state set by TransformFeedbackVaryings or using transform feedback
    layout qualifiers has no effect on the execution of the program until
    program is subsequently linked.  When LinkProgram is called, the program
    is linked so that the values of the specified outputs for the vertices of
    each primitive generated by the GL are written to one or more buffer
    objects.  If the set of output variables to record in transform feedback
    mode is specified by TransformFeedbackVaryings, a program will fail to
    link if:

    (insert after the first set of bullets, p. 386)

    If the set of output variables to record in transform feedback mode is
    specified using layout qualifiers, a program will fail to link if:

      * any pair of variables associated with the same binding point overlap
        in memory (where the offset of the first variable is less than or
        equal to the offset of the second, but the sum of the offset and size
        of the first variable is greater than the offset of the second);

      * any binding point has a stride declared using the "xfb_stride" layout
        qualifier and the sum of the offset and size of any variable
        associated with that binding point exceeds the value of this stride;

      * any variable containing double-precision floating-point components

          * has an "xfb_offset" layout qualifier that is not a multiple of
            eight; or

          * is associated with a binding point with an "xfb_stride" layout
            qualifier that is not a multiple of eight;

      * the sum of the offset and size of any variable exceeds the maximum
        stride supported by the implementation (four times the value
        of MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS); or

      * the "xfb_stride" layout qualifier for any binding point exceeds the
        maximum stride supported by the implementation.

    (modify the two paragraphs following the bullets, p. 386)

    For transform feedback purposes, each component of outputs declared as
    double-precision floating-point scalars, vectors, or matrices are
    considered to consume eight basic machine units, and each component of any
    other type is considered to consume four basic machine units.

    To determine the set of output variables in a linked program object that
    will be captured in transform feedback mode and the binding points to
    which those variables are written, applications can query the properties
    and active resources of the TRANSFORM_FEEDBACK_VARYING and
    TRANSFORM_FEEDBACK_BUFFER interfaces.

    (insert before the fourth paragraph, starting with "Additionally, the
     command" on p. 386)

    If the shader used to record output variables for transform feedback
    varyings uses the "xfb_buffer", "xfb_offset", or "xfb_stride" layout
    qualifiers, the values specified by TransformFeedbackVaryings are
    ignored, and the set of variables captured for transform feedback is
    instead derived from the specified layout qualifiers.


    Modify Section 13.2.2, Transform Feedback Primitive Capture, p. 457

    (split the first paragraph, p. 459, and replace the second half of the
    paragraph with the following language)

    ... attributes of the subsequent vertices.

    When capturing vertices, the stride associated with each transform
    feedback binding point indicates the number of basic machine units of
    storage reserved for each vertex in the bound buffer object.  For every
    vertex captured, each output variable with an assigned transform feedback
    offset will be written to the storage reserved for the vertex at the
    associated binding point.  When writing output variables that are arrays
    or structures, individual array elements or structure members are written
    in order.  For vector types, individual components are written in order.
    For matrix types, outputs are written as an array of column vectors.  If
    any component of an output with an assigned transform feedback offset was
    not written to by its shader, the value recorded for that component is
    undefined.  The results of writing an output variable to a transform
    feedback buffer are undefined if any component of that variable would be
    written at an offset not aligned to the size of the component.  When
    capturing a vertex, any portion of the reserved storage not associated
    with an output variable with an assigned transform feedback offset will be
    unmodified.

    (delete the last three paragraphs, p. 459, which describe
    INTERLEAVED_ATTRIBS and SEPARATE_ATTRIBS mode; this is already handled by
    the language defining TransformFeedbackAttribs in terms of offsets and
    strides)

    (modify the first paragraph, p. 460, removing the incorrect reference to
    "geometry program")

    When using a geometry shader that writes vertices to multiple ...
    
    (modify the third paragraph, p. 460)

    Any transform feedback binding point used for capturing vertices must have
    buffer objects bound when BeginTransformFeedback is called.  A binding
    point requires a bound buffer object if and only if its associated stride
    in the program object used for transform feedback primitive capture is
    non-zero.


    Modify Section 15.2.3, Shader Outputs (Fragment Shader Variables), p. 514

    (modify the fifth paragraph, p. 515, making an output variable binding
     refer to "components of a fragment color")

    The binding of a user-defined output variable to components of a fragment
    color number can be specified explicitly in shader text or using the
    command...

    (modify the third paragraph, p. 516)

    When a program is linked, each active user-defined fragment shader output
    variable will have a binding consisting of a fragment color number, a
    fragment color index, and a component index.  Output variables declared
    with "location", "component", or "index" layout qualifiers will use the
    values specified in the shader text.  Output variables without such layout
    qualifiers will use bindings specified by BindFragDataLocationIndexed or
    BindFragDataLocation, if any.  Otherwise, the linker will automatically
    assign a fragment color number, using any color number not already
    assigned to another active fragment shader output variable.  The fragment
    color index and component index of an output variable binding will default
    to zero unless values are explicitly specified by a layout qualifer or
    BindFragDataLocationIndexed.  The properties of an active fragment shader
    output variable binding can be queried using the command
    GetProgramResourceiv with a <programInterface> of PROGRAM_OUTPUT and
    <props> values of LOCATION, LOCATION_INDEX, and LOCATION_COMPONENT.

    When a fragment shader terminates, the value of each active user-defined
    output variable is written to components of the fragment color output to
    which it is bound.  The set of fragment color components written is
    determined according to the variable's data type and component index
    binding, using the mappings in table X.1.  For an output variable declared
    as an array bound to fragment color number <i>, individual active array
    elements are written to consecutive fragment color numbers beginning with
    <i>, with the components written determined from the array element's data
    type and the array variable's component index binding.

    Output binding assignments will cause LinkProgram to fail:

    (modify the third bullet immediately below the previous edit, p. 516, and
     add a new bullet immediately after it)

      * if two output variables are bound to the same output number and index
        with overlapping components selected;

      * if two output variables with different component types (signed
        integer, unsigned integer, or floating-point) are bound to the same
        output number, even if selected components do not overlap; or
      
Additions to the OpenGL Shading Language

    Including the following line in a shader can be used to control the
    language features described in this extension:

        #extension GL_ARB_enhanced_layouts : <behavior>

    where <behavior> is as specified in section 3.3.

    New preprocessor #defines are added to the OpenGL Shading Language:

        #define GL_ARB_enhanced_layouts 1

Additions to Chapter 4 "Variables and Types" of the OpenGL Shading Language

    Section 4.4 "Layout Qualifiers"

    The existing last paragraph already says:

        "More than one layout qualifier may appear in a single declaration. If
        the same layout-qualifier-name occurs in multiple layout qualifiers
        for the same declaration, the last one overrides the former ones."

    Expand it to say:

        "More than one layout qualifier may appear in a single declaration.
        Additionally, the same layout-qualifier-name can occur multiple times 
        within a layout qualifier or across multiple layout qualifiers in the 
        same declaration. When the same layout-qualifier-name occurs 
        multiple times, in a single declaration, the last occurrence overrides 
        the former occurrence(s).  Further, if such a layout-qualifier-name 
        will effect subsequent declarations or other observable behavior, it 
        is only the last occurrence that will have any effect, behaving as if 
        the earlier occurrence(s) within the declaration are not present.  
        This is also true for overriding layout-qualifier-names, where one 
        overrides the other (e.g., row_major vs. column_major); only the last 
        occurrence has any effect."
    
    Section 4.4.1 "Input Layout Qualifiers"

    Change

        "All shaders, except compute shaders, allow input layout location 
        qualifiers on input variable declarations."

    To

        "All shaders, except compute shaders, allow *location* layout qualifiers 
        on input variable declarations, input block declarations, and input 
        block member declarations.  Of these, variables and block members 
        (but not blocks) additionally allow the *component* layout qualifier."

    Change

        "The layout qualifier identifier for inputs is

            "layout-qualifier-id
                location = integer-constant

        "Only one argument is accepted. For example,"

    to

        "The layout qualifier identifiers for inputs are

            "layout-qualifier-id
                location = integral-constant-expression
                component = integral-constant-expression

        "where integral-constant-expression is defined in Section 4.3.3 
        Constant Expressions as /integral constant expression/"

        "For example,"

    Add more examples:

            const int start = 6;
            layout(location = start + 2) int vec4 v;

    and change the first sentence describing them to

        "will establish that the shader input normal is assigned to vector 
        location number 3 and v is assigned location number 8."

    About 18 other occurrences of "integer-constant" all need to be changed per
    above to "integral-constant-expression", throughout Sections 4.4.1.2 
    through 4.4.6.2.

    Change

        "If the declared input is a structure, its members will be
        assigned consecutive locations in the order of declaration, with the 
        first member assigned the location specified for the structure."

    To

        "If the declared input is a structure or block, its members will be
        assigned consecutive locations in their order of declaration, with the 
        first member assigned the location provided in the layout qualifier.  
        For a structure.  It is a compile-time error to use a location 
        qualifier on a member of a structure.  For a block, this process 
        applies to the entire block, or until the first member is reached 
        that has a location layout qualifier.  When a block member is declared 
        with a location qualifier, its location comes from that qualifier:  The
        member's location qualifier overrides the block-level declaration.
        Subsequent members are again assigned consecutive locations, based
        on the newest location, until the next member declared with a *location*
        layout qualifier.  The values used for locations do not have to be 
        declared in increasing order.

        "It is a compile-time error to declare a block with some of its members 
        having a location, but not all.  Thus, if a block has no 
        block-level *location* layout qualifier, it is required that either all 
        or none of its members have a *location* layout qualifier."

    Change the next paragraph so it reads

        "The locations consumed by block and structure members are
        determined..."

    Change the subsequent examples to 

          layout(location = 3) in struct S {
              vec3 a;                       // gets location 3
              mat2 b;                       // gets locations 4 and 5
              vec4 c[2];                    // gets locations 6 and 7
              layout (location = 8) vec2 A; // ERROR, can't use on struct member
          } s;

          layout(location = 4) in block {
              vec4 d;                       // gets location 4
              vec4 e;                       // gets location 5
              layout(location = 7) vec4 f;  // gets location 7
              vec4 g;                       // gets location 8
              layout (location = 1) vec4 h; // gets location 1
              vec4 i;                       // gets location 2
              vec4 j;                       // gets location 3
              vec4 k;                       // ERROR, location 4 already used
          };

    Remove the paragraph

        "Location layout qualifiers may be used on input variables declared as 
        structures, but not on individual members. Location layout qualifiers 
        may not be used on input blocks or input block members. Compile-time 
        errors result if these rules are not followed."

    Replace the paragraph (parts of it show up again at the end of this section)

        "A program will fail to link if any two non-vertex shader input 
        variables or block members are assigned to the same location...."

    with part of it's last sentence (keep this here):

        "A program will fail to link if explicit location assignments leave the
        linker unable to find space for other variables without explicit 
        assignments."

    Add, after the specification for 'location', the following:

        "The *component* qualifier allows the location to be more finely 
        specified for scalars and vectors, down to the individual components 
        within a location that are
        consumed.  It is a compile-time error to use *component* without
        also specifying *location* (order does not matter).  The components 
        within a location are 0, 1, 2, and 3. A variable or block member
        starting at component N will consume components N, N+1, N+2, ... up 
        through its size.  For example:

            // a consumes components 2 and 3 of location 4
            layout(location = 4, component = 2) vec2 a;  

            // b consumes component 1 of location 4
            layout(location = 4, component = 1) float b; 

            // ERROR: c overflows components 2 and 3
            layout(location = 3, component = 2) vec3 c;
            
        "If the variable is an array, each element of the array, in order, is 
        assigned to consecutive locations, but all at the same specified 
        component within each location.  For example:

            // component 3 in 6 locations are consumed
            layout(location = 2, component = 3) float d[6];

        "That is, location 2 component 3 will hold d[0], location 3 component 3
        will hold d[1], ..., up through location 7 component 3 holding d[5].

        "This allows packing of two arrays into the same set of locations:

            // e consumes beginning (components 0, 1 and 2) of each of 6 slots
            layout(location = 0, component = 0) vec3 e[6];  

            // f consumes last component of the same 6 slots            
            layout(location = 0, component = 3) float f[6];            

        "If applying this to an array of arrays, all levels of arrayness are
        removed to get to the elements that are assigned per location to the
        specified component.  These non-arrayed elements will fill the locations
        in the order specified for arrays of arrays in section 4.1.9 "Arrays".

        "It is a compile-time error to apply the *component* qualifier to a
        matrix, a structure, a block, or an array containing any of these.
        It is a link-time error to specify different components for the same
        variable within a program.

        "/Location aliasing/ is causing two variables or block members to have 
        the same location number.  /Component aliasing/ is assigning the same 
        (or overlapping) component numbers for two location aliases.  (Recall 
        if component is not used, component's are assigned starting with 0.)  
        With one exception, location aliasing is allowed only if it does not 
        cause component aliasing; it is a compile-time or link-time error to 
        cause component aliasing.  Further, when location aliasing, the aliases
        sharing the location must have the same underlying numerical type 
        (floating-point or integer) and the same auxiliary storage and 
        interpolation qualification.  The one exception where component aliasing 
        is permitted is for two input variables (not block members) to a vertex 
        shader, which are allowed to have component aliasing.  This 
        vertex-variable component aliasing is intended only to support vertex 
        shaders where each execution path accesses at most one input per each 
        aliased component.  Implementations are permitted, but not required, to
        generate link-time errors if they detect that every path through the 
        vertex shader executable accesses multiple inputs aliased to any single 
        component."
        
    Section 4.4.2 "Output Qualifiers"

    Change
    
        "All shaders, except compute shaders, allow location output layout 
        qualfiers on output variable declarations."

    To
        
        "As with input layout qualifiers, all shaders except compute shaders 
        allow *location* layout qualifiers on output variable declarations, 
        output block declarations, and output block member declarations.  Of 
        these, variables and block members (but not blocks) additionally 
        allow the *component* layout qualifier."

    And add the layout-qualifier-id:
                
                component = integer-constant-expression

    Following that, add this new paragraph:

        "The usage and rules for using the *component* qualifier, and applying
        *location* qualifier to blocks and structures, are as described in
        section 4.4.1 "Input Layout Qualifiers".  Additionally, for fragment 
        shader outputs, if two variables are placed within the same location, 
        they must have the same underlying type (floating-point or integer).
        No component aliasing of output variables or members is allowed."

    Remove the second (redundant)

                location = integer-constant

    Add a new section 4.4.2.1 "Transform Feedback Layout Qualifiers"

        "The vertex, tessellation, and geometry stages allow shaders to control
        transform feedback.  When doing this, shaders will dictate which 
        transform feedback buffers are in use, which output variables will be
        written to which buffers, and how each buffer is laid out.  To 
        accomplish this, shaders allow the following layout qualifier identifiers
        on output declarations:

            layout-qualifier-id
                xfb_buffer = integral-constant-expression
                xfb_offset = integral-constant-expression
                xfb_stride = integral-constant-expression

    "Any shader making any static use (after preprocessing) of any of these 
    *xfb_* qualifiers will cause the shader to be in a transform feedback 
    capturing mode and hence responsible for describing the transform feedback 
    setup.  This mode will capture any output selected by 
    *xfb_offset*, directly or indirectly, to a transform feedback buffer.

    "The *xfb_buffer* qualifier specifies which transform feedback buffer will 
    capture those outputs selected with *xfb_offset*.  The *xfb_buffer* 
    qualifier can be applied to the qualifier out, to output variables, to 
    output blocks, and to output block members.  Shaders in the transform 
    feedback capturing mode have an initial global default of

        layout(xfb_buffer = 0) out;
  
    "This default can be changed by declaring a different buffer with xfb_buffer
    on the interface qualifier out.  This is the only way the global default can
    be changed.  When a variable or output block is declared without an 
    xfb_buffer qualifier, it inherits the global default buffer.  When a variable
    or output block is declared with an xfb_buffer qualifier, it has that 
    declared buffer.  All members of a block inherit the block's buffer.  A 
    member is allowed to declare an xfb_buffer, but it must match the buffer
    inherited from its block, or a compile-time error results.

    "The *xfb_buffer* qualifier follows the same conventions, behavior, 
    defaults, and inheritance rules as the qualifier stream, and the examples 
    for stream apply here as well.  This includes a block's inheritance of the 
    current global default buffer, a block member's inheritance of  the block's 
    buffer, and the requirement that any *xfb_buffer* declared on a block 
    member must match the buffer inherited from the block.

        layout(xfb_buffer=2, xfb_offset=0) out block {  // block's buffer is 2
            layout(xfb_buffer = 2) vec4 v; // okay, matches the inherited 2
            layout(xfb_buffer = 3) vec4 u; // ERROR, mismatched buffer
            vec4 w;                        // inherited
        };
        layout (xfb_offset=16) out vec4 t; // initial default is buffer 0
        layout (xfb_buffer=1) out;         // new global default of 1
        out block {                        // block has buffer 1
            vec4 x;                        // x has buffer 1 (not captured)
            layout(xfb_buffer = 1) vec4 y; // okay (not captured)
            layout(xfb_buffer = 0) vec4 z; // ERROR, mismatched buffer
        };
        layout(xfb_offset=0) out vec4 g;   // g has buffer 1
        layout(xfb_buffer=2) out vec4 h;   // does not change global default
        layout(xfb_offset=16) out vec4 j;  // j has buffer 1

    "Note this means all members of a block that go to a transform feedback 
    buffer will go to the same buffer.

    "It is a compile-time error to specify an *xfb_buffer* that is greater than 
    the implementation-dependent constant gl_MaxTransformFeedbackBuffers.

    "The *xfb_offset* qualifier assigns a byte offset within a transform 
    feedback buffer.  Only variables, block members, or blocks can be qualified 
    with *xfb_offset*.  If a block is qualified with *xfb_offset*, all its 
    members are assigned transform feedback buffer offsets.  If a block is 
    not qualified with *xfb_offset*, any members of that block not qualified
    with an *xfb_offset* will not be assigned transform feedback buffer 
    offsets.  Only variables and block members that are assigned offsets will 
    be captured (thus, a proper subset of a block can be captured).  Each time 
    such a variable or block member is written in a shader, the written value 
    is captured at the assigned offset.  If such a block member or variable is 
    not written during a shader invocation, the buffer contents at the assigned 
    offset will be undefined.  Even if there are no static writes to a variable 
    or member that is assigned a transform feedback offset, the space is still 
    allocated in the buffer and still affects the stride.

    "Variables and block members qualified with *xfb_offset* can be scalars, 
    vectors, matrices, structures, and (sized) arrays of these.  The offset must be
    a multiple of the size of the first component of the first qualified variable 
    or block member, or a compile-time error results.  Further, if applied to 
    an aggregate containing a double, the offset must also be a multiple of 8, 
    and the space taken in the buffer will be a multiple of 8.  The given 
    offset applies to the first component of the first member of the qualified 
    entity.  Then, within the qualified entity, subsequent components are each 
    assigned, in order, to the next available offset aligned to a multiple of 
    that component's size.  Aggregate types are flattened down to the component 
    level to get this sequence of components.  It is a compile-time error to 
    apply xfb_offset to the declaration of an unsized array.

    "The *xfb_stride* qualifier specifies how many bytes are consumed by each 
    captured vertex.  It applies to the transform feedback buffer for that 
    declaration, whether it is inherited or explicitly declared. It can be 
    applied to variables, 
    blocks, block members, or just the qualifier out.  If the buffer is 
    capturing any double-typed outputs, the stride must be a multiple of 8, 
    otherwise it must be a multiple of 4, or a compile-time or link-time error 
    results.  It is a compile-time or link-time error to have any *xfb_offset* 
    that overflows *xfb_stride*, whether stated on declarations before or 
    after the *xfb_stride*, or in different compilation units.  While 
    *xfb_stride* can be declared multiple times for the same buffer, it is a 
    compile-time or link-time error to have different values specified for the 
    stride for the same buffer.

    "For example:

        // buffer 1 has 32-byte stride
        layout (xfb_buffer = 1, xfb_stride = 32) out;  

        // same as previous example; order within layout does not matter
        layout (xfb_stride = 32, xfb_buffer = 1) out;  
            
        // everything in this block goes to buffer 0
        layout (xfb_buffer = 0, xfb_stride = 32) out block1 {
            layout (xfb_offset = 0)  vec4 a; // a goes to byte offset 0 of buffer 0
            layout (xfb_offset = 16) vec4 b; // b goes to offset 16 of buffer 0
        };
        
        layout (xfb_buffer = 1, xfb_offset = 12) out block2 {
            vec4 v;  // v will be written to byte offsets 12 through 27 of buffer 1
            float u; // u will be written to offset 28
            layout(xfb_offset = 40) vec4 w;
            vec4 x;  // x will be written to offset 56, the next available offset
        };            

        layout (xfb_buffer = 2, xfb_stride = 32) out block3 {
            layout (xfb_offset = 12) vec3 c;
            layout (xfb_offset = 24) vec3 d; // ERROR, requires stride of 36
            layout (xfb_offset = 0)  vec3 g; // okay, increasing order not required
        };

    "When no *xfb_stride* is specified for a buffer, the stride of a buffer will 
    be the smallest needed to hold the variable placed at the highest offset,
    including any required padding.  For example:

        // if there no other declarations for buffer 3, it has stride 32
        layout (xfb_buffer = 3) out block4 {
            layout (xfb_offset = 0)  vec4 e;
            layout (xfb_offset = 16) vec4 f;
        };

    "The resulting stride (implicit or explicit) must be less than or equal to 
    the implementation-dependent constant 
    gl_MaxTransformFeedbackInterleavedComponents."

    Section 4.4.2.1 Tessellation Control Outputs

    Insert in front of the first sentence:
        
        "Other than for the transform feedback layout qualifiers, 

    Section 4.4.5 "Uniform and Shader Storage Blocks"

    Add offset and align to the list, making it be

        layout-qualifier-id
            shared
            packed
            std140
            std430
            row_major
            column_major
            binding = integral-constant-expression
            offset = integral-constant-expression
            align = integral-constant-expression

    Modify the paragraph starting soon after as "Default layouts..." to read:

    "Default layouts for shared, packed, std140, std430, row_major, and 
    column_major are established at global scope for uniform blocks as"
    
    At the end of the section, add descriptions of these:

    "The *offset* qualifier can only be used on block members of blocks 
    declared with *std140* or *std430* layouts.
    The *offset* qualifier forces the qualified member to start at or after the 
    specified integral-constant-expression, which will be its byte offset 
    from the beginning of the buffer.  It is a compile-time error to 
    specify an *offset* that is smaller than the offset of the previous 
    member in the block or that lies within the previous member of the 
    block.  Two blocks linked together in the same program with the same 
    block name must have the exact same set of members qualified with 
    *offset* and their integral-constant-expression values must be the 
    same, or a link-time error results.  The specified offset must be a 
    multiple of the base alignment of the type of the block member it 
    qualifies, or a compile-time error results.

    "The *align* qualifier can only be used on blocks or block members, and 
    only for blocks declared with *std140* or *std430* layouts.  The *align* 
    qualifier makes the start of each block member have a minimum byte 
    alignment.  It does not affect the internal layout within each member, 
    which will still follow the std140 or std430 rules.  The specified 
    alignment must be a power of 2, or a compile-time error results.
      
    "The /actual alignment/ of a member will be the greater of the specified 
    *align* alignment and the standard (e.g., *std140*) base alignment for the 
    member's type.  The /actual offset/ of a member is computed as follows:  
    If *offset* was declared, start with that offset, otherwise start with the 
    next available offset.  If the resulting offset is not a multiple of the 
    /actual alignment/, increase it to the first offset that is a multiple of 
    the /actual alignment/.  This results in the /actual offset/ the member 
    will have.

    "When *align* is applied to an array, it effects only the start of the 
    array, not the array's internal stride.  Both an *offset* and an *align* 
    qualifier can be specified on a declaration.

    "The *align* qualifier, when used on a block, has the same effect as 
    qualifying each member with the same *align* value as declared on the 
    block, and gets the same compile-time results and errors as if this had 
    been done.  As described in general earlier, an individual member can 
    specify its own *align*, which overrides the block-level *align*, but 
    just for that member."

    Section 4.5.1 "4.5.1 Redeclaring Built-in Interpolation Variables in the Compatibility Profile"

    Modify the paragraph starting "Ideally, these are redeclared..." to read

    "Ideally, these are redeclared as part of the redeclaration of an interface 
    block, as described in section 7.1.1 `Compatibility Profile Built-In Language 
    Variables'.  However, for the above purpose, they can be redeclared as
    individual variables at global scope, outside an interface block.  Such 
    redeclarations also allow adding the transform-feedback qualifiers 
    xfb_buffer, xfb_stride, and xfb_offset to output variables.  (Using 
    xfb_buffer on a variable does not change the global default buffer.)...
    <rest of paragraph>."

    Section 7.1 "Built-In Language Variables"

    Near the end of this section, around 2nd to last paragraph, which is:

    "This establishes the output interface the shader will use with the 
    subsequent pipeline stage.  It must be a subset of the built-in 
    members of gl_PerVertex."

    Add the following:

    "Such a redeclaration can also add the invariant qualifier, interpolation 
    qualifiers, and the layout qualifiers xfb_offset, xfb_buffer, and xfb_stride.  
    It can also add an array size for unsized arrays. For example:

        out layout(xfb_buffer = 1, xfb_stride = 16) gl_PerVertex {
            vec4 gl_Position;
            layout(xfb_offset = 0) float gl_ClipDistance[4];
        };

    "Other layout qualifiers, like location, cannot be added to such a 
    redeclaration, unless specifically stated."

Examples:

        layout(std140) uniform block {
            vec4 a;
            layout(offset = 20) vec3 b; // b takes offsets 20-31
            layout(offset = 28) vec2 c; // ERROR, lies within previous member
            layout(offset = 36) vec2 d; // d takes offsets 36-43
            layout(align = 16) float e; // e takes offsets 48-51
            layout(align = 2) double f; // f takes offsets 56-63
            layout(align = 6) double g; // ERROR, 6 is not a power of 2
            layout(offset = 68) float h; // h takes offsets 64-71
            layout(align = 16) dvec3 i;  // i takes offsets 80-103
            layout(offset = 105, align = 4) float i; // i takes offsets 108-111
        };"


Additions to Chapter 7.3 "Built-In Constants" of the OpenGL Shading Language

    Add

            const int gl_MaxTransformFeedbackBuffers = 4;
            const int gl_MaxTransformFeedbackInterleavedComponents = 64;

Additions to Chapter 9 "Shading Language Grammar for Core Profile" of the OpenGL Shading Language

    Change

        IDENTIFIER EQUAL INTCONSTANT
        
    to
        IDENTIFIER EQUAL constant_expression

Additions to the AGL/EGL/GLX/WGL Specifications

    None

GLX Protocol

    None

Dependencies on OpenGL 3.3 and ARB_explicit_attrib_location

    If neither OpenGL 3.3 nor ARB_explicit_attrib_location are supported, new
    "location" and "component" layout qualifier support for vertex shader
    inputs and fragment shader outputs is not supported.

Dependencies on OpenGL 4.0 and ARB_vertex_attrib_64bit

    If neither OpenGL 4.0 nor ARB_vertex_attrib_64bit is supported, references
    to double-precision attribute variables should be removed.

Dependencies on OpenGL 4.0 and ARB_transform_feedback3

    If neither OpenGL 4.0 nor ARB_transform_feedback3 are supported, only a
    single binding point can be used for transform feedback using
    INTERLEAVED_ATTRIBS, including the new layout qualifier approach.  It will
    be a compile-time error to use an "xfb_buffer" layout qualifier with a
    value other than zero and the value of the implementation-dependent GLSL
    constant gl_MaxTransformFeedbackBuffers will be 1.

Dependencies on OpenGL 4.1 and ARB_separate_shader_objects

    If neither OpenGL 4.1 nor ARB_separate_shader_objects are supported, new
    "location" and "component" layout qualifier support for inputs and outputs
    other than vertex shader inputs and fragment shader outputs is not
    supported.

Dependencies on OpenGL 4.3 and ARB_shader_storage_buffer_object

    If neither OpenGL 4.3 nor ARB_shader_storage_buffer_object is supported,
    references to shader storage blocks should be removed.

Dependencies on OpenGL 4.3 and ARB_program_interface_query

    If neither OpenGL 4.3 nor ARB_program_interface_query is supported, edits
    to section 7.3.1 and the corresponding tokens should be removed.  Add an
    edit to the spec language describing GetTransformFeedbackVarying to
    indicate that when layout qualifiers are used to specify transform
    feedback offsets, the set of active transform feedback variables
    enumerated by GetTransformFeedbackVarying and related APIs appears in
    arbitrary order.


Errors

    No new API errors.

New State

    Modify Table 23.53, Program Object Resource State (cont'd)

                                                             Initial
    Get Value                         Type  Get Command      Value    Description                Sec.
    -----------------------           ----  -----------      -------  ------------------------   -----
    LOCATION_COMPONENT                Z+    GetProgram-         -     location component         7.3.1
                                              Resourceiv              assigned to active
                                                                      resource

New Implementation Dependent State

    None.

Conformance Tests

    TBD

Issues

    1) Do we need a sizeof() operator to aid in assigning layout locations?
       Would it need to be queried from the app as well?

       Aligning based on the size of previous member is what the system already
       does.  Do we have a use case that needs custom packing following a 
       structure, which cannot be handled by an *align* layout identifier?
       
       RESOLUTION: No.

    2) Do we need to allow layout locations to be placed on blocks?

       Discussion:  Yes, for SSO matching by location.  But, do we still 
       need them on members?  A block could still be a well-defined block
       of memory, and if an interface is mixing/matching content of a block
       it seems they put the wrong things together in a block.

       RESOLUTION: Add for members for symmetry with UBOs and some utility
       as well.  Order doesn't matter.

    3) Do we need to support discovery of the current offset?  E.g.,
       
           layout(offset = currentOffset + 3)

       RESOLUTION:  No.

    4) Should we add a component-space for layout locations, which is no longer
       vec4 centric, but purely component centric?  This is perhaps difficult
       as an add-on feature, but rather needs the specs as a whole to drop the
       vec4 nature of inputs/outputs.

       RESOLUTION:  No.  This is deferred until a future release that can make
       a larger change in this area, e.g., wholly drop the vec4 slot nature of
       inputs/outputs.

    5) Instead of dynamic selection of outputs for transform/feedback, use
       locations.

       RESOLUTION: Use syntax in the shader layout blocks, not an entry point 
       in the API.  Either "layout(transformfeedback: var1, var2 var3) out;"
       or tag individual members.  Applies to both inside and outside blocks.

    6) Is it an error to specify an *offset* that is not naturally aligned?

       RESOLUTION:  Yes, all offsets should be naturally aligned, but see 
       issue 10: it is natural alignment of the type, not the component.

    7) Is there an error at some point if an xfb_buffer is not valid?  There
       are two cases here A) the buffer number is valid, B) the buffer number
       is out of range.

       RESOLVED A) No, there is no error, it is valid because the shader said so.

       RESOLVED B) This should be a compile-time or link-time error.

    8) What API changes are needed to support component locations?  There is
       currently no mention of stages in the specification language above,
       implying all stages' inputs and outputs can specify component
       locations.  Probably, we either need to drop input components to 
       the vertex stage and output components from the fragment stage, or
       consider API changes needed to support them.

       RESOLUTION: Behavior is well-defined for all stages.  Need to broaden
       query functions to include component numbers.

    9) How do we keep xfb buffers within implementation-dependent widths?
       Is this known at compile time?

       RESOLUTION: The actual stride of the buffer is determined by the stride in
       the shader, overriding any API settings.  However, it is a link-time
       error to go over the limits of either
       
            MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS
       
       GLSL only needs to include the limits for interleaved components.

    10) For uniform-like buffers only: might want offset of a vec3 to be vec4 
        aligned, not just component-sized aligned.  Is there a portable rule?
        Or implementation-dependent rule?

        RESOLUTION: Alignments will be multiples of the base alignment of the
        member's type.

    11) The location associated with a vertex shader input variable or fragment
        shader output variable can be specified in the shader using a location
        layout qualifier or in the OpenGL API using commands such as
        BindAttribLocation and BindFragDataLocation.  Should we provide new
        variants of the OpenGL API commands (e.g., BindAttribLocationComponent)
        allowing applications to specify components with locations?

        RESOLVED:  No.

    12) Vertex shader input and fragment shader output variables declared
        without a location layout qualifier will have a location assigned by
        the compiler.  What components will be assigned to such variables?

        RESOLVED:  All variables declared without a 'location' layout
        qualifier will be assigned a 'component' value of zero.  The first
        component of any such vertex input variable will be taken from the
        first component of the corresponding generic attribute.  The first
        component of any such fragment output variable will be written to the
        first component of corresponding fragment color.

        If we allowed to compiler to automatically assign vertex input or
        fragment output variables to components other than zero, it could
        avoid link errors in cases where a shader requires more locations than
        the implementation supports.  However, such a change would break
        existing applications that query the locations of their input or
        output variables, since they wouldn't be expecting component
        assignments other than zero.  If we really wanted to support this,
        we'd probably need a directive in the shader indicating that the
        compiler can assign to arbitrary components.

    13) How should we allow applications to query the components associated
        with shader input and output variables?

        RESOLVED:  Extend the generic ARB_program_interface_query (OpenGL
        4.3) active resource query API GetProgramResourceiv by providing a new
        property LOCATION_COMPONENT.  This will query the component associated
        with a location assignment, in the same way that the existing LOCATION
        and LOCATION_INDEX properties query the location and location index
        numbers.

    14) OpenGL 4.3 also includes the queries GetProgramResourceLocation and
        GetProgramResourceLocationIndex to directly query the location and
        location index of a named variable.  Should we provide a similar query
        GetProgramResourceLocationComponent for location components?

        RESOLVED:  No.

        ARB_program_interface_query provided the GetProgramResourceLocation
        entry point to serve as a generic version of pre-4.3 entry points such
        as GetUniformLocation, and to a lesser extent GetActiveAttrib and
        GetFragDataLocation.  These entry points, particularly
        GetUniformLocation, are commonly used.  We also provided
        GetProgramResourceLocationIndex to query the much less commonly-used
        location index, mostly for completeness.  Both commands are simply
        short-cuts; it's possible for an application to perform such queries
        by calling GetProgramResourceIndex to map a variable name to an active
        resource index and then calling GetProgramResourceiv to query the
        location or location index.  If we care about full orthogonality, we
        should add a new GetProgramResourceComponent command.  If not,
        applications could still query component bindings with the sequence
        above.

        Since the only way to assign non-zero component indices to input or
        output variables is via explicit shader text, these queries seem less
        important.  In earlier versions of OpenGL, the compiler always
        assigned the locations of uniforms, and it was always necessary to
        query their locations to perform an update.

    15) OpenGL 4.3 also includes older APIs to query the locations of vertex
        shader inputs and fragment shader outputs (GetActiveAttrib,
        GetFragDataLocation, GetFragDataIndex).  Should we provide similar
        queries for location components?

        RESOLVED:  No.  We added the generic ARB_program_interface_query
        feature to OpenGL 4.3 so we didn't have to keep adding new APIs and
        tokens for every combination of resource type and property.

    16) For active vertex shader inputs and fragment shader outputs, what
        happens if two variables with different basic component types are
        bound to different components of the same generic attribute or
        fragment color output?

        RESOLVED:  For fragment shader outputs, generate a link error.  For
        vertex shader inputs, no link error occurs.  However, the values of
        any vertex shader input not matching the attribute type programmed in
        the API (via VertexAttrib* or VertexAttrib*Pointer) will be undefined.

        In unextended OpenGL 4.3, we already require that the generic
        attribute associated with a vertex shader input variable be specified
        using the same component type as the variable.  Additionally, we
        require that the framebuffer attachments receiving a fragment output
        color must have the same component type as the output variable.  In
        either case, values are undefined to avoid the overhead of a mandatory
        draw-time error check based on frequently-changed vertex attribute
        values.  In code like the following:

          layout(location=3) in float var1;
          layout(location=4) in int var2;

        the value of <var1> is undefined if generic attribute 3 isn't
        specified with floating-point values and the value of <var2> is
        undefined if generic attribute 4 isn't specified with integer values.
        But it's always possible for an application to specify correct
        attribute values for each type.

        Mismatches due to component layout qualifers have similar problems.
        In a vertex shader with the following declarations:

          layout(location=3, component=0) in float var1;
          layout(location=3, component=1) in int var2;

        the vertex shader would want to read the <x> component of generic
        attribute 3 as a floating-point value and the <y> component of that
        attribute as a signed integer.  We provide no way to specify separate
        components of a single attribute with a different type, so one of the
        values must be undefined if the shader is considered legal.

        We chose to make this illegal for fragment shader outputs, since it
        can't possibly do the right thing without relying on undefined raw
        bit-cast behavior.  We do allow this for vertex shader inputs, because
        we've supported "aliasing" behavior since OpenGL 2.0.  This allows for
        an "uber-shader" with variables like:

          layout(location=3) in float var1;
          layout(location=3) in int var2;

        where sometimes it uses <var1> and sometimes <var2>.  Since we don't
        treat the code above (with overlapping components) as an error, it
        would be strange to treat non-overlapping component assignments as an
        error.
        
    17) How will applications be able to query the layout of transform
        feedback varyings if they are specified in the shader?

        RESOLVED:  Add the ability to query offset and active buffer
        associations for each variable in the TRANSFORM_FEEDBACK_VARYING
        interface, which can now be specified by layout qualifier.
        Additionally, add a new interface TRANSFORM_FEEDBACK_BUFFER, which
        enumerates the set of active binding points used in transform feedback
        (similar to the ATOMIC_COUNTER_BUFFER interface for atomic counter
        uniforms).

        In unextended OpenGL 4.3, transform feedback varyings are specified by
        passing a list of name strings to TransformFeedbackVaryings() before
        linking, where those name strings include both real variables and
        special "marker" variables like "gl_SkipComponents1" and
        "gl_NextBuffer".  The application can then query back the list of
        transform feedback varyings and their properties, including markers,
        using the TRANSFORM_FEEDBACK_VARYING interface with the
        GetProgramResourceName and GetProgramResourceiv APIs.  Additionally,
        applications can use the legacy OpenGL 3.0 API
        GetTransformFeedbackVarying().  The varyings are enumerated in the
        order specified in TransformFeedbackVaryings(), and it's up to the
        application to figure out the offsets/buffers assigned to each.
        ("Figuring" this out is often unnecessary, since applications have
        already specified the variable list.)  The special markers need to be
        enumerated as variables in this API to allow the applications
        applications can figure out the storage.

        When using the existing enumeration API with variables with transform
        feedback layout qualifiers, the active variables are enumerated in
        arbitrary order and offsets/bindings can be queried explicitly.  No
        special markers like "gl_NextBuffer" are enumerated.

        One other option considered was specifying that the linker
        reverse-engineer a list of outputs for TransformFeedbackVaryings based
        on layout qualifiers and then operate as if that list were provided
        directly.  For example, if you specified something like:

          layout(xfb_buffer=0, xfb_stride=48) out;
          layout(xfb_buffer=0, xfb_offset=4) out vec4 batman;
          layout(xfb_buffer=2, xfb_offset=0) out vec4 robin;
          layout(xfb_buffer=2, xfb_offset=16) out vec3 joker;

        this reverse-engineering would build the following list:

          gl_SkipComponents1    // first 4 bytes
          batman                // next 16 bytes
          gl_SkipComponents4    // another 16 bytes, still in buffer 0
          gl_SkipComponents3    // final 12 bytes, per xfb_stride
          gl_NextBuffer
          gl_NextBuffer
          robin                 // first 16 bytes in buffer 2
          joker                 // last 12 bytes in buffer 2

        Having an API to query offsets and buffers more directly seemed
        preferable.

        The new API is patterned after the ATOMIC_COUNTER_BUFFER interface,
        which also has variables associated with a collection of numbered
        binding points.  Consider the code above and an implementation that
        sorts active binding points and variables by declaration order.  The
        commands

          GetProgramInterface(program, TRANSFORM_FEEDBACK_BUFFER,
                              ACTIVE_RESOURCES, &value);
          GetProgramInterface(program, TRANSFORM_FEEDBACK_VARYING,
                              ACTIVE_RESOURCES, &value);

        return 2 (binding points 0 and 2) and 3 ("batman", "robin", and
        "joker").

          GetProgramInterface(program, TRANSFORM_FEEDBACK_BUFFER,
                              MAX_NUM_ACTIVE_VARIABLES, &value);

        returns 2 (the two variables "robin" and "joker" associated with
        binding point 2).  GetProgramResourceiv for the two active binding
        points in the TRANSFORM_FEEDBACK_BUFFER interface would return:

          property              index 0 (binding 0)   index 1 (binding 2)
          --------------------  --------------------  --------------------
          BUFFER_BINDING        0                     2
          NUM_ACTIVE_VARIABLES  1                     2
          ACTIVE_VARIABLES      { 0 }                 { 1, 2 }
          TRANSFORM_FEEDBACK_   48                    28
            BUFFER_STRIDE

       GetProgramResourceiv for the three active variables in the
       TRANSFORM_FEEDBACK_VARYING interface would return:

                                (batman)      (robin)       (joker)
          property              index 0       index 1       index 2
          --------------------  ------------  ------------  ------------
          NAME_LENGTH           7             6             6
          TYPE                  FLOAT_VEC4    FLOAT_VEC4    FLOAT_VEC3
          ARRAY_SIZE            0             0             0
          OFFSET                4             0             16
          TRANSFORM_FEEDBACK_   0             1             1
            BUFFER_INDEX        

    18) If you have a program where transform feedback layout qualifiers are
        specified both in the shader text and via TransformFeedbackVaryings,
        what happens?

        RESOLVED:  To be consistent with other features where similar things
        can happen (e.g., BindAttribLocation), we should allow the
        declarations in the shader text to "win".  When LinkProgram is called,
        transform feedback state specified via TransformFeedbackVaryings() is
        ignored if the shader used for transform feedback specifies an
        "xfb_offset" layout qualifier on any of its variables.
     
    19) Do we need #extension support for this feature?

        RESOLVED:  Yes.  There is no reason we couldn't support some of the
        features (e.g, UBO offset) on OpenGL 3.X hardware.  We will require
        OpenGL 3.1 / GLSL 1.40, since this is where layout qualifiers were
        first supported.  For each extended feature, we will require the
        relevant core version or extension:

        * OpenGL 3.3 and ARB_explicit_attrib_location for location and
          component qualifiers on vertex shader inputs and fragment shader
          outputs.

        * OpenGL 4.1 and ARB_separate_shader_objects for location and
          component qualifiers all other shader inputs and outputs.

        * OpenGL 4.0 and ARB_transform_feedback3 on multiple output buffers in
          interleaved mode (i.e., "xfb_buffer" values other than zero).

        * OpenGL 4.3 and ARB_shader_storage_buffer_object for extended layout
          qualifiers on shader storage blocks.

        * OpenGL 4.3 and ARB_program_interface_query to query offsets assigned
          to transform feedback varyings.

    20) For "varyings" (e.g., vertex shader outputs, fragment shader inputs),
        component selection via layout qualifiers allow you to store two
        different variables in a single vector "location".  Those variables
        might have different data types or interpolation qualifiers?  Is this
        a problem for any implemenations of this extension?

        RESOLVED:  We will have a compile-time or link-time error for
        differing types or different interpolation qualifiers assigned to the
        same location.

    21) Is the new ability to query offsets and active buffers for each
        variable in the TRANSFORM_FEEDBACK_VARYING interface supported for
        programs whose transform feedback outputs are specified via
        TransformFeedbackVaryings?

        RESOLVED:  Yes.  The implementation will build a list of
        offsets/bindings during linking.

    22) We do need to precisely define what it means to have transform
        feedback layout declared in the shader text (e.g., the XFB layout
        qualifiers are declared anywhere), and how various corner cases work.
        Examples:

        A) What qualifiers can be used globally on "out", on block
          declarations, and individual variables? 
  
        B) If a shader has an "xfb_stride" qualifier for a buffer, but doesn't
          declare "xfb_offset" for any variable associated with that buffer,
          what happens?

        C) If the shader has an "xfb_buffer" qualifier identifying a buffer,
          but doesn't declare "xfb_offset" on anything associated with it,
          what happens?

        D) If we have variables with "xfb_offset" associated with buffers 0 and
          2, what happens with buffer 1?

        E) If the shader declares "xfb_offset" on some but not all block
          members, what happens with the ones without an offset?  Are they not
          captured?

        F) If a shader variable is qualified with "xfb_offset" but is not
          statically referenced, what happens?

        RESOLVED:  For issue (A), we allow "xfb_offset" on blocks, block
        members, and variables.  When using "xfb_offset" on a block, all
        members are assigned consecutive offsets.  For issue (B), the buffer
        has N bytes reserved for each vertex, but nothing will be written to
        it.  For issue (C), variables not qualified with "xfb_offset" are not
        captured, which makes the associated "xfb_buffer" qualifier
        irrelevant.  For issue (D), nothing is captured to buffer 1, and if no
        "xfb_stride" qualifier is specified for buffer 1, no storage will be
        reserved there.  For issue (E), block members without an offset are
        not captured.  For issue (F), all variables with an assigned offset
        will have storage reserved (possibly affecting the stride) whether or
        not they are statically referenced.  Unreferenced variables, as well
        as referenced variables not written for a given shader invocation,
        will be treated as having undefined values.

    23) This is related to issues 16 and 20.  Its resolution was that we
        would have an error if two fragment shader outputs with different 
        component types were assigned to different components of the same
        location.  We wouldn't have an error for vertex shader inputs
        because of the aliasing allowed in the spec since 2.0.

        What should we do for "varyings", which don't interface with
        resources in the API (vertex shader inputs, fragment shader outputs).
        Would implementations have a problem with the following pair of 
        vertex shader outputs/fragment shader inputs?

          // different types, different components, same vector
          layout(location=2,component=1) out float f;
          layout(location=2,component=2) out int g;

        Further, for the "mixed component types in a vector", do we need 
        language related to the automatic assignment of variables without a 
        location? For example, let's say we had fragment outputs like:

            layout(location=0,component=3) out int f;
            layout(location=0,component=0) out vec3 g;

        we'd have an error due to the component type mismatch.  But what if we 
        had this?

            layout(location=0,component=3) out int f;
            out vec3 g;  // location assigned by compiler

        Should the compiler would be required to avoid location 0 in this 
        case, even though it could "fit" into the first three components?

        RESOLVED:  For fragment outputs, no mixing is allowed, while 
        for varyings between stages, the compiler is free to assign locations
        as it sees fit.  If the underlying hardware is vector-based and
        requires all components of a vector to have identical
        types/qualifiers, it may need to avoid certain locations.  If there is
        no such limitation, the compiler is free to pack variables of
        different types into a single location.

    24) Should we allow "xfb_stride" layout qualifiers on block declations?
        Strides must be associated with a binding point ("xfb_binding"), but
        there is not a 1:1 correspondence between blocks and binding points.

        UNRESOLVED:  TBD

    25) Should we allow "xfb_offset" on block declarations to specify that all
        block members are captured with increasing offset?  If so, should we
        allow the "xfb_offset" qualifier on block members to override the
        offset for that member and subsequent ones?  Also, if we allow it,
        what happens if you try to qualfy a block member with a different
        value for "xfb_buffer"?

        UNRESOLVED:  TBD

    26) How should we handle "xfb_offset" and "xfb_stride" layout qualifiers
        when the shader specifies that it wants to capture double-precision
        scalars, vectors, matrices, as well as arrays and structures
        containing these types?

        UNRESOLVED:  In unextended OpenGL 4.3, we specify undefined behavior
        if we attempt to capture any double-precision component that doesn't
        have an offset aligned to a multiple of 8 bytes.  This is discussed in
        issue (4) of the ARB_gpu_shader_fp64 extension, which notes that to
        align all doubles captured, three things must happen:

          (a) the offset of the base of a buffer object must be a multiple of
              eight bytes;

          (b) the amount of data captured per vertex must be a multiple of
              eight bytes; and

          (c) each double-precision variable captured must be aligned to a
              multiple of eight bytes relative to the beginning of a vertex.

        We could have enforced restrictions (b) and (c) in LinkProgram in
        ARB_gpu_shader_fp64, but chose not to because we couldn't conveniently
        enforce (a).  Applications can always work around issues (b) and (c)
        by injecting padding via "gl_SkipComponents1" markers in their list of
        varyings.  We also could have (but didn't) specified that the linker
        would insert such padding automatically.

        It might have been a good idea to have enforced (b) and (c) anyway to
        reduce the cases where undefined behavior occurs.  Since this
        extension provides a new way to specify output layout, we can choose
        to specify a new behavior when using the new method, without changing
        the handling of the old method.  We are choosing to specify a link
        error if "xfb_offset" or "xfb_stride" is specified but incorrectly
        aligned, and to specify that the linker injects padding if the
        offset/stride are derived automatically.


Revision History

    Revision 1, 19-Dec-2012 (JohnK)
      - Create overview.
    Revision 2, 21-Jan-2013 (JohnK)
      - Pin down a specific proposal in the overview, and add first 
        5 issues.
    Revision 3, 23-Jan-2013 (JohnK)
      - Allow locations on input/output blocks/members
      - Add details about alignment rules, aliasing, number ranges, etc.
      - Resolve issues 1, 2, 3, and 5.
    Revision 4, 14-Feb-2013 (JohnK)
      - Update from ARB meeting
      - Resolve issue 4
      - Incorporate resolution of issue 5
    Revision 5, 13-Mar-2013 (JohnK)
      - Simplify overview
      - First draft specification language for features 1-5 (not 6).
    Revision 6, 28-Mar-2013 (JohnK)
      - Change xfb streams and components to buffers and offsets 
        (aligned and non aliasing)
      - Uniform buffer-like offsets must be naturally aligned.
      - Updated issues 6-9
    Revision 7, 28-Mar-2013 (JohnK)
      - xfb_width -> xfb_stride, order doesn't matter
      - resolve issues 2, 7, 8, and 9
      - add issue 10
    Revision 8, 18-Apr-2013 (pbrown)
      - Add API specification language to query components assigned to
        input/output variables.
      - Add spec language describing the effects of component assignments
        to vertex shader inputs and fragment shader outputs, which interface
        with other API resources (generic attributes, FBO attachments).
      - Add stub spec language describing how transform feedback layout
        qualifiers operate in the API; we have issues to resolve before
        attempting the final language.
      - Add issues 11-18.
    Revision 9, 18-Apr-2013 (pbrown)
      - Add more issues, including issue 19.
    Revision 10, 3-May-2013 (pbrown)
      - Add new program interface query support for transform feedback
        varyings (to query offsets and binding points for each variable)
        and transform feedback buffers (to query stride).
      - Add an example of the enumeration API in issue 17.
      - Start reworking the transform feedback section to use a collection
        of variables with offsets and strides instead of a list of
        consecutive variables.
      - Add errors if a fragment shader output location is shared between
        variables with differetn component types.
      - Add clarifications on the process of assigning locations to fragment
        shader outputs (avoiding locations used by any explicit assignments).
      - Close a number of previously unresolved issues.
      - Add issues 20 and 21, and fork issue 22 from issue 18.
    Revision 11, 6-May-2013 (JohnK)
      - Resolve bug 10132, which includes doing the following:
      - Expand on the rules for repeated layout qualifiers, ordering, effect
      - Don't allow /component/ on structs
      - Initial statef of "layout(xfb_buffer = 0) out;"
      - rules for applying xfb_offset to a block, array, or matrix
      - add gl_MaxTransformFeedbackInterleavedComponents
      - restrict *align* to blocks and block members
      - unresolve issue 7
      - update issue 9
      - add issue 23
    Revision 12, 7-May-2013 (JohnK)
      - Resolve bug 10130, which means the following:
      - Resolve issue 10
      - alignments from the align qualifier will be a multiple of the base 
        alignment of the type
      - offset qualifier ids must be a multiple of the base alignment of the 
        type
      - minor typo fixes
    Revision 13, 9-May-2013 (JohnK)
      - Allow location layout qualifiers on input/output blocks
      - This incorporates the resolution of issue 2
    Revision 14, 9-May-2013 (JohnK)
      - Resolved issues 7, 19, 20, 21, and 23.
    Revision 15, 10-May-2013 (JohnK)
      - Address feedback from pbrown review cycle
    Revision 16, 13-May-2013 (JohnK)
      - Add #extension (issue 19)
      - Add gl_MaxTransformFeedbackInterleavedComponents = 64;
      - Incorporated issues 7, 20, and 23
      - Update issue 22
      - Break out xfb_ stuff into its own section
      - Flesh out output location/component qualifier specification
      - Lots of editorial changes, including moving to bold for layout qualifier names
    Revision 17, 16-May-2013 (JohnK)
      - Resolve and incorporate issue 22.
    Revision 18, 18-May-2013 (pbrown)
      - Add API specification language for transform feedback-related link
        errors to cover cases of variables overflowing the specified stride
        of their associated binding.
      - Rework the API specification language describing how primitives are
        captured in transform feedback mode to deal in offsets and strides
        instead of ordered lists of variables.  Revision 10 had already
        re-defined TransformFeedbackVaryings as specifying offsets and
        strides.
      - Clarify that the OFFSET property of the TRANSFORM_FEEDBACK_VARYING
        returns the actual offset used for the variable, whether it was
        specified directly using a layout qualifier or indirectly using
        TransformFeedbackVaryings (issue 21).
      - Remove reference to MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS in
        issue 9; when using layout qualifiers, we always capture in
        INTERLEAVED_ATTRIBS mode.
      - Cleaned up issue 22, added resolutions for each of the sub-issues.
      - Add issues 24 and 25.
      - Minor cleanups for a few other issues.
    Revision 19, 18-May-2013 (pbrown)
      - Add dependencies for use of ARB_enhanced_layouts as an extension.
        Require OpenGL 3.1 / GLSL 1.40, since that's where layout qualifiers
        were first added.  For various features involving layout qualifers, 
        require the extension or core version where those layout qualifiers
        were first supported.
      - Fix a typo involving MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS.
      - Close issue 19.
    Revision 20, 21-May-2013 (JohnK)
      - Remove erroneous disembodied xfb_stride example
    Revision 21, 21-May-2013 (pdaniell)
      - Assign enum token values
    Revision 22, 28-May-2013 (JohnK)
      - Fix bugs 10249 and 10267: Expand on (stream's) rules of inheritance for 
        xfb_buffer, allow xbf_offset to be on both a block its members, and 
        xfb_stride can appear an anything.  Other clarifications.
      - Fix bug 10266: xfb_stride must be a multiple of 8 if capturing doubles,
        and offsets are aligned to multiples of the component's size.
      - Fix bug 10247: Describe how actual offsets are computed based on offset 
        and align.
      - Fix bug 10248: Either a whole block has location layout qualification or 
        none of it does.
      - Other minor editorial changes.
    Revision 23, 28-May-2013 (pbrown)
      - Add API language specifying that automatically derived transform
        feedback strides (when xfb_stride is not used) will be padded out to a
        multiple of 8 when the buffer captures one or more doubles.
      - Add API language specifying a link error if the "xfb_offset" set for
        any variable containing doubles is not a multiple of 8, or if the
        "xfb_stride" set for any binding point with an associated variable
        containing doubles is not a multiple of 8.
      - Add issue 26.
    Revision 24, 30-May-2013 (pbrown)
      - Fixed a typo in the dependencies section for OpenGL 4.1 and
        ARB_separate_shader_objects.
    Revision 25, 31-May-2013 (JohnK)
      - Bug 10248: Redo aliasing language regarding location and component 
        aliasing.
      - Bug 10318: More strongly state that align operates at the member 
        level and not internally within members.
      - Bug 10321: More strongly state that xfb_offset applied to aggregates 
        (arrays, structures, nesting,...) operates by flattening the aggregate 
        down to a sequence of components.
    Revision 26, 3-July-2013 (JohnK)
      - Include mention of API changes in the overview, and fix the offset example.
      - Bug 10371: Be explicit that when the gl_PerVertex block is redeclared,
        the declaration can add on invariant, xfb_offset, xfb_buffer, and 
        xfb_strideto its members, as well as array size for gl_ClipDistance.
      - Bug 10327: Editorial: Expanded the introduction to the transform-feedback 
        section. Described inheritance for xfb_bufferwithout referring to stream.
      - A few minor editorial corrections.
    Revision 27, June 13, 2014 (Jon Leech)
      - Remove GetProgramResourceLocation* as commands accepting the
        TRANSFORM_FEEDBACK_BUFFER interface from the New Tokens section (Bug
        10588).
