From f57c074270ef53c03d4e1db1e13fac3f13300756 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Fri, 12 Mar 2021 23:03:49 -0800 Subject: [PATCH] gallium/dri: Allow use of R8G8_R8B8 for YUYV and G8R8_B8R8 for UYVY v2: Add missing FALLTHROUGH. Caught by CI. Reviewed-by: Emma Anholt Part-of: --- src/gallium/frontends/dri/dri2.c | 35 ++++++++++++++++++++++ src/mesa/state_tracker/st_atom_sampler.c | 6 ++++ src/mesa/state_tracker/st_atom_texture.c | 8 +++++ src/mesa/state_tracker/st_cb_eglimage.c | 38 ++++++++++++++++-------- src/mesa/state_tracker/st_program.c | 4 ++- src/mesa/state_tracker/st_program.h | 10 +++++++ src/mesa/state_tracker/st_sampler_view.c | 5 ++++ 7 files changed, 93 insertions(+), 13 deletions(-) diff --git a/src/gallium/frontends/dri/dri2.c b/src/gallium/frontends/dri/dri2.c index 08a9ed9693c..d70715077c7 100644 --- a/src/gallium/frontends/dri/dri2.c +++ b/src/gallium/frontends/dri/dri2.c @@ -739,6 +739,24 @@ static const struct dri2_format_mapping r8_g8b8_mapping = { { 1, 1, 1, __DRI_IMAGE_FORMAT_GR88 } } }; +static const struct dri2_format_mapping r8g8_r8b8_mapping = { + DRM_FORMAT_YUYV, + __DRI_IMAGE_FORMAT_NONE, + __DRI_IMAGE_COMPONENTS_Y_XUXV, + PIPE_FORMAT_R8G8_R8B8_UNORM, 2, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88 }, + { 0, 1, 0, __DRI_IMAGE_FORMAT_ARGB8888 } } +}; + +static const struct dri2_format_mapping g8r8_b8r8_mapping = { + DRM_FORMAT_UYVY, + __DRI_IMAGE_FORMAT_NONE, + __DRI_IMAGE_COMPONENTS_Y_XUXV, + PIPE_FORMAT_G8R8_B8R8_UNORM, 2, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88 }, + { 0, 1, 0, __DRI_IMAGE_FORMAT_ABGR8888 } } +}; + static __DRIimage * dri2_create_image_from_winsys(__DRIscreen *_screen, int width, int height, const struct dri2_format_mapping *map, @@ -772,6 +790,23 @@ dri2_create_image_from_winsys(__DRIscreen *_screen, tex_usage |= PIPE_BIND_SAMPLER_VIEW; } + /* If the hardware supports R8G8_R8B8 style subsampled RGB formats, these + * can be used for YUYV and UYVY formats. + */ + if (!tex_usage && map->pipe_format == PIPE_FORMAT_YUYV && + pscreen->is_format_supported(pscreen, PIPE_FORMAT_R8G8_R8B8_UNORM, + screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) { + map = &r8g8_r8b8_mapping; + tex_usage |= PIPE_BIND_SAMPLER_VIEW; + } + + if (!tex_usage && map->pipe_format == PIPE_FORMAT_UYVY && + pscreen->is_format_supported(pscreen, PIPE_FORMAT_G8R8_B8R8_UNORM, + screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) { + map = &g8r8_b8r8_mapping; + tex_usage |= PIPE_BIND_SAMPLER_VIEW; + } + if (!tex_usage && util_format_is_yuv(map->pipe_format)) { /* YUV format sampling can be emulated by the GL gallium frontend by * using multiple samplers of varying formats. diff --git a/src/mesa/state_tracker/st_atom_sampler.c b/src/mesa/state_tracker/st_atom_sampler.c index 6810a98fc1c..5a49b06bc1a 100644 --- a/src/mesa/state_tracker/st_atom_sampler.c +++ b/src/mesa/state_tracker/st_atom_sampler.c @@ -363,6 +363,12 @@ update_shader_samplers(struct st_context *st, case PIPE_FORMAT_Y216: case PIPE_FORMAT_YUYV: case PIPE_FORMAT_UYVY: + if (stObj->pt->format == PIPE_FORMAT_R8G8_R8B8_UNORM || + stObj->pt->format == PIPE_FORMAT_G8R8_B8R8_UNORM) { + /* no additional views needed */ + break; + } + /* we need one additional sampler: */ extra = u_bit_scan(&free_slots); states[extra] = sampler; diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c index eafccfe87ca..fbc6aee4c44 100644 --- a/src/mesa/state_tracker/st_atom_texture.c +++ b/src/mesa/state_tracker/st_atom_texture.c @@ -221,6 +221,10 @@ update_textures(struct st_context *st, pipe->create_sampler_view(pipe, stObj->pt->next->next, &tmpl); break; case PIPE_FORMAT_YUYV: + if (stObj->pt->format == PIPE_FORMAT_R8G8_R8B8_UNORM) + /* no additional views needed */ + break; + /* we need one additional BGRA8888 view: */ tmpl.format = PIPE_FORMAT_BGRA8888_UNORM; tmpl.swizzle_b = PIPE_SWIZZLE_Z; @@ -230,6 +234,10 @@ update_textures(struct st_context *st, pipe->create_sampler_view(pipe, stObj->pt->next, &tmpl); break; case PIPE_FORMAT_UYVY: + if (stObj->pt->format == PIPE_FORMAT_G8R8_B8R8_UNORM) + /* no additional views needed */ + break; + /* we need one additional RGBA8888 view: */ tmpl.format = PIPE_FORMAT_RGBA8888_UNORM; tmpl.swizzle_b = PIPE_SWIZZLE_Z; diff --git a/src/mesa/state_tracker/st_cb_eglimage.c b/src/mesa/state_tracker/st_cb_eglimage.c index c613ad333bc..0c487d01021 100644 --- a/src/mesa/state_tracker/st_cb_eglimage.c +++ b/src/mesa/state_tracker/st_cb_eglimage.c @@ -101,20 +101,26 @@ is_format_supported(struct pipe_screen *screen, enum pipe_format format, nr_storage_samples, usage); break; case PIPE_FORMAT_YUYV: - supported = screen->is_format_supported(screen, PIPE_FORMAT_RG88_UNORM, + supported = screen->is_format_supported(screen, PIPE_FORMAT_R8G8_R8B8_UNORM, PIPE_TEXTURE_2D, nr_samples, - nr_storage_samples, usage) && - screen->is_format_supported(screen, PIPE_FORMAT_BGRA8888_UNORM, - PIPE_TEXTURE_2D, nr_samples, - nr_storage_samples, usage); + nr_storage_samples, usage) || + (screen->is_format_supported(screen, PIPE_FORMAT_RG88_UNORM, + PIPE_TEXTURE_2D, nr_samples, + nr_storage_samples, usage) && + screen->is_format_supported(screen, PIPE_FORMAT_BGRA8888_UNORM, + PIPE_TEXTURE_2D, nr_samples, + nr_storage_samples, usage)); break; case PIPE_FORMAT_UYVY: - supported = screen->is_format_supported(screen, PIPE_FORMAT_RG88_UNORM, + supported = screen->is_format_supported(screen, PIPE_FORMAT_G8R8_B8R8_UNORM, PIPE_TEXTURE_2D, nr_samples, - nr_storage_samples, usage) && - screen->is_format_supported(screen, PIPE_FORMAT_RGBA8888_UNORM, - PIPE_TEXTURE_2D, nr_samples, - nr_storage_samples, usage); + nr_storage_samples, usage) || + (screen->is_format_supported(screen, PIPE_FORMAT_RG88_UNORM, + PIPE_TEXTURE_2D, nr_samples, + nr_storage_samples, usage) && + screen->is_format_supported(screen, PIPE_FORMAT_RGBA8888_UNORM, + PIPE_TEXTURE_2D, nr_samples, + nr_storage_samples, usage)); break; case PIPE_FORMAT_AYUV: supported = screen->is_format_supported(screen, PIPE_FORMAT_RGBA8888_UNORM, @@ -327,8 +333,16 @@ st_bind_egl_image(struct gl_context *ctx, break; case PIPE_FORMAT_YUYV: case PIPE_FORMAT_UYVY: - texFormat = MESA_FORMAT_RG_UNORM8; - texObj->RequiredTextureImageUnits = 2; + if (stimg->texture->format == PIPE_FORMAT_R8G8_R8B8_UNORM) { + texFormat = MESA_FORMAT_RG_RB_UNORM8; + texObj->RequiredTextureImageUnits = 1; + } else if (stimg->texture->format == PIPE_FORMAT_G8R8_B8R8_UNORM) { + texFormat = MESA_FORMAT_GR_BR_UNORM8; + texObj->RequiredTextureImageUnits = 1; + } else { + texFormat = MESA_FORMAT_RG_UNORM8; + texObj->RequiredTextureImageUnits = 2; + } break; case PIPE_FORMAT_AYUV: texFormat = MESA_FORMAT_R8G8B8A8_UNORM; diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index d66e5cc5645..99c81b8970a 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -1455,7 +1455,8 @@ st_create_fp_variant(struct st_context *st, if (unlikely(key->external.lower_nv12 || key->external.lower_iyuv || key->external.lower_xy_uxvx || key->external.lower_yx_xuxv || key->external.lower_ayuv || key->external.lower_xyuv || - key->external.lower_yuv || key->external.lower_y41x)) { + key->external.lower_yuv || key->external.lower_yu_yv || + key->external.lower_y41x)) { st_nir_lower_samplers(st->screen, state.ir.nir, stfp->shader_program, &stfp->Base); @@ -1468,6 +1469,7 @@ st_create_fp_variant(struct st_context *st, options.lower_ayuv_external = key->external.lower_ayuv; options.lower_xyuv_external = key->external.lower_xyuv; options.lower_yuv_external = key->external.lower_yuv; + options.lower_yu_yv_external = key->external.lower_yu_yv; options.lower_y41x_external = key->external.lower_y41x; NIR_PASS_V(state.ir.nir, nir_lower_tex, &options); finalize = true; diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h index 7cff5cc64ae..1a76260a286 100644 --- a/src/mesa/state_tracker/st_program.h +++ b/src/mesa/state_tracker/st_program.h @@ -58,6 +58,7 @@ struct st_external_sampler_key GLuint lower_ayuv; GLuint lower_xyuv; GLuint lower_yuv; + GLuint lower_yu_yv; GLuint lower_y41x; }; @@ -95,12 +96,21 @@ st_get_external_sampler_key(struct st_context *st, struct gl_program *prog) key.lower_iyuv |= (1 << unit); break; case PIPE_FORMAT_YUYV: + if (stObj->pt->format == PIPE_FORMAT_R8G8_R8B8_UNORM) { + key.lower_yu_yv |= (1 << unit); + break; + } + FALLTHROUGH; case PIPE_FORMAT_Y210: case PIPE_FORMAT_Y212: case PIPE_FORMAT_Y216: key.lower_yx_xuxv |= (1 << unit); break; case PIPE_FORMAT_UYVY: + if (stObj->pt->format == PIPE_FORMAT_G8R8_B8R8_UNORM) { + key.lower_yu_yv |= (1 << unit); + break; + } key.lower_xy_uxvx |= (1 << unit); break; case PIPE_FORMAT_AYUV: diff --git a/src/mesa/state_tracker/st_sampler_view.c b/src/mesa/state_tracker/st_sampler_view.c index 3e5bf387718..eee8fcc5594 100644 --- a/src/mesa/state_tracker/st_sampler_view.c +++ b/src/mesa/state_tracker/st_sampler_view.c @@ -525,6 +525,11 @@ get_sampler_view_format(struct st_context *st, break; case PIPE_FORMAT_YUYV: case PIPE_FORMAT_UYVY: + if (stObj->pt->format == PIPE_FORMAT_R8G8_R8B8_UNORM || + stObj->pt->format == PIPE_FORMAT_G8R8_B8R8_UNORM) { + format = stObj->pt->format; + break; + } format = PIPE_FORMAT_R8G8_UNORM; break; case PIPE_FORMAT_AYUV: