1 /*
2 * Copyright © 2016 Red Hat.
3 * Copyright © 2016 Bas Nieuwenhuizen
4 * Copyright © 2023 Valve Corporation
5 *
6 * SPDX-License-Identifier: MIT
7 */
8
9 #include "nir.h"
10 #include "nir_builder.h"
11 #include "radv_nir.h"
12
13 /**
14 * We use layered rendering to implement multiview, which means we need to map
15 * view_index to gl_Layer. The code generates a load from the layer_id sysval,
16 * but since we don't have a way to get at this information from the fragment
17 * shader, we also need to lower this to the gl_Layer varying. This pass
18 * lowers both to a varying load from the LAYER slot, before lowering io, so
19 * that nir_assign_var_locations() will give the LAYER varying the correct
20 * driver_location.
21 */
22 bool
radv_nir_lower_view_index(nir_shader * nir)23 radv_nir_lower_view_index(nir_shader *nir)
24 {
25 bool progress = false;
26 nir_function_impl *entry = nir_shader_get_entrypoint(nir);
27 nir_builder b = nir_builder_create(entry);
28
29 nir_foreach_block (block, entry) {
30 nir_foreach_instr_safe (instr, block) {
31 if (instr->type != nir_instr_type_intrinsic)
32 continue;
33
34 nir_intrinsic_instr *load = nir_instr_as_intrinsic(instr);
35 if (load->intrinsic != nir_intrinsic_load_view_index)
36 continue;
37
38 b.cursor = nir_before_instr(instr);
39 nir_def *def = nir_load_layer_id(&b);
40 nir_def_rewrite_uses(&load->def, def);
41
42 nir_instr_remove(instr);
43 progress = true;
44 }
45 }
46
47 if (progress)
48 nir_metadata_preserve(entry, nir_metadata_control_flow);
49 else
50 nir_metadata_preserve(entry, nir_metadata_all);
51
52 return progress;
53 }
54