From 68d70fb96996c41a71ed81b7f6ccbec0fb95145b Mon Sep 17 00:00:00 2001 From: James Jones Date: Mon, 3 Feb 2020 13:17:01 -0800 Subject: [PATCH] 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 Part-of: --- 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 fe3003b..7154ad0 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 1fac4d6..09987a6 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 96cd96e..ebb61d5 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 e2d6612..3b31d96 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 6f98926..0c01684 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 dc7be42..54125e9 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); }; -- 2.7.4