diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_blitter.cc b/src/gallium/drivers/freedreno/a6xx/fd6_blitter.cc index b7050d220d3..65264cbdda1 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_blitter.cc +++ b/src/gallium/drivers/freedreno/a6xx/fd6_blitter.cc @@ -1411,6 +1411,17 @@ fd6_blitter_init(struct pipe_context *pctx) 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) { @@ -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 b803e59cc54..d9cff9bc5b4 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 d581cf1827a..b8f96bee616 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 e04aa41e021..63f9705c0a5 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 d34be04ef0e..8ec300f8553 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 423caf9196e..48ec8812157 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);