| 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 |
| |
| Specification Update Policy |
| |
| Khronos-approved extension specifications are updated in response to |
| issues and bugs prioritized by the Khronos OpenGL Working Group. For |
| extensions which have been promoted to a core Specification, fixes will |
| first appear in the latest version of that core Specification, and will |
| eventually be backported to the extension document. This policy is |
| described in more detail at |
| https://www.khronos.org/registry/OpenGL/docs/update_policy.php |
| |
| Status |
| |
| Complete. Approved by the ARB on 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 a 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 a 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 |