-
Notifications
You must be signed in to change notification settings - Fork 98
/
GL_EXT_nonuniform_qualifier.txt
executable file
·221 lines (150 loc) · 7.57 KB
/
GL_EXT_nonuniform_qualifier.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
Name
EXT_nonuniform_qualifier
Name Strings
GL_EXT_nonuniform_qualifier
Contact
Jeff Bolz, NVIDIA Corporation (jbolz 'at' nvidia.com)
Contributors
John Kessenich, Google
Status
Draft
Version
Last Modified Date: March 12, 2018
Revision: 1
Number
TBD
Dependencies
This extension requires GL_KHR_vulkan_glsl
Overview
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
None.
New Tokens
None.
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:
nonuniformEXT
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
expressions.
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
redeclaration.
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:
nonuniform_qualifier:
NONUNIFORM
Under the rule for single_type_qualifier, add:
| nonuniform_qualifier
Under the rule for function_identifier, add:
| nonuniform_qualifier
Errors
None.
Issues
(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.