diff options
author | Alyssa Rosenzweig <[email protected]> | 2020-03-18 11:55:45 -0400 |
---|---|---|
committer | Marge Bot <[email protected]> | 2020-03-19 03:23:07 +0000 |
commit | 32e5a7e6e91b43105d51047cc315119928ff09ab (patch) | |
tree | b08cdd12bb0a588738dd367d033ca4fec7f63c74 /src/panfrost | |
parent | 37f14c9e50ce144cc81bebf5124e7a9cd0ef0288 (diff) |
pan/bi: Emit load_vary ops
Annoyingly long code to do so, but this should theoretically work for
both direct and indirect load_vary. Still need to handle destination.
Signed-off-by: Alyssa Rosenzweig <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4242>
Diffstat (limited to 'src/panfrost')
-rw-r--r-- | src/panfrost/bifrost/bi_pack.c | 42 | ||||
-rw-r--r-- | src/panfrost/bifrost/bifrost.h | 3 |
2 files changed, 45 insertions, 0 deletions
diff --git a/src/panfrost/bifrost/bi_pack.c b/src/panfrost/bifrost/bi_pack.c index 2637f427cbb..377990f83be 100644 --- a/src/panfrost/bifrost/bi_pack.c +++ b/src/panfrost/bifrost/bi_pack.c @@ -371,6 +371,46 @@ bi_pack_fma(bi_clause *clause, bi_bundle bundle, struct bi_registers *regs) } static unsigned +bi_pack_add_ld_vary(bi_instruction *ins, struct bi_registers *regs) +{ + unsigned size = nir_alu_type_get_type_size(ins->dest_type); + assert(size == 32 || size == 16); + + unsigned op = (size == 32) ? + BIFROST_ADD_OP_LD_VAR_32 : + BIFROST_ADD_OP_LD_VAR_16; + + unsigned cmask = bi_from_bytemask(ins->writemask, size / 8); + unsigned channels = util_bitcount(cmask); + assert(cmask == ((1 << channels) - 1)); + + unsigned packed_addr = 0; + + if (ins->src[0] & BIR_INDEX_CONSTANT) { + /* Direct uses address field directly */ + packed_addr = ins->src[0] & ~BIR_INDEX_CONSTANT; + assert(packed_addr < 0b1000); + } else { + /* Indirect gets an extra source */ + packed_addr = bi_get_src(ins, regs, 0, false) | 0b11000; + } + + assert(channels >= 1 && channels <= 4); + + struct bifrost_ld_var pack = { + .src0 = bi_get_src(ins, regs, 1, false), + .addr = packed_addr, + .channels = MALI_POSITIVE(channels), + .interp_mode = ins->load_vary.interp_mode, + .reuse = ins->load_vary.reuse, + .flat = ins->load_vary.flat, + .op = op + }; + + RETURN_PACKED(pack); +} + +static unsigned bi_pack_add(bi_clause *clause, bi_bundle bundle, struct bi_registers *regs) { if (!bundle.add) @@ -390,7 +430,9 @@ bi_pack_add(bi_clause *clause, bi_bundle bundle, struct bi_registers *regs) case BI_LOAD: case BI_LOAD_UNIFORM: case BI_LOAD_ATTR: + return BIFROST_ADD_NOP; case BI_LOAD_VAR: + return bi_pack_add_ld_vary(bundle.add, regs); case BI_LOAD_VAR_ADDRESS: case BI_MINMAX: case BI_MOV: diff --git a/src/panfrost/bifrost/bifrost.h b/src/panfrost/bifrost/bifrost.h index 292c35db11d..c7e6bcf8630 100644 --- a/src/panfrost/bifrost/bifrost.h +++ b/src/panfrost/bifrost/bifrost.h @@ -240,6 +240,9 @@ enum bifrost_interp_mode { BIFROST_INTERP_EXPLICIT = 0x3 }; +#define BIFROST_ADD_OP_LD_VAR_16 (0x1a << 1) +#define BIFROST_ADD_OP_LD_VAR_32 (0x0a << 1) + struct bifrost_ld_var { unsigned src0 : 3; |