gallium/st: add non-CSC lowering of YV12 as PIPE_FORMAT_R8_B8_G8_420
authorItalo Nicola <italonicola@collabora.com>
Fri, 21 Jul 2023 00:31:48 +0000 (00:31 +0000)
committerMarge Bot <emma+marge@anholt.net>
Fri, 11 Aug 2023 18:43:38 +0000 (18:43 +0000)
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 <italonicola@collabora.com>
Reviewed-by: Daniel Stone <daniels@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24266>

src/gallium/frontends/dri/dri2.c
src/mesa/state_tracker/st_atom_sampler.c
src/mesa/state_tracker/st_atom_texture.c
src/mesa/state_tracker/st_cb_eglimage.c
src/mesa/state_tracker/st_program.h
src/mesa/state_tracker/st_sampler_view.c
src/util/format/u_format.csv
src/util/format/u_format_table.py
src/util/format/u_formats.h

index 2d7f3b3..8b7e929 100644 (file)
@@ -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
index 4157a10..c34d275 100644 (file)
@@ -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;
          }
index ed3e0d8..a923f05 100644 (file)
@@ -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;
 
index 6156d00..41ce901 100644 (file)
@@ -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 {
index 7a826f8..7028083 100644 (file)
@@ -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;
          }
index 753b677..7359009 100644 (file)
@@ -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;
index 93517ce..c82eeac 100644 (file)
@@ -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
 
index 8427760..1cd66a9 100644 (file)
@@ -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',
index 45af123..f705d12 100644 (file)
@@ -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,