From 6f24dad00e69a877596be82261a9e44268c6e4ba Mon Sep 17 00:00:00 2001 From: "Eric R. Smith" Date: Wed, 25 Jun 2025 21:02:23 +0000 Subject: [PATCH] panfrost: add 422 AFBC formats Most of the infrastructure was already in place for 8 bit (we just had to add the AFBC mode to use). We also needed to add support for the 10 bit format (X6R10X6G10_X6R10X6B10_UNORM). Note that this 10 bit format is only supported for AFBC, for linear we have to fall back to the old multi-plane way of handling it. Reviewed-by: Boris Brezillon Part-of: --- src/gallium/drivers/panfrost/pan_screen.c | 8 ++++++++ src/panfrost/lib/pan_afbc.h | 17 +++++++++++++++++ src/panfrost/lib/pan_format.c | 1 + src/panfrost/lib/pan_mod.c | 2 +- src/panfrost/lib/pan_texture.c | 1 + 5 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/panfrost/pan_screen.c b/src/gallium/drivers/panfrost/pan_screen.c index ec3597fb05f..91356aaa916 100644 --- a/src/gallium/drivers/panfrost/pan_screen.c +++ b/src/gallium/drivers/panfrost/pan_screen.c @@ -344,8 +344,12 @@ panfrost_lower_yuv_format(struct panfrost_device *dev, TRY_LOWERING(PIPE_FORMAT_R10G10B10_420_UNORM_PACKED); break; case PIPE_FORMAT_Y210: + TRY_LOWERING(PIPE_FORMAT_X6R10X6G10_X6R10X6B10_422_UNORM); + TRY_LOWERING(PIPE_FORMAT_RG1616_UNORM, PIPE_FORMAT_R16G16B16A16_UNORM); + break; case PIPE_FORMAT_Y212: case PIPE_FORMAT_Y216: + TRY_LOWERING(PIPE_FORMAT_R16G16_R16B16_422_UNORM); TRY_LOWERING(PIPE_FORMAT_RG1616_UNORM, PIPE_FORMAT_R16G16B16A16_UNORM); break; case PIPE_FORMAT_P010: @@ -519,12 +523,16 @@ panfrost_is_dmabuf_modifier_supported(struct pipe_screen *screen, unsigned int uint_extern_only = 0; int count; + if (format_requires_afbc(format) && !drm_is_afbc(modifier)) + return false; + panfrost_walk_dmabuf_modifiers(screen, format, 1, &unused, &uint_extern_only, &count, modifier, true); if (external_only) *external_only = uint_extern_only ? true : false; + return count > 0; } diff --git a/src/panfrost/lib/pan_afbc.h b/src/panfrost/lib/pan_afbc.h index dfe9669b12c..9ddb2828b50 100644 --- a/src/panfrost/lib/pan_afbc.h +++ b/src/panfrost/lib/pan_afbc.h @@ -524,6 +524,11 @@ pan_afbc_format(unsigned arch, enum pipe_format format, unsigned plane_idx) return PAN_AFBC_MODE_YUV420_6C8; case PIPE_FORMAT_R10G10B10_420_UNORM_PACKED: return PAN_AFBC_MODE_YUV420_6C10; + case PIPE_FORMAT_R8G8_R8B8_UNORM: + case PIPE_FORMAT_R8B8_R8G8_UNORM: + return PAN_AFBC_MODE_YUV422_4C8; + case PIPE_FORMAT_X6R10X6G10_X6R10X6B10_422_UNORM: + return PAN_AFBC_MODE_YUV422_4C10; default: break; } @@ -759,6 +764,18 @@ pan_afbc_decompression_mode(enum pipe_format view_format, } #endif +static inline bool +format_requires_afbc(enum pipe_format format) { + switch (format) { + case PIPE_FORMAT_R8G8B8_420_UNORM_PACKED: + case PIPE_FORMAT_R10G10B10_420_UNORM_PACKED: + case PIPE_FORMAT_X6R10X6G10_X6R10X6B10_422_UNORM: + return true; + default: + return false; + } +} + #ifdef __cplusplus } /* extern C */ #endif diff --git a/src/panfrost/lib/pan_format.c b/src/panfrost/lib/pan_format.c index 5a530a4e526..647373fab26 100644 --- a/src/panfrost/lib/pan_format.c +++ b/src/panfrost/lib/pan_format.c @@ -197,6 +197,7 @@ const struct pan_format GENX(pan_pipe_format)[PIPE_FORMAT_COUNT] = { /* special internal formats */ FMT_YUV(R8G8B8_420_UNORM_PACKED, Y8_UV8_420, YUVA, NO_SWAP, CENTER, _T___), FMT_YUV(R10G10B10_420_UNORM_PACKED, Y10_UV10_420, YUVA, NO_SWAP, CENTER, _T___), + FMT_YUV(X6R10X6G10_X6R10X6B10_422_UNORM, YUYV10, UVYA, NO_SWAP, CENTER_422, _T___), #endif FMTC(ETC1_RGB8, ETC2_RGB8, RGBA8_UNORM, RGB1, L), diff --git a/src/panfrost/lib/pan_mod.c b/src/panfrost/lib/pan_mod.c index 2d61de70732..72285e495c9 100644 --- a/src/panfrost/lib/pan_mod.c +++ b/src/panfrost/lib/pan_mod.c @@ -586,8 +586,8 @@ pan_mod_linear_test_props(const struct pan_kmod_dev_props *dprops, /* AFBC-only formats. */ case PIPE_FORMAT_R8G8B8_420_UNORM_PACKED: case PIPE_FORMAT_R10G10B10_420_UNORM_PACKED: + case PIPE_FORMAT_X6R10X6G10_X6R10X6B10_422_UNORM: return PAN_MOD_NOT_SUPPORTED; - default: /* We assume that all "better" mods have been tested before linear, and * declare it as optimal so it's always picked when tested, unless it's diff --git a/src/panfrost/lib/pan_texture.c b/src/panfrost/lib/pan_texture.c index 247924ced68..aa464f070c3 100644 --- a/src/panfrost/lib/pan_texture.c +++ b/src/panfrost/lib/pan_texture.c @@ -281,6 +281,7 @@ pan_clump_format(enum pipe_format format) case PIPE_FORMAT_R10G10B10_420_UNORM_PACKED: return MALI_CLUMP_FORMAT_Y10_UV10_420; case PIPE_FORMAT_R10_G10B10_422_UNORM: + case PIPE_FORMAT_X6R10X6G10_X6R10X6B10_422_UNORM: return MALI_CLUMP_FORMAT_Y10_UV10_422; default: UNREACHABLE("unhandled clump format");