Module: Mesa
Branch: main
Commit: b1064e91f17c7af8478d9d7f1eb34ec3aa7e1871
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=b1064e91f17c7af8478d9d7f1eb34ec3aa7e1871

Author: Simon Perretta <[email protected]>
Date:   Wed Feb 15 22:26:29 2023 +0000

pvr: Add support for ST

Signed-off-by: Simon Perretta <[email protected]>
Acked-by: Frank Binns <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21474>

---

 .../rogue/passes/rogue_schedule_instr_groups.c     |  41 +++++--
 src/imagination/rogue/rogue.h                      |   3 +
 src/imagination/rogue/rogue_encode.c               | 126 +++++++++++++++------
 src/imagination/rogue/rogue_info.c                 |  19 ++++
 src/imagination/rogue/rogue_isa.h                  |  51 +++++++++
 5 files changed, 192 insertions(+), 48 deletions(-)

diff --git a/src/imagination/rogue/passes/rogue_schedule_instr_groups.c 
b/src/imagination/rogue/passes/rogue_schedule_instr_groups.c
index af234289758..8775b019ad4 100644
--- a/src/imagination/rogue/passes/rogue_schedule_instr_groups.c
+++ b/src/imagination/rogue/passes/rogue_schedule_instr_groups.c
@@ -561,6 +561,21 @@ static void rogue_calc_alu_instrs_size(rogue_instr_group 
*group,
 #undef DM
 #undef SM
 
+#define OM(op_mod) BITFIELD64_BIT(ROGUE_BACKEND_OP_MOD_##op_mod)
+static bool rogue_backend_cachemode_is_set(const rogue_backend_instr *backend)
+{
+   return !!(backend->mod & (OM(BYPASS) | OM(FORCELINEFILL) | OM(WRITETHROUGH) 
|
+                             OM(WRITEBACK) | OM(LAZYWRITEBACK)));
+}
+
+static bool
+rogue_backend_slccachemode_is_set(const rogue_backend_instr *backend)
+{
+   return !!(backend->mod & (OM(SLCBYPASS) | OM(SLCWRITEBACK) |
+                             OM(SLCWRITETHROUGH) | OM(SLCNOALLOC)));
+}
+#undef OM
+
 #define OM(op_mod) ROGUE_BACKEND_OP_MOD_##op_mod
 static void rogue_calc_backend_instrs_size(rogue_instr_group *group,
                                            rogue_backend_instr *backend,
@@ -586,9 +601,20 @@ static void 
rogue_calc_backend_instrs_size(rogue_instr_group *group,
    case ROGUE_BACKEND_OP_LD:
       group->size.instrs[phase] = 2;
 
-      /* TODO: or, if slccachemode is being overridden */
-      if (rogue_ref_is_val(&backend->src[1].ref))
+      if (rogue_ref_is_val(&backend->src[1].ref) ||
+          rogue_backend_slccachemode_is_set(backend)) {
          group->size.instrs[phase] = 3;
+      }
+      break;
+
+   case ROGUE_BACKEND_OP_ST:
+      group->size.instrs[phase] = 3;
+
+      if (rogue_backend_op_mod_is_set(backend, OM(TILED)) ||
+          rogue_backend_slccachemode_is_set(backend) ||
+          !rogue_ref_is_io_none(&backend->src[5].ref)) {
+         group->size.instrs[phase] = 4;
+      }
       break;
 
    case ROGUE_BACKEND_OP_SMP1D:
@@ -599,17 +625,10 @@ static void 
rogue_calc_backend_instrs_size(rogue_instr_group *group,
       if (rogue_backend_op_mod_is_set(backend, OM(ARRAY))) {
          group->size.instrs[phase] = 5;
       } else if (rogue_backend_op_mod_is_set(backend, OM(WRT)) ||
-                 rogue_backend_op_mod_is_set(backend, OM(BYPASS)) ||
-                 rogue_backend_op_mod_is_set(backend, OM(FORCELINEFILL)) ||
-                 rogue_backend_op_mod_is_set(backend, OM(WRITETHROUGH)) ||
-                 rogue_backend_op_mod_is_set(backend, OM(WRITEBACK)) ||
-                 rogue_backend_op_mod_is_set(backend, OM(LAZYWRITEBACK)) ||
                  rogue_backend_op_mod_is_set(backend, OM(SCHEDSWAP)) ||
                  rogue_backend_op_mod_is_set(backend, OM(F16)) ||
-                 rogue_backend_op_mod_is_set(backend, OM(SLCBYPASS)) ||
-                 rogue_backend_op_mod_is_set(backend, OM(SLCWRITEBACK)) ||
-                 rogue_backend_op_mod_is_set(backend, OM(SLCWRITETHROUGH)) ||
-                 rogue_backend_op_mod_is_set(backend, OM(SLCNOALLOC))) {
+                 rogue_backend_cachemode_is_set(backend) ||
+                 rogue_backend_slccachemode_is_set(backend)) {
          group->size.instrs[phase] = 4;
       } else if (rogue_backend_op_mod_is_set(backend, OM(TAO)) ||
                  rogue_backend_op_mod_is_set(backend, OM(SOO)) ||
diff --git a/src/imagination/rogue/rogue.h b/src/imagination/rogue/rogue.h
index 04c1d61eb28..e70c15e3f11 100644
--- a/src/imagination/rogue/rogue.h
+++ b/src/imagination/rogue/rogue.h
@@ -1348,6 +1348,7 @@ enum rogue_backend_op {
    ROGUE_BACKEND_OP_EMITPIX,
 
    ROGUE_BACKEND_OP_LD,
+   ROGUE_BACKEND_OP_ST,
 
    ROGUE_BACKEND_OP_FITR_PIXEL,
    /* ROGUE_BACKEND_OP_SAMPLE, */
@@ -1417,6 +1418,8 @@ enum rogue_backend_op_mod {
    ROGUE_BACKEND_OP_MOD_INFO, /* Sample bypass mode: info. */
    ROGUE_BACKEND_OP_MOD_BOTH, /* Sample bypass mode: both. */
 
+   ROGUE_BACKEND_OP_MOD_TILED, /* Tiled LD/ST. */
+
    ROGUE_BACKEND_OP_MOD_BYPASS, /* MCU cache mode (read): bypass. */
    ROGUE_BACKEND_OP_MOD_FORCELINEFILL, /* MCU cache mode (read): force line
                                         * fill.
diff --git a/src/imagination/rogue/rogue_encode.c 
b/src/imagination/rogue/rogue_encode.c
index 7e52739ab37..e9ce7829e56 100644
--- a/src/imagination/rogue/rogue_encode.c
+++ b/src/imagination/rogue/rogue_encode.c
@@ -294,6 +294,39 @@ static void rogue_encode_alu_instr(const rogue_alu_instr 
*alu,
 #undef SM
 
 #define OM(op_mod) ROGUE_BACKEND_OP_MOD_##op_mod
+static unsigned rogue_backend_get_cachemode(const rogue_backend_instr *backend)
+{
+   if (rogue_backend_op_mod_is_set(backend, OM(BYPASS)))
+      return CACHEMODE_LD_BYPASS;
+   else if (rogue_backend_op_mod_is_set(backend, OM(FORCELINEFILL)))
+      return CACHEMODE_LD_FORCE_LINE_FILL;
+   else if (rogue_backend_op_mod_is_set(backend, OM(WRITETHROUGH)))
+      return CACHEMODE_ST_WRITE_THROUGH;
+   else if (rogue_backend_op_mod_is_set(backend, OM(WRITEBACK)))
+      return CACHEMODE_ST_WRITE_BACK;
+   else if (rogue_backend_op_mod_is_set(backend, OM(LAZYWRITEBACK)))
+      return CACHEMODE_ST_WRITE_BACK_LAZY;
+
+   /* Default cache mode. */
+   return CACHEMODE_LD_NORMAL; /* == CACHEMODE_ST_WRITE_THROUGH */
+}
+
+static unsigned
+rogue_backend_get_slccachemode(const rogue_backend_instr *backend)
+{
+   if (rogue_backend_op_mod_is_set(backend, OM(SLCBYPASS)))
+      return SLCCACHEMODE_BYPASS;
+   else if (rogue_backend_op_mod_is_set(backend, OM(SLCWRITEBACK)))
+      return SLCCACHEMODE_WRITE_BACK;
+   else if (rogue_backend_op_mod_is_set(backend, OM(SLCWRITETHROUGH)))
+      return SLCCACHEMODE_WRITE_THROUGH;
+   else if (rogue_backend_op_mod_is_set(backend, OM(SLCNOALLOC)))
+      return SLCCACHEMODE_CACHED_READS;
+
+   /* Default SLC cache mode. */
+   return SLCCACHEMODE_BYPASS;
+}
+
 static void rogue_encode_backend_instr(const rogue_backend_instr *backend,
                                        unsigned instr_size,
                                        rogue_instr_encoding *instr_encoding)
@@ -359,13 +392,10 @@ static void rogue_encode_backend_instr(const 
rogue_backend_instr *backend,
       instr_encoding->backend.dma.dmaop = DMAOP_LD;
       instr_encoding->backend.dma.ld.drc =
          rogue_ref_get_drc_index(&backend->src[0].ref);
-      instr_encoding->backend.dma.ld.cachemode = CACHEMODE_LD_NORMAL;
-      instr_encoding->backend.dma.ld.srcseladd =
-         rogue_ref_get_io_src_index(&backend->src[2].ref);
+      instr_encoding->backend.dma.ld.cachemode =
+         rogue_backend_get_cachemode(backend);
 
       bool imm_burstlen = rogue_ref_is_val(&backend->src[1].ref);
-      /* Only supporting immediate burst lengths for now. */
-      assert(imm_burstlen);
 
       rogue_burstlen burstlen = {
          ._ = imm_burstlen ? rogue_ref_get_val(&backend->src[1].ref) : 0
@@ -378,13 +408,60 @@ static void rogue_encode_backend_instr(const 
rogue_backend_instr *backend,
             rogue_ref_get_io_src_index(&backend->src[1].ref);
       }
 
+      instr_encoding->backend.dma.ld.srcseladd =
+         rogue_ref_get_io_src_index(&backend->src[2].ref);
+
       if (instr_size == 3) {
          instr_encoding->backend.dma.ld.ext = 1;
-         instr_encoding->backend.dma.ld.slccachemode = SLCCACHEMODE_BYPASS;
-         instr_encoding->backend.dma.ld.notimmbl = !imm_burstlen;
-
          if (imm_burstlen)
             instr_encoding->backend.dma.ld.burstlen_3 = burstlen._3;
+
+         instr_encoding->backend.dma.ld.slccachemode =
+            rogue_backend_get_slccachemode(backend);
+         instr_encoding->backend.dma.ld.notimmbl = !imm_burstlen;
+      }
+
+      break;
+   }
+
+   case ROGUE_BACKEND_OP_ST: {
+      instr_encoding->backend.op = BACKENDOP_DMA;
+      instr_encoding->backend.dma.dmaop = DMAOP_ST;
+      instr_encoding->backend.dma.st.drc =
+         rogue_ref_get_drc_index(&backend->src[1].ref);
+
+      bool imm_burstlen = rogue_ref_is_val(&backend->src[3].ref);
+
+      instr_encoding->backend.dma.st.immbl = imm_burstlen;
+
+      if (imm_burstlen) {
+         rogue_burstlen burstlen = { ._ = rogue_ref_get_val(
+                                        &backend->src[3].ref) };
+         instr_encoding->backend.dma.st.burstlen_2_0 = burstlen._2_0;
+         instr_encoding->backend.dma.st.burstlen_3 = burstlen._3;
+      } else {
+         instr_encoding->backend.dma.st.srcselbl =
+            rogue_ref_get_io_src_index(&backend->src[3].ref);
+      }
+
+      instr_encoding->backend.dma.st.cachemode =
+         rogue_backend_get_cachemode(backend);
+      instr_encoding->backend.dma.st.srcseladd =
+         rogue_ref_get_io_src_index(&backend->src[4].ref);
+
+      instr_encoding->backend.dma.st.dsize =
+         rogue_ref_get_val(&backend->src[1].ref);
+      instr_encoding->backend.dma.st.srcseldata =
+         rogue_ref_get_io_src_index(&backend->src[0].ref);
+
+      if (instr_size == 4) {
+         instr_encoding->backend.dma.st.ext = 1;
+         instr_encoding->backend.dma.st.srcmask =
+            rogue_ref_get_io_src_index(&backend->src[5].ref);
+         instr_encoding->backend.dma.st.slccachemode =
+            rogue_backend_get_slccachemode(backend);
+         instr_encoding->backend.dma.st.nottiled =
+            !rogue_backend_op_mod_is_set(backend, OM(TILED));
       }
 
       break;
@@ -481,41 +558,16 @@ static void rogue_encode_backend_instr(const 
rogue_backend_instr *backend,
          instr_encoding->backend.dma.smp.w =
             rogue_backend_op_mod_is_set(backend, OM(WRT));
 
-         if (rogue_backend_op_mod_is_set(backend, OM(BYPASS))) {
-            instr_encoding->backend.dma.smp.cachemode = CACHEMODE_LD_BYPASS;
-         } else if (rogue_backend_op_mod_is_set(backend, OM(FORCELINEFILL))) {
-            instr_encoding->backend.dma.smp.cachemode =
-               CACHEMODE_LD_FORCE_LINE_FILL;
-         } else if (rogue_backend_op_mod_is_set(backend, OM(WRITETHROUGH))) {
-            instr_encoding->backend.dma.smp.cachemode =
-               CACHEMODE_ST_WRITE_THROUGH;
-         } else if (rogue_backend_op_mod_is_set(backend, OM(WRITEBACK))) {
-            instr_encoding->backend.dma.smp.cachemode = 
CACHEMODE_ST_WRITE_BACK;
-         } else if (rogue_backend_op_mod_is_set(backend, OM(LAZYWRITEBACK))) {
-            instr_encoding->backend.dma.smp.cachemode =
-               CACHEMODE_ST_WRITE_BACK_LAZY;
-         } else {
-            instr_encoding->backend.dma.smp.cachemode =
-               CACHEMODE_LD_NORMAL; /* == CACHEMODE_ST_WRITE_THROUGH */
-         }
+         instr_encoding->backend.dma.smp.cachemode =
+            rogue_backend_get_cachemode(backend);
 
          instr_encoding->backend.dma.smp.swap =
             rogue_backend_op_mod_is_set(backend, OM(SCHEDSWAP));
          instr_encoding->backend.dma.smp.f16 =
             rogue_backend_op_mod_is_set(backend, OM(F16));
 
-         if (rogue_backend_op_mod_is_set(backend, OM(SLCWRITEBACK))) {
-            instr_encoding->backend.dma.smp.slccachemode =
-               SLCCACHEMODE_WRITE_BACK;
-         } else if (rogue_backend_op_mod_is_set(backend, OM(SLCWRITETHROUGH))) 
{
-            instr_encoding->backend.dma.smp.slccachemode =
-               SLCCACHEMODE_WRITE_THROUGH;
-         } else if (rogue_backend_op_mod_is_set(backend, OM(SLCNOALLOC))) {
-            instr_encoding->backend.dma.smp.slccachemode =
-               SLCCACHEMODE_CACHED_READS;
-         } else {
-            instr_encoding->backend.dma.smp.slccachemode = SLCCACHEMODE_BYPASS;
-         }
+         instr_encoding->backend.dma.smp.slccachemode =
+            rogue_backend_get_slccachemode(backend);
       }
 
       if (instr_size > 4) {
diff --git a/src/imagination/rogue/rogue_info.c 
b/src/imagination/rogue/rogue_info.c
index c90f3bc595b..bdcb8fad87c 100644
--- a/src/imagination/rogue/rogue_info.c
+++ b/src/imagination/rogue/rogue_info.c
@@ -272,6 +272,7 @@ const rogue_backend_op_info 
rogue_backend_op_infos[ROGUE_BACKEND_OP_COUNT] = {
    /* .src[1] and .src[2] can actually be S0-5. */
    [ROGUE_BACKEND_OP_LD] = { .str = "ld", .num_dsts = 1, .num_srcs = 3,
       .phase_io = { .dst[0] = IO(S3), .src[2] = IO(S0), },
+      .supported_op_mods = OM(BYPASS) | OM(FORCELINEFILL) | OM(SLCBYPASS) | 
OM(SLCNOALLOC),
       .supported_dst_types = { [0] = T(REG) | T(REGARRAY), },
       .supported_src_types = {
          [0] = T(DRC),
@@ -284,6 +285,23 @@ const rogue_backend_op_info 
rogue_backend_op_infos[ROGUE_BACKEND_OP_COUNT] = {
       .src_stride = {
          [2] = 1,
       },
+   },
+   /* .src[0] and .src[3] can actually be S0-5. */
+   [ROGUE_BACKEND_OP_ST] = { .str = "st", .num_srcs = 6,
+      .phase_io = { .src[0] = IO(S3), .src[3] = IO(S0), },
+      .supported_op_mods = OM(TILED) | OM(WRITETHROUGH) | OM(WRITEBACK) | 
OM(LAZYWRITEBACK) |
+         OM(SLCBYPASS) | OM(SLCWRITEBACK) | OM(SLCWRITETHROUGH) | 
OM(SLCNOALLOC),
+      .supported_src_types = {
+         [0] = T(REG) | T(REGARRAY),
+         [1] = T(VAL),
+         [2] = T(DRC),
+         [3] = T(VAL),
+         [4] = T(REGARRAY),
+         [5] = T(IO),
+      },
+      .src_stride = {
+         [4] = 1,
+      },
    },
        [ROGUE_BACKEND_OP_FITR_PIXEL] = { .str = "fitr.pixel", .num_dsts = 1, 
.num_srcs = 3,
       .phase_io = { .dst[0] = IO(S3), .src[1] = IO(S0), },
@@ -419,6 +437,7 @@ const rogue_backend_op_mod_info 
rogue_backend_op_mod_infos[ROGUE_BACKEND_OP_MOD_
    [ROGUE_BACKEND_OP_MOD_DATA]  = { .str = "data", .exclude = OM(INFO) | 
OM(BOTH) },
    [ROGUE_BACKEND_OP_MOD_INFO]  = { .str = "info", .exclude = OM(DATA) | 
OM(BOTH) },
    [ROGUE_BACKEND_OP_MOD_BOTH]  = { .str = "both", .exclude = OM(DATA) | 
OM(INFO) },
+   [ROGUE_BACKEND_OP_MOD_TILED] = { .str = "tiled", },
    [ROGUE_BACKEND_OP_MOD_BYPASS]  = { .str = "bypass", .exclude = 
OM(FORCELINEFILL) | OM(WRITETHROUGH) | OM(WRITEBACK) | OM(LAZYWRITEBACK) },
    [ROGUE_BACKEND_OP_MOD_FORCELINEFILL]  = { .str = "forcelinefill", .exclude 
= OM(BYPASS) | OM(WRITETHROUGH) | OM(WRITEBACK) | OM(LAZYWRITEBACK) },
    [ROGUE_BACKEND_OP_MOD_WRITETHROUGH]  = { .str = "writethrough", .exclude = 
OM(BYPASS) | OM(FORCELINEFILL) | OM(WRITEBACK) | OM(LAZYWRITEBACK) },
diff --git a/src/imagination/rogue/rogue_isa.h 
b/src/imagination/rogue/rogue_isa.h
index a3b210e0007..7634ba46eef 100644
--- a/src/imagination/rogue/rogue_isa.h
+++ b/src/imagination/rogue/rogue_isa.h
@@ -832,6 +832,56 @@ enum cachemode_ld {
    CACHEMODE_LD_FORCE_LINE_FILL = 0b10,
 };
 
+typedef struct rogue_backend_dma_st_encoding {
+   /* Byte 0 */
+   struct {
+      unsigned : 3;
+      unsigned drc : 1;
+      unsigned immbl : 1;
+      unsigned : 3;
+   } PACKED;
+
+   /* Byte 1 */
+   union {
+      struct {
+         unsigned cachemode : 2;
+         unsigned burstlen_2_0 : 3;
+         unsigned srcseladd : 3;
+      } PACKED;
+
+      struct {
+         unsigned : 2;
+         unsigned srcselbl : 3;
+         unsigned : 3;
+      } PACKED;
+   } PACKED;
+
+   /* Byte 2 */
+   struct {
+      unsigned burstlen_3 : 1;
+      unsigned : 1;
+      unsigned dsize : 2;
+      unsigned srcseldata : 3;
+      unsigned ext : 1;
+   } PACKED;
+
+   /* Byte 3 */
+   struct {
+      unsigned srcmask : 3;
+      unsigned slccachemode : 2;
+      unsigned nottiled : 1; /* N.B. default is 1 if ext = 0. */
+      unsigned : 2;
+   } PACKED;
+} PACKED rogue_backend_dma_st_encoding;
+static_assert(sizeof(rogue_backend_dma_st_encoding) == 4,
+              "sizeof(rogue_backend_dma_st_encoding) != 4");
+
+enum dsize {
+   DSIZE_8 = 0b00,
+   DSIZE_16 = 0b01,
+   DSIZE_BURSTLEN = 0b10,
+};
+
 enum cachemode_st {
    CACHEMODE_ST_WRITE_THROUGH = 0b00,
    CACHEMODE_ST_WRITE_BACK = 0b01,
@@ -953,6 +1003,7 @@ typedef struct rogue_backend_dma_encoding {
       rogue_backend_dma_smp_encoding smp;
       rogue_backend_dma_idf_encoding idf;
       rogue_backend_dma_ld_encoding ld;
+      rogue_backend_dma_st_encoding st;
    } PACKED;
 } PACKED rogue_backend_dma_encoding;
 static_assert(sizeof(rogue_backend_dma_encoding) == 5,

Reply via email to