Mesa (master): broadcom/vc5: Add appropriate height padding for bank conflicts.

Eric Anholt anholt at kemper.freedesktop.org
Thu Feb 1 19:02:53 UTC 2018


Module: Mesa
Branch: master
Commit: 5329f35ea12fe70e9eff131b60979b810cbc5028
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=5329f35ea12fe70e9eff131b60979b810cbc5028

Author: Eric Anholt <eric at anholt.net>
Date:   Sun Jan 21 10:25:10 2018 +0800

broadcom/vc5: Add appropriate height padding for bank conflicts.

I thought I didn't need this because I was doing level-0-always-UIF and
that the pad there would propagate down, but it turns out that for level 1
the padding ends up being chosen by the HW.  This brings us closer to
being able to turn on UIF XOR for increased performance, as well.

---

 src/gallium/drivers/vc5/vc5_resource.c | 50 ++++++++++++++++++++++++++++++++++
 src/gallium/drivers/vc5/vc5_resource.h |  1 +
 src/gallium/drivers/vc5/vc5_screen.h   |  8 ++++++
 src/gallium/drivers/vc5/vc5_state.c    |  4 +++
 4 files changed, 63 insertions(+)

diff --git a/src/gallium/drivers/vc5/vc5_resource.c b/src/gallium/drivers/vc5/vc5_resource.c
index 9ecd083b05..f37ffe928f 100644
--- a/src/gallium/drivers/vc5/vc5_resource.c
+++ b/src/gallium/drivers/vc5/vc5_resource.c
@@ -327,6 +327,52 @@ vc5_resource_get_handle(struct pipe_screen *pscreen,
         return FALSE;
 }
 
+/**
+ * Computes the HW's UIFblock padding for a given height/cpp.
+ *
+ * The goal of the padding is to keep pages of the same color (bank number) at
+ * least half a page away from each other vertically when crossing between
+ * between columns of UIF blocks.
+ */
+static uint32_t
+vc5_get_ub_pad(struct vc5_resource *rsc, uint32_t height)
+{
+        uint32_t utile_h = vc5_utile_height(rsc->cpp);
+        uint32_t uif_block_h = utile_h * 2;
+        uint32_t height_ub = height / uif_block_h;
+        uint32_t ub_row_size = 256 * 4;
+
+        uint32_t page_ub_rows = VC5_UIFCFG_PAGE_SIZE / ub_row_size;
+        uint32_t pc_ub_rows = VC5_PAGE_CACHE_SIZE / ub_row_size;
+        uint32_t height_offset_in_pc = height_ub % pc_ub_rows;
+
+        /* For the perfectly-aligned-for-UIF-XOR case, don't add any pad. */
+        if (height_offset_in_pc == 0)
+                return 0;
+
+        uint32_t half_page_ub_rows = (page_ub_rows * 3) >> 1;
+
+        /* Try padding up to where we're offset by at least half a page. */
+        if (height_offset_in_pc < half_page_ub_rows) {
+                /* If we fit entirely in the page cache, don't pad. */
+                if (height_ub < pc_ub_rows)
+                        return 0;
+                else
+                        return half_page_ub_rows - height_offset_in_pc;
+        }
+
+        /* If we're close to being aligned to page cache size, then round up
+         * and rely on XOR.
+         */
+        if (height_offset_in_pc > (pc_ub_rows - half_page_ub_rows))
+                return pc_ub_rows - height_offset_in_pc;
+
+        /* Otherwise, we're far enough away (top and bottom) to not need any
+         * padding.
+         */
+        return 0;
+}
+
 static void
 vc5_setup_slices(struct vc5_resource *rsc)
 {
@@ -400,6 +446,10 @@ vc5_setup_slices(struct vc5_resource *rsc)
                                                     4 * uif_block_w);
                                 level_height = align(level_height,
                                                      uif_block_h);
+
+                                slice->ub_pad = vc5_get_ub_pad(rsc,
+                                                               level_height);
+                                level_height += slice->ub_pad * uif_block_h;
                         }
                 }
 
diff --git a/src/gallium/drivers/vc5/vc5_resource.h b/src/gallium/drivers/vc5/vc5_resource.h
index 631a7b8fba..31b2b66cf6 100644
--- a/src/gallium/drivers/vc5/vc5_resource.h
+++ b/src/gallium/drivers/vc5/vc5_resource.h
@@ -74,6 +74,7 @@ struct vc5_resource_slice {
         uint32_t offset;
         uint32_t stride;
         uint32_t size;
+        uint8_t ub_pad;
         enum vc5_tiling_mode tiling;
 };
 
diff --git a/src/gallium/drivers/vc5/vc5_screen.h b/src/gallium/drivers/vc5/vc5_screen.h
index 28925d791c..52967e6bec 100644
--- a/src/gallium/drivers/vc5/vc5_screen.h
+++ b/src/gallium/drivers/vc5/vc5_screen.h
@@ -40,6 +40,14 @@ struct vc5_bo;
 #define VC5_MAX_DRAW_BUFFERS 4
 #define VC5_MAX_ATTRIBUTES 16
 
+/* These are tunable parameters in the HW design, but all the V3D
+ * implementations agree.
+ */
+#define VC5_UIFCFG_BANKS 8
+#define VC5_UIFCFG_PAGE_SIZE 4096
+#define VC5_UIFCFG_XOR_VALUE (1 << 4)
+#define VC5_PAGE_CACHE_SIZE (VC5_UIFCFG_PAGE_SIZE * VC5_UIFCFG_BANKS)
+
 struct vc5_simulator_file;
 
 struct vc5_screen {
diff --git a/src/gallium/drivers/vc5/vc5_state.c b/src/gallium/drivers/vc5/vc5_state.c
index ea867279a0..a055d252b6 100644
--- a/src/gallium/drivers/vc5/vc5_state.c
+++ b/src/gallium/drivers/vc5/vc5_state.c
@@ -31,6 +31,7 @@
 #include "util/u_helpers.h"
 
 #include "vc5_context.h"
+#include "vc5_tiling.h"
 #include "broadcom/common/v3d_macros.h"
 #include "broadcom/cle/v3dx_pack.h"
 
@@ -787,6 +788,9 @@ vc5_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *prsc,
                 tex.level_0_xor_enable = (rsc->slices[0].tiling ==
                                           VC5_TILING_UIF_XOR);
 
+                if (tex.level_0_is_strictly_uif)
+                        tex.level_0_ub_pad = rsc->slices[0].ub_pad;
+
 #if V3D_VERSION >= 40
                 if (tex.uif_xor_disable ||
                     tex.level_0_is_strictly_uif) {




More information about the mesa-commit mailing list