From 26e3be513dc855f235ee12c8ebc0e7d1a82cd4cf Mon Sep 17 00:00:00 2001 From: Italo Nicola Date: Wed, 1 Feb 2023 21:59:38 +0000 Subject: [PATCH] gallium/st: add support for PIPE_FORMAT_NV21 and PIPE_FORMAT_G8_B8R8_420 Signed-off-by: Italo Nicola Reviewed-by: Daniel Stone Part-of: --- src/gallium/auxiliary/vl/vl_video_buffer.c | 1 + src/gallium/frontends/dri/dri2.c | 18 ++++++++++++++++++ src/gallium/frontends/dri/dri_helpers.c | 4 ++++ src/mesa/state_tracker/st_atom_sampler.c | 5 +++++ src/mesa/state_tracker/st_atom_texture.c | 12 ++++++++++++ src/mesa/state_tracker/st_cb_eglimage.c | 16 ++++++++++++++++ src/mesa/state_tracker/st_program.c | 8 +++++--- src/mesa/state_tracker/st_program.h | 8 ++++++++ src/mesa/state_tracker/st_sampler_view.c | 6 ++++++ 9 files changed, 75 insertions(+), 3 deletions(-) diff --git a/src/gallium/auxiliary/vl/vl_video_buffer.c b/src/gallium/auxiliary/vl/vl_video_buffer.c index c973624..1d6b90b 100644 --- a/src/gallium/auxiliary/vl/vl_video_buffer.c +++ b/src/gallium/auxiliary/vl/vl_video_buffer.c @@ -76,6 +76,7 @@ vl_video_buffer_plane_order(enum pipe_format format) return const_resource_plane_order_YVU; case PIPE_FORMAT_NV12: + case PIPE_FORMAT_NV21: case PIPE_FORMAT_Y8_U8_V8_444_UNORM: case PIPE_FORMAT_R8G8B8A8_UNORM: case PIPE_FORMAT_R8G8B8X8_UNORM: diff --git a/src/gallium/frontends/dri/dri2.c b/src/gallium/frontends/dri/dri2.c index 10fe477..1983b0b 100644 --- a/src/gallium/frontends/dri/dri2.c +++ b/src/gallium/frontends/dri/dri2.c @@ -859,6 +859,16 @@ static const struct dri2_format_mapping r8_g8b8_mapping = { { 1, 1, 1, __DRI_IMAGE_FORMAT_GR88 } } }; +static const struct dri2_format_mapping g8_b8r8_mapping = { + DRM_FORMAT_NV21, + __DRI_IMAGE_FORMAT_NONE, + __DRI_IMAGE_COMPONENTS_Y_UV, + PIPE_FORMAT_G8_B8R8_420_UNORM, + 2, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 }, + { 1, 1, 1, __DRI_IMAGE_FORMAT_GR88 } } +}; + static const struct dri2_format_mapping r8g8_r8b8_mapping = { DRM_FORMAT_YUYV, __DRI_IMAGE_FORMAT_NONE, @@ -908,6 +918,14 @@ dri2_create_image_from_winsys(__DRIscreen *_screen, tex_usage |= PIPE_BIND_SAMPLER_VIEW; } + /* For NV21, see if we have support for sampling g8_b8r8 */ + if (!tex_usage && map->pipe_format == PIPE_FORMAT_NV21 && + pscreen->is_format_supported(pscreen, PIPE_FORMAT_G8_B8R8_420_UNORM, + screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) { + map = &g8_b8r8_mapping; + 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. */ diff --git a/src/gallium/frontends/dri/dri_helpers.c b/src/gallium/frontends/dri/dri_helpers.c index bfbe811..c30a026 100644 --- a/src/gallium/frontends/dri/dri_helpers.c +++ b/src/gallium/frontends/dri/dri_helpers.c @@ -577,6 +577,10 @@ static const struct dri2_format_mapping dri2_format_table[] = { __DRI_IMAGE_COMPONENTS_Y_UV, PIPE_FORMAT_NV12, 2, { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 }, { 1, 1, 1, __DRI_IMAGE_FORMAT_GR88 } } }, + { DRM_FORMAT_NV21, __DRI_IMAGE_FORMAT_NONE, + __DRI_IMAGE_COMPONENTS_Y_UV, PIPE_FORMAT_NV21, 2, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8 }, + { 1, 1, 1, __DRI_IMAGE_FORMAT_GR88 } } }, { DRM_FORMAT_P010, __DRI_IMAGE_FORMAT_NONE, __DRI_IMAGE_COMPONENTS_Y_UV, PIPE_FORMAT_P010, 2, diff --git a/src/mesa/state_tracker/st_atom_sampler.c b/src/mesa/state_tracker/st_atom_sampler.c index bedd223..5725e1c 100644 --- a/src/mesa/state_tracker/st_atom_sampler.c +++ b/src/mesa/state_tracker/st_atom_sampler.c @@ -269,6 +269,11 @@ update_shader_samplers(struct st_context *st, /* no additional views needed */ break; FALLTHROUGH; + case PIPE_FORMAT_NV21: + if (stObj->pt->format == PIPE_FORMAT_G8_B8R8_420_UNORM) + /* no additional views needed */ + break; + FALLTHROUGH; case PIPE_FORMAT_P010: case PIPE_FORMAT_P012: case PIPE_FORMAT_P016: diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c index 9ab69f1..e74c5ef 100644 --- a/src/mesa/state_tracker/st_atom_texture.c +++ b/src/mesa/state_tracker/st_atom_texture.c @@ -186,6 +186,18 @@ st_get_sampler_views(struct st_context *st, sampler_views[extra] = pipe->create_sampler_view(pipe, stObj->pt->next, &tmpl); break; + case PIPE_FORMAT_NV21: + if (stObj->pt->format == PIPE_FORMAT_G8_B8R8_420_UNORM) + /* no additional views needed */ + break; + + /* we need one additional R8G8 view: */ + tmpl.format = PIPE_FORMAT_RG88_UNORM; + tmpl.swizzle_g = PIPE_SWIZZLE_Y; /* tmpl from Y plane is R8 */ + extra = u_bit_scan(&free_slots); + sampler_views[extra] = + pipe->create_sampler_view(pipe, stObj->pt->next, &tmpl); + break; case PIPE_FORMAT_P010: case PIPE_FORMAT_P012: case PIPE_FORMAT_P016: diff --git a/src/mesa/state_tracker/st_cb_eglimage.c b/src/mesa/state_tracker/st_cb_eglimage.c index b232699..2a3a59b 100644 --- a/src/mesa/state_tracker/st_cb_eglimage.c +++ b/src/mesa/state_tracker/st_cb_eglimage.c @@ -63,6 +63,7 @@ is_format_supported(struct pipe_screen *screen, enum pipe_format format, nr_storage_samples, usage); break; case PIPE_FORMAT_NV12: + case PIPE_FORMAT_NV21: supported = screen->is_format_supported(screen, PIPE_FORMAT_R8_UNORM, PIPE_TEXTURE_2D, nr_samples, nr_storage_samples, usage) && @@ -157,6 +158,17 @@ is_nv12_as_r8_g8b8_supported(struct pipe_screen *screen, struct st_egl_image *ou return true; } + if (out->format == PIPE_FORMAT_NV21 && + out->texture->format == PIPE_FORMAT_G8_B8R8_420_UNORM && + screen->is_format_supported(screen, PIPE_FORMAT_G8_B8R8_420_UNORM, + PIPE_TEXTURE_2D, + out->texture->nr_samples, + out->texture->nr_storage_samples, + usage)) { + *native_supported = false; + return true; + } + return false; } @@ -301,9 +313,13 @@ st_bind_egl_image(struct gl_context *ctx, if (!native_supported) { switch (stimg->format) { case PIPE_FORMAT_NV12: + case PIPE_FORMAT_NV21: if (stimg->texture->format == PIPE_FORMAT_R8_G8B8_420_UNORM) { texFormat = MESA_FORMAT_R8G8B8X8_UNORM; texObj->RequiredTextureImageUnits = 1; + } else if (stimg->texture->format == PIPE_FORMAT_G8_B8R8_420_UNORM) { + texFormat = MESA_FORMAT_R8G8B8X8_UNORM; + texObj->RequiredTextureImageUnits = 1; } else { texFormat = MESA_FORMAT_R_UNORM8; texObj->RequiredTextureImageUnits = 2; diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index b6962ed..e1c32a4 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -999,7 +999,8 @@ st_create_fp_variant(struct st_context *st, bool need_lower_tex_src_plane = false; - if (unlikely(key->external.lower_nv12 || key->external.lower_iyuv || + if (unlikely(key->external.lower_nv12 || key->external.lower_nv21 || + 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_yu_yv || @@ -1010,6 +1011,7 @@ st_create_fp_variant(struct st_context *st, nir_lower_tex_options options = {0}; options.lower_y_uv_external = key->external.lower_nv12; + options.lower_y_vu_external = key->external.lower_nv21; options.lower_y_u_v_external = key->external.lower_iyuv; options.lower_xy_uxvx_external = key->external.lower_xy_uxvx; options.lower_yx_xuxv_external = key->external.lower_yx_xuxv; @@ -1036,8 +1038,8 @@ st_create_fp_variant(struct st_context *st, if (unlikely(need_lower_tex_src_plane)) { NIR_PASS_V(state.ir.nir, st_nir_lower_tex_src_plane, ~fp->SamplersUsed, - key->external.lower_nv12 | key->external.lower_xy_uxvx | - key->external.lower_yx_xuxv, + key->external.lower_nv12 | key->external.lower_nv21 | + key->external.lower_xy_uxvx | key->external.lower_yx_xuxv, key->external.lower_iyuv); finalize = true; } diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h index c86cafc..44c1ccb 100644 --- a/src/mesa/state_tracker/st_program.h +++ b/src/mesa/state_tracker/st_program.h @@ -48,6 +48,7 @@ extern "C" { struct st_external_sampler_key { GLuint lower_nv12; /**< bitmask of 2 plane YUV samplers */ + GLuint lower_nv21; GLuint lower_iyuv; /**< bitmask of 3 plane YUV samplers */ GLuint lower_xy_uxvx; /**< bitmask of 2 plane YUV samplers */ GLuint lower_yx_xuxv; /**< bitmask of 2 plane YUV samplers */ @@ -92,6 +93,13 @@ st_get_external_sampler_key(struct st_context *st, struct gl_program *prog) case PIPE_FORMAT_P030: key.lower_nv12 |= (1 << unit); break; + case PIPE_FORMAT_NV21: + if (stObj->pt->format == PIPE_FORMAT_G8_B8R8_420_UNORM) { + key.lower_yuv |= (1 << unit); + break; + } + key.lower_nv21 |= (1 << unit); + break; case PIPE_FORMAT_IYUV: key.lower_iyuv |= (1 << unit); break; diff --git a/src/mesa/state_tracker/st_sampler_view.c b/src/mesa/state_tracker/st_sampler_view.c index 3e8e0af..d39341a 100644 --- a/src/mesa/state_tracker/st_sampler_view.c +++ b/src/mesa/state_tracker/st_sampler_view.c @@ -386,6 +386,12 @@ st_get_sampler_view_format(const struct st_context *st, break; } FALLTHROUGH; + case PIPE_FORMAT_NV21: + if (texObj->pt->format == PIPE_FORMAT_G8_B8R8_420_UNORM) { + format = PIPE_FORMAT_G8_B8R8_420_UNORM; + break; + } + FALLTHROUGH; case PIPE_FORMAT_IYUV: format = PIPE_FORMAT_R8_UNORM; break; -- 2.7.4