Mesa (master): gallium: Add format modifier plane count query

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Nov 11 11:49:23 UTC 2020


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

Author: James Jones <jajones at nvidia.com>
Date:   Mon Feb  3 13:17:01 2020 -0800

gallium: Add format modifier plane count query

Rather than hard-code a list of all the format
modifiers supported by any gallium driver and the
number of aux planes they require in the dri state
tracker, add a screen proc that queries the number
of planes required for a given modifier+format
pair.

Since the only format modifiers that require
auxiliary planes currently are the iris driver's
I915_FORMAT_MOD_Y_TILED_CCS,
I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS, and
I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS, the absence
of the screen proc implies zero aux planes for all
of the screen's supported modifiers.  Hence, when
a driver does not expose the proc, derive the
number of planes directly from the format.

Signed-off-by: James Jones <jajones at nvidia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/3723>

---

 docs/gallium/screen.rst                         | 11 ++++++
 src/gallium/auxiliary/driver_rbug/rbug_screen.c | 12 ++++++
 src/gallium/drivers/iris/iris_resource.c        | 17 +++++++++
 src/gallium/drivers/tegra/tegra_screen.c        | 14 +++++++
 src/gallium/frontends/dri/dri2.c                | 50 +++++++++----------------
 src/gallium/include/pipe/p_screen.h             | 21 +++++++++++
 6 files changed, 93 insertions(+), 32 deletions(-)

diff --git a/docs/gallium/screen.rst b/docs/gallium/screen.rst
index fe3003ba788..7154ad005ce 100644
--- a/docs/gallium/screen.rst
+++ b/docs/gallium/screen.rst
@@ -1044,6 +1044,17 @@ false if non-external texture targets are supported with the specified modifier+
 format, or true if only external texture targets are supported.
 
 
+get_dmabuf_modifier_planes
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Query the number of planes required by the image layout specified by the
+**modifier** and **format** parameters.  The value returned includes both planes
+dictated by **format** and any additional planes required for driver-specific
+auxiliary data necessary for the layout defined by **modifier**.
+If the proc is NULL, no auxiliary planes are required for any layout supported by
+**screen** and the number of planes can be derived directly from **format**.
+
+
 Thread safety
 -------------
 
diff --git a/src/gallium/auxiliary/driver_rbug/rbug_screen.c b/src/gallium/auxiliary/driver_rbug/rbug_screen.c
index 1fac4d62e17..09987a618fe 100644
--- a/src/gallium/auxiliary/driver_rbug/rbug_screen.c
+++ b/src/gallium/auxiliary/driver_rbug/rbug_screen.c
@@ -180,6 +180,17 @@ rbug_screen_is_dmabuf_modifier_supported(struct pipe_screen *_screen,
                                                external_only);
 }
 
+static unsigned int
+rbug_screen_get_dmabuf_modifier_planes(struct pipe_screen *_screen,
+                                       uint64_t modifier,
+                                       enum pipe_format format)
+{
+   struct rbug_screen *rb_screen = rbug_screen(_screen);
+   struct pipe_screen *screen = rb_screen->screen;
+
+   return screen->get_dmabuf_modifier_planes(screen, modifier, format);
+}
+
 static struct pipe_context *
 rbug_screen_context_create(struct pipe_screen *_screen,
                            void *priv, unsigned flags)
@@ -443,6 +454,7 @@ rbug_screen_create(struct pipe_screen *screen)
    rb_screen->base.is_format_supported = rbug_screen_is_format_supported;
    SCR_INIT(query_dmabuf_modifiers);
    SCR_INIT(is_dmabuf_modifier_supported);
+   SCR_INIT(get_dmabuf_modifier_planes);
    rb_screen->base.context_create = rbug_screen_context_create;
    SCR_INIT(can_create_resource);
    rb_screen->base.resource_create = rbug_screen_resource_create;
diff --git a/src/gallium/drivers/iris/iris_resource.c b/src/gallium/drivers/iris/iris_resource.c
index 96cd96e41b3..ebb61d508a2 100644
--- a/src/gallium/drivers/iris/iris_resource.c
+++ b/src/gallium/drivers/iris/iris_resource.c
@@ -263,6 +263,22 @@ iris_is_dmabuf_modifier_supported(struct pipe_screen *pscreen,
    return false;
 }
 
+static unsigned int
+iris_get_dmabuf_modifier_planes(struct pipe_screen *pscreen, uint64_t modifier,
+                                enum pipe_format format)
+{
+   unsigned int planes = util_format_get_num_planes(format);
+
+   switch (modifier) {
+   case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
+   case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
+   case I915_FORMAT_MOD_Y_TILED_CCS:
+      return 2 * planes;
+   default:
+      return planes;
+   }
+}
+
 enum isl_format
 iris_image_view_get_format(struct iris_context *ice,
                            const struct pipe_image_view *img)
@@ -2250,6 +2266,7 @@ iris_init_screen_resource_functions(struct pipe_screen *pscreen)
 {
    pscreen->query_dmabuf_modifiers = iris_query_dmabuf_modifiers;
    pscreen->is_dmabuf_modifier_supported = iris_is_dmabuf_modifier_supported;
+   pscreen->get_dmabuf_modifier_planes = iris_get_dmabuf_modifier_planes;
    pscreen->resource_create_with_modifiers =
       iris_resource_create_with_modifiers;
    pscreen->resource_create = u_transfer_helper_resource_create;
diff --git a/src/gallium/drivers/tegra/tegra_screen.c b/src/gallium/drivers/tegra/tegra_screen.c
index e2d66128292..3b31d96788b 100644
--- a/src/gallium/drivers/tegra/tegra_screen.c
+++ b/src/gallium/drivers/tegra/tegra_screen.c
@@ -35,6 +35,7 @@
 #include "loader/loader.h"
 #include "pipe/p_state.h"
 #include "util/u_debug.h"
+#include "util/format/u_format.h"
 #include "util/u_inlines.h"
 
 #include "frontend/drm_driver.h"
@@ -526,6 +527,18 @@ tegra_screen_is_dmabuf_modifier_supported(struct pipe_screen *pscreen,
                                                     format, external_only);
 }
 
+static unsigned int
+tegra_screen_get_dmabuf_modifier_planes(struct pipe_screen *pscreen,
+                                        uint64_t modifier,
+                                        enum pipe_format format)
+{
+   struct tegra_screen *screen = to_tegra_screen(pscreen);
+
+   return screen->gpu->get_dmabuf_modifier_planes ?
+      screen->gpu->get_dmabuf_modifier_planes(screen->gpu, modifier, format) :
+      util_format_get_num_planes(format);
+}
+
 static struct pipe_memory_object *
 tegra_screen_memobj_create_from_handle(struct pipe_screen *pscreen,
                                        struct winsys_handle *handle,
@@ -605,6 +618,7 @@ tegra_screen_create(int fd)
    screen->base.resource_create_with_modifiers = tegra_screen_resource_create_with_modifiers;
    screen->base.query_dmabuf_modifiers = tegra_screen_query_dmabuf_modifiers;
    screen->base.is_dmabuf_modifier_supported = tegra_screen_is_dmabuf_modifier_supported;
+   screen->base.get_dmabuf_modifier_planes = tegra_screen_get_dmabuf_modifier_planes;
    screen->base.memobj_create_from_handle = tegra_screen_memobj_create_from_handle;
 
    return &screen->base;
diff --git a/src/gallium/frontends/dri/dri2.c b/src/gallium/frontends/dri/dri2.c
index 6f98926b5db..0c0168497a2 100644
--- a/src/gallium/frontends/dri/dri2.c
+++ b/src/gallium/frontends/dri/dri2.c
@@ -887,48 +887,33 @@ dri2_create_image_from_name(__DRIscreen *_screen,
 }
 
 static unsigned
-dri2_get_modifier_num_planes(uint64_t modifier, int fourcc)
+dri2_get_modifier_num_planes(__DRIscreen *_screen,
+                             uint64_t modifier, int fourcc)
 {
+   struct pipe_screen *pscreen = dri_screen(_screen)->base.screen;
    const struct dri2_format_mapping *map = dri2_get_mapping_by_fourcc(fourcc);
 
    if (!map)
       return 0;
 
    switch (modifier) {
-   case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
-   case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
-   case I915_FORMAT_MOD_Y_TILED_CCS:
-      return 2 * util_format_get_num_planes(map->pipe_format);
-   case DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED:
-   case DRM_FORMAT_MOD_ARM_AFBC(
-                        AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
-                        AFBC_FORMAT_MOD_SPARSE |
-                        AFBC_FORMAT_MOD_YTR):
-   case DRM_FORMAT_MOD_ARM_AFBC(
-                        AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
-                        AFBC_FORMAT_MOD_SPARSE):
-   case DRM_FORMAT_MOD_BROADCOM_UIF:
-   case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED:
    case DRM_FORMAT_MOD_LINEAR:
    /* DRM_FORMAT_MOD_NONE is the same as LINEAR */
-   case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_EIGHT_GOB:
-   case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_FOUR_GOB:
-   case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_ONE_GOB:
-   case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_SIXTEEN_GOB:
-   case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_THIRTYTWO_GOB:
-   case DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_TWO_GOB:
-   case DRM_FORMAT_MOD_QCOM_COMPRESSED:
-   case DRM_FORMAT_MOD_VIVANTE_SPLIT_SUPER_TILED:
-   case DRM_FORMAT_MOD_VIVANTE_SPLIT_TILED:
-   case DRM_FORMAT_MOD_VIVANTE_SUPER_TILED:
-   case DRM_FORMAT_MOD_VIVANTE_TILED:
-   /* FD_FORMAT_MOD_QCOM_TILED is not in drm_fourcc.h */
-   case I915_FORMAT_MOD_X_TILED:
-   case I915_FORMAT_MOD_Y_TILED:
    case DRM_FORMAT_MOD_INVALID:
       return util_format_get_num_planes(map->pipe_format);
    default:
-      return 0;
+      if (!pscreen->is_dmabuf_modifier_supported ||
+          !pscreen->is_dmabuf_modifier_supported(pscreen, modifier,
+                                                 map->pipe_format, NULL)) {
+         return 0;
+      }
+
+      if (pscreen->get_dmabuf_modifier_planes) {
+         return pscreen->get_dmabuf_modifier_planes(pscreen, modifier,
+                                                    map->pipe_format);
+      }
+
+      return map->nplanes;
    }
 }
 
@@ -944,7 +929,7 @@ dri2_create_image_from_fd(__DRIscreen *_screen,
    __DRIimage *img = NULL;
    unsigned err = __DRI_IMAGE_ERROR_SUCCESS;
    int i;
-   const int expected_num_fds = dri2_get_modifier_num_planes(modifier, fourcc);
+   const int expected_num_fds = dri2_get_modifier_num_planes(_screen, modifier, fourcc);
 
    if (!map || expected_num_fds == 0) {
       err = __DRI_IMAGE_ERROR_BAD_MATCH;
@@ -1483,7 +1468,8 @@ dri2_query_dma_buf_format_modifier_attribs(__DRIscreen *_screen,
 
    switch (attrib) {
    case __DRI_IMAGE_FORMAT_MODIFIER_ATTRIB_PLANE_COUNT: {
-      uint64_t mod_planes = dri2_get_modifier_num_planes(modifier, fourcc);
+      uint64_t mod_planes = dri2_get_modifier_num_planes(_screen, modifier,
+                                                         fourcc);
       if (mod_planes > 0)
          *value = mod_planes;
       return mod_planes > 0;
diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h
index dc7be42a062..54125e903d9 100644
--- a/src/gallium/include/pipe/p_screen.h
+++ b/src/gallium/include/pipe/p_screen.h
@@ -576,6 +576,27 @@ struct pipe_screen {
    bool (*is_dmabuf_modifier_supported)(struct pipe_screen *screen,
                                         uint64_t modifier, enum pipe_format,
                                         bool *external_only);
+
+   /**
+    * Get the number of planes required for a given modifier/format pair.
+    *
+    * If not NULL, this function returns the number of planes needed to
+    * represent \p format in the layout specified by \p modifier, including
+    * any driver-specific auxiliary data planes.
+    *
+    * Must only be called on a modifier supported by the screen for the
+    * specified format.
+    *
+    * If NULL, no auxiliary planes are required for any modifier+format pairs
+    * supported by \p screen.  Hence, the plane count can be derived directly
+    * from \p format.
+    *
+    * \return Number of planes needed to store image data in the layout defined
+    *         by \p format and \p modifier.
+    */
+   unsigned int (*get_dmabuf_modifier_planes)(struct pipe_screen *screen,
+                                              uint64_t modifier,
+                                              enum pipe_format format);
 };
 
 



More information about the mesa-commit mailing list