Skip to content
Branch: master
Find file Copy path
Find file Copy path
1 contributor

Users who have contributed to this file

executable file 222 lines (150 sloc) 7.57 KB
Name Strings
Jeff Bolz, NVIDIA Corporation (jbolz 'at'
John Kessenich, Google
Last Modified Date: March 12, 2018
Revision: 1
This extension requires GL_KHR_vulkan_glsl
This extension adds a "nonuniform" type qualifier and constructor, which
is required by the Vulkan API to be used when indexing descriptor
bindings with an index that is not dynamically uniform.
This extension also allows arrays of resources declared using unsized
arrays to become run-time sized arrays.
New Procedures and Functions
New Tokens
Modifications to GL_KHR_vulkan_glsl
Add to the "Mapping to SPIR-V" section
Mapping of nonuniformEXT type qualifier:
nonuniformEXT -> NonUniformEXT decoration on variables
Mapping of arrays:
Explicitly- and implicitly-sized arrays use OpTypeArray. Run-time sized
arrays use OpTypeRuntimeArray, and are only supported for the last
member of a storage block, or for an array of resources. Resources
include all variables with storage class code:Uniform,
code:StorageBuffer, or code:UniformConstant (e.g. an array of
samplers or images in uniform storage, or uniform/buffer blocks),
or for the outermost dimension of an array of arrays of resources.
Modifications to the OpenGL Shading Language Specification, Version 4.50
Including the following line in a shader can be used to control the
language features described in this extension:
#extension GL_EXT_nonuniform_qualifier : <behavior>
where <behavior> is as specified in section 3.3
New preprocessor #defines are added to the OpenGL Shading Language:
#define GL_EXT_nonuniform_qualifier 1
Add to section 3.6 Keywords:
Modify section 4.1.9:
Replace the first paragraph:
Variables of the same type can be aggregated into arrays by declaring
a name followed by brackets ( [] ) enclosing an optional size.
When an array size is specified in a declaration, it must be an
integral constant expression (see section 4.3.3 "Constant Expressions")
greater than zero.
An array whose size is specified in its declaration or determined by
its initializer is _explicitly-sized_.
An array whose size is not specified in a declaration is _unsized_.
Unsized arrays can either be implicitly sized or run-time sized.
A _run-time sized_ array has its size determined by a buffer or
descriptor set bound via the API.
An _implicitly sized_ array has its size determined by the largest
(constant expression) index used to index the array.
If the last member of a shader storage block is an unsized array, it is
run-time sized.
Unsized arrays of opaque uniforms, uniform blocks, and shader storage
blocks are run-time sized if there is a static use of a non-constant
expression to index that array.
All other unsized arrays are implicitly sized.
Implicitly sized arrays must only be indexed with integral constant
Unsized arrays must not be passed as an argument to a function, and
arrays declared as formal parameters in a function declaration must
be explicitly sized.
Violation of any of these rules result in compile-time errors.
It is legal to declare an array without a size and then later redeclare
the same name as an array of the same type and specify a size, and such
an array is considered to be explicitly sized.
However, unless noted otherwise, blocks cannot be redeclared; an
unsized array in a user-declared block cannot be sized by a block
It is a compile-time error to declare an array with a size, and then
later (in the same shader) index the same array with an integral
constant expression greater than or equal to the declared size.
It is a compile-time error to redeclare an unsized array with a size
equal to or smaller than any index used earlier in the shader to index
the array.
It is also a compile-time error to index an array with a negative
constant expression.
Undefined behavior results from indexing an array with a non-constant
expression that's greater than or equal to the array's size or less
than 0.
Arrays only have a single dimension (a single entry within "[]"),
however, arrays of arrays can be declared.
All types (basic types, structures, arrays) can be formed into an array.
Add a new section:
"4.X Nonuniform qualifier"
The nonuniformEXT qualifier can be used to assert that a variable or
expression is not dynamically uniform. In a declaration, it is
syntactically treated as a qualifier. It can be applied to:
* variable declarations qualified as *in*
* global variable declarations with no storage qualifier
* local variable declarations with no storage qualifier
* function parameter declarations and function return types.
Any other use on a declaration results in a compile-time error.
The nonuniformEXT qualifier can also be used with constructor syntax to
assert that an expression is not dynamically uniform. For example:
layout(location = 0) flat in int i;
layout(set = 0, binding = 0) uniform sampler2D tex[2];
color = texture(tex[nonuniformEXT(i)], ...);
This constructor syntax takes a single argument of any type and returns
the value with the same type, qualified with nonuniformEXT.
Only some operations discussed in Chapter 5 (Operators and Expressions)
can be applied to nonuniform value(s) and still yield a result that is
nonuniform. The operations that do so are listed below. When a
nonuniform value is operated on with one of these operators (regardless
of whether any and other operands are nonuniform), the result is
implicitly nonuniform:
* All Operators in Section 5.1 (Operators), except for assignment,
arithmetic assignment, and sequence
* Component selection in Section 5.5
* Matrix components in Section 5.6
* Structure and Array Operations in Section 5.7, except for the length
method and assignment operator.
Constructors and builtin functions, which all have return types that
are not qualified by nonuniformEXT, will not generate nonuniform results.
Shaders need to use the constructor syntax (or assignment to a
nonuniformEXT-qualified variable) to re-add the nonuniformEXT qualifier
to the result of builtin functions. Similarly, when a nonuniform value
is passed as a function parameter, whether it is treated as nonuniform
inside the function is based solely on the function parameter
declaration, and not on whether the value passed in was nonuniform.
Changes to the grammar:
Add the token NONUNIFORM
Add a new rule:
Under the rule for single_type_qualifier, add:
| nonuniform_qualifier
Under the rule for function_identifier, add:
| nonuniform_qualifier
(1) Can nonuniformEXT be used on structure or block members?
RESOLVED: No, for simplicity it can only be applied to variables and not
in structure or block type declarations.
Revision History
Revision 1
- Internal revisions.
You can’t perform that action at this time.