-
Notifications
You must be signed in to change notification settings - Fork 103
/
GLSL_EXT_buffer_reference.txt
249 lines (169 loc) · 8.67 KB
/
GLSL_EXT_buffer_reference.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
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
Name
EXT_buffer_reference
Name Strings
GL_EXT_buffer_reference
Contact
Jeff Bolz, NVIDIA Corporation (jbolz 'at' nvidia.com)
Contributors
Status
Draft
Version
Last Modified Date: February 18, 2019
Revision: 1
Number
TBD
Dependencies
This extension can be applied to OpenGL GLSL versions 4.50
(#version 450) and higher.
This extension can be applied to OpenGL ES ESSL versions 3.20
(#version 320) and higher.
This extension is written against the OpenGL Shading Language
Specification, version 4.60, dated July 23, 2017.
Interacts with GL_KHR_vulkan_glsl.
Interacts with GL_ARB_gpu_shader_int64 and
GL_EXT_shader_explicit_arithmetic_types_int64.
Overview
This extension allows storage block names to be declared with
a "buffer_reference" layout, which lets them act as reference type names
and be used to declare references within another block declaration, or as
variables.
A corresponding API extension provides functionality to retrieve the
address value for a given buffer, and also defines the size and alignment
of the reference types.
New Procedures and Functions
None.
New Tokens
None.
Modifications to GL_KHR_vulkan_glsl
Add to the "Mapping to SPIR-V" section
Uses the SPV_EXT_physical_storage_buffer extension to define reference
types as pointer types to the PhysicalStorageBufferEXT storage class.
Modifications to the OpenGL Shading Language Specification, Version 4.60
Including the following line in a shader can be used to control the
language features described in this extension:
#extension GL_EXT_buffer_reference : <behavior>
where <behavior> is as specified in section 3.3
New preprocessor #defines are added to the OpenGL Shading Language:
#define GL_EXT_buffer_reference 1
Modify section 4.1.9 (Arrays)
Add to the end of the section:
It is a compile-time error to use the *length* method on an unsized
array member of a shader storage block type declared with the
buffer_reference layout.
Modify section 4.3.2 (Constant Qualifier)
Change the first paragraph to clarify that the constant qualifier is
disallowed on reference types:
Named compile-time constants or read-only variables can be declared
using the const qualifier. The const qualifier can be used with any of
the non-void transparent basic data types (this does not include
reference types), ...
Modify section 4.3.9 (Interface Blocks)
Add to the end of the section:
Shader storage blocks can be declared with the "buffer_reference" layout
qualifier, which alters their behavior to create a type that is a
reference to the block (as if the block were a structure type). The
reference type's name is the block name. If there is no instance name,
then no block variable is declared. If there is an instance name, then
a block variable is declared and that variable behaves the same as if
"buffer_reference" were not used. Set and binding layouts as well as
qualifiers like coherent and volatile don't apply to the reference
type, but do apply to the instance variable.
The reference type can be used to declare block references in any
storage type, including as block members, local variables, and function
parameters and return types. When a reference type is used as a buffer
or uniform block member, it is treated as an eight byte scalar type
for the purposes of the block layout rules. Reference types are treated
as transparent types (but not as a "basic type").
The field selector ( . ) operator is used to access members through a
reference. The only operators allowed to operate on reference types are
field selector, assignment ( = ), ternary selection ( ?: ), and
sequence ( , ).
Additionally, the "buffer_reference" layout qualifier can be used to
define a forward declaration to the reference type, so it can be used
in other block declarations or in its own block declaration. A forward
declaration is made by omitting the member list and instance name.
If any access through a buffer reference value uses an address that is
not within the bounds of a buffer, it produces undefined behavior.
Each buffer reference type has an alignment that can be specified via
the "buffer_reference_align" layout qualifier. This must be a power of
two and be greater than or equal to the largest scalar/component type
in the block. If the layout qualifier is not specified, it defaults to
16 bytes. All buffer reference addresses used for a particular buffer
reference type are assumed to be aligned to this alignment value. That
is, the base of the block must be aligned, and members of the block can
be aligned within the block using standard layouts and offset layout
qualifiers.
Example:
// forward declaration
layout(buffer_reference) buffer blockType;
// complete reference type definition
layout(buffer_reference, std430, buffer_reference_align = 16) buffer blockType {
int x;
blockType next;
};
// A normal block declaration that includes a reference to blockType
layout(std430) buffer rootBlock {
blockType root;
} r;
void main()
{
blockType b = r.root;
// "pointer chasing" through a linked list
b = b.next.next.next.next.next;
// ...
// use b.x;
}
Modify section 4.4 (Layout Qualifiers):
Update the table to add a row for "buffer_reference":
Layout Qualifier Qualifier Only Individual Variable Block Block Member Allowed Interfaces
buffer_reference X X buffer
buffer_reference_align X X buffer
Modify section 4.4.5 (Uniform and Shader Storage Block Layout Qualifiers):
Add "buffer_reference" and "buffer_reference_align = integer-constant-expression"
to the layout-qualifier-id grammar rule.
Modify section 5.4.1 (Conversion and Scalar Constructors)
Add to the end of the section:
Buffer reference types can be constructed from other buffer reference
types. Buffer reference types can be constructed from a single uint64_t
value, and a uint64_t value can be constructed from a buffer reference
type value.
Modify section 5.9 (Expressions)
Change the bullet about the equality operators:
The equality operators equal ( == ), and not equal ( != ) operate on
all types except opaque types, aggregates that contain opaque types,
subroutine uniforms, aggregates that contain subroutine uniforms,
reference types, and aggregates that contain reference types. ...
Errors
None.
Interactions with GL_ARB_gpu_shader_int64 and
GL_EXT_shader_explicit_arithmetic_types_int64
If neither GL_ARB_gpu_shader_int64 nor
GL_EXT_shader_explicit_arithmetic_types_int64 is supported, then remove
the constructors to convert to and from uint64_t.
Interactions with GL_KHR_vulkan_glsl
If GL_KHR_vulkan_glsl isn't supported, remove mention of descriptor set
decorations.
Issues
(1) Why "references" and not pointers?
RESOLVED: Extending the block syntax to allow the types to be used
similarly to C++ references is a small incremental change to the language
and grammar, and provides most of the same functionality.
(2) Should we provide a way to compare a reference to "null"?
RESOLVED: No. Shaders can convert to uint64_t and compare the value
against the NULL value specified by the API (zero, for Vulkan).
(3) What operations are supported for reference types?
RESOLVED: Certain operations are disallowed because they don't have a
direct mapping to SPIR-V. Equality == and != are disallowed because there
are no pointer comparison instructions in SPIR-V, though it is possible
to convert to uint64_t and compare those integer values. The constant
qualifier is disallowed because OpConstant doesn't support generating
pointer constants (but note that reference types *can* participate in
constant expressions).
Revision History
Revision 1
- Internal revisions.
Revision 2
- Clarify that reference types are "transparent" types. Clarify that
the constant qualifier is forbidden on reference types. Clarify that
only assignment, construction, conversion, and field selection
operators are supported.