Mesa (main): freedreno+turnip: Add has_cp_reg_write

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Jul 14 02:20:02 UTC 2021


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

Author: Rob Clark <robdclark at chromium.org>
Date:   Thu Jul  8 10:28:43 2021 -0700

freedreno+turnip: Add has_cp_reg_write

Newer a6xx devices drop this packet from the sqe firmware, and use
direct (pkt4) register writes instead for the few cases that previously
used CP_REG_WRITE.

The turnip part was adapted from Jonathans patch on !10892

Signed-off-by: Rob Clark <robdclark at chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11790>

---

 src/freedreno/common/freedreno_dev_info.h     |  5 +++++
 src/freedreno/common/freedreno_devices.py     |  4 ++++
 src/freedreno/vulkan/tu_clear_blit.c          |  4 ++++
 src/freedreno/vulkan/tu_cmd_buffer.c          | 10 ++++++++++
 src/freedreno/vulkan/tu_pipeline.c            | 10 +++++++---
 src/gallium/drivers/freedreno/a6xx/fd6_gmem.c | 11 ++++++++---
 6 files changed, 38 insertions(+), 6 deletions(-)

diff --git a/src/freedreno/common/freedreno_dev_info.h b/src/freedreno/common/freedreno_dev_info.h
index b4e4cf7b6c6..eaa64015e58 100644
--- a/src/freedreno/common/freedreno_dev_info.h
+++ b/src/freedreno/common/freedreno_dev_info.h
@@ -89,6 +89,11 @@ struct fd_dev_info {
 
          bool has_sample_locations;
 
+         /* The firmware on newer a6xx drops CP_REG_WRITE support as we
+          * can now use direct register writes for these regs.
+          */
+         bool has_cp_reg_write;
+
          struct {
             uint32_t RB_UNKNOWN_8E04_blit;
             uint32_t PC_UNKNOWN_9805;
diff --git a/src/freedreno/common/freedreno_devices.py b/src/freedreno/common/freedreno_devices.py
index 7e8bd6df89e..eb29fea6fd3 100644
--- a/src/freedreno/common/freedreno_devices.py
+++ b/src/freedreno/common/freedreno_devices.py
@@ -112,6 +112,10 @@ class A6xxGPUInfo(GPUInfo):
         self.a6xx.magic.PC_UNKNOWN_9805 = PC_UNKNOWN_9805
         self.a6xx.magic.SP_UNKNOWN_A0F8 = SP_UNKNOWN_A0F8
 
+        # Things that earlier gens have and later gens remove, provide
+        # defaults here and let them be overridden by sub-gen template:
+        self.a6xx.has_cp_reg_write = True
+
         for name, val in template.items():
             setattr(self.a6xx, name, val)
 
diff --git a/src/freedreno/vulkan/tu_clear_blit.c b/src/freedreno/vulkan/tu_clear_blit.c
index 5384b9e5bd7..1b2f7e95fc7 100644
--- a/src/freedreno/vulkan/tu_clear_blit.c
+++ b/src/freedreno/vulkan/tu_clear_blit.c
@@ -482,6 +482,7 @@ r3d_common(struct tu_cmd_buffer *cmd, struct tu_cs *cs, bool blit, uint32_t num_
    tu_cs_emit_regs(cs, A6XX_PC_PRIMITIVE_CNTL_0());
    tu_cs_emit_regs(cs, A6XX_VFD_CONTROL_0());
 
+   if (cmd->device->physical_device->info->a6xx.has_cp_reg_write) {
    /* Copy what the blob does here. This will emit an extra 0x3f
     * CP_EVENT_WRITE when multiview is disabled. I'm not exactly sure what
     * this is working around yet.
@@ -490,6 +491,9 @@ r3d_common(struct tu_cmd_buffer *cmd, struct tu_cs *cs, bool blit, uint32_t num_
    tu_cs_emit(cs, CP_REG_WRITE_0_TRACKER(UNK_EVENT_WRITE));
    tu_cs_emit(cs, REG_A6XX_PC_MULTIVIEW_CNTL);
    tu_cs_emit(cs, 0);
+   } else {
+      tu_cs_emit_regs(cs, A6XX_PC_MULTIVIEW_CNTL());
+   }
    tu_cs_emit_regs(cs, A6XX_VFD_MULTIVIEW_CNTL());
 
    tu6_emit_vpc(cs, &vs, NULL, NULL, NULL, &fs, 0);
diff --git a/src/freedreno/vulkan/tu_cmd_buffer.c b/src/freedreno/vulkan/tu_cmd_buffer.c
index 4ff660dabee..ee69aa6d94c 100644
--- a/src/freedreno/vulkan/tu_cmd_buffer.c
+++ b/src/freedreno/vulkan/tu_cmd_buffer.c
@@ -324,9 +324,13 @@ tu6_emit_render_cntl(struct tu_cmd_buffer *cmd,
                      bool binning)
 {
    const struct tu_framebuffer *fb = cmd->state.framebuffer;
+   /* doesn't RB_RENDER_CNTL set differently for binning pass: */
+   bool no_track = !cmd->device->physical_device->info->a6xx.has_cp_reg_write;
    uint32_t cntl = 0;
    cntl |= A6XX_RB_RENDER_CNTL_UNK4;
    if (binning) {
+      if (no_track)
+         return;
       cntl |= A6XX_RB_RENDER_CNTL_BINNING;
    } else {
       uint32_t mrts_ubwc_enable = 0;
@@ -349,6 +353,12 @@ tu6_emit_render_cntl(struct tu_cmd_buffer *cmd,
             cntl |= A6XX_RB_RENDER_CNTL_FLAG_DEPTH;
       }
 
+      if (no_track) {
+         tu_cs_emit_pkt4(cs, REG_A6XX_RB_RENDER_CNTL, 1);
+         tu_cs_emit(cs, cntl);
+         return;
+      }
+
       /* In the !binning case, we need to set RB_RENDER_CNTL in the draw_cs
        * in order to set it correctly for the different subpasses. However,
        * that means the packets we're emitting also happen during binning. So
diff --git a/src/freedreno/vulkan/tu_pipeline.c b/src/freedreno/vulkan/tu_pipeline.c
index 3e2f51e0db6..a7b495a04f6 100644
--- a/src/freedreno/vulkan/tu_pipeline.c
+++ b/src/freedreno/vulkan/tu_pipeline.c
@@ -1612,9 +1612,13 @@ tu6_emit_program(struct tu_cs *cs,
     * CP_EVENT_WRITE when multiview is disabled. I'm not exactly sure what
     * this is working around yet.
     */
-   tu_cs_emit_pkt7(cs, CP_REG_WRITE, 3);
-   tu_cs_emit(cs, CP_REG_WRITE_0_TRACKER(UNK_EVENT_WRITE));
-   tu_cs_emit(cs, REG_A6XX_PC_MULTIVIEW_CNTL);
+   if (builder->device->physical_device->info->a6xx.has_cp_reg_write) {
+      tu_cs_emit_pkt7(cs, CP_REG_WRITE, 3);
+      tu_cs_emit(cs, CP_REG_WRITE_0_TRACKER(UNK_EVENT_WRITE));
+      tu_cs_emit(cs, REG_A6XX_PC_MULTIVIEW_CNTL);
+   } else {
+      tu_cs_emit_pkt4(cs, REG_A6XX_PC_MULTIVIEW_CNTL, 1);
+   }
    tu_cs_emit(cs, multiview_cntl);
 
    tu_cs_emit_pkt4(cs, REG_A6XX_VFD_MULTIVIEW_CNTL, 1);
diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c b/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c
index 3e71cdd9ebc..f2cb7e8a7e8 100644
--- a/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c
+++ b/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c
@@ -335,6 +335,7 @@ update_render_cntl(struct fd_batch *batch, struct pipe_framebuffer_state *pfb,
                    bool binning)
 {
    struct fd_ringbuffer *ring = batch->gmem;
+   struct fd_screen *screen = batch->ctx->screen;
    uint32_t cntl = 0;
    bool depth_ubwc_enable = false;
    uint32_t mrts_ubwc_enable = 0;
@@ -363,9 +364,13 @@ update_render_cntl(struct fd_batch *batch, struct pipe_framebuffer_state *pfb,
    if (binning)
       cntl |= A6XX_RB_RENDER_CNTL_BINNING;
 
-   OUT_PKT7(ring, CP_REG_WRITE, 3);
-   OUT_RING(ring, CP_REG_WRITE_0_TRACKER(TRACK_RENDER_CNTL));
-   OUT_RING(ring, REG_A6XX_RB_RENDER_CNTL);
+   if (screen->info->a6xx.has_cp_reg_write) {
+      OUT_PKT7(ring, CP_REG_WRITE, 3);
+      OUT_RING(ring, CP_REG_WRITE_0_TRACKER(TRACK_RENDER_CNTL));
+      OUT_RING(ring, REG_A6XX_RB_RENDER_CNTL);
+   } else {
+      OUT_PKT4(ring, REG_A6XX_RB_RENDER_CNTL, 1);
+   }
    OUT_RING(ring, cntl |
                      COND(depth_ubwc_enable, A6XX_RB_RENDER_CNTL_FLAG_DEPTH) |
                      A6XX_RB_RENDER_CNTL_FLAG_MRTS(mrts_ubwc_enable));



More information about the mesa-commit mailing list