From b890a5ff619e41ced38780a93099af86df06a86a Mon Sep 17 00:00:00 2001 From: Italo Nicola Date: Fri, 21 Jul 2023 00:31:48 +0000 Subject: [PATCH] gallium/st: add non-CSC lowering of YV12 as PIPE_FORMAT_R8_B8_G8_420 YV12 is the same as DRM_FORMAT_YVU420. We lower it to PIPE_FORMAT_R8_B8_G8_420, which is equivalent to PIPE_FORMAT_R8_G8_B8_420 with U/V planes swapped. This is used for hardware that can sample from YUV but need CSC in shader. Signed-off-by: Italo Nicola Reviewed-by: Daniel Stone Part-of: --- src/gallium/frontends/dri/dri2.c | 31 ++++++++++++++++++------ src/mesa/state_tracker/st_atom_sampler.c | 3 ++- src/mesa/state_tracker/st_atom_texture.c | 3 ++- src/mesa/state_tracker/st_cb_eglimage.c | 14 ++++++++++- src/mesa/state_tracker/st_program.h | 3 ++- src/mesa/state_tracker/st_sampler_view.c | 5 ++-- src/util/format/u_format.csv | 1 + src/util/format/u_format_table.py | 1 + src/util/format/u_formats.h | 1 + 9 files changed, 49 insertions(+), 13 deletions(-) diff --git a/src/gallium/frontends/dri/dri2.c b/src/gallium/frontends/dri/dri2.c index 2d7f3b3916f..8b7e929f0ef 100644 --- a/src/gallium/frontends/dri/dri2.c +++ b/src/gallium/frontends/dri/dri2.c @@ -858,6 +858,17 @@ dri2_update_tex_buffer(struct dri_drawable *drawable, /* no-op */ } +static const struct dri2_format_mapping r8_b8_g8_mapping = { + DRM_FORMAT_YVU420, + __DRI_IMAGE_FORMAT_NONE, + __DRI_IMAGE_COMPONENTS_Y_U_V, + PIPE_FORMAT_R8_B8_G8_420_UNORM, + 3, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 }, + { 2, 1, 1, __DRI_IMAGE_FORMAT_R8 }, + { 1, 1, 1, __DRI_IMAGE_FORMAT_R8 } } +}; + static const struct dri2_format_mapping r8_g8_b8_mapping = { DRM_FORMAT_YUV420, __DRI_IMAGE_FORMAT_NONE, @@ -964,13 +975,19 @@ dri2_create_image_from_winsys(__DRIscreen *_screen, tex_usage |= PIPE_BIND_SAMPLER_VIEW; } - /* For I420, see if we have support for sampling r8_g8_b8 */ - if (!tex_usage && map->pipe_format == PIPE_FORMAT_IYUV && - map->dri_fourcc == DRM_FORMAT_YUV420 && - pscreen->is_format_supported(pscreen, PIPE_FORMAT_R8_G8_B8_420_UNORM, - screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) { - map = &r8_g8_b8_mapping; - tex_usage |= PIPE_BIND_SAMPLER_VIEW; + /* For YV12 and I420, see if we have support for sampling r8_b8_g8 or r8_g8_b8 */ + if (!tex_usage && map->pipe_format == PIPE_FORMAT_IYUV) { + if (map->dri_fourcc == DRM_FORMAT_YUV420 && + pscreen->is_format_supported(pscreen, PIPE_FORMAT_R8_G8_B8_420_UNORM, + screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) { + map = &r8_g8_b8_mapping; + tex_usage |= PIPE_BIND_SAMPLER_VIEW; + } else if (map->dri_fourcc == DRM_FORMAT_YVU420 && + pscreen->is_format_supported(pscreen, PIPE_FORMAT_R8_B8_G8_420_UNORM, + screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) { + map = &r8_b8_g8_mapping; + tex_usage |= PIPE_BIND_SAMPLER_VIEW; + } } /* If the hardware supports R8G8_R8B8 style subsampled RGB formats, these diff --git a/src/mesa/state_tracker/st_atom_sampler.c b/src/mesa/state_tracker/st_atom_sampler.c index 4157a105c0d..c34d2759513 100644 --- a/src/mesa/state_tracker/st_atom_sampler.c +++ b/src/mesa/state_tracker/st_atom_sampler.c @@ -298,7 +298,8 @@ update_shader_samplers(struct st_context *st, states[extra] = sampler; break; case PIPE_FORMAT_IYUV: - if (stObj->pt->format == PIPE_FORMAT_R8_G8_B8_420_UNORM) { + if (stObj->pt->format == PIPE_FORMAT_R8_G8_B8_420_UNORM || + stObj->pt->format == PIPE_FORMAT_R8_B8_G8_420_UNORM) { /* no additional views needed */ break; } diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c index ed3e0d8bc0e..a923f05151c 100644 --- a/src/mesa/state_tracker/st_atom_texture.c +++ b/src/mesa/state_tracker/st_atom_texture.c @@ -210,7 +210,8 @@ st_get_sampler_views(struct st_context *st, pipe->create_sampler_view(pipe, stObj->pt->next, &tmpl); break; case PIPE_FORMAT_IYUV: - if (stObj->pt->format == PIPE_FORMAT_R8_G8_B8_420_UNORM) + if (stObj->pt->format == PIPE_FORMAT_R8_G8_B8_420_UNORM || + stObj->pt->format == PIPE_FORMAT_R8_B8_G8_420_UNORM) /* no additional views needed */ break; diff --git a/src/mesa/state_tracker/st_cb_eglimage.c b/src/mesa/state_tracker/st_cb_eglimage.c index 6156d00f76e..41ce901d2a1 100644 --- a/src/mesa/state_tracker/st_cb_eglimage.c +++ b/src/mesa/state_tracker/st_cb_eglimage.c @@ -210,6 +210,17 @@ is_i420_as_r8_g8_b8_420_supported(struct pipe_screen *screen, return true; } + if (out->format == PIPE_FORMAT_IYUV && + out->texture->format == PIPE_FORMAT_R8_B8_G8_420_UNORM && + screen->is_format_supported(screen, PIPE_FORMAT_R8_B8_G8_420_UNORM, + PIPE_TEXTURE_2D, + out->texture->nr_samples, + out->texture->nr_storage_samples, + usage)) { + *native_supported = false; + return true; + } + return false; } @@ -391,7 +402,8 @@ st_bind_egl_image(struct gl_context *ctx, texObj->RequiredTextureImageUnits = 1; break; case PIPE_FORMAT_IYUV: - if (stimg->texture->format == PIPE_FORMAT_R8_G8_B8_420_UNORM) { + if (stimg->texture->format == PIPE_FORMAT_R8_G8_B8_420_UNORM || + stimg->texture->format == PIPE_FORMAT_R8_B8_G8_420_UNORM) { texFormat = MESA_FORMAT_R8G8B8X8_UNORM; texObj->RequiredTextureImageUnits = 1; } else { diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h index 7a826f832fd..70280832721 100644 --- a/src/mesa/state_tracker/st_program.h +++ b/src/mesa/state_tracker/st_program.h @@ -104,7 +104,8 @@ st_get_external_sampler_key(struct st_context *st, struct gl_program *prog) key.lower_nv21 |= (1 << unit); break; case PIPE_FORMAT_IYUV: - if (stObj->pt->format == PIPE_FORMAT_R8_G8_B8_420_UNORM) { + if (stObj->pt->format == PIPE_FORMAT_R8_G8_B8_420_UNORM || + stObj->pt->format == PIPE_FORMAT_R8_B8_G8_420_UNORM) { key.lower_yuv |= (1 << unit); break; } diff --git a/src/mesa/state_tracker/st_sampler_view.c b/src/mesa/state_tracker/st_sampler_view.c index 753b67733f2..73590097ebc 100644 --- a/src/mesa/state_tracker/st_sampler_view.c +++ b/src/mesa/state_tracker/st_sampler_view.c @@ -393,8 +393,9 @@ st_get_sampler_view_format(const struct st_context *st, } FALLTHROUGH; case PIPE_FORMAT_IYUV: - if (texObj->pt->format == PIPE_FORMAT_R8_G8_B8_420_UNORM) { - format = PIPE_FORMAT_R8_G8_B8_420_UNORM; + if (texObj->pt->format == PIPE_FORMAT_R8_G8_B8_420_UNORM || + texObj->pt->format == PIPE_FORMAT_R8_B8_G8_420_UNORM) { + format = texObj->pt->format; break; } format = PIPE_FORMAT_R8_UNORM; diff --git a/src/util/format/u_format.csv b/src/util/format/u_format.csv index 93517cec310..c82eeac34d2 100644 --- a/src/util/format/u_format.csv +++ b/src/util/format/u_format.csv @@ -408,6 +408,7 @@ PIPE_FORMAT_Y8_400_UNORM , other , 1, 1, 1, un8, , , , x0 PIPE_FORMAT_R8_G8B8_420_UNORM , planar2, 1, 1, 1, un8, , , , xyzw, rgb PIPE_FORMAT_G8_B8R8_420_UNORM , planar2, 1, 1, 1, un8, , , , xyzw, rgb PIPE_FORMAT_R8_G8_B8_420_UNORM , planar3, 1, 1, 1, un8, , , , xyzw, rgb +PIPE_FORMAT_R8_B8_G8_420_UNORM , planar3, 1, 1, 1, un8, , , , xyzw, rgb PIPE_FORMAT_G8_B8_R8_420_UNORM , planar3, 1, 1, 1, un8, , , , xyzw, rgb PIPE_FORMAT_R8_G8_B8_UNORM , planar3, 1, 1, 1, un8, , , , xyzw, rgb diff --git a/src/util/format/u_format_table.py b/src/util/format/u_format_table.py index 8427760a2a4..1cd66a98889 100644 --- a/src/util/format/u_format_table.py +++ b/src/util/format/u_format_table.py @@ -115,6 +115,7 @@ def has_access(format): 'r8_g8b8_420_unorm', 'g8_b8r8_420_unorm', 'r8_g8_b8_420_unorm', + 'r8_b8_g8_420_unorm', 'g8_b8_r8_420_unorm', 'r8_g8_b8_unorm', 'y8_unorm', diff --git a/src/util/format/u_formats.h b/src/util/format/u_formats.h index 45af123b9ef..f705d12adf7 100644 --- a/src/util/format/u_formats.h +++ b/src/util/format/u_formats.h @@ -513,6 +513,7 @@ enum pipe_format { PIPE_FORMAT_R8_G8B8_420_UNORM, PIPE_FORMAT_G8_B8R8_420_UNORM, PIPE_FORMAT_R8_G8_B8_420_UNORM, + PIPE_FORMAT_R8_B8_G8_420_UNORM, PIPE_FORMAT_G8_B8_R8_420_UNORM, PIPE_FORMAT_R8_G8_B8_UNORM, PIPE_FORMAT_Y8_UNORM,