From: Rob Clark Date: Thu, 5 Oct 2023 22:26:12 +0000 (-0700) Subject: freedreno: Rework supported-modifiers handling X-Git-Tag: upstream/23.3.3~1176 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1e820ac128506bd66a20fb7345fd562feb9e730b;p=platform%2Fupstream%2Fmesa.git freedreno: Rework supported-modifiers handling We should be taking into account the format while deciding if we support a given modifier or not. So a simple array of supported modifiers does not do the trick. While we are at it, also handle QCOM_TILED3. (We really only use QCOM_TILED2 in GMEM so it isn't user visible.) Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/9938 Signed-off-by: Rob Clark Part-of: --- diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_blitter.cc b/src/gallium/drivers/freedreno/a6xx/fd6_blitter.cc index b7050d2..65264cb 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_blitter.cc +++ b/src/gallium/drivers/freedreno/a6xx/fd6_blitter.cc @@ -1412,6 +1412,17 @@ template void fd6_blitter_init(struct pipe_context *pctx); template void fd6_blitter_init(struct pipe_context *pctx); unsigned +fd6_tile_mode_for_format(enum pipe_format pfmt) +{ + /* basically just has to be a format we can blit, so uploads/downloads + * via linear staging buffer works: + */ + if (ok_format(pfmt)) + return TILE6_3; + + return TILE6_LINEAR; +} +unsigned fd6_tile_mode(const struct pipe_resource *tmpl) { /* if the mipmap level 0 is still too small to be tiled, then don't @@ -1421,11 +1432,5 @@ fd6_tile_mode(const struct pipe_resource *tmpl) !util_format_is_depth_or_stencil(tmpl->format)) return TILE6_LINEAR; - /* basically just has to be a format we can blit, so uploads/downloads - * via linear staging buffer works: - */ - if (ok_format(tmpl->format)) - return TILE6_3; - - return TILE6_LINEAR; + return fd6_tile_mode_for_format(tmpl->format); } diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_blitter.h b/src/gallium/drivers/freedreno/a6xx/fd6_blitter.h index b803e59..d9cff9b 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_blitter.h +++ b/src/gallium/drivers/freedreno/a6xx/fd6_blitter.h @@ -35,6 +35,7 @@ template void fd6_blitter_init(struct pipe_context *pctx); +unsigned fd6_tile_mode_for_format(enum pipe_format pfmt); unsigned fd6_tile_mode(const struct pipe_resource *tmpl); /* diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_resource.cc b/src/gallium/drivers/freedreno/a6xx/fd6_resource.cc index d581cf1..b8f96be 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_resource.cc +++ b/src/gallium/drivers/freedreno/a6xx/fd6_resource.cc @@ -29,6 +29,7 @@ #include "drm-uapi/drm_fourcc.h" +#include "a6xx/fd6_blitter.h" #include "fd6_resource.h" #include "fdl/fd6_format_table.h" @@ -333,10 +334,22 @@ fd6_layout_resource_for_modifier(struct fd_resource *rsc, uint64_t modifier) } } -static const uint64_t supported_modifiers[] = { - DRM_FORMAT_MOD_LINEAR, - DRM_FORMAT_MOD_QCOM_COMPRESSED, -}; +static bool +fd6_is_format_supported(struct pipe_screen *pscreen, + enum pipe_format fmt, + uint64_t modifier) +{ + switch (modifier) { + case DRM_FORMAT_MOD_LINEAR: + return true; + case DRM_FORMAT_MOD_QCOM_COMPRESSED: + return ok_ubwc_format(pscreen, fmt); + case DRM_FORMAT_MOD_QCOM_TILED3: + return fd6_tile_mode_for_format(fmt) == TILE6_3; + default: + return false; + } +} void fd6_resource_screen_init(struct pipe_screen *pscreen) @@ -345,6 +358,5 @@ fd6_resource_screen_init(struct pipe_screen *pscreen) screen->setup_slices = fd6_setup_slices; screen->layout_resource_for_modifier = fd6_layout_resource_for_modifier; - screen->supported_modifiers = supported_modifiers; - screen->num_supported_modifiers = ARRAY_SIZE(supported_modifiers); + screen->is_format_supported = fd6_is_format_supported; } diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c index e04aa41..63f9705 100644 --- a/src/gallium/drivers/freedreno/freedreno_resource.c +++ b/src/gallium/drivers/freedreno/freedreno_resource.c @@ -1629,10 +1629,6 @@ static const struct u_transfer_vtbl transfer_vtbl = { .get_stencil = fd_resource_get_stencil, }; -static const uint64_t supported_modifiers[] = { - DRM_FORMAT_MOD_LINEAR, -}; - static int fd_layout_resource_for_modifier(struct fd_resource *rsc, uint64_t modifier) { @@ -1746,10 +1742,6 @@ fd_resource_screen_init(struct pipe_screen *pscreen) if (!screen->layout_resource_for_modifier) screen->layout_resource_for_modifier = fd_layout_resource_for_modifier; - if (!screen->supported_modifiers) { - screen->supported_modifiers = supported_modifiers; - screen->num_supported_modifiers = ARRAY_SIZE(supported_modifiers); - } /* GL_EXT_memory_object */ pscreen->memobj_create_from_handle = fd_memobj_create_from_handle; diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c index d34be04..8ec300f 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.c +++ b/src/gallium/drivers/freedreno/freedreno_screen.c @@ -951,29 +951,42 @@ fd_screen_bo_get_handle(struct pipe_screen *pscreen, struct fd_bo *bo, } } +static bool +is_format_supported(struct pipe_screen *pscreen, + enum pipe_format format, + uint64_t modifier) +{ + struct fd_screen *screen = fd_screen(pscreen); + if (screen->is_format_supported) + return screen->is_format_supported(pscreen, format, modifier); + return modifier == DRM_FORMAT_MOD_LINEAR; +} + static void fd_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen, enum pipe_format format, int max, uint64_t *modifiers, unsigned int *external_only, int *count) { - struct fd_screen *screen = fd_screen(pscreen); - int i, num = 0; + const uint64_t all_modifiers[] = { + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_QCOM_COMPRESSED, + DRM_FORMAT_MOD_QCOM_TILED3, + }; - max = MIN2(max, screen->num_supported_modifiers); + int num = 0; - if (!max) { - max = screen->num_supported_modifiers; - external_only = NULL; - modifiers = NULL; - } + for (int i = 0; i < ARRAY_SIZE(all_modifiers); i++) { + if (!is_format_supported(pscreen, format, all_modifiers[i])) + continue; - for (i = 0; i < max; i++) { - if (modifiers) - modifiers[num] = screen->supported_modifiers[i]; + if (num < max) { + if (modifiers) + modifiers[num] = all_modifiers[i]; - if (external_only) - external_only[num] = 0; + if (external_only) + external_only[num] = false; + } num++; } @@ -987,19 +1000,7 @@ fd_screen_is_dmabuf_modifier_supported(struct pipe_screen *pscreen, enum pipe_format format, bool *external_only) { - struct fd_screen *screen = fd_screen(pscreen); - int i; - - for (i = 0; i < screen->num_supported_modifiers; i++) { - if (modifier == screen->supported_modifiers[i]) { - if (external_only) - *external_only = false; - - return true; - } - } - - return false; + return is_format_supported(pscreen, format, modifier); } struct fd_bo * diff --git a/src/gallium/drivers/freedreno/freedreno_screen.h b/src/gallium/drivers/freedreno/freedreno_screen.h index 423caf9..48ec881 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.h +++ b/src/gallium/drivers/freedreno/freedreno_screen.h @@ -129,6 +129,8 @@ struct fd_screen { unsigned (*tile_mode)(const struct pipe_resource *prsc); int (*layout_resource_for_modifier)(struct fd_resource *rsc, uint64_t modifier); + bool (*is_format_supported)(struct pipe_screen *pscreen, + enum pipe_format fmt, uint64_t modifier); /* indirect-branch emit: */ void (*emit_ib)(struct fd_ringbuffer *ring, struct fd_ringbuffer *target);