Module: Mesa
Branch: main
Commit: 26e3be513dc855f235ee12c8ebc0e7d1a82cd4cf
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=26e3be513dc855f235ee12c8ebc0e7d1a82cd4cf

Author: Italo Nicola <[email protected]>
Date:   Wed Feb  1 21:59:38 2023 +0000

gallium/st: add support for PIPE_FORMAT_NV21 and PIPE_FORMAT_G8_B8R8_420

Signed-off-by: Italo Nicola <[email protected]>
Reviewed-by: Daniel Stone <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21219>

---

 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 c9736244cac..1d6b90b312c 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 10fe4777b86..1983b0bdea1 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 bfbe8113873..c30a02624c5 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 bedd223d84f..5725e1cd7ec 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 9ab69f13d4d..e74c5ef6353 100644
--- a/src/mesa/state_tracker/st_atom_texture.c
+++ b/src/mesa/state_tracker/st_atom_texture.c
@@ -179,6 +179,18 @@ st_get_sampler_views(struct st_context *st,
             /* 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_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 */
diff --git a/src/mesa/state_tracker/st_cb_eglimage.c 
b/src/mesa/state_tracker/st_cb_eglimage.c
index b23269979ff..2a3a59bca7d 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 b6962ed1e4f..e1c32a4fa8a 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 c86cafc0cc9..44c1ccb7e4c 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 3e8e0afe6ed..d39341a86af 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;

Reply via email to