From fddd455e9c8cfe89361ad7bf3ec811b4089b1fb4 Mon Sep 17 00:00:00 2001 From: "Eric R. Smith" Date: Thu, 15 May 2025 09:39:07 +0200 Subject: [PATCH] pan: Teach libpanfrost about YU08/Y010 This is just a matter of adding a few entries to existing arrays/switch-statements, the rest of the logic stays unchanged. Reviewed-by: Boris Brezillon Reviewed-by: Erik Faye-Lund Part-of: --- src/gallium/drivers/panfrost/pan_screen.c | 8 ++++++++ src/panfrost/lib/pan_afbc.h | 4 ++++ src/panfrost/lib/pan_format.c | 3 +++ src/panfrost/lib/pan_format.h | 13 +++++++++++++ src/panfrost/lib/pan_layout.h | 2 ++ src/panfrost/lib/pan_mod.c | 4 ++-- src/panfrost/lib/pan_texture.c | 2 ++ src/panfrost/lib/tests/test-layout.cpp | 10 +++++++++- src/panfrost/vulkan/panvk_image.c | 4 ++++ 9 files changed, 47 insertions(+), 3 deletions(-) diff --git a/src/gallium/drivers/panfrost/pan_screen.c b/src/gallium/drivers/panfrost/pan_screen.c index be9cc9552e2..59f623a6ab0 100644 --- a/src/gallium/drivers/panfrost/pan_screen.c +++ b/src/gallium/drivers/panfrost/pan_screen.c @@ -278,6 +278,8 @@ panfrost_lower_yuv_format(struct panfrost_device *dev, SINGLE_RES(NV20, R10_G10B10_422_UNORM) SINGLE_RES(IYUV, R8_G8_B8_420_UNORM) SINGLE_RES(YV12, R8_B8_G8_420_UNORM) + SINGLE_RES(Y8U8V8_420_UNORM_PACKED, R8G8B8_420_UNORM_PACKED) + SINGLE_RES(Y10U10V10_420_UNORM_PACKED, R10G10B10_420_UNORM_PACKED) #undef SINGLE_RES @@ -390,6 +392,12 @@ panfrost_walk_dmabuf_modifiers(struct pipe_screen *screen, native_mods[i] == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) continue; + /* Some formats only work with AFBC. */ + if ((native_mods[i] == DRM_FORMAT_MOD_LINEAR || + native_mods[i] == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) && + !pan_u_tiled_or_linear_supports_format(format)) + continue; + if (test_modifier != DRM_FORMAT_MOD_INVALID && test_modifier != native_mods[i]) continue; diff --git a/src/panfrost/lib/pan_afbc.h b/src/panfrost/lib/pan_afbc.h index 97fbda9ef8f..2e3299f8293 100644 --- a/src/panfrost/lib/pan_afbc.h +++ b/src/panfrost/lib/pan_afbc.h @@ -376,6 +376,10 @@ pan_afbc_format(unsigned arch, enum pipe_format format, unsigned plane_idx) case PIPE_FORMAT_R10_G10B10_422_UNORM: return plane_idx == 0 ? PAN_AFBC_MODE_YUV422_1C10 : PAN_AFBC_MODE_YUV422_2C10; + case PIPE_FORMAT_R8G8B8_420_UNORM_PACKED: + return PAN_AFBC_MODE_YUV420_6C8; + case PIPE_FORMAT_R10G10B10_420_UNORM_PACKED: + return PAN_AFBC_MODE_YUV420_6C10; default: break; } diff --git a/src/panfrost/lib/pan_format.c b/src/panfrost/lib/pan_format.c index 947225662b1..1de9d84fa9f 100644 --- a/src/panfrost/lib/pan_format.c +++ b/src/panfrost/lib/pan_format.c @@ -194,6 +194,9 @@ const struct pan_format GENX(pan_pipe_format)[PIPE_FORMAT_COUNT] = { FMT_YUV(R10_G10B10_420_UNORM, Y10_UV10_420, YUVA, NO_SWAP, CENTER, _T___), FMT_YUV(R10_G10B10_422_UNORM, Y10_UV10_422, YUVA, NO_SWAP, CENTER_422, _T___), + /* 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___), #endif FMTC(ETC1_RGB8, ETC2_RGB8, RGBA8_UNORM, RGB1, L), diff --git a/src/panfrost/lib/pan_format.h b/src/panfrost/lib/pan_format.h index 78e85c44b85..63612e81f8b 100644 --- a/src/panfrost/lib/pan_format.h +++ b/src/panfrost/lib/pan_format.h @@ -93,6 +93,19 @@ ((mod >> 52) == \ (DRM_FORMAT_MOD_ARM_TYPE_AFRC | (DRM_FORMAT_MOD_VENDOR_ARM << 4))) +static inline bool +pan_u_tiled_or_linear_supports_format(enum pipe_format format) +{ + switch (format) { + case PIPE_FORMAT_R8G8B8_420_UNORM_PACKED: + case PIPE_FORMAT_R10G10B10_420_UNORM_PACKED: + return false; + + default: + return true; + } +} + /* Formats */ static inline unsigned diff --git a/src/panfrost/lib/pan_layout.h b/src/panfrost/lib/pan_layout.h index cd131a49035..befabbb325d 100644 --- a/src/panfrost/lib/pan_layout.h +++ b/src/panfrost/lib/pan_layout.h @@ -210,6 +210,7 @@ pan_linear_or_tiled_row_align_req(unsigned arch, enum pipe_format format, switch (format) { /* For v7+, NV12/NV21/I420 have a looser alignment requirement of 16 bytes */ + case PIPE_FORMAT_R8G8B8_420_UNORM_PACKED: case PIPE_FORMAT_R8_G8B8_420_UNORM: case PIPE_FORMAT_G8_B8R8_420_UNORM: case PIPE_FORMAT_R8_G8_B8_420_UNORM: @@ -218,6 +219,7 @@ pan_linear_or_tiled_row_align_req(unsigned arch, enum pipe_format format, case PIPE_FORMAT_R8_B8G8_422_UNORM: return 16; /* the 10 bit formats have even looser alignment */ + case PIPE_FORMAT_R10G10B10_420_UNORM_PACKED: case PIPE_FORMAT_R10_G10B10_420_UNORM: case PIPE_FORMAT_R10_G10B10_422_UNORM: return 1; diff --git a/src/panfrost/lib/pan_mod.c b/src/panfrost/lib/pan_mod.c index 9d3138416ea..618995caef2 100644 --- a/src/panfrost/lib/pan_mod.c +++ b/src/panfrost/lib/pan_mod.c @@ -310,7 +310,7 @@ pan_mod_u_tiled_match(uint64_t mod) static bool pan_mod_u_tiled_supports_format(uint64_t mod, enum pipe_format format) { - return true; + return pan_u_tiled_or_linear_supports_format(format); } static uint32_t @@ -431,7 +431,7 @@ pan_mod_linear_match(uint64_t mod) static bool pan_mod_linear_supports_format(uint64_t mod, enum pipe_format format) { - return true; + return pan_u_tiled_or_linear_supports_format(format); } static uint32_t diff --git a/src/panfrost/lib/pan_texture.c b/src/panfrost/lib/pan_texture.c index cfdbf44b0ea..9154622b2f1 100644 --- a/src/panfrost/lib/pan_texture.c +++ b/src/panfrost/lib/pan_texture.c @@ -275,8 +275,10 @@ pan_clump_format(enum pipe_format format) case PIPE_FORMAT_R8_B8G8_420_UNORM: case PIPE_FORMAT_R8_G8_B8_420_UNORM: case PIPE_FORMAT_R8_B8_G8_420_UNORM: + case PIPE_FORMAT_R8G8B8_420_UNORM_PACKED: return MALI_CLUMP_FORMAT_Y8_UV8_420; case PIPE_FORMAT_R10_G10B10_420_UNORM: + case PIPE_FORMAT_R10G10B10_420_UNORM_PACKED: return MALI_CLUMP_FORMAT_Y10_UV10_420; case PIPE_FORMAT_R10_G10B10_422_UNORM: return MALI_CLUMP_FORMAT_Y10_UV10_422; diff --git a/src/panfrost/lib/tests/test-layout.cpp b/src/panfrost/lib/tests/test-layout.cpp index 65ba93b78d9..64f30ba68a6 100644 --- a/src/panfrost/lib/tests/test-layout.cpp +++ b/src/panfrost/lib/tests/test-layout.cpp @@ -603,7 +603,15 @@ format_can_do_mod(unsigned arch, enum pipe_format format, unsigned plane_idx, assert(modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED || modifier == DRM_FORMAT_MOD_LINEAR); - return true; + switch (format) { + case PIPE_FORMAT_R8G8B8_420_UNORM_PACKED: + case PIPE_FORMAT_R10G10B10_420_UNORM_PACKED: + /* Those are only supported with AFBC. */ + return false; + + default: + return true; + } } } diff --git a/src/panfrost/vulkan/panvk_image.c b/src/panfrost/vulkan/panvk_image.c index eaf97aa4c47..645a4a65358 100644 --- a/src/panfrost/vulkan/panvk_image.c +++ b/src/panfrost/vulkan/panvk_image.c @@ -110,6 +110,10 @@ panvk_image_can_use_mod(struct panvk_image *image, uint64_t mod) return true; } + /* Some formats can only be used with AFBC. */ + if (!pan_u_tiled_or_linear_supports_format(pfmt)) + return false; + if (mod == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) { /* Multiplanar YUV with U-interleaving isn't supported by the HW. We * also need to make sure images that can be aliased to planes of