[Mesa-dev] [PATCH] gallium: Add format modifier aux plane query

James Jones jajones at nvidia.com
Wed Feb 5 20:36:26 UTC 2020


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

Since the only format modifier that requires
auxiliary planes currently is the iris driver's
I915_FORMAT_MOD_Y_TILED_CCS, provide a generic
implementation of this screen proc as a utility
function, and use that in every driver besides
the iris driver, which requires a trivial
customization on top of it.

Signed-off-by: James Jones <jajones at nvidia.com>
---
 src/gallium/auxiliary/util/u_screen.c         | 35 ++++++++++++++++++
 src/gallium/auxiliary/util/u_screen.h         |  7 ++++
 src/gallium/drivers/etnaviv/etnaviv_screen.c  |  1 +
 .../drivers/freedreno/freedreno_screen.c      |  1 +
 src/gallium/drivers/iris/iris_resource.c      | 17 +++++++++
 src/gallium/drivers/lima/lima_screen.c        |  1 +
 .../drivers/nouveau/nvc0/nvc0_resource.c      |  2 ++
 src/gallium/drivers/tegra/tegra_screen.c      | 12 +++++++
 src/gallium/drivers/v3d/v3d_screen.c          |  1 +
 src/gallium/drivers/vc4/vc4_screen.c          |  1 +
 src/gallium/include/pipe/p_screen.h           | 15 ++++++++
 src/gallium/state_trackers/dri/dri2.c         | 36 ++++++++-----------
 12 files changed, 107 insertions(+), 22 deletions(-)

diff --git a/src/gallium/auxiliary/util/u_screen.c b/src/gallium/auxiliary/util/u_screen.c
index 785d1bd3e24..0697d483372 100644
--- a/src/gallium/auxiliary/util/u_screen.c
+++ b/src/gallium/auxiliary/util/u_screen.c
@@ -412,3 +412,38 @@ u_pipe_screen_get_param_defaults(struct pipe_screen *pscreen,
       unreachable("bad PIPE_CAP_*");
    }
 }
+
+bool
+u_pipe_screen_get_modifier_aux_planes(struct pipe_screen *pscreen,
+                                      uint64_t modifier,
+                                      enum pipe_format format,
+                                      unsigned *num_aux_planes)
+{
+   int num_mods, i;
+   uint64_t *supported_mods;
+
+   pscreen->query_dmabuf_modifiers(pscreen, format, 0, NULL, NULL,
+                                   &num_mods);
+
+   if (!num_mods)
+      return false;
+
+   supported_mods = malloc(num_mods * sizeof(supported_mods[0]));
+
+   if (!supported_mods)
+      return false;
+
+   pscreen->query_dmabuf_modifiers(pscreen, format, num_mods, supported_mods,
+                                   NULL, &num_mods);
+
+   for (i = 0; i < num_mods && supported_mods[i] != modifier; i++);
+
+   free(supported_mods);
+
+   if (i == num_mods)
+      return false;
+
+   *num_aux_planes = 0;
+
+   return true;
+}
diff --git a/src/gallium/auxiliary/util/u_screen.h b/src/gallium/auxiliary/util/u_screen.h
index 3952a11f2ca..0abcfd282b1 100644
--- a/src/gallium/auxiliary/util/u_screen.h
+++ b/src/gallium/auxiliary/util/u_screen.h
@@ -23,6 +23,7 @@
 
 struct pipe_screen;
 enum pipe_cap;
+enum pipe_format;
 
 #ifdef __cplusplus
 extern "C" {
@@ -32,6 +33,12 @@ int
 u_pipe_screen_get_param_defaults(struct pipe_screen *pscreen,
                                  enum pipe_cap param);
 
+bool
+u_pipe_screen_get_modifier_aux_planes(struct pipe_screen *pscreen,
+                                      uint64_t modifier,
+                                      enum pipe_format format,
+                                      unsigned *num_aux_planes);
+
 #ifdef __cplusplus
 };
 #endif
diff --git a/src/gallium/drivers/etnaviv/etnaviv_screen.c b/src/gallium/drivers/etnaviv/etnaviv_screen.c
index dcceddc4729..32909a4e5ea 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_screen.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_screen.c
@@ -1019,6 +1019,7 @@ etna_screen_create(struct etna_device *dev, struct etna_gpu *gpu,
    pscreen->context_create = etna_context_create;
    pscreen->is_format_supported = etna_screen_is_format_supported;
    pscreen->query_dmabuf_modifiers = etna_screen_query_dmabuf_modifiers;
+   pscreen->get_modifier_aux_planes = u_pipe_screen_get_modifier_aux_planes;
 
    etna_fence_screen_init(pscreen);
    etna_query_screen_init(pscreen);
diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c
index 3c0ed69a9cb..5d25df02ebf 100644
--- a/src/gallium/drivers/freedreno/freedreno_screen.c
+++ b/src/gallium/drivers/freedreno/freedreno_screen.c
@@ -984,6 +984,7 @@ fd_screen_create(struct fd_device *dev, struct renderonly *ro)
 	pscreen->fence_get_fd = fd_fence_get_fd;
 
 	pscreen->query_dmabuf_modifiers = fd_screen_query_dmabuf_modifiers;
+	pscreen->get_modifier_aux_planes = u_pipe_screen_get_modifier_aux_planes;
 
 	if (!screen->supported_modifiers) {
 		static const uint64_t supported_modifiers[] = {
diff --git a/src/gallium/drivers/iris/iris_resource.c b/src/gallium/drivers/iris/iris_resource.c
index bdd715df2c9..a3b0e87070f 100644
--- a/src/gallium/drivers/iris/iris_resource.c
+++ b/src/gallium/drivers/iris/iris_resource.c
@@ -38,6 +38,7 @@
 #include "util/u_cpu_detect.h"
 #include "util/u_inlines.h"
 #include "util/format/u_format.h"
+#include "util/u_screen.h"
 #include "util/u_threaded_context.h"
 #include "util/u_transfer.h"
 #include "util/u_transfer_helper.h"
@@ -193,6 +194,21 @@ iris_query_dmabuf_modifiers(struct pipe_screen *pscreen,
    *count = supported_mods;
 }
 
+static bool
+iris_get_modifier_aux_planes(struct pipe_screen *pscreen,
+                             uint64_t modifier,
+                             enum pipe_format format,
+                             unsigned *num_aux_planes)
+{
+   bool ret = u_pipe_screen_get_modifier_aux_planes(pscreen, modifier, format,
+                                                    num_aux_planes);
+
+   if (ret && modifier == I915_FORMAT_MOD_Y_TILED_CCS)
+      *num_aux_planes = 1;
+
+   return ret;
+}
+
 static isl_surf_usage_flags_t
 pipe_bind_to_isl_usage(unsigned bindings)
 {
@@ -2075,6 +2091,7 @@ void
 iris_init_screen_resource_functions(struct pipe_screen *pscreen)
 {
    pscreen->query_dmabuf_modifiers = iris_query_dmabuf_modifiers;
+   pscreen->get_modifier_aux_planes = iris_get_modifier_aux_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/lima/lima_screen.c b/src/gallium/drivers/lima/lima_screen.c
index 0995ac86e6d..19ff3deeda1 100644
--- a/src/gallium/drivers/lima/lima_screen.c
+++ b/src/gallium/drivers/lima/lima_screen.c
@@ -598,6 +598,7 @@ lima_screen_create(int fd, struct renderonly *ro)
    screen->base.is_format_supported = lima_screen_is_format_supported;
    screen->base.get_compiler_options = lima_screen_get_compiler_options;
    screen->base.query_dmabuf_modifiers = lima_screen_query_dmabuf_modifiers;
+   screen->base.get_modifier_aux_planes = u_pipe_screen_get_modifier_aux_planes;
 
    lima_resource_screen_init(screen);
    lima_fence_screen_init(screen);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_resource.c b/src/gallium/drivers/nouveau/nvc0/nvc0_resource.c
index d73ecf71624..ab7bc69022c 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_resource.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_resource.c
@@ -3,6 +3,7 @@
 #include "pipe/p_context.h"
 #include "nvc0/nvc0_resource.h"
 #include "nouveau_screen.h"
+#include "util/u_screen.h"
 
 
 static struct pipe_resource *
@@ -117,6 +118,7 @@ nvc0_screen_init_resource_functions(struct pipe_screen *pscreen)
    pscreen->resource_create = nvc0_resource_create;
    pscreen->resource_create_with_modifiers = nvc0_resource_create_with_modifiers;
    pscreen->query_dmabuf_modifiers = nvc0_query_dmabuf_modifiers;
+   pscreen->get_modifier_aux_planes = u_pipe_screen_get_modifier_aux_planes;
    pscreen->resource_from_handle = nvc0_resource_from_handle;
    pscreen->resource_get_handle = u_resource_get_handle_vtbl;
    pscreen->resource_destroy = u_resource_destroy_vtbl;
diff --git a/src/gallium/drivers/tegra/tegra_screen.c b/src/gallium/drivers/tegra/tegra_screen.c
index 9ec3f6fe1d4..638f9b12797 100644
--- a/src/gallium/drivers/tegra/tegra_screen.c
+++ b/src/gallium/drivers/tegra/tegra_screen.c
@@ -514,6 +514,17 @@ static void tegra_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen,
                                        external_only, count);
 }
 
+static bool tegra_screen_get_modifier_aux_planes(struct pipe_screen *pscreen,
+                                                 uint64_t modifier,
+                                                 enum pipe_format format,
+                                                 unsigned *num_aux_planes)
+{
+   struct tegra_screen *screen = to_tegra_screen(pscreen);
+
+   return screen->gpu->get_modifier_aux_planes(screen->gpu, modifier, format,
+                                               num_aux_planes);
+}
+
 static struct pipe_memory_object *
 tegra_screen_memobj_create_from_handle(struct pipe_screen *pscreen,
                                        struct winsys_handle *handle,
@@ -592,6 +603,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.get_modifier_aux_planes = tegra_screen_get_modifier_aux_planes;
    screen->base.memobj_create_from_handle = tegra_screen_memobj_create_from_handle;
 
    return &screen->base;
diff --git a/src/gallium/drivers/v3d/v3d_screen.c b/src/gallium/drivers/v3d/v3d_screen.c
index 1b0c219cb58..c818edc158c 100644
--- a/src/gallium/drivers/v3d/v3d_screen.c
+++ b/src/gallium/drivers/v3d/v3d_screen.c
@@ -719,6 +719,7 @@ v3d_screen_create(int fd, const struct pipe_screen_config *config,
         pscreen->get_device_vendor = v3d_screen_get_vendor;
         pscreen->get_compiler_options = v3d_screen_get_compiler_options;
         pscreen->query_dmabuf_modifiers = v3d_screen_query_dmabuf_modifiers;
+        pscreen->get_modifier_aux_planes = u_pipe_screen_get_modifier_aux_planes;
 
         return pscreen;
 
diff --git a/src/gallium/drivers/vc4/vc4_screen.c b/src/gallium/drivers/vc4/vc4_screen.c
index 2be0b6c3fbe..8e4d6e24ea6 100644
--- a/src/gallium/drivers/vc4/vc4_screen.c
+++ b/src/gallium/drivers/vc4/vc4_screen.c
@@ -566,6 +566,7 @@ vc4_screen_create(int fd, struct renderonly *ro)
         pscreen->get_device_vendor = vc4_screen_get_vendor;
         pscreen->get_compiler_options = vc4_screen_get_compiler_options;
         pscreen->query_dmabuf_modifiers = vc4_screen_query_dmabuf_modifiers;
+        pscreen->get_modifier_aux_planes = u_pipe_screen_get_modifier_aux_planes;
 
         if (screen->has_perfmon_ioctl) {
                 pscreen->get_driver_query_group_info = vc4_get_driver_query_group_info;
diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h
index 0f2831b6eda..596056091c0 100644
--- a/src/gallium/include/pipe/p_screen.h
+++ b/src/gallium/include/pipe/p_screen.h
@@ -511,6 +511,21 @@ struct pipe_screen {
     *                  should be.
     */
    void (*finalize_nir)(struct pipe_screen *screen, void *nir, bool optimize);
+
+   /**
+    * Get the number of aux planes required for a given modifier/format pair.
+    *
+    * If this function returns true, \p num_aux_planes will contain the number
+    * of additional planes needed (beyond the standard number dictated by
+    * \p format) to store auxiliary image data for the image layout defined by
+    * \p modifier.
+    *
+    * \return true if the format+modifier pair is supported on \p screen, false
+    *         otherwise.
+    */
+   bool (*get_modifier_aux_planes)(struct pipe_screen *screen,
+                                   uint64_t modifier, enum pipe_format format,
+                                   unsigned *num_aux_planes);
 };
 
 
diff --git a/src/gallium/state_trackers/dri/dri2.c b/src/gallium/state_trackers/dri/dri2.c
index 05ebb4ef1d7..5e688042122 100644
--- a/src/gallium/state_trackers/dri/dri2.c
+++ b/src/gallium/state_trackers/dri/dri2.c
@@ -839,38 +839,29 @@ 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);
+   unsigned num_aux_planes;
 
    if (!map)
       return 0;
 
    switch (modifier) {
-   case I915_FORMAT_MOD_Y_TILED_CCS:
-      return 2;
-   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 map->nplanes;
    default:
-      return 0;
+      if (!pscreen->get_modifier_aux_planes ||
+          !pscreen->get_modifier_aux_planes(pscreen, modifier, map->pipe_format,
+                                            &num_aux_planes)) {
+         return 0;
+      }
+
+      return map->nplanes + num_aux_planes;
    }
 }
 
@@ -886,7 +877,7 @@ dri2_create_image_from_fd(__DRIscreen *_screen,
    __DRIimage *img = NULL;
    unsigned err = __DRI_IMAGE_ERROR_SUCCESS;
    int i, expected_num_fds;
-   int num_handles = dri2_get_modifier_num_planes(modifier, fourcc);
+   int num_handles = dri2_get_modifier_num_planes(_screen, modifier, fourcc);
 
    if (!map || num_handles == 0) {
       err = __DRI_IMAGE_ERROR_BAD_MATCH;
@@ -1415,7 +1406,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;
-- 
2.17.1



More information about the mesa-dev mailing list