Mesa (master): panfrost: Tiled to linear layout conversion

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Jun 12 19:29:51 UTC 2020


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

Author: Icecream95 <ixn at keemail.me>
Date:   Sun Apr 19 15:44:17 2020 +1200

panfrost: Tiled to linear layout conversion

Tiling is expensive, so this patch converts textures that appear to be
used for streaming to a linear layout.

Performance of mpv is significantly improved, with software-decoded
1080p mp4 playback on RK3288 going from 30fps to 50fps when testing
with `--untimed --no-audio`.

To keep things simple, conversion only happens when updating the whole
texture and no mipmapping is used.

v2: Make it clear that the heuristic doesn't rely on a texture being
uninitialized, since layout switching code can get confusing (Alyssa).

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

---

 src/gallium/drivers/panfrost/pan_resource.c | 51 ++++++++++++++++++++++++-----
 src/gallium/drivers/panfrost/pan_resource.h |  8 +++++
 2 files changed, 51 insertions(+), 8 deletions(-)

diff --git a/src/gallium/drivers/panfrost/pan_resource.c b/src/gallium/drivers/panfrost/pan_resource.c
index 84f82ab7689..8c1cda9513d 100644
--- a/src/gallium/drivers/panfrost/pan_resource.c
+++ b/src/gallium/drivers/panfrost/pan_resource.c
@@ -427,6 +427,7 @@ panfrost_resource_create_bo(struct panfrost_device *dev, struct panfrost_resourc
         /* Set the layout appropriately */
         assert(!(must_tile && !can_tile)); /* must_tile => can_tile */
         pres->layout = ((can_tile && should_tile) || must_tile) ? MALI_TEXTURE_TILED : MALI_TEXTURE_LINEAR;
+        pres->layout_constant = must_tile || !can_tile;
 
         size_t bo_size;
 
@@ -725,14 +726,48 @@ panfrost_transfer_unmap(struct pipe_context *pctx,
                         } else if (prsrc->layout == MALI_TEXTURE_TILED) {
                                 assert(transfer->box.depth == 1);
 
-                                panfrost_store_tiled_image(
-                                        bo->cpu + prsrc->slices[transfer->level].offset,
-                                        trans->map,
-                                        transfer->box.x, transfer->box.y,
-                                        transfer->box.width, transfer->box.height,
-                                        prsrc->slices[transfer->level].stride,
-                                        transfer->stride,
-                                        prsrc->internal_format);
+                                /* Do we overwrite the entire resource? If so,
+                                 * we don't need an intermediate blit so it's a
+                                 * good time to switch the layout. */
+
+                                bool discards_content = prsrc->base.last_level == 0
+                                    && transfer->box.width == prsrc->base.width0
+                                    && transfer->box.height == prsrc->base.height0
+                                    && transfer->box.x == 0
+                                    && transfer->box.y == 0
+                                    && !prsrc->layout_constant;
+
+                                /* It also serves as a good heuristic for
+                                 * streaming textures (e.g. in video players),
+                                 * but we could do better */
+
+                                if (discards_content)
+                                        ++prsrc->layout_updates;
+
+                                if (prsrc->layout_updates >= LAYOUT_CONVERT_THRESHOLD)
+                                {
+                                        prsrc->layout = MALI_TEXTURE_LINEAR;
+
+                                        util_copy_rect(
+                                                bo->cpu + prsrc->slices[0].offset,
+                                                prsrc->base.format,
+                                                prsrc->slices[0].stride,
+                                                0, 0,
+                                                transfer->box.width,
+                                                transfer->box.height,
+                                                trans->map,
+                                                transfer->stride,
+                                                0, 0);
+                                } else {
+                                        panfrost_store_tiled_image(
+                                                bo->cpu + prsrc->slices[transfer->level].offset,
+                                                trans->map,
+                                                transfer->box.x, transfer->box.y,
+                                                transfer->box.width, transfer->box.height,
+                                                prsrc->slices[transfer->level].stride,
+                                                transfer->stride,
+                                                prsrc->internal_format);
+                                }
                         }
                 }
         }
diff --git a/src/gallium/drivers/panfrost/pan_resource.h b/src/gallium/drivers/panfrost/pan_resource.h
index 0a25e305de0..c6226cbe272 100644
--- a/src/gallium/drivers/panfrost/pan_resource.h
+++ b/src/gallium/drivers/panfrost/pan_resource.h
@@ -34,6 +34,8 @@
 #include "drm-uapi/drm.h"
 #include "util/u_range.h"
 
+#define LAYOUT_CONVERT_THRESHOLD 8
+
 struct panfrost_resource {
         struct pipe_resource base;
         struct {
@@ -57,9 +59,15 @@ struct panfrost_resource {
         /* Internal layout (tiled?) */
         enum mali_texture_layout layout;
 
+        /* Whether the layout can be changed */
+        bool layout_constant;
+
         /* Is transaciton elimination enabled? */
         bool checksummed;
 
+        /* Used to decide when to convert to another layout */
+        uint16_t layout_updates;
+
         enum pipe_format internal_format;
 
         /* Cached min/max values for index buffers */



More information about the mesa-commit mailing list