1 /*
2 * Copyright 2023 Valve Corporation
3 * SPDX-License-Identifier: MIT
4 */
5
6 #include "compiler/nir/nir.h"
7 #include "compiler/nir/nir_builder.h"
8 #include "agx_nir.h"
9
10 bool
agx_nir_lower_layer(nir_shader * s)11 agx_nir_lower_layer(nir_shader *s)
12 {
13 assert(s->info.stage == MESA_SHADER_VERTEX);
14 assert(s->info.outputs_written & (VARYING_BIT_LAYER | VARYING_BIT_VIEWPORT));
15
16 /* Writes are in the last block, search */
17 nir_function_impl *impl = nir_shader_get_entrypoint(s);
18 nir_block *last = nir_impl_last_block(impl);
19
20 nir_def *layer = NULL, *viewport = NULL;
21 nir_cursor last_cursor;
22
23 nir_foreach_instr(instr, last) {
24 if (instr->type != nir_instr_type_intrinsic)
25 continue;
26
27 nir_intrinsic_instr *store = nir_instr_as_intrinsic(instr);
28 if (store->intrinsic != nir_intrinsic_store_output)
29 continue;
30
31 nir_io_semantics sem = nir_intrinsic_io_semantics(store);
32 nir_def *value = store->src[0].ssa;
33
34 if (sem.location == VARYING_SLOT_LAYER) {
35 assert(layer == NULL && "only written once");
36 layer = value;
37 } else if (sem.location == VARYING_SLOT_VIEWPORT) {
38 assert(viewport == NULL && "only written once");
39 viewport = value;
40 } else {
41 continue;
42 }
43
44 last_cursor = nir_after_instr(&store->instr);
45
46 /* Leave the store as a varying-only, no sysval output */
47 sem.no_sysval_output = true;
48 nir_intrinsic_set_io_semantics(store, sem);
49 }
50
51 assert((layer || viewport) && "metadata inconsistent with program");
52
53 /* Pack together and write out */
54 nir_builder b = nir_builder_at(last_cursor);
55
56 nir_def *zero = nir_imm_intN_t(&b, 0, 16);
57 nir_def *packed =
58 nir_pack_32_2x16_split(&b, layer ? nir_u2u16(&b, layer) : zero,
59 viewport ? nir_u2u16(&b, viewport) : zero);
60
61 /* Written with a sysval-only store, no varying output */
62 nir_store_output(&b, packed, nir_imm_int(&b, 0),
63 .io_semantics.location = VARYING_SLOT_LAYER,
64 .io_semantics.num_slots = 1,
65 .io_semantics.no_varying = true);
66
67 nir_metadata_preserve(impl,
68 nir_metadata_dominance | nir_metadata_block_index);
69 return true;
70 }
71