• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2023 Alyssa Rosenzweig
3  * SPDX-License-Identifier: MIT
4  */
5 #include "agx_builder.h"
6 #include "agx_compiler.h"
7 
8 /*
9  * Not all instructions can take uniforms. Memory instructions can take
10  * uniforms, but only for their base (first) source and only in the
11  * low-half of the uniform file.
12  *
13  * This pass lowers invalid uniforms.
14  */
15 static bool
should_lower(enum agx_opcode op,agx_index uniform,unsigned src_index)16 should_lower(enum agx_opcode op, agx_index uniform, unsigned src_index)
17 {
18    if (uniform.type != AGX_INDEX_UNIFORM)
19       return false;
20 
21    /* Some instructions only seem able to access uniforms in the low half */
22    bool high = uniform.value >= 256;
23 
24    switch (op) {
25    case AGX_OPCODE_IMAGE_LOAD:
26    case AGX_OPCODE_TEXTURE_LOAD:
27    case AGX_OPCODE_TEXTURE_SAMPLE:
28       return src_index != 1 && src_index != 2;
29    case AGX_OPCODE_DEVICE_LOAD:
30       return src_index != 0 || high;
31    case AGX_OPCODE_DEVICE_STORE:
32    case AGX_OPCODE_ATOMIC:
33       return src_index != 1 || high;
34    case AGX_OPCODE_LOCAL_LOAD:
35       return src_index != 0;
36    case AGX_OPCODE_LOCAL_STORE:
37       return src_index != 1;
38    case AGX_OPCODE_IMAGE_WRITE:
39       return src_index != 3;
40    case AGX_OPCODE_ZS_EMIT:
41    case AGX_OPCODE_ST_TILE:
42    case AGX_OPCODE_LD_TILE:
43    case AGX_OPCODE_BLOCK_IMAGE_STORE:
44    case AGX_OPCODE_UNIFORM_STORE:
45    case AGX_OPCODE_ST_VARY:
46    case AGX_OPCODE_LOCAL_ATOMIC:
47    case AGX_OPCODE_SAMPLE_MASK:
48    case AGX_OPCODE_ITER:
49    case AGX_OPCODE_ITERPROJ:
50    case AGX_OPCODE_STACK_LOAD:
51    case AGX_OPCODE_STACK_STORE:
52       return true;
53    default:
54       return false;
55    }
56 }
57 
58 void
agx_lower_uniform_sources(agx_context * ctx)59 agx_lower_uniform_sources(agx_context *ctx)
60 {
61    agx_foreach_instr_global_safe(ctx, I) {
62       agx_builder b = agx_init_builder(ctx, agx_before_instr(I));
63 
64       agx_foreach_src(I, s) {
65          if (should_lower(I->op, I->src[s], s))
66             I->src[s] = agx_mov(&b, I->src[s]);
67       }
68    }
69 }
70