panfrost: Respect modifiers in resource management
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Mon, 20 Jul 2020 22:03:56 +0000 (18:03 -0400)
committerAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Wed, 12 Aug 2020 13:59:20 +0000 (09:59 -0400)
Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Tested-by: Icecream95 <ixn@keemail.me>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6159>

src/gallium/drivers/panfrost/pan_resource.c
src/panfrost/lib/pan_texture.c
src/panfrost/lib/pan_texture.h

index 21a56479a907749f81df6c4c7bb60611a7299413..614c22f67deab6b4918c1d877581661b8e37d7fd 100644 (file)
@@ -40,6 +40,7 @@
 #include "util/u_transfer.h"
 #include "util/u_transfer_helper.h"
 #include "util/u_gen_mipmap.h"
+#include "util/u_drm.h"
 
 #include "pan_bo.h"
 #include "pan_context.h"
@@ -75,7 +76,8 @@ panfrost_resource_from_handle(struct pipe_screen *pscreen,
 
         rsc->bo = panfrost_bo_import(dev, whandle->handle);
         rsc->internal_format = templat->format;
-        rsc->modifier = DRM_FORMAT_MOD_LINEAR;
+        rsc->modifier = (whandle->modifier == DRM_FORMAT_MOD_INVALID) ?
+                DRM_FORMAT_MOD_LINEAR : whandle->modifier;
         rsc->slices[0].stride = whandle->stride;
         rsc->slices[0].offset = whandle->offset;
         rsc->slices[0].initialized = true;
@@ -89,6 +91,11 @@ panfrost_resource_from_handle(struct pipe_screen *pscreen,
                 rsc->checksummed = true;
         }
 
+        if (drm_is_afbc(whandle->modifier)) {
+                rsc->slices[0].header_size =
+                        panfrost_afbc_header_size(templat->width0, templat->height0);
+        }
+
         if (dev->ro) {
                 rsc->scanout =
                         renderonly_create_gpu_import_for_resource(prsc, dev->ro, NULL);
@@ -109,7 +116,7 @@ panfrost_resource_get_handle(struct pipe_screen *pscreen,
         struct panfrost_resource *rsrc = (struct panfrost_resource *) pt;
         struct renderonly_scanout *scanout = rsrc->scanout;
 
-        handle->modifier = DRM_FORMAT_MOD_INVALID;
+        handle->modifier = rsrc->modifier;
 
         if (handle->type == WINSYS_HANDLE_TYPE_SHARED) {
                 return false;
@@ -206,7 +213,8 @@ panfrost_surface_destroy(struct pipe_context *pipe,
 
 static struct pipe_resource *
 panfrost_create_scanout_res(struct pipe_screen *screen,
-                            const struct pipe_resource *template)
+                            const struct pipe_resource *template,
+                            uint64_t modifier)
 {
         struct panfrost_device *dev = pan_device(screen);
         struct pipe_resource scanout_templat = *template;
@@ -220,7 +228,7 @@ panfrost_create_scanout_res(struct pipe_screen *screen,
                 return NULL;
 
         assert(handle.type == WINSYS_HANDLE_TYPE_FD);
-        /* TODO: handle modifiers? */
+        handle.modifier = modifier;
         res = screen->resource_from_handle(screen, template, &handle,
                                            PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE);
         close(handle.handle);
@@ -519,7 +527,7 @@ panfrost_resource_create_with_modifier(struct pipe_screen *screen,
 
         if (dev->ro && (template->bind &
             (PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT | PIPE_BIND_SHARED)))
-                return panfrost_create_scanout_res(screen, template);
+                return panfrost_create_scanout_res(screen, template, modifier);
 
         struct panfrost_resource *so = rzalloc(screen, struct panfrost_resource);
         so->base = *template;
@@ -549,6 +557,26 @@ panfrost_resource_create(struct pipe_screen *screen,
                         DRM_FORMAT_MOD_INVALID);
 }
 
+/* If no modifier is specified, we'll choose. Otherwise, the order of
+ * preference is compressed, tiled, linear. */
+
+static struct pipe_resource *
+panfrost_resource_create_with_modifiers(struct pipe_screen *screen,
+                         const struct pipe_resource *template,
+                         const uint64_t *modifiers, int count)
+{
+        for (unsigned i = 0; i < PAN_MODIFIER_COUNT; ++i) {
+                if (drm_find_modifier(pan_best_modifiers[i], modifiers, count)) {
+                        return panfrost_resource_create_with_modifier(screen, template,
+                                        pan_best_modifiers[i]);
+                }
+        }
+
+        /* If we didn't find one, app specified invalid */
+        assert(count == 1 && modifiers[0] == DRM_FORMAT_MOD_INVALID);
+        return panfrost_resource_create(screen, template);
+}
+
 static void
 panfrost_resource_destroy(struct pipe_screen *screen,
                           struct pipe_resource *pt)
@@ -913,8 +941,8 @@ panfrost_resource_screen_init(struct pipe_screen *pscreen)
 
         bool fake_rgtc = !panfrost_supports_compressed_format(dev, MALI_BC4_UNORM);
 
-        //pscreen->base.resource_create_with_modifiers =
-        //        panfrost_resource_create_with_modifiers;
+        pscreen->resource_create_with_modifiers =
+                panfrost_resource_create_with_modifiers;
         pscreen->resource_create = u_transfer_helper_resource_create;
         pscreen->resource_destroy = u_transfer_helper_resource_destroy;
         pscreen->resource_from_handle = panfrost_resource_from_handle;
index 84721ff734dda5ada1681fbfb802389e48135b3d..4466b6f0ca49618bf64cee28b9a78e41ba5ebc44 100644 (file)
  * to us here.
  */
 
+/* List of supported modifiers, in descending order of preference. AFBC is
+ * faster than u-interleaved tiling which is faster than linear. Within AFBC,
+ * enabling the YUV-like transform is typically a win where possible. */
+
+uint64_t pan_best_modifiers[PAN_MODIFIER_COUNT] = {
+        DRM_FORMAT_MOD_ARM_AFBC(
+                AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
+                AFBC_FORMAT_MOD_SPARSE |
+                AFBC_FORMAT_MOD_YTR),
+
+        DRM_FORMAT_MOD_ARM_AFBC(
+                AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
+                AFBC_FORMAT_MOD_SPARSE),
+
+        DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED,
+        DRM_FORMAT_MOD_LINEAR
+};
+
 /* Map modifiers to mali_texture_layout for packing in a texture descriptor */
 
 static enum mali_texture_layout
index 55f5f796b2853db726bbfde7ac2a4bec0c84e6a3..a085e5a7fe788a72a4345a696ddccb53fa7cff2a 100644 (file)
@@ -35,6 +35,9 @@
 #include "panfrost-job.h"
 #include "pan_bo.h"
 
+#define PAN_MODIFIER_COUNT 4
+extern uint64_t pan_best_modifiers[PAN_MODIFIER_COUNT];
+
 struct panfrost_slice {
         unsigned offset;
         unsigned stride;