2 * Copyright © 2019 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
24 #include "compiler/nir/nir.h"
25 #include "compiler/nir/nir_builder.h"
27 #include "ir_uniform.h"
29 #include "util/compiler.h"
30 #include "main/mtypes.h"
33 get_block_array_index(nir_builder
*b
, nir_deref_instr
*deref
,
34 const struct gl_shader_program
*shader_program
)
36 unsigned array_elements
= 1;
38 /* Build a block name such as "block[2][0]" for finding in the list of
39 * blocks later on as well as an optional dynamic index which gets added
40 * to the block index later.
43 const char *block_name
= "";
44 nir_ssa_def
*nonconst_index
= NULL
;
45 while (deref
->deref_type
== nir_deref_type_array
) {
46 nir_deref_instr
*parent
= nir_deref_instr_parent(deref
);
47 assert(parent
&& glsl_type_is_array(parent
->type
));
48 unsigned arr_size
= glsl_get_length(parent
->type
);
50 if (nir_src_is_const(deref
->arr
.index
)) {
51 unsigned arr_index
= nir_src_as_uint(deref
->arr
.index
);
53 /* We're walking the deref from the tail so prepend the array index */
54 block_name
= ralloc_asprintf(b
->shader
, "[%u]%s", arr_index
,
57 binding
+= arr_index
* array_elements
;
59 nir_ssa_def
*arr_index
= nir_ssa_for_src(b
, deref
->arr
.index
, 1);
60 arr_index
= nir_umin(b
, arr_index
, nir_imm_int(b
, arr_size
- 1));
61 nir_ssa_def
*arr_offset
= nir_amul_imm(b
, arr_index
, array_elements
);
63 nonconst_index
= nir_iadd(b
, nonconst_index
, arr_offset
);
65 nonconst_index
= arr_offset
;
67 /* We're walking the deref from the tail so prepend the array index */
68 block_name
= ralloc_asprintf(b
->shader
, "[0]%s", block_name
);
71 array_elements
*= arr_size
;
75 assert(deref
->deref_type
== nir_deref_type_var
);
76 binding
+= deref
->var
->data
.binding
;
77 block_name
= ralloc_asprintf(b
->shader
, "%s%s",
78 glsl_get_type_name(deref
->var
->interface_type
),
81 struct gl_linked_shader
*linked_shader
=
82 shader_program
->_LinkedShaders
[b
->shader
->info
.stage
];
85 struct gl_uniform_block
**blocks
;
86 if (deref
->mode
== nir_var_mem_ubo
) {
87 num_blocks
= linked_shader
->Program
->info
.num_ubos
;
88 blocks
= linked_shader
->Program
->sh
.UniformBlocks
;
90 assert(deref
->mode
== nir_var_mem_ssbo
);
91 num_blocks
= linked_shader
->Program
->info
.num_ssbos
;
92 blocks
= linked_shader
->Program
->sh
.ShaderStorageBlocks
;
95 /* Block names are optional with ARB_gl_spirv so use the binding instead. */
96 bool use_bindings
= shader_program
->data
->spirv
;
98 for (unsigned i
= 0; i
< num_blocks
; i
++) {
99 if (( use_bindings
&& binding
== blocks
[i
]->Binding
) ||
100 (!use_bindings
&& strcmp(block_name
, blocks
[i
]->Name
) == 0)) {
102 return nir_iadd_imm(b
, nonconst_index
, i
);
104 return nir_imm_int(b
, i
);
108 /* TODO: Investigate if we could change the code to assign Bindings to the
109 * blocks that were not explicitly assigned, so we can always compare
114 unreachable("Failed to find the block by binding");
116 unreachable("Failed to find the block by name");
120 get_block_index_offset(nir_variable
*var
,
121 const struct gl_shader_program
*shader_program
,
122 gl_shader_stage stage
,
123 unsigned *index
, unsigned *offset
)
126 struct gl_linked_shader
*linked_shader
=
127 shader_program
->_LinkedShaders
[stage
];
130 struct gl_uniform_block
**blocks
;
131 if (var
->data
.mode
== nir_var_mem_ubo
) {
132 num_blocks
= linked_shader
->Program
->info
.num_ubos
;
133 blocks
= linked_shader
->Program
->sh
.UniformBlocks
;
135 assert(var
->data
.mode
== nir_var_mem_ssbo
);
136 num_blocks
= linked_shader
->Program
->info
.num_ssbos
;
137 blocks
= linked_shader
->Program
->sh
.ShaderStorageBlocks
;
140 /* Block names are optional with ARB_gl_spirv so use the binding instead. */
141 bool use_bindings
= shader_program
->data
->spirv
;
143 for (unsigned i
= 0; i
< num_blocks
; i
++) {
144 const char *block_name
= glsl_get_type_name(var
->interface_type
);
145 if (( use_bindings
&& blocks
[i
]->Binding
== var
->data
.binding
) ||
146 (!use_bindings
&& strcmp(block_name
, blocks
[i
]->Name
) == 0)) {
148 *offset
= blocks
[i
]->Uniforms
[var
->data
.location
].Offset
;
154 unreachable("Failed to find the block by binding");
156 unreachable("Failed to find the block by name");
160 lower_buffer_interface_derefs_impl(nir_function_impl
*impl
,
161 const struct gl_shader_program
*shader_program
)
163 bool progress
= false;
166 nir_builder_init(&b
, impl
);
168 nir_foreach_block(block
, impl
) {
169 nir_foreach_instr_safe(instr
, block
) {
170 switch (instr
->type
) {
171 case nir_instr_type_deref
: {
172 nir_deref_instr
*deref
= nir_instr_as_deref(instr
);
173 if (!(deref
->mode
& (nir_var_mem_ubo
| nir_var_mem_ssbo
)))
176 /* We use nir_address_format_32bit_index_offset */
177 assert(deref
->dest
.is_ssa
);
178 assert(deref
->dest
.ssa
.bit_size
== 32);
179 deref
->dest
.ssa
.num_components
= 2;
183 b
.cursor
= nir_before_instr(&deref
->instr
);
186 if (deref
->deref_type
== nir_deref_type_var
&&
187 !glsl_type_is_interface(glsl_without_array(deref
->var
->type
))) {
188 /* This variable is contained in an interface block rather than
189 * containing one. We need the block index and its offset
192 unsigned index
, offset
;
193 get_block_index_offset(deref
->var
, shader_program
,
194 b
.shader
->info
.stage
,
196 ptr
= nir_imm_ivec2(&b
, index
, offset
);
197 } else if (glsl_type_is_interface(deref
->type
)) {
198 /* This is the last deref before the block boundary.
199 * Everything after this point is a byte offset and will be
200 * handled by nir_lower_explicit_io().
202 nir_ssa_def
*index
= get_block_array_index(&b
, deref
,
204 ptr
= nir_vec2(&b
, index
, nir_imm_int(&b
, 0));
206 /* This will get handled by nir_lower_explicit_io(). */
210 nir_deref_instr
*cast
= nir_build_deref_cast(&b
, ptr
, deref
->mode
,
212 nir_ssa_def_rewrite_uses(&deref
->dest
.ssa
,
213 nir_src_for_ssa(&cast
->dest
.ssa
));
214 nir_deref_instr_remove_if_unused(deref
);
218 case nir_instr_type_intrinsic
: {
219 nir_intrinsic_instr
*intrin
= nir_instr_as_intrinsic(instr
);
220 switch (intrin
->intrinsic
) {
221 case nir_intrinsic_load_deref
: {
222 nir_deref_instr
*deref
= nir_src_as_deref(intrin
->src
[0]);
223 if (!(deref
->mode
& (nir_var_mem_ubo
| nir_var_mem_ssbo
)))
226 /* UBO and SSBO Booleans are 32-bit integers where any non-zero
227 * value is considered true. NIR Booleans, on the other hand
228 * are 1-bit values until you get to a very late stage of the
229 * compilation process. We need to turn those 1-bit loads into
230 * a 32-bit load wrapped in an i2b to get a proper NIR boolean
233 if (glsl_type_is_boolean(deref
->type
)) {
234 assert(intrin
->dest
.is_ssa
);
235 b
.cursor
= nir_after_instr(&intrin
->instr
);
236 intrin
->dest
.ssa
.bit_size
= 32;
237 nir_ssa_def
*bval
= nir_i2b(&b
, &intrin
->dest
.ssa
);
238 nir_ssa_def_rewrite_uses_after(&intrin
->dest
.ssa
,
239 nir_src_for_ssa(bval
),
246 case nir_intrinsic_store_deref
: {
247 nir_deref_instr
*deref
= nir_src_as_deref(intrin
->src
[0]);
248 if (!(deref
->mode
& (nir_var_mem_ubo
| nir_var_mem_ssbo
)))
251 /* SSBO Booleans are 32-bit integers where any non-zero value
252 * is considered true. NIR Booleans, on the other hand are
253 * 1-bit values until you get to a very late stage of the
254 * compilation process. We need to turn those 1-bit stores
255 * into a b2i32 followed by a 32-bit store. Technically the
256 * value we write doesn't have to be 0/1 so once Booleans are
257 * lowered to 32-bit values, we have an unneeded sanitation
258 * step but in practice it doesn't cost much.
260 if (glsl_type_is_boolean(deref
->type
)) {
261 assert(intrin
->src
[1].is_ssa
);
262 b
.cursor
= nir_before_instr(&intrin
->instr
);
263 nir_ssa_def
*ival
= nir_b2i32(&b
, intrin
->src
[1].ssa
);
264 nir_instr_rewrite_src(&intrin
->instr
, &intrin
->src
[1],
265 nir_src_for_ssa(ival
));
271 case nir_intrinsic_copy_deref
:
272 unreachable("copy_deref should be lowered by now");
283 break; /* Nothing to do */
289 nir_metadata_preserve(impl
, nir_metadata_block_index
|
290 nir_metadata_dominance
);
297 gl_nir_lower_buffers(nir_shader
*shader
,
298 const struct gl_shader_program
*shader_program
)
300 bool progress
= false;
302 /* First, we lower the derefs to turn block variable and array derefs into
303 * a nir_address_format_32bit_index_offset pointer. From there forward,
304 * we leave the derefs in place and let nir_lower_explicit_io handle them.
306 nir_foreach_function(function
, shader
) {
307 if (function
->impl
&&
308 lower_buffer_interface_derefs_impl(function
->impl
, shader_program
))
312 /* If that did something, we validate and then call nir_lower_explicit_io
313 * to finish the process.
316 nir_validate_shader(shader
, "Lowering buffer interface derefs");
317 nir_lower_explicit_io(shader
, nir_var_mem_ubo
| nir_var_mem_ssbo
,
318 nir_address_format_32bit_index_offset
);