blob: 99ffa0aff953d3efad7f5300983769c3f19cd7db [file] [log] [blame]
Name
EXT_separate_shader_objects
Name Strings
GL_EXT_separate_shader_objects
Contributors
Contributors to ARB_separate_shader_objects and
ARB_explicit_attrib_location desktop OpenGL extensions from which this
extension borrows heavily
Contact
Benj Lipchak, Apple (lipchak 'at' apple.com)
Status
Complete
NOTE: there is an unrelated OpenGL extension also named
"GL_EXT_separate_shader_objects", found in the OpenGL extension registry
at http://www.opengl.org/registry/ . These two extensions have similar
purposes, but completely different interfaces.
Version
Date: November 08, 2013
Revision: 7
Number
OpenGL ES Extension #101
Dependencies
Requires OpenGL ES 2.0.
Written based on the wording of the OpenGL ES 2.0.25 Full Specification
(November 2, 2010).
Written based on the wording of The OpenGL ES Shading Language 1.0.17
Specification (May 12, 2009).
OpenGL ES 3.0 affects the definition of this extension.
NV_non_square_matrices affects the definition of this extension.
Overview
This extension is a subset of ARB_separate_shader_objects appropriate for
OpenGL ES, and also tacks on ARB_explicit_attrib_location functionality.
Conventional GLSL requires multiple shader stages (vertex and fragment) 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, GPU hardware supports 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 application's 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,
UseProgramStagesEXT is used. The VERTEX_SHADER_BIT_EXT and
FRAGMENT_SHADER_BIT_EXT tokens refer to the conventional vertex and
fragment stages, respectively. ActiveShaderProgramEXT specifies the
program that Uniform* commands will update.
While ActiveShaderProgramEXT provides a selector for setting and querying
uniform values of a program object with the conventional Uniform* commands,
the ProgramUniform* 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 input 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 also introduces a layout location qualifier to GLSL to pre-
assign attribute and varying locations to shader variables. This allows
applications to globally assign a particular semantic meaning, such as
diffuse color or vertex normal, to a particular attribute and/or varying
location without knowing how that variable will be named in any particular
shader.
New Procedures and Functions
void UseProgramStagesEXT(uint pipeline, bitfield stages,
uint program);
void ActiveShaderProgramEXT(uint pipeline, uint program);
uint CreateShaderProgramvEXT(enum type, sizei count,
const char **strings);
void BindProgramPipelineEXT(uint pipeline);
void DeleteProgramPipelinesEXT(sizei n, const uint *pipelines);
void GenProgramPipelinesEXT(sizei n, uint *pipelines);
boolean IsProgramPipelineEXT(uint pipeline);
void ProgramParameteriEXT(uint program, enum pname, int value);
void GetProgramPipelineivEXT(uint pipeline, enum pname, int *params);
void ProgramUniform1iEXT(uint program, int location,
int x);
void ProgramUniform2iEXT(uint program, int location,
int x, int y);
void ProgramUniform3iEXT(uint program, int location,
int x, int y, int z);
void ProgramUniform4iEXT(uint program, int location,
int x, int y, int z, int w);
void ProgramUniform1fEXT(uint program, int location,
float x);
void ProgramUniform2fEXT(uint program, int location,
float x, float y);
void ProgramUniform3fEXT(uint program, int location,
float x, float y, float z);
void ProgramUniform4fEXT(uint program, int location,
float x, float y, float z, float w);
void ProgramUniform1uiEXT(uint program, int location,
uint x);
void ProgramUniform2uiEXT(uint program, int location,
uint x, uint y);
void ProgramUniform3uiEXT(uint program, int location,
uint x, uint y, uint z);
void ProgramUniform4uiEXT(uint program, int location,
uint x, uint y, uint z, uint w);
void ProgramUniform1ivEXT(uint program, int location,
sizei count, const int *value);
void ProgramUniform2ivEXT(uint program, int location,
sizei count, const int *value);
void ProgramUniform3ivEXT(uint program, int location,
sizei count, const int *value);
void ProgramUniform4ivEXT(uint program, int location,
sizei count, const int *value);
void ProgramUniform1fvEXT(uint program, int location,
sizei count, const float *value);
void ProgramUniform2fvEXT(uint program, int location,
sizei count, const float *value);
void ProgramUniform3fvEXT(uint program, int location,
sizei count, const float *value);
void ProgramUniform4fvEXT(uint program, int location,
sizei count, const float *value);
void ProgramUniform1uivEXT(uint program, int location,
sizei count, const uint *value);
void ProgramUniform2uivEXT(uint program, int location,
sizei count, const uint *value);
void ProgramUniform3uivEXT(uint program, int location,
sizei count, const uint *value);
void ProgramUniform4uivEXT(uint program, int location,
sizei count, const uint *value);
void ProgramUniformMatrix2fvEXT(uint program, int location,
sizei count, boolean transpose,
const float *value);
void ProgramUniformMatrix3fvEXT(uint program, int location,
sizei count, boolean transpose,
const float *value);
void ProgramUniformMatrix4fvEXT(uint program, int location,
sizei count, boolean transpose,
const float *value);
void ProgramUniformMatrix2x3fvEXT(uint program, int location,
sizei count, boolean transpose,
const float *value);
void ProgramUniformMatrix3x2fvEXT(uint program, int location,
sizei count, boolean transpose,
const float *value);
void ProgramUniformMatrix2x4fvEXT(uint program, int location,
sizei count, boolean transpose,
const float *value);
void ProgramUniformMatrix4x2fvEXT(uint program, int location,
sizei count, boolean transpose,
const float *value);
void ProgramUniformMatrix3x4fvEXT(uint program, int location,
sizei count, boolean transpose,
const float *value);
void ProgramUniformMatrix4x3fvEXT(uint program, int location,
sizei count, boolean transpose,
const float *value);
void ValidateProgramPipelineEXT(uint pipeline);
void GetProgramPipelineInfoLogEXT(uint pipeline, sizei bufSize,
sizei *length, char *infoLog);
New Tokens
Accepted by <stages> parameter to UseProgramStagesEXT:
VERTEX_SHADER_BIT_EXT 0x00000001
FRAGMENT_SHADER_BIT_EXT 0x00000002
ALL_SHADER_BITS_EXT 0xFFFFFFFF
Accepted by the <pname> parameter of ProgramParameteriEXT and
GetProgramiv:
PROGRAM_SEPARABLE_EXT 0x8258
Accepted by <type> parameter to GetProgramPipelineivEXT:
ACTIVE_PROGRAM_EXT 0x8259
Accepted by the <pname> parameter of GetBooleanv, GetIntegerv, and
GetFloatv:
PROGRAM_PIPELINE_BINDING_EXT 0x825A
Additions to Chapter 2 of the OpenGL ES 2.0 Specification (OpenGL Operation):
-- Section 2.10 "Vertex Shaders" (page 26)
Modify the fourth and fifth paragraphs:
"To use a vertex shader, shader source code is first loaded into a shader
object and then compiled. Alternatively, pre-compiled shader binary code
may be directly loaded into a shader object. An OpenGL ES implementation
must support one of these methods for loading shaders. If the boolean value
SHADER_COMPILER is TRUE, then the shader compiler is supported. If the
integer value NUM_SHADER_BINARY_FORMATS is greater than zero, then shader
binary loading is supported.
A shader object corresponds to a stage in the rendering pipeline referred
to as its shader stage or type. A vertex shader object is attached to a
program object. The program object is then linked, which generates
executable code from the compiled shader object(s) 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 sixth paragraph:
"... A single program object can contain either a vertex shader, a fragment
shader, or both."
Modify the seventh 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, the results of vertex shader execution are undefined."
-- Section 2.10.3 "Program Objects" (page 30)
Modify the description of linking failures following the description of
LinkProgram to read:
"... if <program> is not separable and does not contain both a vertex and a
fragment shader, ..."
Modify second paragraph, p. 31:
"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 paragraph immediately after preceding paragraph:
"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.10.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, the results of vertex and/or fragment processing will be undefined.
However, this is not an error."
Modify fourth and fifth paragraphs, p. 31:
"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, UseProgramStagesEXT, or
BindProgramPipelineEXT 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 UseProgramStagesEXT 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
UseProgramStagesEXT 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 BindProgramPipelineEXT."
Insert prior to the description of DeleteProgram, p. 31:
"Program parameters control aspects of how the program is linked,
executed, or stored. To set a program parameter, call
void ProgramParameteriEXT(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_EXT, <value> must be TRUE or FALSE
and indicates whether the <program> can be bound for individual
pipeline stages via UseProgramStagesEXT after it is next linked."
Modify the last paragraph of the section, p. 31:
"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 at the end of the section, p. 31:
"The command
uint CreateShaderProgramvEXT(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. CreateShaderProgramvEXT
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);
ProgramParameteriEXT(program, PROGRAM_SEPARABLE_EXT, 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 CreateShaderProgramvEXT 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."
-- Add new section 2.10.PPO "Program Pipeline Objects" after 2.10.3
"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 GenProgramPipelinesEXT(sizei n, uint *pipelines);
returns <n> previously unused program pipeline object names in
<pipelines>. These names are marked as used, for the purposes of
GenProgramPipelinesEXT only, but they acquire state only when they are
first bound.
Program pipeline objects are deleted by calling
void DeleteProgramPipelinesEXT(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
GenProgramPipelinesEXT with the command
void BindProgramPipelineEXT(uint pipeline);
<pipeline> is the program pipeline object name. The resulting program
pipeline object is a new state vector, comprising all the state and with
the same initial values listed in table 6.PPO.
BindProgramPipelineEXT 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 BindProgramPipelineEXT 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.10.3.
BindProgramPipelineEXT fails and an INVALID_OPERATION error is
generated if <pipeline> is not zero or a name returned from a
previous call to GenProgramPipelinesEXT, or if such a name has since
been deleted with DeleteProgramPipelinesEXT.
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 UseProgramStagesEXT(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 vertex or fragment indicated by
VERTEX_SHADER_BIT_EXT or FRAGMENT_SHADER_BIT_EXT respectively. The
constant ALL_SHADER_BITS_EXT 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 UseProgramStagesEXT is called with <program> set to
zero or with a program object that contains no executable code for the
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_EXT 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_EXT 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 GenProgramPipelinesEXT, 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 BindProgramPipelineEXT
creates a new program pipeline object. If <pipeline> is not a name
returned from a previous call to GenProgramPipelinesEXT or if such a
name has since been deleted by DeleteProgramPipelinesEXT, an
INVALID_OPERATION error is generated.
The command
void ActiveShaderProgramEXT(uint pipeline, uint program);
sets the linked program named by <program> to be the active program
(discussed later in the secion 2.10.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 GenProgramPipelinesEXT, 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 BindProgramPipelineEXT
creates a new program pipeline object. If <pipeline> is not a name
returned from a previous call to GenProgramPipelinesEXT or if such a
name has since been deleted by DeleteProgramPipelinesEXT, an
INVALID_OPERATION error is generated.
Shader Interface Matching
When linking a non-separable program object with multiple shader types,
the outputs of one stage form an interface with the inputs of the next
stage. These inputs and outputs must typically match in name, type,
and qualification. When both sides of an interface are contained in
the same program object, LinkProgram will detect mismatches on an
interface and generate link errors.
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 inputs and outputs are
considered to match exactly if and only if:
* For every user-declared input variable declared, there is an output
variable declared in the previous shader matching exactly in name,
type, and qualification.
* There are no user-defined output variables declared without a matching
input 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.6.1 and
4.3.6.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 an output with the
same location qualifier, data type, and qualification. Also, an input
will be well-defined if the other program writes to an output matching
the input in everything but data type as long as the output data type
has the same basic component type and more components. The names of
variables need not match when matching by location. For the purposes
of interface matching, an input with a location qualifier is considered
to match a corresponding output only if that output has an identical
location qualifier.
Built-in inputs or outputs 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:
* Three unsigned integers (initially all zero) are required to hold
each respective name of the current vertex stage program, current
fragment 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.10.4 "Shader Variables" subsection "Vertex Attributes"
Change the first sentence of the second full paragraph (p. 34):
"When a program is linked, any active attributes without a binding
specified either through BindAttribLocation or explicitly set
within the shader text will be automatically bound to vertex
attributes by the GL."
Add the following sentence to the end of that same paragraph:
"If an active attribute has a binding explicitly set within the shader text
and a different binding assigned by BindAttribLocation, the assignment in
the shader text is used."
-- Section 2.10.4 "Shader Variables" subsection "Uniform Variables"
Replace the paragraph introducing Uniform* (p. 37):
"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
ActiveShaderProgramEXT is the active program object. If the current
program pipeline object has no active program or there is no current
program pipeline object, then there is no active program.
The given values are loaded into the ... "
Change the last bullet in the "Uniform Variables" subsection (p. 38) to:
"* if there is no active program in use."
Add to the end of the "Uniform Variables" subsection (p. 38):
To load values into the uniform variables of a program which may not
necessarily be bound, use the commands
void ProgramUniform{1234}{if}EXT(uint program, int location,
T value);
void ProgramUniform{1234}uiEXT(uint program, int location,
T value);
void ProgramUniform{1234}{if}vEXT(uint program, int location,
sizei count, const T *value);
void ProgramUniform{1234}uivEXT(uint program, int location,
sizei count, const uint *value);
void ProgramUniformMatrix{234}fvEXT(uint program, int location,
sizei count, boolean transpose,
const float *value);
void ProgramUniformMatrix{2x3,3x2,2x4,
4x2,3x4,4x3}fvEXT(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.10.5 "Shader Execution" (p. 40)
Change the first paragraph:
"If there is an active program object present for the vertex stage, the
executable code for this active program is used to process incoming vertex
values."
Change first paragraph of subsection "Validation", p. 41:
"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 (DrawArrays or DrawElements) 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" (p. 41):
"* A program object is active for at least one, but not all of the
shader stages that were present when the program was linked.
* There is no 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 UseProgramStagesEXT with the
PROGRAM_SEPARABLE_EXT 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 ValidateProgramPipelineEXT(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 GetProgramPipelineivEXT (See section 6.1.8).
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 GenProgramPipelinesEXT, 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 BindProgramPipelineEXT
creates a new program pipeline object. If <pipeline> is not a name
returned from a previous call to GenProgramPipelinesEXT or if such a
name has since been deleted by DeleteProgramPipelinesEXT, an
INVALID_OPERATION error is generated.
Additions to Chapter 3 of the OpenGL ES 2.0 Specification (Rasterization)
-- Section 3.8 "Fragment Shaders" (p. 86)
Replace the last paragraph with:
"When the program object currently in use for the fragment stage
includes a fragment shader, its fragment shader is considered active and
is used to process fragments. If the current fragment stage program
object has no fragment shader or no program object is current for the
fragment stage, the results of fragment shader execution are undefined."
Additions to Chapter 4 of the OpenGL ES 2.0 Specification (Per-Fragment
Operations and the Frame Buffer)
None
Additions to Chapter 5 of the OpenGL ES 2.0 Specification (Special Functions)
None
Additions to Chapter 6 of the OpenGL ES 2.0 Specification (State and State
Requests)
-- Section 6.1.8 "Shader and Program Queries"
Add to GetProgramiv description:
"If <pname> is PROGRAM_SEPARABLE_EXT, 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 UseProgramStagesEXT."
Add after GetProgramiv description:
"The command
boolean IsProgramPipelineEXT(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, IsProgramPipelineEXT returns FALSE. No error
is generated if <pipeline> is not a valid program pipeline object
name.
The command
GetProgramPipelineivEXT(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 GenProgramPipelinesEXT, 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 BindProgramPipelineEXT
creates a new program pipeline object. If <pipeline> is not a name
returned from a previous call to GenProgramPipelinesEXT or if such a
name has since been deleted by DeleteProgramPipelinesEXT, an
INVALID_OPERATION error is generated.
If <pname> is ACTIVE_PROGRAM_EXT, 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 VALIDATE_STATUS, the validation status of the
program pipeline object, as determined by ValidateProgramPipelineEXT
(see section 2.10.5) 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."
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 GetProgramPipelineInfoLogEXT(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 GetProgramPipelineivEXT 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 ES 2.0 Specification (Shared Objects and
Multiple Contexts)
(add sentence to third paragraph, p. 164) Program pipeline objects are not
shared.
Additions to the OpenGL ES Shading Language Specification, Version 1.0.17
Including the following line in a shader can be used to control
the language feature described in thie extension:
#extension GL_EXT_separate_shader_objects : <behavior>
where <behavior> is as described in section 3.3.
A new preprocessor #define is added to the OpenGL ES Shading Language:
#define GL_EXT_separate_shader_objects 1
-- Section 4.3.3 "Attribute" (page 30):
Add new section 4.3.3.1 "Attribute Layout Qualifiers"
"Vertex shaders allow location layout qualifiers on attribute variable
declarations. The location layout qualifier identifier for vertex shader
attributes is:
layout-qualifier-id
location = integer-constant
Only one argument is accepted. For example,
layout(location = 3) attribute vec4 normal;
establishes that the vertex shader attribute <normal> is copied in from
vector location number 3.
If an input variable with no location assigned in the shader text has a
location specified through the OpenGL ES API, the API-assigned location will
be used. Otherwise, such variables will be assigned a location by the
linker. See section 2.10.4 of the OpenGL Specification for more details.
A link error will occur if an attribute variable is declared in multiple
vertex shaders with conflicting locations.
-- Section 4.3.5 "Varying" (page 31):
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
vertex shader varying outputs and fragment shader varying inputs 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 varying layout qualifiers (Section 4.3.5.1) or
by using identical varying declarations. Complete rules for interface
matching are found in the "Shader Interface Matching" portion of section
2.10.PPO of the OpenGL Specification."
Add new section 4.3.5.1 "Varying Layout Qualifiers"
"All shaders allow location layout qualifiers on varying variable
declarations. The location layout qualifier identifier for varyings is:
layout-qualifier-id
location = integer-constant
Only one argument is accepted. For example,
layout(location = 3) varying vec4 normal;
establishes that the shader varying <normal> is assigned to vector
location number 3.
If the declared varying 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) varying vec4 colors[3];
will establish that the input <colors> is assigned to vector
location numbers 6, 7, and 8.
If the declared varying is an <n>x<m> 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) varying mat4 transforms[2];
will establish that varying <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.
The number of varying locations available to a shader is limited to the
implementation-dependent advertised maximum varying vector 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 varying variables are assigned to
the same location, or if explicit location assignments leave the linker
unable to find space for other variables without explicit assignments."
Dependencies on OpenGL ES 3.0
If OpenGL ES 3.0 isn't present, references to
ProgramUniform{1234}ui[v] should be ignored. Also, any redundant
language about explicit shader variable locations set within the
shader text should also be ignored.
If neither OpenGL ES 3.0 nor NV_non_square_matrices is present,
references to ProgramUniformMatrix{2x3,3x2,2x4,4x2,3x4,4x3}fv
should be ignored.
The behavior of mixing GLSL ES 1.00 shaders with GLSL ES 3.00 shaders
in the same rendering pipeline is undefined.
If the GL is OpenGL ES 3.0, make the following changes:
Replace this sentence from the first paragraph of section 2.10.PPO Shader
Interface Matching:
"These inputs and outputs must typically match in name, type, and
qualification."
with the following language:
"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."
Add this paragraph after the first paragraph of section 2.10.PPO:
"Variables declared as structures are considered to match in type if and
only if structure members match in name, type, qualification, and
declaration order. Variables 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 match in qualification are
found in the OpenGL Shading Language Specification."
Replace the last paragraph from section 2.10.PPO:
"Built-in inputs or outputs 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."
with the following new language:
"When using GLSL ES 1.00 shaders, built-in inputs or outputs 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.
When using GLSL ES 3.00 shaders in separable programs, gl_Position and
gl_PointSize built-in outputs must be redeclared according to Section 7.5
of the OpenGL Shading Language Specification. Other built-in inputs or
outputs 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."
and add to GLSL ES 3.00 new section 7.5, 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
When compiling shaders using either of the above variables, both such
variables must be redeclared prior to use. ((Note: This restriction
applies only to shaders using version 300 that enable the
EXT_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."
Dependencies on NV_non_square_matrices
If NV_non_square_matrices is supported,
ProgramUniformMatrix{2x3,3x2,2x4,4x2,3x4,4x3}fvEXT is supported in
OpenGL ES 2.0.
Errors
UseProgramStagesEXT generates INVALID_OPERATION if the program
parameter has not been successfully linked.
UseProgramStagesEXT generates INVALID_VALUE if <stages> has a bit
set for any other than VERTEX_SHADER_BIT_EXT or
FRAGMENT_SHADER_BIT_EXT, unless <stages> is ALL_SHADER_BITS_EXT.
ActiveShaderProgramEXT generates INVALID_OPERATION if <program>
has not been successfully linked.
DrawArrays and DrawElements generate INVALID_OPERATION 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.
New State
Add to table 6.15 (Program Object State):
Initial
Get Value Type Get Command Value Description Sec
------------------ ---- ----------------------- ------- ------------------------ ------
PROGRAM_PIPELINE_- Z+ GetIntegerv 0 Current program pipeline 2.10.PPO
BINDING_EXT object binding
Add new table 6.PPO (Program Pipeline Object State):
Initial
Get Value Type Get Command Value Description Sec
------------------ ---- ---------------------------- ------- ------------------------ ------
ACTIVE_PROGRAM_EXT Z+ GetProgramPipelineivEXT 0 The program object 2.10.PPO
that Uniform* commands
update when PPO bound
VERTEX_SHADER Z+ GetProgramPipelineivEXT 0 Name of current vertex 2.10.PPO
shader program object
FRAGMENT_SHADER Z+ GetProgramPipelineivEXT 0 Name of current fragment 2.10.PPO
shader program object
VALIDATE_STATUS B GetProgramPipelineivEXT FALSE Validate status of 2.10.PPO
program pipeline object
S GetProgramPipelineInfoLogEXT empty Info log for program 6.1.8
pipeline object
INFO_LOG_LENGTH Z+ GetProgramPipelineivEXT 0 Length of info log 6.1.8
New Implementation Dependent State
None
Issues
See ARB_separate_shader_objects extension specification for issues
documented while working on the original desktop OpenGL extension.
Revision History
Rev. Date Author Changes
---- ---------- --------- ---------------------------------------------
1 2011-06-17 Benj Initial revision for ES based on
ARB_separate_shader_objects extension.
2 2011-07-22 Benj Rename APPLE to EXT, specify that PPOs are
not shareable.
3 2011-07-26 Benj Add VALIDATE_STATUS to state tables and
GetProgramPipelineivEXT description, remove
the language erroneously deleting
CURRENT_PROGRAM.
4 2013-03-07 Jon Leech Added note about the unrelated OpenGL
extension of the same name.
5 2013-03-25 Benj Add interactions with OpenGL ES 3.0.
6 2013-09-20 dkoch Add interactions with NV_non_square_matrices.
7 2013-11-08 marka Clarify ProgramUniform*ui availability.