freedreno: Rework supported-modifiers handling
authorRob Clark <robdclark@chromium.org>
Thu, 5 Oct 2023 22:26:12 +0000 (15:26 -0700)
committerMarge Bot <emma+marge@anholt.net>
Sun, 8 Oct 2023 18:07:37 +0000 (18:07 +0000)
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 <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25575>

src/gallium/drivers/freedreno/a6xx/fd6_blitter.cc
src/gallium/drivers/freedreno/a6xx/fd6_blitter.h
src/gallium/drivers/freedreno/a6xx/fd6_resource.cc
src/gallium/drivers/freedreno/freedreno_resource.c
src/gallium/drivers/freedreno/freedreno_screen.c
src/gallium/drivers/freedreno/freedreno_screen.h

index b7050d2..65264cb 100644 (file)
@@ -1412,6 +1412,17 @@ 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)
 {
    /* if the mipmap level 0 is still too small to be tiled, then don't
@@ -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);
 }
index b803e59..d9cff9b 100644 (file)
@@ -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);
 
 /*
index d581cf1..b8f96be 100644 (file)
@@ -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;
 }
index e04aa41..63f9705 100644 (file)
@@ -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;
index d34be04..8ec300f 100644 (file)
@@ -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 *
index 423caf9..48ec881 100644 (file)
@@ -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);