summaryrefslogtreecommitdiffstats
path: root/src/panfrost
diff options
context:
space:
mode:
authorAlyssa Rosenzweig <[email protected]>2020-03-18 11:55:45 -0400
committerMarge Bot <[email protected]>2020-03-19 03:23:07 +0000
commit32e5a7e6e91b43105d51047cc315119928ff09ab (patch)
treeb08cdd12bb0a588738dd367d033ca4fec7f63c74 /src/panfrost
parent37f14c9e50ce144cc81bebf5124e7a9cd0ef0288 (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.c42
-rw-r--r--src/panfrost/bifrost/bifrost.h3
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;