• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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