From 8c68512b842045ba3cfd9e14f18846089ec775cb Mon Sep 17 00:00:00 2001 From: "Eric R. Smith" Date: Thu, 15 May 2025 09:33:53 +0200 Subject: [PATCH] gallium/st: Teach the state tracker about YU08 and YU10 formats Add the necessary bits to the state tracker to support single plane YUV 420 formats (YU08 and YU10 fourcc codes). Reviewed-by: Boris Brezillon Reviewed-by: Erik Faye-Lund Part-of: --- src/mesa/state_tracker/st_cb_eglimage.c | 49 ++++++++++++++++++++++++ src/mesa/state_tracker/st_program.h | 13 +++++++ src/mesa/state_tracker/st_sampler_view.c | 13 +++++++ 3 files changed, 75 insertions(+) diff --git a/src/mesa/state_tracker/st_cb_eglimage.c b/src/mesa/state_tracker/st_cb_eglimage.c index 39e01f24594..15489c74f12 100644 --- a/src/mesa/state_tracker/st_cb_eglimage.c +++ b/src/mesa/state_tracker/st_cb_eglimage.c @@ -232,6 +232,42 @@ is_fmt_as_r10_g10b10_supported(struct pipe_screen *screen, struct st_egl_image * return false; } +static bool +is_yuv420_as_r8g8b8_supported(struct pipe_screen *screen, + struct st_egl_image *out, + unsigned usage, bool *native_supported) +{ + if (out->format == PIPE_FORMAT_Y8U8V8_420_UNORM_PACKED && + out->texture->format == PIPE_FORMAT_R8G8B8_420_UNORM_PACKED && + screen->is_format_supported(screen, PIPE_FORMAT_R8G8B8_420_UNORM_PACKED, + PIPE_TEXTURE_2D, + out->texture->nr_samples, + out->texture->nr_storage_samples, + usage)) { + *native_supported = false; + return true; + } + return false; +} + +static bool +is_yuv420_as_r10g10b10_supported(struct pipe_screen *screen, + struct st_egl_image *out, + unsigned usage, bool *native_supported) +{ + if (out->format == PIPE_FORMAT_Y10U10V10_420_UNORM_PACKED && + out->texture->format == PIPE_FORMAT_R10G10B10_420_UNORM_PACKED && + screen->is_format_supported(screen, PIPE_FORMAT_R10G10B10_420_UNORM_PACKED, + PIPE_TEXTURE_2D, + out->texture->nr_samples, + out->texture->nr_storage_samples, + usage)) { + *native_supported = false; + return true; + } + return false; +} + static bool is_i420_as_r8_g8_b8_420_supported(struct pipe_screen *screen, struct st_egl_image *out, @@ -287,6 +323,8 @@ st_get_egl_image(struct gl_context *ctx, GLeglImageOES image_handle, if (!is_fmt_as_r8_g8b8_supported(screen, out, usage, native_supported) && !is_fmt_as_r10_g10b10_supported(screen, out, usage, native_supported) && !is_i420_as_r8_g8_b8_420_supported(screen, out, usage, native_supported) && + !is_yuv420_as_r8g8b8_supported(screen, out, usage, native_supported) && + !is_yuv420_as_r10g10b10_supported(screen, out, usage, native_supported) && !is_format_supported(screen, out->format, out->texture->nr_samples, out->texture->nr_storage_samples, usage, native_supported)) { @@ -404,6 +442,16 @@ st_bind_egl_image(struct gl_context *ctx, */ if (!native_supported) { switch (stimg->format) { + case PIPE_FORMAT_Y8U8V8_420_UNORM_PACKED: + assert(stimg->texture->format == PIPE_FORMAT_R8G8B8_420_UNORM_PACKED); + texFormat = MESA_FORMAT_R8G8B8X8_UNORM; + texObj->RequiredTextureImageUnits = 1; + break; + case PIPE_FORMAT_Y10U10V10_420_UNORM_PACKED: + assert(stimg->texture->format == PIPE_FORMAT_R10G10B10_420_UNORM_PACKED); + texFormat = MESA_FORMAT_R10G10B10X2_UNORM; + texObj->RequiredTextureImageUnits = 1; + break; case PIPE_FORMAT_NV12: case PIPE_FORMAT_NV21: if (stimg->texture->format == PIPE_FORMAT_R8_G8B8_420_UNORM || @@ -511,6 +559,7 @@ st_bind_egl_image(struct gl_context *ctx, } } else { texFormat = st_pipe_format_to_mesa_format(stimg->format); + /* Use previously derived internalformat as specified by * EXT_EGL_image_storage. */ diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h index eca993ddd06..08e3b4b2177 100644 --- a/src/mesa/state_tracker/st_program.h +++ b/src/mesa/state_tracker/st_program.h @@ -84,6 +84,19 @@ st_get_external_sampler_key(struct st_context *st, struct gl_program *prog) continue; switch (format) { + case PIPE_FORMAT_Y8U8V8_420_UNORM_PACKED: + /* This format is HW-defined, so we can't lower it to anything but its + * YUV-as-RGB variant. */ + assert(stObj->pt->format == PIPE_FORMAT_R8G8B8_420_UNORM_PACKED); + key.lower_yuv |= (1 << unit); + break; + case PIPE_FORMAT_Y10U10V10_420_UNORM_PACKED: + /* This format is HW-defined, so we can't lower it to anything but its + * YUV-as-RGB variant. */ + assert(stObj->pt->format == PIPE_FORMAT_R10G10B10_420_UNORM_PACKED); + key.lower_yuv |= (1 << unit); + break; + case PIPE_FORMAT_NV16: if (stObj->pt->format == PIPE_FORMAT_R8_G8B8_422_UNORM) { key.lower_yuv |= (1 << unit); diff --git a/src/mesa/state_tracker/st_sampler_view.c b/src/mesa/state_tracker/st_sampler_view.c index 574f3266cd9..3765e530cf9 100644 --- a/src/mesa/state_tracker/st_sampler_view.c +++ b/src/mesa/state_tracker/st_sampler_view.c @@ -352,6 +352,19 @@ st_get_sampler_view_format(const struct st_context *st, /* Use R8_UNORM for video formats */ switch (format) { + case PIPE_FORMAT_Y8U8V8_420_UNORM_PACKED: + /* This format is HW-defined, so we can't lower it to anything but its + * YUV-as-RGB variant. */ + assert(texObj->pt->format == PIPE_FORMAT_R8G8B8_420_UNORM_PACKED); + format = PIPE_FORMAT_R8G8B8_420_UNORM_PACKED; + break; + case PIPE_FORMAT_Y10U10V10_420_UNORM_PACKED: + /* This format is HW-defined, so we can't lower it to anything but its + * YUV-as-RGB variant. */ + assert(texObj->pt->format == PIPE_FORMAT_R10G10B10_420_UNORM_PACKED); + format = PIPE_FORMAT_R10G10B10_420_UNORM_PACKED; + break; + case PIPE_FORMAT_NV12: if (texObj->pt->format == PIPE_FORMAT_R8_G8B8_420_UNORM) { format = PIPE_FORMAT_R8_G8B8_420_UNORM;