blob: 3e9f92e40d503c0a202547d117b9b846d6ac9fe9 [file] [log] [blame]
Name
ARB_explicit_uniform_location
Name Strings
GL_ARB_explicit_uniform_location
Contact
Piers Daniell, NVIDIA (pdaniell 'at' nvidia.com)
Contributors
Bruce Merry
Christophe Riccio, AMD
Pat Brown, NVIDIA
Notice
Copyright (c) 2012-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 2012/06/12.
Version
Last Modified Date: 05/15/2012
Revision: 6
Number
ARB Extension #128
Dependencies
Requires OpenGL 3.3 or ARB_explicit_attrib_location.
This extension interacts with ARB_shader_subroutine.
This extension is written against the OpenGL 4.2 (Compatibility Profile)
and the OpenGL Shading Language 4.20.11 specification.
Overview
This extension provides a method to pre-assign uniform locations to
uniform variables in the default uniform block, including subroutine
uniforms. This allows an application to modify the uniform values without
requiring a GL query like GetUniformLocation, GetSubroutineUniformLocation
and GetSubroutineIndex.
IP Status
No known IP claims.
New Procedures and Functions
None
New Tokens
Accepted by the <pname> parameter of GetBooleanv, GetIntegerv,
GetFloatv, GetDoublev, and GetInteger64v:
MAX_UNIFORM_LOCATIONS 0x826E
Additions to Chapter 2 of the OpenGL 4.2 Specification (OpenGL Operation)
Section 2.14.7 "Uniform Variables":
Modify the third paragraph on page 114 to read:
"When a program is successfully linked, all active uniforms, except for
atomic counters, belonging to the program object's default uniform block
are initialized as defined by the version of the OpenGL Shading Language
used to compile the program. A successful link will also generate a
location for any active uniform in the default uniform block which don't
already have an explicit location defined in the shader. The generated
locations will never take the location of a uniform with an explicit
location defined in the shader, even if that uniform is determined to
be inactive. The values of active uniforms in the default uniform block
can be changed using this location and the appropriate Uniform* command
(see below). These generated locations are invalidated and new ones
assigned after each successful re-link. The explicitly defined locations
and the generated locations must be in the range of 0 to
MAX_UNIFORM_LOCATIONS minus one."
Section 2.14.8 "Subroutine Uniform Variables":
Modify the last paragraph on page 136 to read:
"The command
int GetSubroutineUniformLocation(uint program, enum shadertype,
const char *name);
will return the location of the subroutine uniform variable <name> in the
shader stage of type <shadertype> attached to <program>, with behavior
otherwise identical to GetUniformLocation. The value -1 will be returned
if <name> is not the name of an active subroutine uniform. The subroutine
uniform may have an explicit location specified in the shader. At link
time, all active subroutine uniforms without an explicit location will be
assigned a unique location. The value ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS
is the largest assigned or generated location plus one. An assigned
location will never take the location of an explicitly assigned location
in, even if that subroutine uniform is inactive. Between the location 0
and ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS minus one there may be unused
locations either because they weren't assigned a subroutine uniform or
because the subroutine uniform was determined to be inactive by the
linker. These locations will be ignored when assigning the subroutine
index as described below.
There is an implementation-dependent limit on the number of active
subroutine uniform locations in each shader stage; a program will fail
to link if the number of subroutine uniform locations required is greater
than the value of MAX_SUBROUTINE_UNIFORM_LOCATIONS or if an explicit
subroutine uniform location is outside this limit. If <program> has not
been successfully linked, the error INVALID_OPERATION will be generated.
For active subroutine uniforms declared as arrays, the declared array
elements are assigned consecutive locations.
Each function in a shader associated with a subroutine type is considered
an active subroutine, unless the compiler conclusively determines that
the function could never be assigned to an active subroutine uniform.
The subroutine functions can be assigned an explicit index in the shader
between 0 and MAX_SUBROUTINES minus one. At link time, all active
subroutines without an explicit index will be assigned an index between 0
and ACTIVE_SUBROUTINES minus one. An assigned index will never take the
same index of an explicitly assigned index in the shader, even if that
subroutine is inactive. Between index 0 and ACTIVE_SUBROUTINES minus one
there may be unused indices either because they weren't assigned an
index by the linker or because the subroutine was determined to be
inactive by the linker. If there are no explicitly defined subroutine
indices in the shader the implementation must assign indices between
0 and ACTIVE_SUBROUTINES minus one with no index unused. It is
recommended, but not required, the application assigns a range of tightly
packed indices starting from zero to avoid indices between 0 and
ACTIVE_SUBROUTINES minus one being unused.
The index can be queried with the command:
uint GetSubroutineIndex(uint program, enum shadertype,
const char *name);
where name is the null-terminated name of a function in the shader stage
of type <shadertype> attached to <program>. The value INVALID_INDEX will
be returned if name is not the name of an active subroutine in the shader
stage. After the program has been linked, the subroutine index will not
change unless the program is re-linked."
Modify the second paragraph on page 138 to read:
"The name of an active subroutine can be queried given its subroutine
index with the command:
void GetActiveSubroutineName(uint program, enum shadertype, uint index,
sizei bufsize, dizei *length, char *name);
<program> and <shadertype> specify the program and shader stage. <index>
must be a subroutine index in the range from zero to the value of
ACTIVE_SUBROUTINES minus one for the shader stage. If <index> is greater
than or equal to the value of ACTIVE_SUBROUTINES, the error INVALID_VALUE
is generated. The name of the selected subroutine is returned as a null-
terminated string in name. The actual number of characters written into
name, excluding the null terminator, is returned in length. If length is
NULL, no length is returned. If the index refers to an unused subroutine
index, the string returned in <name> is an empty string and the length
returned is zero. ..."
Modify the last paragraph on page 138 to read:
"The command
void UniformSubroutinesuiv(enum shadertype, sizei count,
const uint *indices);
will load all active subroutine uniforms for shader stage <shadertype>
with subroutine indices from <indices>, storing <indices>[i] into the
uniform at location i. Any locations between 0 and
ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS minus one which are not used will be
ignored. If <count> is not equal to the value of
ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS for the program currently in use at
shader stage <shadertype>, or if the uniform at location i is used and
the value in <indices>[i] is greater than or equal to the value
of ACTIVE_SUBROUTINES for the shader stage, the error INVALID_VALUE is
generated. If the value of <indices>[i] for a used location specifies an
unused index the error INVALID_VALUE is generated. If, for any subroutine
index being loaded to a particular uniform location, the function
corresponding to the subroutine index was not associated (as defined in
section 6.1.2 of the OpenGL Shading Language Specification) with the type
of the subroutine variable at that location, then the error
INVALID_OPERATION is generated. If no program is active, the error
INVALID_OPERATION is generated."
Additions to Chapter 6 of the OpenGL 4.2 Specification (OpenGL Operation)
Section 6.1.18 "Shader and Program Queries":
Modify the second paragraph on page 501:
"The command
void GetUniformSubroutineuiv(enum shadertype, int location, uint *params);
returns the value of the subroutine uniform at location <location> for
shader stage <shadertype> of the current program. If <location> is
greater than or equal to the value of ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS
for the shader currently in use at shader stage <shadertype>, the error
INVALID_VALUE is generated. If <location> represents an unused location,
the value INVALID_INDEX is returned and no error is generated. If no
program is active, the error INVALID_OPERATION is generated."
Additions to the AGL/GLX/WGL Specifications
None.
Dependencies on ARB_shader_subroutine
If ARB_shader_subroutine is not supported, remove all references to
subroutine uniform locations and subroutine indices.
GLX protocol
None
Errors
INVALID_VALUE is generated if an unused index is assigned to an
active and used subroutine uniform variable by UniformSubroutinesuiv.
New State
None
New Implementation Dependent State
Changes to table 6.64, p. 568 (Implementation Dependent Values)
Minimum
Get Value Type Get Command Value Description Sec. Attribute
--------- ---- ----------- ------- ----------- ---- ---------
MAX_UNIFORM_LOCATIONS Z+ GetIntegerv 1024 Maximum number of user- 2.14.7 -
assignable uniform locations
Modifications to The OpenGL Shading Language Specification, Version 4.20.06
Including the following line in a shader can be used to control
the language feature described in thie extension:
#extension GL_ARB_explicit_uniform_location : <behavior>
where <behavior> is as described in section 3.3.
A new preprocessor #define is added to the OpenGL Shading Language:
#define GL_ARB_explicit_uniform_location 1
Insert a new section called 4.4.3 "Uniform Variable Layout Qualifiers":
"Layout qualifiers can be used for uniform variables and subroutine
uniforms. The layout qualifier identifiers for uniform variables and
subroutine uniforms are:
layout-qualifier-id
location = integer-constant
The location idenifier can be used with default-block uniform
variables and subroutine uniforms. The location specifies the
location by which the OpenGL API can reference the uniform and update its value.
Individual elements of a uniform array are assigned consecutive locations
with the first element taking location <location>. No two default-block
uniform variables in the program can have the same location, even if they
are unused, otherwise a compiler or linker error will be generated. No two
subroutine uniform variables can have the same location in the same shader
stage, otherwise a compiler or linker error will be generated. Valid
locations for default-block uniform variable locations are in the range of
0 to the implementation-defined maximum number of uniform locations. Valid
locations for subroutine uniforms are in the range of 0 to the
implementation-defined per-stage maximum number of subroutine uniform
locations minus one.
Locations can be assigned to default-block uniform arrays and structures.
The first inner-most scalar, vector or matrix member or element takes the
specified <location> and the compiler assigns the next inner-most member
or element the next incremental location value. Each subsequent inner-most
member or element gets incremental locations for the entire structure or
array. This rule applies to nested structures and arrays and gives each
inner-most scalar, vector, or matrix type a unique location. For arrays
without an explicit size, the size is calculated based on its static
usage. When the linker generates locations for uniforms without an
explicit location, it assumes for all uniforms with an explicit location
all their array elements and structure members are used and the linker
will not generate a conflicting location, even if that element of member
is deemed unused."
Insert a new section called 4.4.4 "Subroutine Function Layout Qualifiers":
"Layout qualifiers can be used for subroutine functions. The layout
qualifier identifiers for subroutine functions are:
layout-qualifier-id
index = integer-constant
Each subroutine with an index qualifier in the shader must be given
a unique index, otherwise a compile or link error will be generated. The
indices must be in the range of 0 to the implementation defined maximum
number of subroutines minus one. It's recommended, but not required, that
the shader assigns a range of tightly packed <index> values starting
from zero so that the GL subroutine function enumeration API returns a
non-empty name for all active indices."
Issues
1) Can the application mix uniforms with explicit locations with
regular uniforms without explicit locations?
RESOLVED: Yes, uniform locations assigned automatically at link time
will not alias any uniform with explicit locations, even if those
uniforms are inactive.
2) Can the application mix subroutine uniforms with explicit locations
with subroutine uniforms without explicit locations? Also, can the
application mix subroutines with explicit indices with subroutines
without an index specified.
RESOLVED: Yes, any subroutine uniforms without an explicit location
will be assigned a location between 0 and
ACTIVE_UNIFORM_SUBROUTINE_LOCATIONS minus 1 with a location that
has not been used by the shader, regardless of whether it refers
to a subroutine uniform that is unused. The value of
ACTIVE_UNIFORM_SUBROUTINE_LOCATIONS is calculated as the max of
the explicit location and automatically assigned location. If
there are unused locations between 0 and
ACTIVE_UNIFORM_SUBROUTINE_LOCATION, these will be ignored by
UniformSubroutinesiv(). Similarily with the subroutine
indices, the linker will allocate unused indices to the subroutines
without an explicit index and the value of ACTIVE_SUBROUTINES
will be the max of the largest explicit index and the linker
assigned index. There may be unused indices between 0 and
ACTIVE_SUBROUTINES minus 1 and UniformSubroutinesiv() will return
an error if the app attempts to use an unused index with an active
and used subroutine uniform.
3) How should an application determine unique default-block uniform
variable locations?
RESOLVED: Each transparent basic-type uniform variable consumes exactly
one location, regarless of it's type. Transparent basic-types, as defined
in section 4.1 are booleans, integers, floats, doubles, vectors and
matrices. An array of basic-type uniforms consumes consecutive locations,
incrementing by one for each consecutive element. Structures of
basic-type uniforms assign consecutive locations to each member
where the first base member takes the first location. These rules apply
recursively to nested structures and arrays assigning consecutive
locations each consecutive basic-type variable.
Any uniform variables without an explicit location assigned will be
assigned a unique location by the linker. It's implementation defined
what locations the linker chooses for these variables, the only
requirement being that these generated locations do not alias any
explicitly defined locations.
Note that subroutine uniform variables are not in the same namespace
as default-block uniform variables. Subroutine uniform locations
are per shader stage rather than per program and they are referenced
through a different API so can have the same locations as uniform
variables.
4) What happens if Uniform* is called with an explicitly defined
uniform location, but that uniform is deemed inactive by the
linker?
RESOLVED: The call is ignored for inactive uniform variables and
no error is generated. Uniforms without an explicit location that
are determined to be inactive return -1 for the the location when
GetUniformLocation is queried. Calling Uniform* with a location
of -1 is also ignored. That behavior isn't changed.
5) What is the value of ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS after
successfully compiling and linking a program?
RESOLVED: The value of ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS is
calculated per shader stage to be the max of the explicitly
defined subroutine uniform variable locations and the generated
locations for subroutine uniform variables without a defined
location. The consequence of this is that there will be some
locations between 0 and ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS minus one
that are unused. UniformSubroutinesuiv ignores index entries for
unused locations.
6) Does the application need to query ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS
to figure out the <count> parameter to UniformSubroutine?
RESOLVED: No, it doesn't have to. If the application knows the shader
source and it only uses explicit subroutine uniform variables locations
it can figure out ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS by simply taking the
maximum location defined plus one. If there are generated subroutine
uniform locations the application will need to query
ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS like before.
7) What is the value of ACTIVE_SUBROUTINES after successfully compiling
and linking a program?
RESOLVED: The value of ACTIVE_SUBROUTINES is calculated per shader
stage to be the max of the explicitly defined subroutine index
values and the generated indices for subroutines without a defined
index. The consequence of this is that there will be some invalid
indices between 0 and ACTIVE_SUBROUTINES minus one which don't
reference any subroutine. If GetActiveSubroutineName is called with
one of these unused indices, no error is generated but the <name>
returned will be an empty string and the <length> will be zero.
8) Does the query for ACTIVE_UNIFORMS in the program include inactive
uniform variables with explicit locations?
RESOLVED: No, only the active default-block uniforms are included in
this count. It's only the <location> of inactive uniform variables that
can be used with existing GL fuctions like Uniform*, UniformMatrix*,
ProgramUniform*, etc. and are ignored. Otherwise these inactive uniforms
operate like they did before this extension.
9) Should we introduce the concept of "location" in addition to the
existing "index" for subroutine functions? This would make it more
consistent with regular uniforms. You would use the "index" property
for the purposes of enumerating the enties with GetActiveSubroutineName
and "location" for the purposes of UniformSubroutinesuiv. This will
avoid the issue of GetActiveSubroutineName having possibly empty
strings returned for indices between 0 and ACTIVE_SUBROUTINES-1.
RESOLVED: No, not at this time. The downside of introducing a "location"
property is that we'll need to introduce a new function called
GetSubroutineLocation, which would return an "int" where -1 means
invalid location, and then use these values instead of indexes with
UniformSubroutinesuiv. Unfortunately, UniformSubroutinesuiv takes
an array of "uints". Also, it would be quite confusing to have both
GetSubroutineLocation and GetSubroutineIndex, especially for existing
apps that already used GetSubroutineIndex. It would be tricky to
specify which should be used and tricky the support the transition
of apps between OpenGL 4.2 and OpenGL 4.3 usage. And that complexity
feels less attractive than the benefit of solving the enumeration
issue. Apps that tightly pack their index assignments won't have
a problem so in practice a holey enumeration would be an app choice.
Revision History
Rev. Date Author Changes
---- -------- -------- -----------------------------------------------
6 05/15/12 pdaniell Fix the Errors section to match the added
spec language.
5 04/26/12 pdaniell Add issue #9 and resolve all issues based on
Dublin face to face discussion. Minor edits
based on feedback from criccio.
4 04/25/12 pdaniell Edits based on feedback from pbrown.
3 04/24/12 pdaniell Further improvements and clarifications. Add
MAX_UNIFORM_LOCATIONS.
2 04/23/12 pdaniell Fixes and improvements based on bmerry's
feedback and discussions with pbrown. Add
new issues.
1 10/26/11 pdaniell Initial version.