Mesa (main): freedreno/a6xx: Handle R8G8 sharp edges in validate_format()

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Jun 15 19:26:49 UTC 2021


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

Author: Rob Clark <robdclark at chromium.org>
Date:   Sun Jun 13 13:27:33 2021 -0700

freedreno/a6xx: Handle R8G8 sharp edges in validate_format()

Because R8G8 has a different layout from R16, we not only need to demote
to uncompressed to (for example) sample R8G8 as R16 (or visa versa) but
we also need to demote further to linear.

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

---

 src/gallium/drivers/freedreno/a6xx/fd6_resource.c  | 28 +++++++++++++++++++++-
 src/gallium/drivers/freedreno/freedreno_resource.c |  7 +++---
 src/gallium/drivers/freedreno/freedreno_resource.h |  3 ++-
 3 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_resource.c b/src/gallium/drivers/freedreno/a6xx/fd6_resource.c
index 43ecfa8f015..dc9079c0593 100644
--- a/src/gallium/drivers/freedreno/a6xx/fd6_resource.c
+++ b/src/gallium/drivers/freedreno/a6xx/fd6_resource.c
@@ -127,6 +127,18 @@ valid_format_cast(struct fd_resource *rsc, enum pipe_format format)
    return true;
 }
 
+/**
+ * R8G8 have a different block width/height and height alignment from other
+ * formats that would normally be compatible (like R16), and so if we are
+ * trying to, for example, sample R16 as R8G8 we need to demote to linear.
+ */
+static bool
+is_r8g8(enum pipe_format format)
+{
+   return (util_format_get_blocksize(format) == 2) &&
+         (util_format_get_nr_components(format) == 2);
+}
+
 /**
  * Ensure the rsc is in an ok state to be used with the specified format.
  * This handles the case of UBWC buffers used with non-UBWC compatible
@@ -136,8 +148,22 @@ void
 fd6_validate_format(struct fd_context *ctx, struct fd_resource *rsc,
                     enum pipe_format format)
 {
+   enum pipe_format orig_format = rsc->b.b.format;
+
    tc_assert_driver_thread(ctx->tc);
 
+   if (orig_format == format)
+      return;
+
+   if (rsc->layout.tile_mode && (is_r8g8(orig_format) != is_r8g8(format))) {
+      perf_debug_ctx(ctx,
+                     "%" PRSC_FMT ": demoted to linear+uncompressed due to use as %s",
+                     PRSC_ARGS(&rsc->b.b), util_format_short_name(format));
+
+      fd_resource_uncompress(ctx, rsc, true);
+      return;
+   }
+
    if (!rsc->layout.ubwc)
       return;
 
@@ -148,7 +174,7 @@ fd6_validate_format(struct fd_context *ctx, struct fd_resource *rsc,
                   "%" PRSC_FMT ": demoted to uncompressed due to use as %s",
                   PRSC_ARGS(&rsc->b.b), util_format_short_name(format));
 
-   fd_resource_uncompress(ctx, rsc);
+   fd_resource_uncompress(ctx, rsc, false);
 }
 
 static void
diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c
index 4d1c96c3e91..54c520f1b1a 100644
--- a/src/gallium/drivers/freedreno/freedreno_resource.c
+++ b/src/gallium/drivers/freedreno/freedreno_resource.c
@@ -531,12 +531,13 @@ fd_try_shadow_resource(struct fd_context *ctx, struct fd_resource *rsc,
  * appears to the gallium frontends as if nothing changed.
  */
 void
-fd_resource_uncompress(struct fd_context *ctx, struct fd_resource *rsc)
+fd_resource_uncompress(struct fd_context *ctx, struct fd_resource *rsc, bool linear)
 {
    tc_assert_driver_thread(ctx->tc);
 
-   bool success =
-      fd_try_shadow_resource(ctx, rsc, 0, NULL, FD_FORMAT_MOD_QCOM_TILED);
+   uint64_t modifier = linear ? DRM_FORMAT_MOD_LINEAR : FD_FORMAT_MOD_QCOM_TILED;
+
+   bool success = fd_try_shadow_resource(ctx, rsc, 0, NULL, modifier);
 
    /* shadow should not fail in any cases where we need to uncompress: */
    debug_assert(success);
diff --git a/src/gallium/drivers/freedreno/freedreno_resource.h b/src/gallium/drivers/freedreno/freedreno_resource.h
index e4939d199f1..d4666b06e10 100644
--- a/src/gallium/drivers/freedreno/freedreno_resource.h
+++ b/src/gallium/drivers/freedreno/freedreno_resource.h
@@ -352,7 +352,8 @@ bool fd_resource_busy(struct pipe_screen *pscreen, struct pipe_resource *prsc,
                       unsigned usage);
 
 void fd_resource_uncompress(struct fd_context *ctx,
-                            struct fd_resource *rsc) assert_dt;
+                            struct fd_resource *rsc,
+                            bool linear) assert_dt;
 void fd_resource_dump(struct fd_resource *rsc, const char *name);
 
 bool fd_render_condition_check(struct pipe_context *pctx) assert_dt;



More information about the mesa-commit mailing list