blob: bea884742a086107b761ba2330fb0a03c7f46494 [file] [log] [blame]
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