Mesa (master): panfrost: Overhaul tilebuffer allocations

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Jul 16 20:16:42 UTC 2020


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

Author: Alyssa Rosenzweig <alyssa.rosenzweig at collabora.com>
Date:   Thu Jul  9 17:35:24 2020 -0400

panfrost: Overhaul tilebuffer allocations

Based on the colour buffers in use, we need to select a tile size
allowing either 128-bits of storage per pixel or 512-bits. Based on the
size chosen, we scale the offsets into the tilebuffer. Likewise, we need
to calculate offsets based on bpp (with special cases) rather than
picking an average case.

Fixes regressions that otherwise would be caused by the next commit.

v2: Fix colour clears (Icecream95).

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5858>

---

 src/gallium/drivers/panfrost/pan_mfbd.c | 40 ++++++++++++++++++++++-----------
 1 file changed, 27 insertions(+), 13 deletions(-)

diff --git a/src/gallium/drivers/panfrost/pan_mfbd.c b/src/gallium/drivers/panfrost/pan_mfbd.c
index 4d48f2dcac3..ac890b5c56f 100644
--- a/src/gallium/drivers/panfrost/pan_mfbd.c
+++ b/src/gallium/drivers/panfrost/pan_mfbd.c
@@ -428,6 +428,23 @@ panfrost_mfbd_upload(struct panfrost_batch *batch,
 
 #undef UPLOAD
 
+/* Determines the # of bytes per pixel we need to reserve for a given format in
+ * the tilebuffer (compared to 128-bit budget, etc). Usually the same as the
+ * bytes per pixel of the format itself, but there are some special cases I
+ * don't understand. */
+
+static unsigned
+pan_bytes_per_pixel_tib(enum pipe_format format)
+{
+        const struct util_format_description *desc =
+                util_format_description(format);
+
+        if (util_format_is_unorm8(desc) || format == PIPE_FORMAT_B5G6R5_UNORM)
+                return 4;
+
+        return desc->block.bits / 8;
+}
+
 /* Determines whether a framebuffer uses too much tilebuffer space (requiring
  * us to scale up the tile at a performance penalty). This is conservative but
  * afaict you get 128-bits per pixel normally */
@@ -440,8 +457,7 @@ pan_is_large_tib(struct panfrost_batch *batch)
         for (int cb = 0; cb < batch->key.nr_cbufs; ++cb) {
                 struct pipe_surface *surf = batch->key.cbufs[cb];
                 assert(surf);
-                unsigned bpp = util_format_get_blocksize(surf->format);
-                size += ALIGN_POT(bpp, 4);
+                size += pan_bytes_per_pixel_tib(surf->format);
         }
 
         return (size > 16);
@@ -515,17 +531,18 @@ panfrost_mfbd_fragment(struct panfrost_batch *batch, bool has_draws)
         unsigned rt_descriptors = MAX2(batch->key.nr_cbufs, 1);
 
         fb.rt_count_1 = MALI_POSITIVE(rt_descriptors);
-        fb.rt_count_2 = rt_descriptors;
         fb.mfbd_flags = 0x100;
 
-        /* TODO: MRT clear */
-        panfrost_mfbd_clear(batch, &fb, &fbx, rts, fb.rt_count_2);
-
+        panfrost_mfbd_clear(batch, &fb, &fbx, rts, rt_descriptors);
 
         /* Upload either the render target or a dummy GL_NONE target */
 
+        unsigned offset = 0;
+        bool is_large = pan_is_large_tib(batch);
+
         for (int cb = 0; cb < rt_descriptors; ++cb) {
                 struct pipe_surface *surf = batch->key.cbufs[cb];
+                unsigned rt_offset = offset * 0x100;
 
                 if (surf && ((batch->clear | batch->draws) & (PIPE_CLEAR_COLOR0 << cb))) {
                         unsigned nr_samples = surf->nr_samples;
@@ -538,12 +555,7 @@ panfrost_mfbd_fragment(struct panfrost_batch *batch, bool has_draws)
 
                         panfrost_mfbd_set_cbuf(&rts[cb], surf);
 
-                        /* What is this? Looks like some extension of the bpp
-                         * field. Maybe it establishes how much internal
-                         * tilebuffer space is reserved? */
-
-                        unsigned bpp = util_format_get_blocksize(surf->format);
-                        fb.rt_count_2 = MAX2(fb.rt_count_2, ALIGN_POT(bpp, 4) / 4);
+                        offset += pan_bytes_per_pixel_tib(surf->format);
                 } else {
                         struct mali_rt_format null_rt = {
                                 .unk1 = 0x4000000,
@@ -561,9 +573,11 @@ panfrost_mfbd_fragment(struct panfrost_batch *batch, bool has_draws)
                 }
 
                 /* TODO: Break out the field */
-                rts[cb].format.unk1 |= (cb * 0x400);
+                rts[cb].format.unk1 |= is_large ? (rt_offset / 4) : rt_offset;
         }
 
+        fb.rt_count_2 = MAX2(DIV_ROUND_UP(offset, is_large ? 16 : 4), 1);
+
         if (batch->key.zsbuf && ((batch->clear | batch->draws) & PIPE_CLEAR_DEPTHSTENCIL)) {
                 panfrost_mfbd_set_zsbuf(&fb, &fbx, batch->key.zsbuf);
         }



More information about the mesa-commit mailing list