[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