pan/bi: Emit load_vary ops
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Wed, 18 Mar 2020 15:55:45 +0000 (11:55 -0400)
committerMarge Bot <eric+marge@anholt.net>
Thu, 19 Mar 2020 03:23:07 +0000 (03:23 +0000)
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 <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4242>

src/panfrost/bifrost/bi_pack.c
src/panfrost/bifrost/bifrost.h

index 2637f427cbb2ccb71c31ccd97e4a4dbbd7ebb831..377990f83be9c3ba90f0d05d2e560bf28281935d 100644 (file)
@@ -370,6 +370,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)
 {
@@ -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:
index 292c35db11d3a8d0b63fe4d2508bbaa1379e8d67..c7e6bcf8630bdc00eeca60fdfa23dd4a6008bb69 100644 (file)
@@ -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;