Name

    ARB_separate_shader_objects

Name Strings

    GL_ARB_separate_shader_objects

Contact

    Mark Kilgard, NVIDIA (mjk 'at' nvidia.com)
    Greg Roth, NVIDIA (groth 'at' nvidia.com)
    Pat Brown, NVIDIA (pbrown 'at' nvidia.com)

Contributors

    Bruce Merry, ARM
    Daniel Koch, TransGaming
    Eric Werness, NVIDIA
    Graham Sellers, AMD
    Greg Roth, NVIDIA
    Jason Green, TransGaming
    John Kessenich, Intel
    Jon Leech
    Kevin Rogovin 
    Nick Haemel, AMD
    Robert Ohannessian

Notice

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

Status

    Complete. Approved by the ARB on June 9, 2010.
    Approved by the Khronos Board of Promoters on July 23, 2010.

Version

    Last Modified Date:  1 August 2011
    Version:             25

Number

    ARB Extension #97

Dependencies

    Written based on the wording of the OpenGL 4.0 Compatibility
    Profile (March 11, 2010) specification.

    Written based on the wording of The OpenGL Shading Language 4.00.8
    (March 10, 2010) specification.

    This extension requires OpenGL 2.0 or ARB_shader_objects.

    This extension interacts with OpenGL 4.0 (Core Profile).

    This extension interacts with GLSL 1.40 (and earlier).

    This extension interacts with ARB_geometry_shader4,
    EXT_geometry_shader4, and/or NV_geometry_shader4.

    This extension depends on ARB_explicit_attrib_location.

    This extension interacts with ARB_tessellation_shader or OpenGL 4.0.

    This extension interacts with GL_ARB_gpu_shader_fp64 or OpenGL 4.0.

    This extension interacts with ARB_explicit_attrib_location,
    ARB_vertex_attrib_64bit, OpenGL 3.3, and OpenGL 4.1.

    This extension interacts with the EXT_separate_shader_objects extension.

    This extension interacts with ARB_vertex_program, ARB_fragment_program,
    NV_gpu_program4 and related assembly extensions.

Overview

    Conventional GLSL requires multiple shader stages (vertex,
    fragment, geometry, tessellation control, and tessellation
    evaluation) to be linked into a single monolithic program object to
    specify a GLSL shader for each stage.

    While GLSL's monolithic approach has some advantages for
    optimizing shaders as a unit that span multiple stages, all
    existing GPU hardware supports the more flexible mix-and-match
    approach.

    Shaders written for HLSL9, Cg, the prior OpenGL assembly program
    extensions, and game console favor a more flexible "mix-and-match"
    approach to specifying shaders independently for these different
    shader stages.  Many developers build their shader content around
    the mix-and-match approach where they can use a single vertex shader
    with multiple fragment shaders (or vice versa).

    This extension adopts a "mix-and-match" shader stage model for GLSL
    allowing multiple different GLSL program objects to be bound at once
    each to an individual rendering pipeline stage independently of
    other stage bindings. This allows program objects to contain only
    the shader stages that best suit the applications needs.

    This extension introduces the program pipeline object that serves as
    a container for the program bound to any particular rendering stage.
    It can be bound, unbound, and rebound to simply save and restore the
    complete shader stage to program object bindings.  Like framebuffer
    and vertex array objects, program pipeline objects are "container"
    objects that are not shared between contexts.

    To bind a program object to a specific shader stage or set of
    stages, UseProgramStages is used.  The VERTEX_SHADER_BIT,
    GEOMETRY_SHADER_BIT, FRAGMENT_SHADER_BIT, TESS_CONTROL_SHADER_BIT,
    and TESS_EVALUATION_SHADER_BIT tokens refer to the conventional
    vertex, geometry, fragment, tessellation control and tessellation
    evaluation stages respectively. ActiveShaderProgram specifies the
    program that Uniform* commands will update.

    While ActiveShaderProgram allows the use of conventional Uniform*
    commands to update uniform variable values for separable program
    objects, this extension provides a preferrable interface in a set
    of ProgramUniform* commands that update the same uniform variables
    but take a parameter indicating the program object to be updated,
    rather than updating the currently active program object. These
    commands mirror those introduced in EXT_direct_state_access.

    While glActiveShaderProgram provides a selector for setting and
    querying uniform values of a program object, the glProgramUniform*
    commands provide a selector-free way to modify uniforms of a GLSL
    program object without an explicit bind. This selector-free model
    reduces API overhead and provides a cleaner interface for
    applications.

    Separate linking creates the possibility that certain output varyings
    of a shader may go unread by the subsequent shader inputting varyings.
    In this case, the output varyings are simply ignored.  It is also
    possible input varyings from a shader may not be written as output
    varyings of a preceding shader.  In this case, the unwritten input
    varying values are undefined.

    This extension builds on the proof-of-concept provided by
    EXT_separate_shader_objects which demonstrated that separate
    shader objects can work for GLSL.  EXT_separate_shader_objects
    was a response to repeated requests for this functionality from
    3D developers.

    This ARB version addresses several "loose ends" in the prior
    EXT extension.  In particular, it allows user-defined varyings
    with explicitly defined locations or implicitly assigned locations.

    This ARB extension extends the GLSL language's use of layout
    qualifiers to provide cross-stage interfacing.
    
IP Status

    No known IP claims.

New Procedures and Functions

    void UseProgramStages(uint pipeline, bitfield stages,
                          uint program);

    void ActiveShaderProgram(uint pipeline, uint program);

    uint CreateShaderProgramv(enum type, sizei count,
                              const char **strings);

    void BindProgramPipeline(uint pipeline);

    void DeleteProgramPipelines(sizei n, const uint *pipelines);

    void GenProgramPipelines(sizei n, uint *pipelines);

    boolean IsProgramPipeline(uint pipeline);

    void ProgramParameteri(uint program, enum pname, int value);

    void GetProgramPipelineiv(uint pipeline, enum pname, int *params);

    void ProgramUniform1i(uint program, int location,
                          int x);
    void ProgramUniform2i(uint program, int location,
                          int x, int y);
    void ProgramUniform3i(uint program, int location,
                          int x, int y, int z);
    void ProgramUniform4i(uint program, int location,
                          int x, int y, int z, int w);

    void ProgramUniform1ui(uint program, int location,
                           uint x);
    void ProgramUniform2ui(uint program, int location,
                           uint x, uint y);
    void ProgramUniform3ui(uint program, int location,
                           uint x, uint y, uint z);
    void ProgramUniform4ui(uint program, int location,
                           uint x, uint y, uint z, uint w);

    void ProgramUniform1f(uint program, int location,
                          float x);
    void ProgramUniform2f(uint program, int location,
                          float x, float y);
    void ProgramUniform3f(uint program, int location,
                          float x, float y, float z);
    void ProgramUniform4f(uint program, int location,
                          float x, float y, float z, float w);

    void ProgramUniform1d(uint program, int location,
                          double x);
    void ProgramUniform2d(uint program, int location,
                          double x, double y);
    void ProgramUniform3d(uint program, int location,
                          double x, double y, double z);
    void ProgramUniform4d(uint program, int location,
                          double x, double y, double z, double w);

    void ProgramUniform1iv(uint program, int location,
                           sizei count, const int *value);
    void ProgramUniform2iv(uint program, int location,
                           sizei count, const int *value);
    void ProgramUniform3iv(uint program, int location,
                           sizei count, const int *value);
    void ProgramUniform4iv(uint program, int location,
                           sizei count, const int *value);

    void ProgramUniform1uiv(uint program, int location,
                            sizei count, const uint *value);
    void ProgramUniform2uiv(uint program, int location,
                            sizei count, const uint *value);
    void ProgramUniform3uiv(uint program, int location,
                            sizei count, const uint *value);
    void ProgramUniform4uiv(uint program, int location,
                            sizei count, const uint *value);

    void ProgramUniform1fv(uint program, int location,
                           sizei count, const float *value);
    void ProgramUniform2fv(uint program, int location,
                           sizei count, const float *value);
    void ProgramUniform3fv(uint program, int location,
                           sizei count, const float *value);
    void ProgramUniform4fv(uint program, int location,
                           sizei count, const float *value);

    void ProgramUniform1dv(uint program, int location,
                           sizei count, const double *value);
    void ProgramUniform2dv(uint program, int location,
                           sizei count, const double *value);
    void ProgramUniform3dv(uint program, int location,
                           sizei count, const double *value);
    void ProgramUniform4dv(uint program, int location,
                           sizei count, const double *value);

    void ProgramUniformMatrix2fv(uint program, int location,
                                 sizei count, boolean transpose,
                                 const float *value);
    void ProgramUniformMatrix3fv(uint program, int location,
                                 sizei count, boolean transpose,
                                 const float *value);
    void ProgramUniformMatrix4fv(uint program, int location,
                                 sizei count, boolean transpose,
                                 const float *value);

    void ProgramUniformMatrix2dv(uint program, int location,
                                 sizei count, boolean transpose,
                                 const double *value);
    void ProgramUniformMatrix3dv(uint program, int location,
                                 sizei count, boolean transpose,
                                 const double *value);
    void ProgramUniformMatrix4dv(uint program, int location,
                                 sizei count, boolean transpose,
                                 const double *value);

    void ProgramUniformMatrix2x3fv(uint program, int location,
                                   sizei count, boolean transpose,
                                   const float *value);
    void ProgramUniformMatrix3x2fv(uint program, int location,
                                   sizei count, boolean transpose,
                                   const float *value);
    void ProgramUniformMatrix2x4fv(uint program, int location,
                                   sizei count, boolean transpose,
                                   const float *value);
    void ProgramUniformMatrix4x2fv(uint program, int location,
                                   sizei count, boolean transpose,
                                   const float *value);
    void ProgramUniformMatrix3x4fv(uint program, int location,
                                   sizei count, boolean transpose,
                                   const float *value);
    void ProgramUniformMatrix4x3fv(uint program, int location,
                                   sizei count, boolean transpose,
                                   const float *value);

    void ProgramUniformMatrix2x3dv(uint program, int location,
                                   sizei count, boolean transpose,
                                   const double *value);
    void ProgramUniformMatrix3x2dv(uint program, int location,
                                   sizei count, boolean transpose,
                                   const double *value);
    void ProgramUniformMatrix2x4dv(uint program, int location,
                                   sizei count, boolean transpose,
                                   const double *value);
    void ProgramUniformMatrix4x2dv(uint program, int location,
                                   sizei count, boolean transpose,
                                   const double *value);
    void ProgramUniformMatrix3x4dv(uint program, int location,
                                   sizei count, boolean transpose,
                                   const double *value);
    void ProgramUniformMatrix4x3dv(uint program, int location,
                                   sizei count, boolean transpose,
                                   const double *value);

   void ValidateProgramPipeline(uint pipeline );

   void GetProgramPipelineInfoLog(uint pipeline, sizei bufSize,
                                  sizei *length, char *infoLog);

New Tokens

    Accepted by <stages> parameter to UseProgramStages:

        VERTEX_SHADER_BIT                      0x00000001
        FRAGMENT_SHADER_BIT                    0x00000002
        GEOMETRY_SHADER_BIT                    0x00000004
        TESS_CONTROL_SHADER_BIT                0x00000008
        TESS_EVALUATION_SHADER_BIT             0x00000010
        ALL_SHADER_BITS                        0xFFFFFFFF

    Accepted by the <pname> parameter of ProgramParameteri and
    GetProgramiv:

        PROGRAM_SEPARABLE                      0x8258

    Accepted by <type> parameter to GetProgramPipelineiv:

        ACTIVE_PROGRAM                         0x8259

    Accepted by the <pname> parameter of GetBooleanv, GetIntegerv,
    GetInteger64v, GetFloatv, and GetDoublev:

        PROGRAM_PIPELINE_BINDING               0x825A

Additions to Chapter 2 of the OpenGL 4.0 Compatibility Profile
Specification (OpenGL Operation):

 -- Section 2.14 "Vertex Shaders" (page 89)

    Modify the third paragraphs:

    To use a vertex shader, shader source code is first loaded into a
    shader object and then compiled. A shader object corresponds to a
    stage in the rendering pipeline referred to as its shader stage or
    type. One or more vertex shader objects are attached to a program
    object. The program object is then linked, which generates
    executable code from all the compiled shader objects attached to the
    program. When program objects are bound to a shader stage, they
    become the current program object for that stage. When the current
    program object for the vertex stage includes a vertex shader, it is
    considered the active program object for the vertex stage. The
    current program object for all stages may be set at once using a
    single unified program object, or the current program object may be
    set for each stage individually using a separable program object
    where different separable program objects may be current for other
    stages. The set of separable program objects current for all stages
    are collected in a program pipeline object that must be bound for
    use. When a linked program object is made active for the vertex
    stage, the executable code for the vertex shaders it contains is
    used to process vertices."

    Modify the last sentence in the fourth paragraph:

    "... A single program object can contain all of vertex, tessellation
    control, tessellation evaluation, geometry, and fragment shaders, or
    any subset thereof."

    Modify the fifth paragraph:

    "When the program object currently in use for the vertex stage
    includes a vertex shader, its vertex shader is considered active and
    is used to process vertices. If the current vertex stage program
    object has no vertex shader or no program object is current for the
    vertex stage, ..."

 -- Section 2.14.2 "Program Objects" (page 91) 

    In the list of linking failures following the description of
    LinkProgram, modify the bullets reading "the program contains no objects
    to form a vertex shader" when using a tessellation control, tessellation
    evaluation, or geometry shader (pp. 92-93) to read:

      - the program is not separable and contains no objects to form a
        vertex shader;

    Modify the eighth paragraph:

    If a program has been successfully linked by LinkProgram, it can be made
    part of the current rendering state for all shader stages with the command

        void UseProgram(uint program);

    If <program> is non-zero, this command will make <program> the current
    program object.  This will install executable code as part of the current
    rendering state for each shader stage present when the program was last
    successfully linked.  If UseProgram is called with <program> set to zero,
    then there is no current program object.  If <program> has not been
    successfully linked, the error INVALID_OPERATION is generated and the
    current rendering state is not modified.

    Insert before the last paragraph, p. 93:

    The executable code for an individual shader stage is taken from the
    current program for that stage.  If there is a current program object
    established by UseProgram, that program is considered current for all
    stages.  Otherwise, if there is a bound program pipeline object (section
    2.14.PPO), the program bound to the appropriate stage of the pipeline
    object is considered current.  If there is no current program object or
    bound program pipeline object, no program is current for any stage.  The
    current program for a stage is considered active if it contains executable
    code for that stage; otherwise, no program is considered active for that
    stage.  If there is no active program for the vertex or fragment shader
    stages,
      [[ Compatibility Profile ]] 
    fixed-function vertex and/or fragment processing will be used to process
    vertices and/or fragments.
      [[ Core Profile ]] 
    the results of vertex and/or fragment processing will be undefined. 
    However, this is not an error.
      [[ End Profile-Specific Language ]]
    If there is no active program for the tessellation control, tessellation
    evaluation, or geometry shader stages, those stages are ignored.

    Insert at the end of the section, p. 94 (note:  this will be inserted
    below several of the edits that follow).

    "The command

        uint CreateShaderProgramv(enum type, sizei count,
                                  const char **strings);

    creates a stand-alone program from an array of null-terminated
    source code strings for a single shader type.  CreateShaderProgramv
    is equivalent to the following command sequence:

        const uint shader = CreateShader(type);
        if (shader) {
            ShaderSource(shader, count, strings, NULL);
            CompileShader(shader);
            const uint program = CreateProgram();
            if (program) {
                int compiled = FALSE;
                GetShaderiv(shader, COMPILE_STATUS, &compiled);
                ProgramParameteri(program, PROGRAM_SEPARABLE, TRUE);
                if (compiled) {
                    AttachShader(program, shader);
                    LinkProgram(program);
                    DetachShader(program, shader);
                }
                append-shader-info-log-to-program-info-log
            }
            DeleteShader(shader);
            return program;
        } else {
            return 0;
        }

    The program may not actually link if the output variables in the
    shader attached to the final stage of the linked program take up
    too many locations. If this situation arises, the info log may
    explain this.

    Because no shader is returned by CreateShaderProgramv and the
    shader that is created is deleted in the course of the command
    sequence, the info log of the shader object is copied to the program
    so the shader's failed info log for the failed compilation is
    accessible to the application."

    Modify first and second paragraphs, p. 94:

    If a program object that is active for any shader stage is re-linked
    successfully, the LinkProgram command will install the generated
    executable code as part of the current rendering state for all shader
    stages where the program is active.  Additionally, the newly generated
    executable code is made part of the state of any program pipeline for all
    stages where the program is attached.

    If a program object that is active for any shader stage is re-linked
    unsuccessfully, the link status will be set to FALSE, but existing
    executables and associated state will remain part of the current rendering
    state until a subsequent call to UseProgram, UseProgramStages, or
    BindProgramPipeline removes them from use.  If such a program is attached
    to any program pipeline object, the existing executables and associated
    state will remain part of the program pipeline object until a subsequent
    call to UseProgramStages removes them from use.  An unsuccessfully linked
    program may not be made part of the current rendering state by UseProgram
    or added to program pipeline objects by UseProgramStages until it is
    successfully re-linked.  If such a program was attached to a program
    pipeline at the time of a failed link, its existing executable may still
    be made part of the current rendering state indirectly by
    BindProgramPipeline.

    Modify the last paragraph of the section, p. 94:

    "If <program> is not current for any GL context, is not the active
    program for any program pipeline object, and is not the current
    program for any stage of any program pipeline object, it is deleted
    immediately. Otherwise, program is flagged ..."

    Insert prior to the description of DeleteProgram, p. 94 (note:  this text
    is inserted above the previous edit):

    "Program parameters control aspects of how the program is linked,
    executed, or stored. To set a program parameter, call

        void ProgramParameteri(uint program, enum pname, int value)

    <pname> identifies which parameter to set for program object
    <program>. <value> holds the value being set.
        If <pname> is PROGRAM_SEPARABLE, <value> must be TRUE or FALSE
    and indicates whether the <program> can be bound for individual
    pipeline stages via UseProgramStages after it is next linked.
        If <pname> is any other value, the error INVALID_ENUM is
    generated.

 -- New section 2.14.PPO "Program Pipeline Objects" after 2.14.2
    "Program Objects"

    Instead of packaging all shader stages into a single program object,
    shader types might be contained in multiple program objects each
    consisting of part of the complete pipeline. A program object may
    even contain only a single shader stage. This facilitates greater
    flexibility when combining different shaders in various ways without
    requiring a program object for each combination.

    Program bindings associating program objects with shader types are
    collected to form a program pipeline object.

    The command

        void GenProgramPipelines(sizei n, uint *pipelines);

    returns <n> previously unused program pipeline object names in
    <pipelines>. These names are marked as used, for the purposes of
    GenProgramPipelines only, but they acquire state only when they are
    first bound.

    Program pipeline objects are deleted by calling

        void DeleteProgramPipelines(sizei n, const uint *pipelines);
    
    <pipelines> contains <n> names of program pipeline objects to be
    deleted. Once a program pipeline object is deleted, it has no
    contents and its name becomes unused. If an object that is currently
    bound is deleted, the binding for that object reverts to zero and no
    program pipeline object becomes current. Unused names in <pipelines>
    are silently ignored, as is the value zero.

    A program pipeline object is created by binding a name returned by
    GenProgramPipelines with the command

        void BindProgramPipeline(uint pipeline);

    <pipeline> is the program pipeline object name. The resulting program
    pipeline object is a new state vector, comprising ACTIVE_PROGRAM,
    VERTEX_SHADER, GEOMETRY_SHADER, FRAGMENT_SHADER, TESS_CONTROL_SHADER,
    and TESS_EVALUATION_SHADER.

    BindProgramPipeline may also be used to bind an existing program
    pipeline object. If the bind is successful, no change is  made to
    the state of the bound program pipeline object, and any previous
    binding is broken. If BindProgramPipeline is called with <pipeline>
    set to zero, then there is no current program pipeline object.

    If no current program object has been established by UseProgram, the
    program objects used for each shader stage and for uniform updates are
    taken from the bound program pipeline object, if any.  If there is a
    current program object established by UseProgram, the bound program
    pipeline object has no effect on rendering or uniform updates.  When a
    bound program pipeline object is used for rendering, individual shader
    executables are taken from its program objects as described in the
    discussion of UseProgram in section 2.14.2.

    BindProgramPipeline fails and an INVALID_OPERATION error is
    generated if <pipeline> is not zero or a name returned from a
    previous call to GenProgramPipelines, or if such a name has since
    been deleted with DeleteProgramPipelines.

    The executables in a program object associated with one or more
    shader stages can be made part of the program pipeline state for
    those shader stages with the command:

       void UseProgramStages(uint pipeline, bitfield stages,
                             uint program);

    where <pipeline> is the program pipeline object to be updated,
    <stages> is the bitwise OR of accepted constants representing
    shader stages, and <program> is the program object from which the
    executables are taken. The bits set in <stages> indicate the program
    stages for which the program object named by <program> becomes
    current. These stages may include tessellation control, tessellation
    evaluation, vertex, geometry, or fragment indicated by TESS_CONTROL_-
    SHADER_BIT, TESS_EVALUATION_SHADER_BIT, VERTEX_SHADER_BIT, GEOMETRY_-
    SHADER_BIT, or FRAGMENT_SHADER_BIT respectively. The constant ALL_-
    SHADER_BITS indicates <program> is to be made current for all
    shader stages. If <program> refers to a program object with a valid
    shader attached for an indicated shader stage, this call installs
    the executable code for that stage in the indicated program pipeline
    object state.  If UseProgramStages is called with <program> set to
    zero or with a program object that contains no executable code for a
    given stages, it is as if the pipeline object has no programmable stage
    configured for the indicated shader stages.  If <stages> is not the
    special value ALL_SHADER_BITS and has a bit set that is not recognized,
    the error INVALID_VALUE is generated.  If the program object named
    by <program> was linked without the PROGRAM_SEPARABLE parameter set
    or was not linked successfully, the error INVALID_OPERATION is 
    generated and the corresponding shader stages in the <pipeline> 
    program pipeline object are not modified.

    If <pipeline> is a name that has been generated (without subsequent
    deletion) by GenProgramPipelines, but refers to a program pipeline
    object that has not been previously bound, the GL first creates a
    new state vector in the same manner as when BindProgramPipeline
    creates a new program pipeline object. If <pipeline> is not a name
    returned from a previous call to GenProgramPipelines or if such a
    name has since been deleted by DeleteProgramPipelines, an INVALID_-
    OPERATION error is generated.

    The command

        void ActiveShaderProgram(uint pipeline, uint program);

    sets the linked program named by <program> to be the active program
    (discussed later in the secion 2.14.4) for the program pipeline
    object <pipeline> .  If <program> has not been successfully linked,
    the error INVALID_OPERATION is generated and active program is not
    modified.

    If <pipeline> is a name that has been generated (without subsequent
    deletion) by GenProgramPipelines, but refers to a program pipeline
    object that has not been previously bound, the GL first creates a
    new state vector in the same manner as when BindProgramPipeline
    creates a new program pipeline object. If <pipeline> is not a name
    returned from a previous call to GenProgramPipelines or if such a
    name has since been deleted by DeleteProgramPipelines, an INVALID_-
    OPERATION error is generated.


    Shader Interface Matching

    When multiple shader stages are active, the outputs of one stage form an
    interface with the inputs of the next stage.  At each such interface,
    shader inputs are matched up against outputs from the previous stage:

      * An output block is considered to match an input block in the
        subsequent shader if the two blocks have the same block name, and the
        members of the block match exactly in name, type, qualification, and
        declaration order.

      * An output variable is considered to match an input variable in the
        subequent shader if:

        * the two variables match in name, type, and qualification; or

        * the two variables are declared with the same location layout
          qualifier and match in type and qualification.

    Variables or block members declared as structures are considered to match
    in type if and only if structure members match in name, type,
    qualification, and declaration order.  Variables or block members declared
    as arrays are considered to match in type only if both declarations
    specify the same element type and array size.  The rules for determining
    if variables or block members match in qualification are found in the
    OpenGL Shading Language Specification.

    Tessellation control shader per-vertex output variables and blocks and
    tessellation control, tessellation evaluation, and geometry shader
    per-vertex input variables and blocks are required to be declared as
    arrays, with each element representing input or output values for a single
    vertex of a multi-vertex primitive.  For the purposes of interface
    matching, such variables and blocks are treated as though they were not
    declared as arrays.

    For program objects containing multiple shaders, LinkProgram will check
    for mismatches on interfaces between shader stages in the program being
    linked and generate a link error if a mismatch is detected.  A link error
    will be generated if any statically referenced input variable or block
    does not have a matching output.  If either shader redeclares the built-in
    array gl_ClipDistance[] ((compatibility profile only: or gl_TexCoord[])),
    the array must have the same size in both shaders.  ((compatibility
    profile only: If either shader redeclares built-in input or output color
    variables, they must have matching interpolation qualifiers, as described
    in the OpenGL Shading Language Specification.))

    With separable program objects, interfaces between shader stages may
    involve the outputs from one program object and the inputs from a
    second program object.  For such interfaces, it is not possible to
    detect mismatches at link time, because the programs are linked
    separately.  When each such program is linked, all inputs or outputs
    interfacing with another program stage are treated as active.  The
    linker will generate an executable that assumes the presence of a
    compatible program on the other side of the interface.  If a mismatch
    between programs occurs, no GL error will be generated, but some or all
    of the inputs on the interface will be undefined.

    At an interface between program objects, the set of inputs and outputs are
    considered to match exactly if and only if:

      * The built-in input and output blocks used on the interface
        ("gl_PerVertex" or "gl_PerFragment") match, as described below.

      * Every declared input block or variable must have a matching output, as
        described above.

      * There are no output blocks or user-defined output variables
        declared without a matching input block or variable declaration.

    When the set of inputs and outputs on an interface between programs
    matches exactly, all inputs are well-defined unless the corresponding
    outputs were not written in the previous shader.  However, any mismatch
    between inputs and outputs results in all inputs being undefined except
    for cases noted below.  Even if an input has a corresponding output
    that matches exactly, mismatches on other inputs or outputs may
    adversely affect the executable code generated to read or write the
    matching variable.

    The inputs and outputs on an interface between programs need not match
    exactly when input and output location qualifiers (sections 4.3.8.1 and
    4.3.8.2 of the GLSL Specification) are used.  When using location
    qualifiers, any input with an input location qualifier will be
    well-defined as long as the other program writes to a matching output, as
    described above.  The names of variables need not match when matching by
    location.

    Additionally, scalar and vector inputs with location layout qualifiers
    will be well-defined if there is a corresponding output satisfying all of
    the following conditions:

      * the input and output match exactly in qualification, including in the
        location layout qualifier;

      * the output is a vector with the same basic component type and has more
        components than the input; and

      * the common component type of the input and output is "int", "uint", or
        "float" (scalars and vectors with "double" component type are
        excluded).

    In this case, the components of the input will be taken from the first
    components of the matching output, and the extra components of the output
    will be ignored.

    To use any built-in input or output in the gl_PerVertex and
    gl_PerFragment blocks in separable program objects, shader code must
    redeclare those blocks prior to use.  A separable program will
    fail to link if:

      * it contains multiple shaders of a single type with different
        redeclarations of these built-in input and output blocks; or

      * any shader uses a built-in block member not found in the
        redeclaration of that block.

    [[ There are two somewhat different versions of the following language --
       one for the compatibility profile and the other for the core
       profile. ]]

    [[ Compatibility Profile ]] 

    As described above, an exact interface match requires matching built-in
    input and output blocks.  At an interface between two non-fragment 
    shader stages, the gl_PerVertex input and output blocks are considered 
    to match if and only if the block members members match exactly in 
    name, type, qualification, and declaration order.  At an interface 
    involving the fragment shader stage, a gl_PerVertex output block is
    considered to match a gl_PerFragment input block if all of the
    following conditions apply:

      * the gl_PerVertex block includes either gl_FrontColor or
        gl_BackColor if and only if the gl_PerFragment block includes
        gl_Color;

      * the gl_PerVertex block includes either gl_FrontSecondaryColor or
        gl_BackSecondaryColor if and only if the gl_PerFragment block
        includes gl_SecondaryColor; 

      * the gl_PerVertex block includes gl_FogFragCoord if and only if the
        gl_PerFragment block also includes gl_FogFragCoord; and

      * the size of gl_TexCoord[] in gl_PerVertex and gl_PerFragment is
        identical.

    At an interface between gl_PerVertex outputs and gl_PerFragment inputs,
    the presence or absence of any block members other than those listed
    immediately above does not affect interface matching.

    [[ Core Profile ]] 

    As described above, an exact interface match requires matching built-in
    input and output blocks.  At an interface between two non-fragment 
    shader stages, the gl_PerVertex input and output blocks are considered 
    to match if and only if the block members members match exactly in 
    name, type, qualification, and declaration order.  At an interface
    involving the fragment shader stage, the presence or absence of any
    built-in output does not affect interface matching.

    [[ End Profile-Specific Language ]]

    Built-in inputs or outputs not found in blocks do not affect interface
    matching.  Any such built-in inputs are well-defined unless they are
    derived from built-in outputs not written by the previous shader stage.


    Program Pipeline Object State

    "The state required to support program pipeline objects consists of
    a single binding name of the current program pipeline object. This
    binding is initially zero indicating no program pipeline object is
    bound.

    The state of each program pipeline object consists of:

    * Six unsigned integers (initially all zero) are  required to hold
      each respective name of the current vertex stage program, current
      geometry stage program, current fragment stage program, current
      tessellation control stage program, current tessellation evaluation
      stage program, and active program respectively.
    * A Boolean holding the status of the last validation attempt,
      initially false
    * An array of type char containing the information log, initially
      empty.
    * An integer holding the length of the information log"

 -- Section 2.14.4 "Uniform Variables" (page 97) 

    Replace the 1st paragraph of the "Loading Uniform Variables In The
    Default Uniform Block" section (page 108):

        "To load values into the uniform variables of the active program
    object, use the commands ...

    ... If a non-zero program object is bound by UseProgram, it is the
    active program object whose uniforms are updated by these commands.
    If no program object is bound using UseProgram, the active program
    object of the current program pipeline object set by ActiveShader-
    Program is the active program object. If the current program pipeline
    object has no active program or there is not current program pipeline
    object, then there is no active program.
        The given values are loaded into the default ... "

    Change the last bullet in the "Loading Uniform Variables In The
    Default Uniform Block" section (page 110) to:

    "* if there is no active program in use."

    Add to the end of the subsection "Loading Uniform Variables In The
    Default Uniform Block" section (page 110): 

    To load values into the uniform variables of the default uniform
    block of a program which may not necessarily be bound, use the
    commands

        void ProgramUniform{1234}{ifd}(uint program, int location,
                                       T value);
        void ProgramUniform{1234}{ifd}v(uint program, int location,
                                        sizei count, const T value);
        void ProgramUniform{1234}ui(uint program, int location,
                                    T value);
        void ProgramUniform{1234}uiv(uint program, int location,
                                     sizei count, T value);
        void ProgramUniformMatrix{234}{fd}v
                                      (uint program, int location,
                                       sizei count, boolean transpose,
                                       const float *value);
        void ProgramUniformMatrix{2x3 3x2 2x4 4x2 3x4 4x3}{fd}v
                                      (uint program, int location,
                                       sizei count, boolean transpose,
                                       const float *value);

    These commands operate identically to the corresponding commands
    above without "Program" in the command name except, rather than
    updating the currently active program object, these "Program"
    commands update the program object named by the initial <program>
    parameter.The remaining parameters following the initial <program>
    parameter match the parameters for the corresponding non-"Program"
    uniform command. If <program> is not the name of a created program
    or shader object, the error INVALID_VALUE is generated. If <program>
    identifies a shader object or a program object that has not been
    linked successfully, the error INVALID_OPERATION is generated.

 -- Section 2.14.4 "Subroutine Uniform Variables" (page 114) 

    Modify the last paragraph of the section, p. 117

    When the active program for a shader stage is re-linked or changed by a
    call to UseProgram, BindProgramPipeline, or UseProgramStages, subroutine
    uniforms for that stage are reset to arbitrarily chosen default functions
    with compatible subroutine types.


 -- Section 2.14.8 "Shader Execution" (page 122) 

    Change the first paragraph:

    "If there is an active program object present for the vertex,
    tessellation control, tessellation evaluation, or geometry shader
    stages, the executable code for these active programs is used
    to process incoming vertex values rather than the fixed-function
    vertex processing described in sections 2.12 through 2.13.  In
    particular, ..."

    Modify first paragraph of "Validation", p. 129

    (replace first paragraph) It is not always possible to determine at link
    time if a program object can execute successfully, given that LinkProgram
    can not know the state of the remainder of the pipeline.  Therefore
    validation is done when the first rendering command is issued, to
    determine if the set of active program objects can be executed.  If the
    current set of active program objects cannot be executed, no primitives
    are processed and the error INVALID_OPERATION will be generated.

    Add to the list in the second paragraph of subsection "Validation"
    (Page 129):

    "* A program object is active for at least one, but not all of the
      shader stages that were present when the program was linked.

    * One program object is active for at least two shader stages and
      a second program is active for a shader stage between two stages
      for which the first program was active.

    * There is an active program for tessellation control, tessellation
      evaluation, or geometry stages with corresponding executable
      shader, but there is no active program with executable vertex
      shader.

    * There is not current unified program object and the current program
      pipeline object includes a program object that was relinked since
      being applied to the pipeline object via UseProgramStages with the
      PROGRAM_SEPARABLE parameter set to FALSE."

    Add after the description of ValidateProgram in subsection
    "Validation":

    "Separable program objects may have validation failures that cannot
    be detected without the complete program pipeline. Mismatched
    interfaces, improper usage of program objects together, and the same
    state-dependent failures can result in validation errors for such
    program objects. As a development aid, use the command

        void ValidateProgramPipeline(uint pipeline );
    
    to validate the program pipeline object <pipeline> against the
    current GL state. Each program pipeline object has a boolean status,
    VALIDATE_STATUS, that is modified as a result of validation. This
    status can be queried with GetProgramPipelineiv (See section 6.1.18).
    If validation succeeded, the program pipeline object is guaranteed
    to execute given the current GL state. 

    If <pipeline> is a name that has been generated (without subsequent
    deletion) by GenProgramPipelines, but refers to a program pipeline
    object that has not been previously bound, the GL first creates a
    new state vector in the same manner as when BindProgramPipeline
    creates a new program pipeline object. If <pipeline> is not a name
    returned from a previous call to GenProgramPipelines or if such a
    name has since been deleted by DeleteProgramPipelines, an INVALID_-
    OPERATION error is generated.

 -- Section 2.15 "Tessellation" (page 131)

    (modify second paragraph, p. 132) ... Tessellation is considered active if
    and only if there is an active tessellation control or tessellation
    evaluation program object.

    (modify next-to-last paragraph, p. 132) Patch primitives are not supported
    by pipeline stages below the tessellation evaluation shader.  If there is
    no active tessellation evaluation program, the error INVALID_OPERATION is
    generated by Begin, and any command that performs an implicit Begin, if
    the primitive mode is PATCHES.

    Modify last paragraph, p. 132:

    "A program object or program pipeline object that includes a
    tessellation shader of any kind must also include a vertex shader.
    If the current program state has a tessellation shader but no
    vertex shader at Begin or any command that implicitly calls Begin, an
    INVALID_OPERATION error will be generated."

 -- Section 2.15.1 "Tessellation Control Shaders" (page 133)

    Change the first paragraph of "Tessellation Control Shader Execution
    Environment" (p. 134)

    "If there is an active program for the tessellation control stage, the
     executable version of the program's tessellation control shader is used
     ..."

 -- Section 2.15.3 "Tessellation Evaluation Shaders" (page 147)

    Change the first paragraph of "Tessellation Evaluation Shader
    Execution Environment" (p. 149)

    "If there is an active program for the tessellation evaluation stage, the
     executable version of the program's tessellation evaluation shader is
     used ..."

 -- Section 2.16, "Geometry Shaders" (page 153)

    Change the 4th paragraph:

    "A program object or program pipeline object that includes a
    geometry shader must also include a vertex shader. If the current
    program state has a geometry shader but no vertex shader at Begin or
    any command that implicitly calls Begin, an INVALID_OPERATION error
    will be generated."

 -- Section 2.16.1, Geometry Shader Input Primitives, p. 153

    (modify first paragraph of the section)  ... will generate an
    INVALID_OPERATION error if the primitive <mode> parameter is incompatible
    with the input primitive type of the geometry shader of the active
    geometry program object, as discussed below.

 -- Section 2.16.4, Geometry Shader Execution Environment

    Change the first paragraph:

    "If there is an active program for the geometry stage, the executable
     version of the program's geometry shader is used ..."

 -- Section 2.20 "Transform Feedback" (page 167)

    Modify first paragraph and add the subsequent paragraphs:

    "In transform feedback mode, attributes of the vertices of
    primitives passed to the transform feedback stage are written out to
    one or more buffer objects.  The vertices are fed back after vertex
    color clamping, but before flatshading and clipping. The transformed
    vertices may be optionally discarded after being stored into one or
    more buffer objects, or they can be passed on down to the clipping
    stage for further processing. The set of attributes captured is
    determined when a program is linked.

    The data captured in transform feedback mode depends on the active
    programs on each of the shader stages.  If a program is active for
    the geometry shader stage, transform feedback captures the vertices
    of each primitive emitted by the geometry shader.  Otherwise, if a
    program is active for the tessellation evaluation shader stage,
    transform feedback captures each primitive produced by the
    tessellation primitive generator, whose vertices are processed by the
    tessellation evaluation shader. Otherwise, transform feedback
    captures each primitive processed by the vertex shader.

    If separable program objects are in use, the set of attributes
    captured is taken from the program object active on the last shader
    stage processing the primitives captured by transform feedback.  The
    set of attributes to capture in transform feedback mode for any
    other program active on a previous shader stage is ignored."

    Add to list of INVALID_OPERATION errors on page 172

    * by UseProgramStages if the program pipeline object it refers to is
    current and the current transform feedback object is active and not
    paused.

    * by BindProgramPipeline if the current transform feedback object is
    active and not paused.

    * by ResumeTransformFeedback if the program pipeline object being
    used by the current transform feedback object is not bound, any of
    its shader stage bindings has changed, or a single program object
    is active and overriding it.

Additions to Chapter 3 of the OpenGL 4.0 Compatibility Profile
Specification (Rasterization)

 -- Section 3.12 "Fragment Shaders" (page 321) 

    Replace the second to the last paragraph with:

    "When the current fragment shader program object currently includes
    a fragment shader, its fragment shader is considered active, and is
    used to process fragments.  If the fragment shader program object
    has no fragment shader, or no fragment shader program object is
    currently in use, the fixed-function fragment processing operations
    described in the previous sections are used."

Additions to Chapter 4 of the OpenGL 4.0 Compatibility Profile
Specification (Per-Fragment Operations and the Frame Buffer)

    None

Additions to Chapter 5 of the OpenGL 4.0 Compatibility Profile
Specification (Special Functions)

 -- Section 5.5 "Display Lists" (page 410) 

    Add CreateShaderProgram, GenProgramPipelines, DeleteProgram-
    Pipelines, and BindProgramPipelines to the "Program and shader
    objects" list of commands that cannot be compiled into a display
    list but are instead executed immediately.

Additions to Chapter 6 of the OpenGL 4.0 Compatibility Profile Specific-
ation (State and State Requests)

 -- Section 6.1.18 "Shader and Program Queries"
    
    Add to GetProgramiv description:

    "If <pname> is PROGRAM_SEPARABLE, TRUE is returned if the program has
    been flagged for use as a separable program object that can be bound
    to individual shader stages with UseProgramStages."

    Add after GetProgramiv description:

    "The command 

        boolean IsProgramPipeline(uint pipeline);

    returns TRUE if <pipeline> is the name of a program pipeline object.
    If <pipeline> is zero, or a non-zero value that is not the name of a
    program pipeline object, IsProgramPipeline returns FALSE. No error
    is generated if <pipeline> is not a valid program pipeline object
    name.

    The command

        GetProgramPipelineiv(uint pipeline, enum pname, int *params);

    returns properties of the program pipeline object named <pipeline>
    in <params>. The parameter value to return is specified by <pname>.

    If <pipeline> is a name that has been generated (without subsequent
    deletion) by GenProgramPipelines, but refers to a program pipeline
    object that has not been previously bound, the GL first creates a
    new state vector in the same manner as when BindProgramPipeline
    creates a new program pipeline object. If <pipeline> is not a name
    returned from a previous call to GenProgramPipelines or if such a
    name has since been deleted by DeleteProgramPipelines, an INVALID_-
    OPERATION error is generated.

       If <pname> is ACTIVE_PROGRAM, the name of the active program
    object of the program pipeline object is returned.
       If <pname> is VERTEX_SHADER, the name of the current program
    object for the vertex shader type of the program pipeline object is
    returned.
       If <pname> is FRAGMENT_SHADER, the name of the current program
    object for the fragment shader type of the program pipeline object
    is returned.
       If <pname> is GEOMETRY_SHADER, the name of the current program
    object for the geometry shader type of the program pipeline object
    is returned;
       If <pname> is TESS_CONTROL_SHADER, the name of the current
    program object for the tessellation control shader type of the
    program pipeline object is returned;
       If <pname> is TESS_EVALUATION_SHADER, the name of the current
    program object for the tessellation evaluations shader type of the
    program pipeline object is returned.
       If <pname> is VALIDATE_STATUS, the validation status of the
    program pipeline object, as determined by ValidateProgramPipeline
    (see section 2.14.8) is returned.
       If <pname> is INFO_LOG_LENGTH, the length of the info log,
    including a null terminator, is returned. If there is no info log,
    zero is returned."
    If <pname> is not the name of an accepted parameter, an INVALID_-
    ENUM error is generated.

    Change paragraph describing GetShaderInfoLog and GetProgram:

    "A string that contains information about the last compilation
    attempt on a shader object, last link or validation attempt on a
    program object, or last validation attempt on a program pipeline
    object, called the info log, can be obtained with the commands

        void GetShaderInfoLog (uint shader, sizei bufSize,
                               sizei *length, char *infoLog);
        void GetProgramInfoLog (uint program, sizei bufSize,
                                sizei *length, char *infoLog);
        void GetProgramPipelineInfoLog (uint pipeline, sizei bufSize,
                                        sizei *length, char *infoLog);

    These commands return the info log string in <infoLog>. This string
    will be null-terminated. The actual number of characters written
    into <infoLog>, excluding the null terminator, is returned in
    <length>. If <length> is NULL, then no length is returned. The
    maximum number of characters that may be written into <infoLog>,
    including the null terminator, is specified by <bufSize>. The number
    of characters in the info log can be queried with GetShaderiv,
    GetProgramiv, or GetProgramPipelineiv with INFO_LOG_LENGTH. If
    <shader> is a shader object, the returned info log will either be an
    empty string or it will contain information about the last compil-
    ation attempt for that object. If <program> is a program object, the
    returned info log will either be an empty string or it will contain
    information about the last link attempt or last validation attempt
    for that object. If <pipeline> is a program pipeline object, the
    returned info log will either be an empty string or it will contain
    information about the last validation attempt for that object.


Additions to Appendix D of the OpenGL 4.0 Compatibility Profile Specific-
ation (Shared Objects and Multiple Contexts)

    (modify third paragraph, p. 533, making program pipeline objects
    non-shared) Framebuffer, query, vertex array, and program pipeline 
    objects are not shared.


Additions to the AGL/GLX/WGL Specifications

    None

Additions to the OpenGL Shading Language Specification, Version 4.00.8

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

      #extension GL_ARB_separate_shader_objects : <behavior>

    where <behavior> is as described in section 3.3.

    A new preprocessor #define is added to the OpenGL Shading Language:

      #define GL_ARB_separate_shader_objects 1

 -- Section 4.3 "Storage Qualifiers" (page 32):

    Add to the end of the section:

    When comparing an output from one shader stage to an input of a second
    shader stage, the input and output are considered to match only if
    compatible storage qualifiers are used.  An output declared with "out",
    "centroid out", "sample out", or "patch out" matches an input only if the
    input is declared with "in", "centroid in", "sample in", or "patch in",
    respectively.  Additionally, an output will only match an input with
    identical interpolation qualifiers.

    [[ Note:  If the GLSL specification is updated to break out "centroid",
       "sample", and "patch" as separate auxillary qualifiers instead of
       tightly coupling with "in" and "out" as in GLSL 4.00, this language
       should be rewritten to require that these auxillary qualifiers match
       (and that "in" match "out", of course). ]]

 -- Section 4.3.4 "Inputs" (page 36):

    Add to the end of the section:

    When an interface between shader stages is formed using shaders from two
    separate program objects, it is not possible to detect mismatches between
    inputs and outputs when the programs are linked.  When there are
    mismatches between inputs and outputs on such interfaces, the values
    passed across the interface will be partially or completely undefined.
    Shaders can ensure matches across such interfaces either by using input
    and output layout qualifiers (Sections 4.3.8.1 and 4.3.8.2) or by using
    identical input and output declarations.  Complete rules for interface
    matching are found in the "Shader Interface Matching" portion of section
    2.14.PPO of the OpenGL Specification.

 -- Section 4.3.8.1 "Input Layout Qualifiers" (page 44):

    All shaders allow location input layout qualifiers on input variable
    declarations. The location layout qualifier identifier for inputs is:

        layout-qualifier-id
            location = integer-constant

    Only one argument is accepted. For example,

        layout(location = 3) in vec4 normal;

    establishes that the shader input <normal> is assigned to location number
    3.  For vertex shader inputs, the location specifies the number of the
    generic vertex attribute from which input values are taken.  For inputs of
    all other shader types, the location specifies a vector number that can be
    used to match against outputs from a previous shader stage, even if that 
    shader is in a different program object.

    If the declared input has a scalar or vector type, it will consume a
    single location, except for non-vertex inputs of type "dvec3" and "dvec4",
    which will consume two consecutive locations.  Inputs of type "double" and
    "dvec2" will consume only a single location in all shaders.

    If the declared input is an array of size <n> and each element takes up
    <m> locations, it will be assigned <m>*<n> consecutive locations starting
    with the location specified.  For example,

        layout(location = 6) in vec4 colors[3];

    will establish that the input <colors> is assigned to vector
    location numbers 6, 7, and 8.

    If the declared input is an <n>x<m> single- or double-precision matrix, it
    will be assigned multiple locations starting with the location specified.
    The number of locations assigned for each matrix will be the same as for
    an <n>-element array of <m>-component vectors.  For example,

        layout(location = 9) in mat4 transforms[2];

    will establish that input <transforms> is assigned to vector location
    numbers 9-16, with transforms[0] being assigned to locations 9-12 and
    transforms[1] being assigned to locations 13-16.

    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.  The number of
    locations consumed by a structure member is determined by applying the
    rules above recursively as though the structure member were declared as
    an input variable of the same type.  For example,

        layout(location = 3) struct S {
           vec3 a;
           mat2 b;
           vec4 c[2];
        } s;

    will assign location 3 to "s.a", locations 4 and 5 to the two column
    vectors of "s.b", and locations 6 and 7 to "s.c".

    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.

    The number of input locations available to a shader is limited.  For
    vertex shaders, the limit is the advertised number of vertex attributes.
    For all other shaders, the limit is implementation-dependent and must be
    no less than one fourth of the advertised maximum input component count.
    A program will fail to link if any attached shader uses a location greater
    than or equal to the number of supported locations, unless
    device-dependent optimizations are able to make the program fit within
    available hardware resources.

    A program will fail to link if any two non-vertex shader input variables
    are assigned to the same location.  For vertex shaders, multiple input
    variables may be assigned to the same location using either layout
    qualifiers or via the OpenGL API.  However, such aliasing is intended only
    to support vertex shaders where each execution path accesses at most one
    input at each location.  Implementations are permitted, but not required,
    to generate link errors if they detect that every path through the vertex
    shader executable accesses multiple inputs assigned to any single
    location.  For all shader types, a program will fail to link if explicit
    location assignments leave the linker unable to find space for other
    variables without explicit assignments.

    For the purposes of determining if a non-vertex input matches an output
    from a previous shader stage, the location layout qualifier (if any) must
    match.

 -- Section 4.3.8.2 "Output Layout Qualifiers" (page 48)

    Modify the description of fragment output qualifiers.

    All shaders allow location output layout qualifiers on output
    variable declarations. The location layout qualifier identifier for
    outputs is:

        layout-qualifier-id
            location = integer-constant

    Fragment shaders allow an additional index output layout qualifiers:

        layout-qualifier-id
            location = integer-constant
            index = integer-constant

    Each of these qualifiers may appear at most once. If index is
    specified, location must also be specified. If index is not
    specified, the value 0 is used. For example, in a fragment shader,

        layout(location = 3) out vec4 color;

    will establish that the fragment shader output <color> is assigned
    to fragment color 3 as the first (index zero) input to the blend
    equation. And,

        layout(location = 3, index = 1) out vec4 factor;

    will establish that the fragment shader output factor is assigned
    to fragment color 3 as the second (index one) input to the blend
    equation.

    For fragment shader outputs, the location and index specify the color
    output number and index receiving the values of the output.  For outputs
    of all other shader types, the location specifies a vector number that can
    be used to match against inputs in a subsequent shader stage, even if that
    shader is in a different program object.

    If the declared output has a scalar or vector type, it will consume a
    single location, except for outputs of type "dvec3" and "dvec4", which
    will consume two consecutive locations.  Outputs of type "double" and
    "dvec2" will consume only a single location in all shaders.

    If the declared output is an array, it will be assigned consecutive
    locations starting with the location specified.  For example,

        layout(location = 2) out vec4 colors[3];

    will establish that <colors> is assigned to vector location
    numbers 2, 3, and 4.

    If the declared output is an <n>x<m> single- or double-precision matrix,
    it will be assigned multiple locations starting with the location
    specified.  The number of locations assigned will be the same as for an
    <n>-element array of <m>-component vectors.

    If the declared output 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.  The number of
    locations consumed by a structure member is determined by applying the
    rules above recursively as though the structure member were declared as
    an output variable of the same type.

    Location layout qualifiers may be used on output variables declared as
    structures, but not on individual members.  Location layout qualifiers may
    not be used on output blocks or output block members.

    The number of output locations available to a shader is limited.  For
    fragment shaders, the limit is the advertised number of draw buffers.  For
    all other shaders, the limit is implementation-dependent and must be no
    less than one fourth of the advertised maximum output component count.  A
    program will fail to link if any attached shader uses a location greater
    than or equal to the number of supported locations, unless
    device-dependent optimizations are able to make the program fit within
    available hardware resources.

    A program will fail to link if any two fragment shader output variables
    are assigned to the same location and index, or if any two output
    variables from the same non-fragment shader stage are assigned to the same
    location.  For fragment shader outputs, locations can be assigned using
    either a layout qualifier or via the OpenGL API.  For all shader types, a
    program will fail to link if explicit location assignments leave the
    linker unable to find space for other variables without explicit
    assignments.

    For the purposes of determining if a non-fragment output matches an input
    from a subsequent shader stage, the location layout qualifier (if any)
    must match.

 -- Section 4.5.2, "Precision Qualifiers" (page 53)

    (add new paragraph to the end of the section) For the purposes of
    determining if an output from one shader stage matches an input of the
    next stage, the precision qualifier need not match.

 -- Section 4.6.1, "The Invariant Qualifier" (page 55)

    (add new paragraph to the end of the section) For the purposes of
    determining if an output from one shader stage matches an input of the
    next stage, the "invariant" qualifier need not match.

 -- Section 4.7, "The Precise Qualifier" (page 56)

    (add new paragraph to the end of the section) For the purposes of
    determining if an output from one shader stage matches an input of the
    next stage, the "precise" qualifier need not match.


GLX Protocol

    The following rendering command is sent to the server as part of a
    glXRender request:

        UseProgramStages
            2           8               rendering command length
            2           ZZZZ            rendering command opcode
            4           ENUM            type
            4           CARD32          program

        ActiveShaderProgram
            2           4               rendering command length
            2           ZZZZ            rendering command opcode
            4           CARD32          program

Errors

    UseProgramStages generates INVALID_OPERATION if the program
    parameter has not been successfully linked.

    UseProgramStages generates INVALID_OPERATION if transform feedback
    is active.

    UseProgramStages generates INVALID_VALUE if <stages> has a bit
    set for any other than TESS_CONTROL_SHADER_BIT, TESS_EVALUATION_-
    SHADER_BIT, VERTEX_SHADER_BIT, GEOMETRY_SHADER_BIT, or FRAGMENT_-
    SHADER_BIT, unless <stages> is ALL_SHADER_BITS.

    ActiveShaderProgram generates INVALID_OPERATION if the program
    parameter has not been successfully linked.

    The INVALID_OPERATION error produced by LinkProgram if the program
    object has a geometry, tessellation control, or tessellation
    evalutations shader attached and no vertex shader attached is now
    produced at Begin time.

    The error INVALID_OPERATION is generated if Begin, or any command
    that implicitly calls Begin, is called when a program object with
    multiple attached shaders is active for one or more, but not all of
    the shader program types corresponding to the shaders that are
    attached.

    The error INVALID_OPERATION is generated if Begin, or any command
    that implicitly calls Begin, is called when an active program object
    has two shaders attached that have shader program types in between
    them with active programs that are not zero and are not equal to the
    active program of the first two shaders.

    INVALID_OPERATION is generated if any of the commands added by this
    extension are executed between the execution of Begin and the
    corresponding execution of End.

Dependencies on OpenGL 4.0 (Core Profile)

    If the OpenGL 4.0 core profile is used, references to built-in shader
    variables found only in the compatibility profile should be removed.
    Additionally, the fragment shader built-in input block "gl_PerFragment"
    doesn't exist, and references to it should be removed.  When matching
    shader outputs to fragment inputs, the members of "gl_PerVertex" output
    block do not affect matching.  References to fixed-function vertex and
    fragment processing should also be removed.

Dependencies on GLSL 1.40 and earlier

    This extension typically requires that shaders redeclare "gl_PerVertex" 
    or "gl_PerFragment" to use members of built-in input or output blocks in
    separable shaders.  However, since input and output interface blocks 
    are not supported in GLSL 1.40 or earlier, such redeclarations are not 
    even possible using older versions of GLSL.

    To deal with this case, this extension provides a specific exception to
    this rule, allowing vertex and fragment shaders using #version 140 or
    lower to redeclare all variables that would otherwise belong to these
    blocks at global scope.  When linking separable programs using such
    shaders, the set of redeclared inputs/outputs are taken to form an
    implicit redeclaration of "gl_PerVertex" or "gl_PerFragment".  After this,
    normal matching rules for the gl_PerVertex and gl_PerFragment blocks are
    applied.  When using this capability:

      * all built-in vertex outputs or fragment inputs must be redeclared;

      * all shaders of a given type must make the same redeclarations; and

      * to get an exact interface match, the vertex output and fragment input
        redeclarations must be compatible according to block matching rules.

    This exception is important because we expect this extension to be
    supported on implementations and GPUs supporting only OpenGL 2.1, which
    doesn't support the interface blocks added by GLSL 1.50.  

    Note that this exception applies only to shaders using #version 140.  When
    using this extension with shaders using #version 150 or higher, the
    shaders must redeclare gl_PerVertex or gl_PerFragment blocks.

    The following edits to the GLSL 1.40 (revision 7) specification are made
    when this extension is enabled by an #extension directive:

      Add new Section 7.7, Built-In Redeclaration and Separable Programs

      The following vertex shader outputs may be redeclared at global scope to
      specify a built-in output interface, with or without special qualifiers:

        gl_Position
        gl_PointSize
        gl_ClipDistance[]
        gl_ClipVertex           (compatibility only)
        gl_FrontColor           (compatibility only)
        gl_BackColor            (compatibility only)
        gl_FrontSecondaryColor  (compatibility only)
        gl_BackSecondaryColor   (compatibility only)
        gl_TexCoord[]           (compatibility only)
        gl_FogFragCoord         (compatibility only)

      The following fragment shader inputs may be redeclared at global scope
      to specify a built-in input interface, with or without special
      qualifiers:

        gl_Color                (compatibility only)
        gl_SecondaryColor       (compatibility only)
        gl_TexCoord[]           (compatibility only)
        gl_FogFragCoord         (compatibility only)

      When compiling shaders using any of the above variables, all such
      variables must be redeclared prior to use.  ((Note:  This restriction
      applies only to shaders using version 140 or earlier that enable the
      ARB_separate_shader objects extension; shaders not enabling the
      extension do not have this requirement.))  A separable program object
      will fail to link if any attached shader uses one of the above variables
      without redeclaration, or if it has two shaders of the same type using
      any of these variables where the sets of variable declarations don't
      match exactly.

    Additionally, the API specification language in this specification
    (written assuming input and output blocks in GLSL) is modified as follows:

      (Add to the end of the "Shader Interface Matching" section)

      When using vertex or fragment shaders with version 140 or lower in
      separable programs, the language doesn't support input and output blocks
      or redeclaration of gl_PerVertex or gl_PerFragment.  In such cases, an
      implicit block redeclaration is formed from the set of vertex shader
      outputs or fragment shader inputs redeclared according to Section 7.7 of
      the OpenGL Shading Language Specification.  The order of individual
      variable redeclarations does not affect the resulting implicit block
      redeclaration.  The block matching rules described above are then
      applied to such implicit block redeclarations.  Note that an implicit
      block redeclaration is never considered to match with an explicit block
      redeclaration.


Dependencies on ARB_geometry_shader4, EXT_geometry_shader4, NV_geometry_-
shader4, and/or OpenGL version 3.2

    If none of ARB_geometry_shader4, EXT_geometry_shader4, NV_geometry_-
    shader4, or OpenGL 3.2 are supported by the implementation, ignore
    all references to geometry shaders and generate an INVALID_ENUM
    error when UseProgramStages is called with GEOMETRY_SHADER_BIT
    set in <stages>.

Dependencies on ARB_tessellation_shader and OpenGL 4.0

    If ARB_tessellation_shader and OpenGL 4.0 are not supported by the
    implementation, ignore references to tessellation control and evaluation
    shaders and generate an INVALID_ENUM error when UseProgramStages is called
    with TESS_CONTROL_SHADER_BIT or TESS_EVALUTAION_SHADER_BIT is set in
    <stages>.

Dependencies on ARB_gpu_shader_fp64 and OpenGL 4.0

    If ARB_gpu_shader_fp64 and OpenGL 4.0 are not supported by the
    implementation, ignore references to double sized uniforms including
    ProgramUniform* calls with a 'd' suffix.  Additionally, references to
    double-precision GLSL variable types should be removed.

Dependencies on ARB_explicit_attrib_location, ARB_vertex_attrib_64bit, OpenGL
3.3, and OpenGL 4.1

    If ARB_explicit_attrib_location (or OpenGL 3.3) is supported, vertex
    shader input variables (including ones with double-precision components)
    can select associated generic attributes with an explicit location layout
    qualifier in lieu of calling BindAttribLocation.  If
    ARB_vertex_attrib_64bit (or OpenGL 4.1) is supported, vertex shader inputs
    can use types with double-precision components.

    When these extensions are supported, there are special rules for the
    number of locations consumed by "dvec3" and "dvec4" types, which require
    more storage than is available in a four-component single-precision
    vector.  The rules are:

      * dvec3/dvec4 vertex inputs consume one location (generic vertex
        attribute), but can count as two vectors for the purposes of
        determining if the vertex shader consumes too many inputs

      * dvec3/dvec4 inputs and outputs for other stages consume two locations

    The relevant spec edits (modifying language introduced by
    ARB_explicit_attrib_location) can be found in this extension.

Dependencies on EXT_separate_shader_objects

    This extension provides program pipeline objects, to which separable
    program objects can be attached via UseProgramStages (for rendering) and
    ActiveShaderProgram (for uniform updates).  A single pipeline object can
    be bound via BindProgramPipeline.  The programs attached to the bound
    pipeline object are used unless a non-separable object is made current via
    UseProgram.  Effectively UseProgram has a higher priority than
    BindProgramPipeline.

    EXT_separate_shader_objects does something very similar, but without
    pipeline objects.  Instead, the single program attachment point set by
    UseProgram is replaced by an array of attachment points updated by
    UseShaderProgramEXT and ActiveProgramEXT.  UseProgram is redefined
    to update all attachment points.  This collection of attachment points is
    functionally equivalent to the program pipeline object in this extension,
    and can be thought of as a special pipeline object.

    If both extensions are supported, the rule giving priority to UseProgram
    over pipeline objects needs to be updated, given that the single
    UseProgram binding point is replaced by a collection of binding points.
    We effectively treat this collection of binding points as another pipeline
    object, and treat that object as higher priority if it has a program
    attached to *any* attachment point.  The priority rules in this spec are
    rewritten as follows:

      The executable code for an individual shader stage is taken from the
      current program for that stage.  If there is a current program object
      for any shader stage or for uniform updates established by UseProgram,
      UseShaderProgramEXT, or ActiveProgramEXT, the current program for that
      stage (if any) is considered current.  Otherwise, if there is a bound
      program pipeline object ...

    Note that with these rules, it's not possible to mix program objects bound
    to the context with program objects bound to a program pipeline object; if
    any program is bound to the context, the current pipeline object is
    ignored.

Dependencies on ARB_vertex_program, ARB_fragment_program, NV_gpu_program4, and
related assembly extensions

    On implementations supporting both GLSL and assembly programmability, it
    is necessary to make a determination of what executable code (if any) is
    run in each program stage.  The logic for determining the active
    executable is as follows:

      * If there is an active GLSL program for the stage, either from a
        program bound by UseProgram or from a program bound to the active
        program pipeline object, that program's executable will be used.

      * Otherwise, the bound assembly program from this stage will be used if
        enabled.

      * Otherwise, the stage will be skipped (tessellation control,
        evaluation, and geometry), fixed function vertex or fragment
        processing will be used (compatibility profile), or undefined results
        will occur (core profile).

    This is the same behavior present without this extension; the only
    difference is that active GLSL programs are determined on a stage-by-stage
    basis with this extension.

New State

    Add to Table 6.45 (Program Object State):

    Get Value            Type  Get Command           Initial Value  Description               Sec      Attribute
    -------------------  ----  --------------------  -------------  ------------------------  ------   ---------
    ACTIVE_PROGRAM         Z+  GetProgramPipelineiv  0              The program object        2.20.2   -
                                                                    that Uniform* commands
                                                                    update when PPO bound
    VERTEX_SHADER          Z+  GetProgramPipelineiv  0              Name of current vertex    2.20.2   -
                                                                    shader program object
    GEOMETRY_SHADER        Z+  GetProgramPipelineiv  0              Name of current geometry  2.20.2   -
                                                                    shader program object
    FRAGMENT_SHADER        Z+  GetProgramPipelineiv  0              Name of current fragment  2.20.2   -
                                                                    shader program object
    TESS_CONTROL_SHADER    Z+  GetProgramPipelineiv  0              Name of current tessell-  2.20.2   -
                                                                    ation control shader
                                                                    program object
    TESS_EVALUATION_SHADER Z+  GetProgramPipelineiv  0              Name of current tessell-  2.20.2   -
                                                                    ation evaluation shader
                                                                    program object
    VALIDATE_STATUS        B   GetProgramPipelineiv  FALSE          Validate status of        2.14.8   -
                                                                    program pipeline object
    PROGRAM_PIPELINE_-     Z+  GetIntegerv           0              Current program pipeline  2.14.PPO - 
    BINDING                                                         object binding
                                                    
New Implementation Dependent State

    None

Issues

    1.  What should this extension be called?

        RESOLVED:  ARB_separate_shader_objects

        The adjective "separate" is used in several extension names
        (EXT_blend_equation_separate, EXT_blend_func_separate,
        EXT_separate_specular_color, ATI_separate_stencil) when joined
        state is made configurable separately.

        The phrase "shader_objects" refers generally to GLSL shader
        objects, matching the ARB_shader_objects name.

        Whether the name should be "separate_shader_objects"
        or "shader_objects_separate" is less clear.  The various
        "separate" extensions have different conventions as to whether
        separate is prefixed or suffixed with the separated state.
        The prefixed form is more natural to say aloud, is consistent
        with the ATI_separate_stencil naming approach, and abbreviates
        to SSO (instead of the inopportune abbreviation SOS).

        The ability to use monolithic program objects that might be more
        optimized with individual shader program objects makes this name
        a little less appropriate.

    1a. How is the extension different from the prior EXT version?

        RESOLVED:  The ARB extension is a strict superset adding:

           *   tessellation interactions, and

           *   GLSL language additions for layout qualifiers to support
               rendezous-by-API-resource and rendezous-by-structure-offset
               cross-stage interfacing.

           *   A container program pipeline object to bind separate
               programs to rather than to the context directly.

           *  Support for transform feedback interactions.

           *  CreateShaderProgramv takes multiple strings to better
              match ShaderSource

           *  More. . . 

    2.  What happens to a user-defined input varying variable that are
        not written by a preceding shader's write to the corresponding
        output varying variable.

        RESOLVED:  The input variable variable's value is left undefined.
        Implementations are encouraged but not required to zero the
        value.

        GLSL has a "rendezvous by name" model for connecting varying
        output variables to varying input variables of a subsequent
        shader.  With separate shaders, there's no assurance whether a
        preceding shader will write a given user-defined input varying
        variable.  HLSL9, Cg, and OpenGL assembly extension programs
        handle this situation by with "rendezvous by API resource" model.
        In GLSL terms, this means separate GLSL shaders /must/ communicate
        by built-in varying variables rather than user-defined varying
        variables.

        It is undesirable from a performance standpoint to attempt to
        support "rendezvous by name" for arbitrary separate shaders
        because the separate shaders won't be naturally compiled to
        match their varying inputs and outputs of the same name without
        a special link step.  Such a special link would introduce an
        extra validation overhead to binding separate shaders.  The link
        itself would have to be deferred until glBegin time since separate
        shaders won't match when transitioning from one set of consistent
        shaders to another.  This special link would still create errors
        or undefined behavior when the names of input and output varyings
        matched but their types did not match.

        Also the expectation from other shading APIs that support
        mix-and-match shader usage is that "rendezvous by API resource"
        is the expected norm.

        Specifying the behavior being undefined allows a future ARB
        version of this extension to be more specific without encumbering
        this extension with enforcing a specific error.

    3.  Do different program objects currently used by different shader
        types share a single name space for uniforms?

        RESOLVED:  No, different program objects have their own separate
        name space for uniforms and each has locations specific to its
        unique program object.

    4.  How do the glUniform* commands determine what program object
        to query?

        RESOLVED:  In a program pipeline object, this extension provides
        separate program binding points for each stage, as well as an "active"
        program specified by glActiveShaderProgram.  When glUniform is called
        when a program pipeline object is active, the active program specifies
        the program used by glUniform* commands.  This active program is
        simply a selector and doesn't actually control any rendering
        operation.

        The active program can be queried with glGetProgramPipelineiv with a
        <pname> of GL_ACTIVE_PROGRAM.

        When a non-zero program is passed to UseProgram, any subsequent
        uniform updates will affect that program, ignoring the active program
        in any bound pipeline object.  For example:

          glUseProgram(0);
          glBindProgramPipeline(1);
          glActiveProgram(1, 2);
          glUniform1f(0, 3.0);          // affects program 2
          glUseProgram(3);
          glUniform1f(0, 3.0);          // affects program 3
          glUseProgram(0);
          glUniform1f(0, 3.0);          // affects program 2


        As an alternative to setting the GL_ACTIVE_PROGRAM selector
        with glActiveShaderProgram, applications are instead encouraged
        to use the glProgramUniform* commands introduced by the
        EXT_direct_state_access extension which do not depend on a
        selector but specify the program object with which to update
        the specified uniform location explicitly.

    5.  Do the glGetUniform* queries depend on the active program state
        (GL_ACTIVE_PROGRAM)?

        RESOLVED:  No, the glGetUniform* queries take the program
        object for the query as an explicit parameter to the query.
        These queries do not rely on a selector.  In other words, the
        uniform queries are always selector-free.

    6a. Should the fragment shader program object be allowed to changed
        within transform feedback mode?

        RESOLVED:  No, this should generate an GL_INVALID_OPERATION error.

        The OpenGL 3.0 and EXT_transform_feedback specifications say
        glUseProgram generates a GL_INVALID_OPERATION error when transform
        feedback is active.

        The rationale for this is that user-defined varying outputs from
        the vertex or geometry shader might change.

        Perhaps it is desirable to allow different shader program objects
        when transform feedback mode is active, but this extension
        doesn't change the existing GLSL error behavior.  In fact,
        glUseProgramStages generate the same error glUseProgram does.

    6b. Should the active program be allowed to changed within transform
        feedback mode?

        RESOLVED:  Yes.

        The active program simply allows uniforms to be changed but
        doesn't actually change how the graphics pipeline itself is
        configured or what programs are used for vertex, geometry,
        and fragment processing.

    7.  What happens if you have a program object current for a shader stage,
        but the program object doesn't contain an executable for that stage?

        RESOLVED:  This is not an error; instead it is as though there were no
        program bound to that stage.  We have two different notions for
        programs bound to shader stages.  A program is "current" for a stage
        if it bound to that stage in the active program pipeline object.  A
        program is "active" for a stage if it is current and it has an
        executable for this stage.  In this case, the program would be current
        but not active.

        When no program is active for a stage, the stage will be replaced with
        fixed functionality logic (compatibility profile vertex and fragment),
        disabled (tessellation control and evaluation, geometry), or have
        undefined results (core profile vertex and fragment).

        Support for programs that are current but not active is intentional
        behavior.  Consider an example where an application wants to use two
        different types of separate program object -- one for all types of
        vertex processing and a second for fragment processing.  Some of the
        vertex pipe programs might include tessellation or geometry shaders;
        others might only include a vertex shader.  With this configuration,
        the application can use code like the following:

          #define GL_ALL_VERTEX_PIPE_SHADER_BITS   \
              (GL_VERTEX_SHADER_BIT             |  \
               GL_TESS_CONTROL_SHADER_BIT       |  \
               GL_TESS_EVALUATION_SHADER_BIT    |  \
               GL_GEOMETRY_SHADER_BIT)

          glUseProgramStages(pipeline, GL_ALL_VERTEX_PIPE_SHADER_BITS,
                             vertex_pipe_program);
          glUseProgramStages(pipeline, GL_FRAGMENT_SHADER_BIT,
                             fragment_pipe_program);

        Such code wouldn't have to determine if <vertex_pipe_program> has
        tessellation or geometry shaders.  Instead, it simply sets all
        possible bits, which removes the old program from all non-fragment
        stages.  For stages not present in the new program, the program will
        be current but not active, and it will be as though no program were
        bound to such stages.

    8a.  What happens if a linked program object with multiple stages (e.g.,
         vertex and fragment) is active on those stages, but there is a second
         program active in stages between the first and last stages of that
         program (e.g., a geometry-only program)?

        RESOLVED:  Such a configuration will result in a draw-time validation
        error.  We allow the linker to perform internal optimizations on the
        interfaces between stages of a multi-stage program object.  For a
        vertex-fragment program, the vertex shader outputs can be optimized to
        pass along only those outputs needed as fragment shader inputs.  Such
        a shader would not necessarily be set up to successfully pass those
        outputs to a separate geometry-only program, even if the declared
        vertex outputs would naturally match up with the declared geometry
        inputs.

    8b.  What happens if a linked program object with multiple stages is
         active on some of its stages, but not on others?

         RESOLVED:  Such a configuration would result in a draw-time
         validation error.  Consider a program with vertex and fragment
         shaders, where the interface between stages is optimized as in the
         previous example.  If the vertex shader from this program were to be
         used with a separate fragment-only program instead of the program's
         fragment shader, the optimized vertex outputs wouldn't necessarily
         match the inputs from the second program, even if the set of
         variables on that interface were compatible.

    9.  Is glUseProgramStages allowed to be compiled within a
        display list?

        RESOLVED:  Yes, just like glUseProgram is allowed within a
        display list.

    10. Should there be some easier to use API for creating a GLSL
        program that programs a single shader type?

        RESOLVED:  Yes, see the glCreateShaderProgram command.

        The existing GLSL API for creating a GLSL program involves a lot
        of steps to support multiple source strings, re-specification of
        source code, attaching and detaching multiple shader objects,
        and cross-stage linking.  These features are not particularly
        relevant for creating separate shader programs.

    11. Can glCreateShaderProgram be compiled into a display list?

        RESOLVED:  No.

        glCreateShaderProgram is equivalent to a sequence of commands
        that are themselves not allowed to be compiled  into a display
        list.

    12. Should glCreateShaderProgram allow user-defined varyings?

        RESOLVED:  Yes.  However, to get defined results when passing
        varying values between separate programs, applications are
        required to match inputs to outputs. This matching can be
        achieved either with the "location" layout qualifier, or by
        declaring the exact same set of inputs and outputs in the adjacent
        shader stages.


    13. How are interpolation modifiers handled for separate shader
        programs?

        RESOLVED:  GLSL only provides interpolation modifiers for user-
        defined varyings. These modifiers can be used in conjunction
        with the layout location qualifiers specified in this extension.
        Such modifiers must match.

    14. Should glLinkProgram work to re-link a shader created with
        glCreateShaderProgram?

        RESOLVED: NO because the shader created by glCreateShaderProgram
        is detached and deleted as part of the glCreateShaderProgram
        sequence.  This means if you call glLinkProgram on a program
        returned from glCreateShaderProgram, you'll find the re-link
        fails because no shader object is attached.

        An application is free to attach one or more new shader objects
        to the program and then relink would work.

        This is fine because re-linking isn't necessary/expected.

    15. Wouldn't re-linking be necessary if the application wanted to
        use glBindAttribLocation to assign a user-defined attribute to
        a specific vertex attribute?

        RESOLVED:  Yes and that's a problem if glCreateShaderProgram
        is used because the shader object is detached and deleted.

        User-defined attributes will work when glCreateShaderProgram
        is used to easily create a vertex shader program, but the
        application must be satisfied with the implementation-dependent
        linker-assigned user-defined attributes returned by
        glGetAttribLocation.

        We could provide a new set of built-in attributes that correspond
        to declared as:

            attribute vec4 gl_VertexAttrib[];

        How would these attributes map to the other built-in attributes?  That
        would depend on the implementation.  As with ARB_vertex_program, some
        implementations could choose to alias such generate vertex attributes
        with conventional vertex attributes (color, fog coord, etc.) or an
        implementation could treat the generic attributes as disjoint from the
        conventional vertex attributes.

        If this is unsatisfactory, the solution is to avoid using
        glCreateShaderProgram and instead use the traditional GLSL
        approach for creating programs (create shader, compile shader,
        attach shader, bind attributes, link shader, use shader).

        Demonstrating how to workaround this particular issue, here's
        an example of creating and using a vertex shader for use with
        separate shader objects that includes explicit binding of output
        varyings to fragment data locations.  First the shader:
        
          varying in vec4 attribA;
          varying in vec4 attribB;
          void main()
          {
            gl_Position = ftransform();
            gl_FrontColor = attribA;
            gl_BackColor = attribB;
          }
          
        Now creating and using a linked program from this shader where
        attribA is initialized by vertex attribute 5 and attribB is
        initialized by vertex attribute 7.

          GLuint ppo;
          GenProgramPipelines(1, &ppo);
          BindProgramPipeline(ppo);
          const GLuint shader = glCreateShader(GL_VERTEX_SHADER);
          if (shader) {
            const GLint len = (GLint) strlen(aboveShaderString);
            glShaderSource(shader, 1, &aboveShaderString, &len);
            glCompileShader(shader);
            const uint program = glCreateProgram();
            if (program) {
              GLint compiled = FALSE;
              glGetShaderiv(shader, COMPILE_STATUS, &compiled);
              if (compiled) {
                glAttachShader(program, shader);

                // Crucial code that glCreateShaderProgram doesn't do
                glBindAttribLocation(program, 5, "attribA");
                glBindAttribLocation(program, 7, "attribB");

                glLinkProgram(program);
                glDetachShader(program, shader);

                // Show this program can actually be used as a vertex shader
                glUseProgramStages(GL_VERTEX_SHADER, program);
              }
            }
            glDeleteShader(shader);
            return program;
          } else {
            return 0;
          }

        Optionally, the glDetachShader and glDeleteShader commands could
        be removed to allow this program to be re-linked after different
        glBindAttribLocation calls.

    16. Can you use glBindFragDataLocation to direct varying output
        variables from a fragment shader program created by
        glCreateShaderProgram to specific color buffers?

        RESOLVED: NO for much the same reason you can't do this with
        attributes as described in issue 15.  But you could create the
        program with the standard GLSL creation process where you attach
        your own shaders and relink.

        For fragment shader programs created with
        glCreateShaderProgram, there is already the gl_FragData[]
        builtin to output to numbered color buffers.  For integer
        framebuffers, we would need to add:

            varying out ivec4 gl_IntFragData[];

        User-defined output fragment shader varyings can still be used
        as long as the application is happy with the linker-assigned
        locations.

        Demonstrating how to workaround this particular issue, here's
        an example of creating and using a fragment shader for use with
        separate shader objects that includes explicit binding of output
        varyings to fragment data locations.  First the shader:

          varying out ivec4 bufferA;
          varying out ivec4 bufferB;
          void main()
          {
            bufferA = ivec4(1,2,3,4);
            bufferB = ivec4(5,6,7,8);
          }

        Now creating and using a linked program from this shader where
        bufferA outputs to color buffer 0 and bufferB outputs to color
        buffer 1:

          GLuint ppo;
          GenProgramPipelines(1, &ppo);
          BindProgramPipeline(ppo);
          const GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
          if (shader) {
            const GLint len = (GLint) strlen(aboveShaderString);
            glShaderSource(shader, 1, &aboveShaderString, &len);
            glCompileShader(shader);
            const uint program = glCreateProgram();
            if (program) {
              GLint compiled = FALSE;
              glGetShaderiv(shader, COMPILE_STATUS, &compiled);
              if (compiled) {
                glAttachShader(program, shader);

                // Crucial code that glCreateShaderProgram doesn't do
                glBindFragDataLocation(program, 0, "bufferA");
                glBindFragDataLocation(program, 1, "bufferB");

                glLinkProgram(program);
                glDetachShader(program, shader);

                // Show this program can actually be used as a fragment shader
                glUseProgramStages(GL_FRAGMENT_SHADER, program);
              }
            }
            glDeleteShader(shader);
            return program;
          } else {
            return 0;
          }

        Optionally, the glDetachShader and glDeleteShader could be
        removed to allow this program to be re-linked after different
        glBindFragDataLocation calls.

    17. Can you output varyings in transform feedback from a separate
        shader program created with glCreateShaderProgram?

        RESOLVED:  No.

        glTransformFeedbackVaryings requires a re-link to take effect on
        a program.  glCreateShaderProgram detaches and deletes the
        shader object use to create the program so a glLinkProgram will
        fail.

        You can still create a vertex or geometry shader program
        with the standard GLSL creation process where you could use
        glTransformFeedbackVaryings and glLinkProgram.

    18. I just don't get it?  Why is it such a big deal to just require
        apps to link all their vertex and fragment shaders together?
        Please explain a situation where mix-and-match shaders is
        substantially better than GLSL as it exists without this
        extension?

        RESOLUTION:  Consider the (not uncommon) case of a vertex shader
        for skinning an character.  The vertex shader is used in four
        distinct types of rendering passes, each using the one vertex
        shader but different fragment shaders.

        For GLSL today, this situation today requires 4 program objects,
        each containing the one vertex shader paired with each one of
        the fragment shaders.

        The one vertex shader has an array of dozens of skinning matrices
        along with numerous other uniform parameters.

        Each fragment shader has its own different set of uniforms too.

        Each GLSL program object has its own (combined) set of GLuint
        locations for the active uniforms of the vertex and fragment
        shaders objects linked into the particular program object.

        The locations for a given program object are arbitrary and
        the location values of two distinct program objects have no
        correlation.  This is true even when they each link in the same
        vertex shader (or alternatively same fragment shader).

        Now the application is saddled with the burden of managing
        distinct location values for the same vertex shader skinning
        matrices and other uniform variables as well as making sure
        the values of these variables are mirroed over all four program
        objects containing the skinning vertex shader.

        What's worse is despite all the program objects being loaded
        with the same vertex shader uniform variables for skinning, the
        driver is exceedingly unlikely to recoginize that binding from
        one of these program objects to another is going to result in
        no actual vertex shader state change.  Noticing that the uniform
        vertex shader variables are changing in lock-step over a series
        of program objects (when the uniform fragment shader variables
        ARE allowed to diverge) is exceedingly expensive.

        This situation is simple to optimize with mix-and-match shaders
        because there is just a single vertex shader to worry about.
        It's only the current fragment shader program that is changing
        so only the fragment shader state must be updated/re-validated.

        It's also much easier and less expensive for the application to
        update the vertex shader state because there is just one copy
        of it to update.

    19. Which should take precedence if both are bound, program objects
        or program pipeline objects?

        RESOLVED: Program objects. Due to concerns about existing
        middleware depending on the program object state to determine
        the current program rendering state, the program object should
        override any program pipeline object that might be bound.


    20. Should UseProgramStages take a bitfield rather than derive the
        information from the program object?

        RESOLVED: Yes. Though it seems pointless to include a bitfield
        that can only be erroneous if it includes bits set for shaders
        not present in the program object, without it there is no way to
        disassociate a shader type from a program object once it has
        been done.

    21. What should the behavior be if a program object is deleted that
        is part of the current program pipeline object?

        RESOLVED: Just as program objects made current via UseProgram
        are flagged for deletion until they are no longer referenced,
        program objects that form part of the current program pipeline
        object will be flagged and remain until no references remain.

        Deletion of current program objects has special treatment in
        OpenGL. Such are not immediately deleted, but rather flagged for
        deletion and remain until they are no longer referenced. Being
        current indirectly as part of the current program pipeline object
        rather than directly via UseProgram makes no fundamental
        difference to the state of the program object or the rendering
        state. Whenever possible, an object made current as part of a
        container object should behave exactly as it would if it were
        to bypass that container object. In defference to that goal,
        objections to perpetuating the irregular behavior of program
        object deletion are set aside in favor of maintaining consistent
        behavior.

    22. If multiple potential sources of transform feedback input are
        active from different program objects, where should transform feedback
        capture its input?

        RESOLVED: The later stage in the ordered pipeline of stages
        should be the source of the transform feedback input. This is
        true at any given time regardless of how the state may change
        due to binding and releasing of different program objects. So if
        a geometry shader program is active and then removed, transform
        feedback input may switch to the vertex shader. This potential
        for changes requires an error with ResumeTransformFeedback if
        the related state has changed since it was paused.

    23. How do built-in inputs in one stage interface with built-in outputs
        from a previous stage?

        UNRESOLVED:  There are several different classes of inputs that
        have different behavior:

        (a) "System inputs" are ones that are not derived directly from a
            corresponding output.  These inputs are treated as though they
            had their own dedicated locations; use of these variables in a
            shader do not affect whether the shader matches up with the
            outputs of a previous shader stage.  Examples of such inputs
            include "gl_InvocationID", "gl_SamplePosition",
            "gl_PointCoord", and "gl_TessCoord".

        (b) "System outputs" are are typically consumed by a fixed-function
            unit.  These outputs are treated as though they had their own
            dedicated locations; use of these variables in a shader do not
            affect whether the shader matches up with the outputs of a
            previous shader stage.  Examples of such outputs include
            "gl_Layer", "gl_TessLevelOuter[]".

        (c) Non-system inputs and outputs are those passed more-or-less
            directly between shader stages.  For fragment shader inputs,
            non-system inputs may be interpolated, but the interpolated
            values will be derived directly from outputs of the previous
            shader stages.  These inputs and outputs are not treated as
            having dedicated locations.  To ensure an exact match between
            two shader stages, the set of non-system inputs and outputs on
            the interface must match.  

        All built-in inputs and outputs not found in the gl_PerVertex and
        gl_PerFragment blocks are treated as belonging to categories (a)
        and (b).  Members of gl_PerVertex may or may not be treated as
        "system" variables, depending on the specific interface.  (See the
        next issue for more details.)

    24. How does the use of built-in inputs or outputs affect the exact
        interface matching?  Does their use affect matching for
        user-defined inputs?

        UNRESOLVED:  As noted in the previous issue, built-ins outside the
        gl_PerVertex and gl_PerFragment blocks are considered "system"
        variables that don't affect interface matching at all.  For members
        of gl_PerVertex and gl_PerFragment, there are two types of
        interface between separable programs with different rules.

        In interfaces not involving a fragment shader (e.g., vertex to
        geometry), shader outputs in gl_PerVertex are not interpreted by
        any fixed-function unit.  As such, we will treat all inputs and
        outputs as non-system.  To get defined results passing these
        built-ins between stages, gl_PerVertex must be declared identically
        on both sides of the interface.

        In interfaces involving a fragment shader, some of the gl_PerVertex
        outputs will be consumed by the rasterizer and may not be passed to
        subsequent stages.  In particular, the built-in outputs
        gl_Position, gl_PointSize, gl_ClipDistance[], and gl_ClipVertex
        (compatibility only) are consumed by the rasterizer.
        gl_ClipDistance[] is available in the fragment shader, but will
        typically not be read there; all other outputs are not available in
        the fragment shader.  As a result, these outputs are treated as
        system outputs and are ignored when testing if gl_PerVertex and
        gl_PerFragment match.  Since gl_PerVertex and gl_PerFragment
        typically won't match, we specify a member-by-member comparison.  A
        mismatch occurs if a gl_PerFragment input is found without a
        corresponding gl_PerVertex output, or vice versa.

        If non-system built-in inputs and outputs don't match on an
        interface, we don't guarantee that correct values are passed
        between stages (inputs are undefined).  Additionally, a mismatch
        will mean that the values passed using user-defined inputs and
        outputs without location qualifiers are also not guaranteed, since
        the locations assigned for these built-ins might affect the
        assignments for user-defined variables.

    25. How does the use of two-sided color built-ins (e.g., gl_FrontColor
        vs. gl_BackColor) affect the matching of inputs and outputs on an
        interface?

        UNRESOLVED:  For interfaces between two non-fragment stages, front
        and back colors are treated as separate variables over the
        interfaces.  For interfaces involving a non-fragment stage with
        fragment, both pairs of front and back colors are treated as a
        single color for matching purposes.  For example, a vertex shader
        is treated as effectively writing the fragment input "gl_Color" if
        it writes either "gl_FrontColor" or "gl_BackColor".

    26. How should built-in inputs behave when used with user-defined
        variables with explicit locations?

        UNRESOLVED:  Built-ins are unaffected by the presence of
        user-defined variables with explicit locations.  A mismatch in
        built-ins does not affect matching of user-defined variables with
        explicit locations.

        Note that built-ins can not be assigned explicit locations.  This
        means that:

          (a) when non-system built-in usage doesn't match, the mismatch
              affects all such built-ins, plus any user-defined variables
              that aren't assigned explicit locations; and

          (b) when user-defined variables without locations don't match
              between shaders, the mismatch affects all non-system
              built-ins as well.

    27. How does the handling of built-in inputs and outputs in this
        extension differ from EXT_separate_shader_objects?

        UNRESOLVED:  In EXT_separate_shader_objects, shaders could only use
        built-ins to pass values between stages.  In this extension,
        user-defined variables can be used.

        In this extension, the usage of "non-system" built-ins is required
        to match between stages.  In EXT_separate_shader_objects, there was
        no requirement that the set of built-in outputs written by one
        stage had to match the inputs read by another stage.

        Implementations supporting EXT_separate_shader_objects are likely to
        provide logically separate locations for all shader built-ins.  That
        extension didn't provide for undefined values when the set of
        built-ins used on one side of the interface didn't exactly match those
        on that other side, so implementations were required to assign
        matching locations even if texture coordinates or colors were used as
        outputs in one program but not inputs in another.

    28. This extension requires shaders to redeclare gl_PerVertex and
        gl_PerFragment to use certain important built-ins.  However, GLSL
        1.40 (OpenGL 3.1 and earlier) doesn't support input and output
        blocks at all.  Should we support this extension on such GL/GLSL
        versions?  If so, how?

        RESOLVED:  Yes, we expect that some implementations will want to
        support this extension on GPUs not capable of supporting OpenGL 3.2
        and GLSL 1.50.

        To handle such cases, we don't require block redeclarations in shaders
        using #version 140 and earlier.  Instead, we treat it these cases as
        though gl_PerVertex and gl_PerFragment existed and were re-declared
        implicitly.  We allow shaders to redeclare all relevant built-ins, and
        require that shaders redeclare each of these built-ins that it uses.
        The set of redeclared built-ins is then assembled into an implicit
        block redeclaration and normal block matching rules are then applied.

        This capability is provided only for shaders using #version 140 or
        lower.  We considered adding a forward compatibility path allowing
        similar constructs in #version 150 and higher shaders, but opted
        against adding a second mechanism where block redeclaration is already
        available.  Additionally, the fact that #version 140 shaders using
        this feature already have to redeclare all relevant variables means
        that shaders written for #version 140 plus this extension are likely
        to already have something looking very much like a block
        redeclaration, and should be easily ported.

        We considered adding support for input and output blocks to GLSL
        1.40 as part of this extension, but decided that was too large of
        a change.

        The relevant language here is only included in the extension spec.  It
        doesn't need to be included in the core, because the only way to use
        the new features here with #version 140 shaders is via this extension.

    29. How do input and output "location" layout qualifiers behave with this
        extension and ARB_explicit_attrib_location?

        RESOLVED:  ARB_explicit_attrib_location added "location" layout
        qualifiers for vertex shader inputs and fragment shader outputs to
        interface with fixed-function vertex pulling and blending hardware.
        This extension adds "location" qualifiers for all other shader inputs
        and outputs.  To use these qualifiers, shaders must either enable the
        appropriate extension(s) using #extension or select a GLSL version
        incorporating the functionality using #version.  In vertex and
        fragment shaders, it may be necessary to enable both extensions -- one
        for inputs and the other for outputs.  

        A shader using location layout qualifiers without an appropriate
        #extension or #version directive will fail to compile.

    30. Can program pipeline objects be shared between contexts?

        RESOLVED:  No.  Like framebuffer and vertex array objects (added by
        OpenGL 3.0), they are considered "container" objects to which other
        shareable objects can be attached.

    31. How does one figure out how many locations are consumed by an input or
        output?

        RESOLVED:  Basic scalar and single-precision vector types are
        considered to consume one (vector) location.  Double-precision scalar
        and vector types consume either one or two locations, as discussed
        further below.  An array with <n> elements, each consuming <m>
        locations, will consume <n>*<m> locations.  Matrix types are treated
        as arrays of two to four column vectors.  Locations are assigned in
        structure types by assigning consecutive locations member-by-member
        according to the member declaration order.

    31. How many locations are consumed by shader inputs and outputs with
        double-precision types?

        RESOLVED:  For inputs and outputs passed between shader stages, values
        of type "double" and "dvec2" consume a single location.  Values of
        type "dvec3" and "dvec4" require more storage than a single-precision
        four-component vector, and thus consume two locations.

        For vertex shader inputs, each location is associated with a generic
        vertex attribute.  Since each such attribute in the API can hold a
        full "dvec4" if specified with VertexAttribL* or VertexAttribLPointer,
        values of type "double", "dvec2", "dvec3", and "dvec4" consume only a
        single location (generic vertex attribute).  However, for the purposes
        of determining if a vertex shader uses "too many" attribute vectors in
        LinkProgram, vertex shader inputs of types "dvec3" and "dvec4" can be
        counted as consuming two vector attributes.  For example, if a vertex
        shader specifies:

          layout(location=4) in dvec4 attribs[4];

        the values for the four elements of "attribs" will be taken from
        vertex attributes 4-7, though "attribs" may be counted as consuming
        eight vectors worth of attributes.

        Arrays or matrix types with double-precision components are treated as
        comprising 

    33. Are location layout qualifiers allowed on block declarations?  On
        block member declarations?

        RESOLVED:  Location layout qualifiers are not allowed on either block
        or block member declarations in this extension.  One implication of
        this behavior is that in input/output interface between programs, the
        sets of declared inputs and outputs must match exactly, since
        interface blocks can not be matched by location.  Future extensions
        may consider relaxing either or both restrictions.

    34. Should we ever allow inputs and outputs to match if they are of
        different type?

        RESOLVED:  The location system in this extension is expressed in units
        of four-component vectors.  Because of this common numeric location,
        we allow outputs with a vector type to be fed to inputs with a scalar
        or smaller vector type as long as they have the same location and
        basic component type.  For example, if a vertex shader includes:

          layout(location = 4) out vec4 vsout;

        and a fragment shader includes:

          layout(location = 4) in vec2 fsin;

        the two components of <fsin> will be obtained by interpolating the x
        and y components of <vsout>.  The z and w components of <vsout> will
        be ignored.

        We do not permit this behavior for double-precision vectors, because
        large types (dvec3, dvec4) consume two locations while smaller types
        (double, dvec2) consume only one.  Allowing this behavior would be 
        problematic for arrays.  For example, in a vertex shader output 
        declared as:

          layout(location = 4) out dvec4 vsout[2];

        "vsout[1]" would be assigned locations 6 and 7, while in a fragment
        shader input declared as

          layout(location = 4) in dvec2 fsin[2];

        "fsin[1]" would be assigned location 5.

    35. What are the rules for determining if inputs and outputs match by
        qualification?

        RESOLVED:  In order for an input in one shader stage to be considered
        to match an output in another, some of the qualifiers must match but
        others need not match.  In particular:

          * The base storage qualifier ("in" and "out") across an interface
            will naturally not match -- one side uses "in", the other uses
            "out".

          * Auxilliary storage qualifiers ("centroid", "sample", and "patch")
            and interpolation qualifiers ("flat", "smooth", "noperspective")
            must match.

          * The location layout qualifier, if specified, must match.

          * Layout qualifiers specific to one shader type (e.g., "stream" for
            geometry shader outputs) need not match.

          * Precision qualifiers have no effect in OpenGL and need not match.

          * The qualifiers "invariant" and "precise" affect only how outputs
            are computed within a shader stage and need not match between
            stages.

    36. How does the behavior of input/output interface matching differ
        between separable programs and non-separable programs?

        RESOLVED:  The rules for matching individual variables or block
        members between stages are identical for separable and non-separable
        programs, with one exception -- matching variables of different type
        with the same location, as discussed in issue 34, applies only to
        separable programs.

        However, the ability to enforce matching requirements differs between
        program types.  In non-separable programs, both sides of an interface
        are contained in the same linked program.  In this case, if the linker
        detects a mismatch, it will generate a link error.  

        For separable programs, the two sides of an interface may be in
        different programs, so the linker will be unable to detect a mismatch.
        In these cases, applications are responsible for ensuring matching
        inputs/outputs are used on either side of the interface.  Input
        variables are undefined when mismatches occur.  Matching can be done
        across the entire interface by ensuring that the exact same set of
        declarations is used on both sides of the interface.  Alternately,
        matching can be done variable-by-variable by using identical types and
        matching location layout qualifiers.

Revision History

    Rev.    Date       Author    Changes
    ----  -----------  --------- ---------------------------------------------
    25    1 Aug 2011   pbrown    More clearly specify interface matching rules
                                 for shader inputs and outputs, for cases
                                 where both sides of an interface are found in
                                 the same program and where they are in
                                 different programs (bug 7030).  Add
                                 dependencies with several ARB extensions and
                                 core version.  Add several new spec issues
                                 related to shader interface matching.

                                 Add GLSL spec language describing what
                                 qualifiers must match for inputs/outputs to
                                 be considered to match in qualification.  Add
                                 clarifications on the number of locations
                                 consumed by different types of shader
                                 inputs/outputs.  Specify that vertex shader
                                 inputs of type "dvec3" and "dvec4" consume a
                                 single location for the purposes of matching
                                 with generic vertex attributes in the API
                                 (bug 7809).  More clearly specify that
                                 location layout qualifiers are not allowed on
                                 blocks and block members.

    24    25 Jul 2011  pbrown    Remove the language erroneously deleting
                                 CURRENT_PROGRAM.  In the EXT extension, this
                                 token was aliased to ACTIVE_PROGRAM_EXT, and
                                 was used to indicate the last program set by
                                 either ActiveProgramEXT or UseProgram.  In
                                 the ARB extension, the SSO active programs
                                 are now program pipeline object state and
                                 CURRENT_PROGRAM should still be used to query
                                 the last program set by UseProgram (bug 7822).

    23    25 Jul 2011  Jon Leech Add VALIDATE_STATUS to state tables and
                                 GetProgramPipelineiv description (bug 7748).

    22    6 Jun 2011   pbrown    Treat program pipeline objects as non-shared
                                 container objects, like framebuffer and
                                 vertex array objects (bug 7713).

    21    9 Aug 2010   pbrown    Expand ProgramUniform* function prototypes
                                 to individual entries for tools parsing
                                 extension specs.  Add missing "*" characters 
                                 for ProgramUniform*v functions.

    20    15 Jul 2010  pbrown    Proposed update to locations for vectors
                                 with double-precision components (bug 6635).

    19    13 Jul 2010  pbrown    Clarify issues 7 and 8.

    18    13 Jul 2010  Jon Leech Clarify interactions of current program
                       & pbrown  object and current program pipeline object,
                                 and error conditions when a PPO with missing
                                 shader stages is current.  Add language for
                                 the interaction of separate shader objects
                                 and per-stage subroutine uniforms (bug 6641).
                                 Specify behavior for successful and failed
                                 links of programs bound to PPOs (bug 6642).
                                 Add interactions for assembly program 
                                 extensions and EXT_separate_shader_objects.
                                 Add missing code for CreateShaderProgramv
                                 treating such programs as separable.
                                 Update miscellaneous spec sections that
                                 don't account for per-stage active programs.

    17    08 Jul 2010  pbrown    Fix interface matching language in "Inputs"
                                 section of GLSL spec; modify API spec to
                                 allow type mismatches when using location
                                 qualifiers (e.g., passing a vec4 to a vec3).

    16    08 Jul 2010  pbrown    Restore error for linking a non-separable
                                 program without a vertex shader (bug 6517).
                                 Modify language describing the number of
                                 available locations (bug 6598).  Add language
                                 disallowing aliasing of inputs and outputs
                                 except for previously allowed vertex shader
                                 input aliasing (bug 6599).  Further work on
                                 block matching rules for built-in input and
                                 output blocks, including final rules for
                                 #version 140 shaders (bug 6636).  
                                 Miscellaneous typo fixes.

    15    07 Jul 2010  pbrown    Minor typo corrections.  Add specific 
                                 language for the core profile, which won't
                                 have gl_PerFragment.  Add issue on the use
                                 of location qualifiers and #extension; fix
                                 spec to match.

    14    21 Jun 2010  pbrown    Updated "Shader Interface Matching"
                                 section to include new rules for built-in
                                 inputs and outputs.  Added more
                                 dependencies on the core profile and older
                                 versions of GLSL.  Added several issues.

    13    07 Jun 2010  groth     Minor relinking clarification. New begin error

    12    01 Jun 2010  groth     More clarifications. Better introduction
                                 More consistency.

    11    28 May 2010  groth     Language clarifications and issue corrections

    10    21 May 2010  groth     move new xfb errors into pre-existing list
                                 cleaned up sundry issues
                                 further clarified deletion behavior
                                 various other non-controversial cleanups

    9     20 May 2010  groth     Add validateProgramPipeline/infolog
                                 clarify xfb interaction
                                 complete interface location allocation 
                                 language.  mention location limits.

    8     19 May 2010  groth     Finish responding to Pat's feedback.
                                 Reorganization for clarity.

    7     15 May 2010  groth     Respond to various feedback

    6     10 May 2010  groth     multiple shaders to CreateShaderProgram.
                                 Rename ActiveProgram, CreateShaderProgram
                                 Sundry corrections.

    5     08 May 2010  groth     remove default PPO. add active program
                                 definitively to PPO. add a few issues. 
                                 fix nits.

    4     06 May 2010  groth     Clarify PPO role. Add language about implicit
                                 interfaces.

    3     04 May 2010  groth     Add container object. Add DSA uniform commands.

    2     23 Apr 2010  groth     Fill out sections explaining GLSL layout
                                 pragmas.  Add tessellation awareness. Forbid
                                 certain use of monolithic and shader programs.

    1     13 Jan 2010  mjk       Initial revision
