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

Author: Rob Clark <[email protected]>
Date:   Thu Oct  5 15:26:12 2023 -0700

freedreno: Rework supported-modifiers handling

We should be taking into account the format while deciding if we support
a given modifier or not.  So a simple array of supported modifiers does
not do the trick.

While we are at it, also handle QCOM_TILED3.  (We really only use
QCOM_TILED2 in GMEM so it isn't user visible.)

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/9938
Signed-off-by: Rob Clark <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25575>

---

 src/gallium/drivers/freedreno/a6xx/fd6_blitter.cc  | 19 +++++---
 src/gallium/drivers/freedreno/a6xx/fd6_blitter.h   |  1 +
 src/gallium/drivers/freedreno/a6xx/fd6_resource.cc | 24 +++++++---
 src/gallium/drivers/freedreno/freedreno_resource.c |  8 ----
 src/gallium/drivers/freedreno/freedreno_screen.c   | 53 +++++++++++-----------
 src/gallium/drivers/freedreno/freedreno_screen.h   |  2 +
 6 files changed, 60 insertions(+), 47 deletions(-)

diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_blitter.cc 
b/src/gallium/drivers/freedreno/a6xx/fd6_blitter.cc
index b7050d220d3..65264cbdda1 100644
--- a/src/gallium/drivers/freedreno/a6xx/fd6_blitter.cc
+++ b/src/gallium/drivers/freedreno/a6xx/fd6_blitter.cc
@@ -1411,6 +1411,17 @@ fd6_blitter_init(struct pipe_context *pctx)
 template void fd6_blitter_init<A6XX>(struct pipe_context *pctx);
 template void fd6_blitter_init<A7XX>(struct pipe_context *pctx);
 
+unsigned
+fd6_tile_mode_for_format(enum pipe_format pfmt)
+{
+   /* basically just has to be a format we can blit, so uploads/downloads
+    * via linear staging buffer works:
+    */
+   if (ok_format(pfmt))
+      return TILE6_3;
+
+   return TILE6_LINEAR;
+}
 unsigned
 fd6_tile_mode(const struct pipe_resource *tmpl)
 {
@@ -1421,11 +1432,5 @@ fd6_tile_mode(const struct pipe_resource *tmpl)
          !util_format_is_depth_or_stencil(tmpl->format))
       return TILE6_LINEAR;
 
-   /* basically just has to be a format we can blit, so uploads/downloads
-    * via linear staging buffer works:
-    */
-   if (ok_format(tmpl->format))
-      return TILE6_3;
-
-   return TILE6_LINEAR;
+   return fd6_tile_mode_for_format(tmpl->format);
 }
diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_blitter.h 
b/src/gallium/drivers/freedreno/a6xx/fd6_blitter.h
index b803e59cc54..d9cff9bc5b4 100644
--- a/src/gallium/drivers/freedreno/a6xx/fd6_blitter.h
+++ b/src/gallium/drivers/freedreno/a6xx/fd6_blitter.h
@@ -35,6 +35,7 @@
 
 template <chip CHIP>
 void fd6_blitter_init(struct pipe_context *pctx);
+unsigned fd6_tile_mode_for_format(enum pipe_format pfmt);
 unsigned fd6_tile_mode(const struct pipe_resource *tmpl);
 
 /*
diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_resource.cc 
b/src/gallium/drivers/freedreno/a6xx/fd6_resource.cc
index d581cf1827a..b8f96bee616 100644
--- a/src/gallium/drivers/freedreno/a6xx/fd6_resource.cc
+++ b/src/gallium/drivers/freedreno/a6xx/fd6_resource.cc
@@ -29,6 +29,7 @@
 
 #include "drm-uapi/drm_fourcc.h"
 
+#include "a6xx/fd6_blitter.h"
 #include "fd6_resource.h"
 #include "fdl/fd6_format_table.h"
 
@@ -333,10 +334,22 @@ fd6_layout_resource_for_modifier(struct fd_resource *rsc, 
uint64_t modifier)
    }
 }
 
-static const uint64_t supported_modifiers[] = {
-   DRM_FORMAT_MOD_LINEAR,
-   DRM_FORMAT_MOD_QCOM_COMPRESSED,
-};
+static bool
+fd6_is_format_supported(struct pipe_screen *pscreen,
+                        enum pipe_format fmt,
+                        uint64_t modifier)
+{
+   switch (modifier) {
+   case DRM_FORMAT_MOD_LINEAR:
+      return true;
+   case DRM_FORMAT_MOD_QCOM_COMPRESSED:
+      return ok_ubwc_format(pscreen, fmt);
+   case DRM_FORMAT_MOD_QCOM_TILED3:
+      return fd6_tile_mode_for_format(fmt) == TILE6_3;
+   default:
+      return false;
+   }
+}
 
 void
 fd6_resource_screen_init(struct pipe_screen *pscreen)
@@ -345,6 +358,5 @@ fd6_resource_screen_init(struct pipe_screen *pscreen)
 
    screen->setup_slices = fd6_setup_slices;
    screen->layout_resource_for_modifier = fd6_layout_resource_for_modifier;
-   screen->supported_modifiers = supported_modifiers;
-   screen->num_supported_modifiers = ARRAY_SIZE(supported_modifiers);
+   screen->is_format_supported = fd6_is_format_supported;
 }
diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c 
b/src/gallium/drivers/freedreno/freedreno_resource.c
index e04aa41e021..63f9705c0a5 100644
--- a/src/gallium/drivers/freedreno/freedreno_resource.c
+++ b/src/gallium/drivers/freedreno/freedreno_resource.c
@@ -1629,10 +1629,6 @@ static const struct u_transfer_vtbl transfer_vtbl = {
    .get_stencil = fd_resource_get_stencil,
 };
 
-static const uint64_t supported_modifiers[] = {
-   DRM_FORMAT_MOD_LINEAR,
-};
-
 static int
 fd_layout_resource_for_modifier(struct fd_resource *rsc, uint64_t modifier)
 {
@@ -1746,10 +1742,6 @@ fd_resource_screen_init(struct pipe_screen *pscreen)
 
    if (!screen->layout_resource_for_modifier)
       screen->layout_resource_for_modifier = fd_layout_resource_for_modifier;
-   if (!screen->supported_modifiers) {
-      screen->supported_modifiers = supported_modifiers;
-      screen->num_supported_modifiers = ARRAY_SIZE(supported_modifiers);
-   }
 
    /* GL_EXT_memory_object */
    pscreen->memobj_create_from_handle = fd_memobj_create_from_handle;
diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c 
b/src/gallium/drivers/freedreno/freedreno_screen.c
index d34be04ef0e..8ec300f8553 100644
--- a/src/gallium/drivers/freedreno/freedreno_screen.c
+++ b/src/gallium/drivers/freedreno/freedreno_screen.c
@@ -951,29 +951,42 @@ fd_screen_bo_get_handle(struct pipe_screen *pscreen, 
struct fd_bo *bo,
    }
 }
 
+static bool
+is_format_supported(struct pipe_screen *pscreen,
+                    enum pipe_format format,
+                    uint64_t modifier)
+{
+   struct fd_screen *screen = fd_screen(pscreen);
+   if (screen->is_format_supported)
+      return screen->is_format_supported(pscreen, format, modifier);
+   return modifier == DRM_FORMAT_MOD_LINEAR;
+}
+
 static void
 fd_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen,
                                  enum pipe_format format, int max,
                                  uint64_t *modifiers,
                                  unsigned int *external_only, int *count)
 {
-   struct fd_screen *screen = fd_screen(pscreen);
-   int i, num = 0;
+   const uint64_t all_modifiers[] = {
+      DRM_FORMAT_MOD_LINEAR,
+      DRM_FORMAT_MOD_QCOM_COMPRESSED,
+      DRM_FORMAT_MOD_QCOM_TILED3,
+   };
 
-   max = MIN2(max, screen->num_supported_modifiers);
+   int num = 0;
 
-   if (!max) {
-      max = screen->num_supported_modifiers;
-      external_only = NULL;
-      modifiers = NULL;
-   }
+   for (int i = 0; i < ARRAY_SIZE(all_modifiers); i++) {
+      if (!is_format_supported(pscreen, format, all_modifiers[i]))
+         continue;
 
-   for (i = 0; i < max; i++) {
-      if (modifiers)
-         modifiers[num] = screen->supported_modifiers[i];
+      if (num < max) {
+         if (modifiers)
+            modifiers[num] = all_modifiers[i];
 
-      if (external_only)
-         external_only[num] = 0;
+         if (external_only)
+            external_only[num] = false;
+      }
 
       num++;
    }
@@ -987,19 +1000,7 @@ fd_screen_is_dmabuf_modifier_supported(struct pipe_screen 
*pscreen,
                                        enum pipe_format format,
                                        bool *external_only)
 {
-   struct fd_screen *screen = fd_screen(pscreen);
-   int i;
-
-   for (i = 0; i < screen->num_supported_modifiers; i++) {
-      if (modifier == screen->supported_modifiers[i]) {
-         if (external_only)
-            *external_only = false;
-
-         return true;
-      }
-   }
-
-   return false;
+   return is_format_supported(pscreen, format, modifier);
 }
 
 struct fd_bo *
diff --git a/src/gallium/drivers/freedreno/freedreno_screen.h 
b/src/gallium/drivers/freedreno/freedreno_screen.h
index 423caf9196e..48ec8812157 100644
--- a/src/gallium/drivers/freedreno/freedreno_screen.h
+++ b/src/gallium/drivers/freedreno/freedreno_screen.h
@@ -129,6 +129,8 @@ struct fd_screen {
    unsigned (*tile_mode)(const struct pipe_resource *prsc);
    int (*layout_resource_for_modifier)(struct fd_resource *rsc,
                                        uint64_t modifier);
+   bool (*is_format_supported)(struct pipe_screen *pscreen,
+                               enum pipe_format fmt, uint64_t modifier);
 
    /* indirect-branch emit: */
    void (*emit_ib)(struct fd_ringbuffer *ring, struct fd_ringbuffer *target);

Reply via email to