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

Author: Italo Nicola <[email protected]>
Date:   Thu Feb  9 13:14:29 2023 +0000

mesa/main: add PIPE_FORMAT_VYUY and PIPE_FORMAT_B8R8_G8R8

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/gallivm/lp_bld_format_yuv.c |  23 +++
 src/gallium/frontends/dri/dri2.c                  |  16 ++
 src/gallium/frontends/dri/dri_helpers.c           |   4 +
 src/mesa/main/format_info.py                      |   2 +-
 src/mesa/main/formats.c                           |   1 +
 src/mesa/main/formats.csv                         |   1 +
 src/mesa/main/formats.h                           |   1 +
 src/mesa/state_tracker/st_atom_sampler.c          |   2 +
 src/mesa/state_tracker/st_atom_texture.c          |   4 +-
 src/mesa/state_tracker/st_cb_eglimage.c           |  15 ++
 src/mesa/state_tracker/st_program.c               |  13 +-
 src/mesa/state_tracker/st_program.h               |   8 +
 src/mesa/state_tracker/st_sampler_view.c          |   2 +
 src/util/format/u_format.c                        |   1 +
 src/util/format/u_format.csv                      |   2 +
 src/util/format/u_format_table.py                 |   1 +
 src/util/format/u_format_tests.c                  |   4 +
 src/util/format/u_format_yuv.c                    | 215 ++++++++++++++++++++++
 src/util/format/u_format_yuv.h                    |  24 +++
 src/util/format/u_formats.h                       |   3 +
 20 files changed, 334 insertions(+), 8 deletions(-)

diff --git a/src/gallium/auxiliary/gallivm/lp_bld_format_yuv.c 
b/src/gallium/auxiliary/gallivm/lp_bld_format_yuv.c
index 8aec9cbabc4..c7138eb2872 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_format_yuv.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_format_yuv.c
@@ -377,6 +377,26 @@ uyvy_to_rgba_aos(struct gallivm_state *gallivm,
    return rgba;
 }
 
+/**
+ * Convert from <n x i32> packed VYUY to <4n x i8> RGBA AoS
+ */
+static LLVMValueRef
+vyuy_to_rgba_aos(struct gallivm_state *gallivm,
+                 unsigned n,
+                 LLVMValueRef packed,
+                 LLVMValueRef i)
+{
+   LLVMValueRef y, u, v;
+   LLVMValueRef r, g, b;
+   LLVMValueRef rgba;
+
+   /* VYUY is UYVY with U/V swapped */
+   uyvy_to_yuv_soa(gallivm, n, packed, i, &y, &v, &u);
+   yuv_to_rgb_soa(gallivm, n, y, u, v, &r, &g, &b);
+   rgba = rgb_to_rgba_aos(gallivm, n, r, g, b);
+
+   return rgba;
+}
 
 /**
  * Convert from <n x i32> packed YUYV to <4n x i8> RGBA AoS
@@ -526,6 +546,9 @@ lp_build_fetch_subsampled_rgba_aos(struct gallivm_state 
*gallivm,
    case PIPE_FORMAT_UYVY:
       rgba = uyvy_to_rgba_aos(gallivm, n, packed, i);
       break;
+   case PIPE_FORMAT_VYUY:
+      rgba = vyuy_to_rgba_aos(gallivm, n, packed, i);
+      break;
    case PIPE_FORMAT_YUYV:
       rgba = yuyv_to_rgba_aos(gallivm, n, packed, i);
       break;
diff --git a/src/gallium/frontends/dri/dri2.c b/src/gallium/frontends/dri/dri2.c
index e2688976f9b..52b6e5c9993 100644
--- a/src/gallium/frontends/dri/dri2.c
+++ b/src/gallium/frontends/dri/dri2.c
@@ -887,6 +887,15 @@ static const struct dri2_format_mapping r8b8_r8g8_mapping 
= {
      { 0, 1, 0, __DRI_IMAGE_FORMAT_ARGB8888 } }
 };
 
+static const struct dri2_format_mapping b8r8_g8r8_mapping = {
+   DRM_FORMAT_VYUY,
+   __DRI_IMAGE_FORMAT_NONE,
+   __DRI_IMAGE_COMPONENTS_Y_XUXV,
+   PIPE_FORMAT_B8R8_G8R8_UNORM, 2,
+   { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88 },
+     { 0, 1, 0, __DRI_IMAGE_FORMAT_ABGR8888 } }
+};
+
 static const struct dri2_format_mapping g8r8_b8r8_mapping = {
    DRM_FORMAT_UYVY,
    __DRI_IMAGE_FORMAT_NONE,
@@ -959,6 +968,13 @@ dri2_create_image_from_winsys(__DRIscreen *_screen,
       tex_usage |= PIPE_BIND_SAMPLER_VIEW;
    }
 
+   if (!tex_usage && map->pipe_format == PIPE_FORMAT_VYUY &&
+       pscreen->is_format_supported(pscreen, PIPE_FORMAT_B8R8_G8R8_UNORM,
+                                    screen->target, 0, 0, 
PIPE_BIND_SAMPLER_VIEW)) {
+      map = &b8r8_g8r8_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/gallium/frontends/dri/dri_helpers.c 
b/src/gallium/frontends/dri/dri_helpers.c
index 8ac95873055..b4cd05500c0 100644
--- a/src/gallium/frontends/dri/dri_helpers.c
+++ b/src/gallium/frontends/dri/dri_helpers.c
@@ -647,6 +647,10 @@ static const struct dri2_format_mapping 
dri2_format_table[] = {
         __DRI_IMAGE_COMPONENTS_Y_UXVX,    PIPE_FORMAT_UYVY, 2,
         { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88 },
           { 0, 1, 0, __DRI_IMAGE_FORMAT_ABGR8888 } } },
+      { DRM_FORMAT_VYUY,          __DRI_IMAGE_FORMAT_NONE,
+        __DRI_IMAGE_COMPONENTS_Y_UXVX,    PIPE_FORMAT_VYUY, 2,
+        { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88 },
+          { 0, 1, 0, __DRI_IMAGE_FORMAT_ABGR8888 } } },
 
       /* The Y21x formats work in a similar fashion to the YUYV and UYVY
        * formats.
diff --git a/src/mesa/main/format_info.py b/src/mesa/main/format_info.py
index 7df0b118991..c88b905f72b 100644
--- a/src/mesa/main/format_info.py
+++ b/src/mesa/main/format_info.py
@@ -126,7 +126,7 @@ def get_channel_bits(fmat, chan_name):
          return bits if fmat.has_channel(chan_name) else 0
       elif fmat.layout == 'atc':
          return 8 if fmat.has_channel(chan_name) else 0
-      elif fmat.layout == 'other' and any(s in fmat.name for s in {'RG_RB', 
'GR_BR', 'RB_RG'}):
+      elif fmat.layout == 'other' and any(s in fmat.name for s in {'RG_RB', 
'GR_BR', 'RB_RG', 'BR_GR'}):
          return 8 if fmat.has_channel(chan_name) else 0
       else:
          assert False
diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c
index e71d7d2bb4a..de9e7da037e 100644
--- a/src/mesa/main/formats.c
+++ b/src/mesa/main/formats.c
@@ -1022,6 +1022,7 @@ _mesa_uncompressed_format_to_type_and_comps(mesa_format 
format,
    case MESA_FORMAT_RG_RB_UNORM8:
    case MESA_FORMAT_RB_RG_UNORM8:
    case MESA_FORMAT_GR_BR_UNORM8:
+   case MESA_FORMAT_BR_GR_UNORM8:
       *datatype = GL_UNSIGNED_SHORT;
       *comps = 2;
       return;
diff --git a/src/mesa/main/formats.csv b/src/mesa/main/formats.csv
index 70c041cd042..1b9ee62f8a7 100644
--- a/src/mesa/main/formats.csv
+++ b/src/mesa/main/formats.csv
@@ -96,6 +96,7 @@ MESA_FORMAT_YCBCR_REV                     , other , 1, 1, 1, 
x16 ,     ,     ,
 MESA_FORMAT_RG_RB_UNORM8                  , other , 2, 1, 1, x16 ,     ,     , 
    , xyz1, rgb
 MESA_FORMAT_RB_RG_UNORM8                  , other , 2, 1, 1, x16 ,     ,     , 
    , xyz1, rgb
 MESA_FORMAT_GR_BR_UNORM8                  , other , 2, 1, 1, x16 ,     ,     , 
    , xyz1, rgb
+MESA_FORMAT_BR_GR_UNORM8                  , other , 2, 1, 1, x16 ,     ,     , 
    , xyz1, rgb
 
 # Array normalized formats
 MESA_FORMAT_A_UNORM8                      , array , 1, 1, 1, un8 ,     ,     , 
    , 000x, rgb
diff --git a/src/mesa/main/formats.h b/src/mesa/main/formats.h
index c55068b5c16..8fce8f6930f 100644
--- a/src/mesa/main/formats.h
+++ b/src/mesa/main/formats.h
@@ -389,6 +389,7 @@ typedef enum pipe_format mesa_format;
 #define MESA_FORMAT_RG_RB_UNORM8                 PIPE_FORMAT_R8G8_R8B8_UNORM
 #define MESA_FORMAT_RB_RG_UNORM8                 PIPE_FORMAT_R8B8_R8G8_UNORM
 #define MESA_FORMAT_GR_BR_UNORM8                 PIPE_FORMAT_G8R8_B8R8_UNORM
+#define MESA_FORMAT_BR_GR_UNORM8                 PIPE_FORMAT_B8R8_G8R8_UNORM
 #define MESA_FORMAT_A_UNORM8                     PIPE_FORMAT_A8_UNORM
 #define MESA_FORMAT_A_UNORM16                    PIPE_FORMAT_A16_UNORM
 #define MESA_FORMAT_L_UNORM8                     PIPE_FORMAT_L8_UNORM
diff --git a/src/mesa/state_tracker/st_atom_sampler.c 
b/src/mesa/state_tracker/st_atom_sampler.c
index 87e7d26869b..9f04aac98ee 100644
--- a/src/mesa/state_tracker/st_atom_sampler.c
+++ b/src/mesa/state_tracker/st_atom_sampler.c
@@ -284,8 +284,10 @@ update_shader_samplers(struct st_context *st,
       case PIPE_FORMAT_YUYV:
       case PIPE_FORMAT_YVYU:
       case PIPE_FORMAT_UYVY:
+      case PIPE_FORMAT_VYUY:
          if (stObj->pt->format == PIPE_FORMAT_R8G8_R8B8_UNORM ||
              stObj->pt->format == PIPE_FORMAT_R8B8_R8G8_UNORM ||
+             stObj->pt->format == PIPE_FORMAT_B8R8_G8R8_UNORM ||
              stObj->pt->format == PIPE_FORMAT_G8R8_B8R8_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 62858a471e2..f816dbdaa40 100644
--- a/src/mesa/state_tracker/st_atom_texture.c
+++ b/src/mesa/state_tracker/st_atom_texture.c
@@ -235,7 +235,9 @@ st_get_sampler_views(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)
+      case PIPE_FORMAT_VYUY:
+         if (stObj->pt->format == PIPE_FORMAT_G8R8_B8R8_UNORM ||
+             stObj->pt->format == PIPE_FORMAT_B8R8_G8R8_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 a132f8a3e82..4b0a639c48a 100644
--- a/src/mesa/state_tracker/st_cb_eglimage.c
+++ b/src/mesa/state_tracker/st_cb_eglimage.c
@@ -136,6 +136,17 @@ is_format_supported(struct pipe_screen *screen, enum 
pipe_format format,
                                                   PIPE_TEXTURE_2D, nr_samples,
                                                   nr_storage_samples, usage));
          break;
+      case PIPE_FORMAT_VYUY:
+         supported = screen->is_format_supported(screen, 
PIPE_FORMAT_B8R8_G8R8_UNORM,
+                                                 PIPE_TEXTURE_2D, nr_samples,
+                                                 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,
                                                  PIPE_TEXTURE_2D, nr_samples,
@@ -367,6 +378,7 @@ st_bind_egl_image(struct gl_context *ctx,
       case PIPE_FORMAT_YUYV:
       case PIPE_FORMAT_YVYU:
       case PIPE_FORMAT_UYVY:
+      case PIPE_FORMAT_VYUY:
          if (stimg->texture->format == PIPE_FORMAT_R8G8_R8B8_UNORM) {
             texFormat = MESA_FORMAT_RG_RB_UNORM8;
             texObj->RequiredTextureImageUnits = 1;
@@ -376,6 +388,9 @@ st_bind_egl_image(struct gl_context *ctx,
          } else if (stimg->texture->format == PIPE_FORMAT_G8R8_B8R8_UNORM) {
             texFormat = MESA_FORMAT_GR_BR_UNORM8;
             texObj->RequiredTextureImageUnits = 1;
+         } else if (stimg->texture->format == PIPE_FORMAT_B8R8_G8R8_UNORM) {
+            texFormat = MESA_FORMAT_BR_GR_UNORM8;
+            texObj->RequiredTextureImageUnits = 1;
          } else {
             texFormat = MESA_FORMAT_RG_UNORM8;
             texObj->RequiredTextureImageUnits = 2;
diff --git a/src/mesa/state_tracker/st_program.c 
b/src/mesa/state_tracker/st_program.c
index ee78aa656a4..f31236104fe 100644
--- a/src/mesa/state_tracker/st_program.c
+++ b/src/mesa/state_tracker/st_program.c
@@ -1002,10 +1002,10 @@ st_create_fp_variant(struct st_context *st,
    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_yx_xvxu || key->external.lower_ayuv ||
-                  key->external.lower_xyuv || key->external.lower_yuv ||
-                  key->external.lower_yu_yv || key->external.lower_yv_yu ||
-                  key->external.lower_y41x)) {
+                  key->external.lower_yx_xvxu || key->external.lower_xy_vxux ||
+                  key->external.lower_ayuv || key->external.lower_xyuv ||
+                  key->external.lower_yuv || key->external.lower_yu_yv ||
+                  key->external.lower_yv_yu || key->external.lower_y41x)) {
 
       st_nir_lower_samplers(st->screen, state.ir.nir,
                               fp->shader_program, fp);
@@ -1015,6 +1015,7 @@ st_create_fp_variant(struct st_context *st,
       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_xy_vxux_external = key->external.lower_xy_vxux;
       options.lower_yx_xuxv_external = key->external.lower_yx_xuxv;
       options.lower_yx_xvxu_external = key->external.lower_yx_xvxu;
       options.lower_ayuv_external = key->external.lower_ayuv;
@@ -1042,8 +1043,8 @@ st_create_fp_variant(struct st_context *st,
       NIR_PASS_V(state.ir.nir, st_nir_lower_tex_src_plane,
                   ~fp->SamplersUsed,
                   key->external.lower_nv12 | key->external.lower_nv21 |
-                     key->external.lower_xy_uxvx | key->external.lower_yx_xuxv 
|
-                     key->external.lower_yx_xvxu,
+                     key->external.lower_xy_uxvx | key->external.lower_xy_vxux 
|
+                     key->external.lower_yx_xuxv | key->external.lower_yx_xvxu,
                   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 61af1d3fd7c..ea35fe5c87a 100644
--- a/src/mesa/state_tracker/st_program.h
+++ b/src/mesa/state_tracker/st_program.h
@@ -51,6 +51,7 @@ struct st_external_sampler_key
    GLuint lower_nv21;
    GLuint lower_iyuv;             /**< bitmask of 3 plane YUV samplers */
    GLuint lower_xy_uxvx;          /**< bitmask of 2 plane YUV samplers */
+   GLuint lower_xy_vxux;          /**< bitmask of 2 plane YUV samplers */
    GLuint lower_yx_xuxv;          /**< bitmask of 2 plane YUV samplers */
    GLuint lower_yx_xvxu;          /**< bitmask of 2 plane YUV samplers */
    GLuint lower_ayuv;
@@ -123,6 +124,13 @@ st_get_external_sampler_key(struct st_context *st, struct 
gl_program *prog)
          }
          key.lower_xy_uxvx |= (1 << unit);
          break;
+      case PIPE_FORMAT_VYUY:
+         if (stObj->pt->format == PIPE_FORMAT_B8R8_G8R8_UNORM) {
+            key.lower_yv_yu |= (1 << unit);
+            break;
+         }
+         key.lower_xy_vxux |= (1 << unit);
+         break;
       case PIPE_FORMAT_YVYU:
          if (stObj->pt->format == PIPE_FORMAT_R8B8_R8G8_UNORM) {
             key.lower_yv_yu |= (1 << unit);
diff --git a/src/mesa/state_tracker/st_sampler_view.c 
b/src/mesa/state_tracker/st_sampler_view.c
index 9f66112c777..59df3922c78 100644
--- a/src/mesa/state_tracker/st_sampler_view.c
+++ b/src/mesa/state_tracker/st_sampler_view.c
@@ -416,8 +416,10 @@ st_get_sampler_view_format(const struct st_context *st,
    case PIPE_FORMAT_YUYV:
    case PIPE_FORMAT_YVYU:
    case PIPE_FORMAT_UYVY:
+   case PIPE_FORMAT_VYUY:
       if (texObj->pt->format == PIPE_FORMAT_R8G8_R8B8_UNORM ||
           texObj->pt->format == PIPE_FORMAT_R8B8_R8G8_UNORM ||
+          texObj->pt->format == PIPE_FORMAT_B8R8_G8R8_UNORM ||
           texObj->pt->format == PIPE_FORMAT_G8R8_B8R8_UNORM) {
          format = texObj->pt->format;
          break;
diff --git a/src/util/format/u_format.c b/src/util/format/u_format.c
index c34b023c16b..17e58b82e52 100644
--- a/src/util/format/u_format.c
+++ b/src/util/format/u_format.c
@@ -631,6 +631,7 @@ util_format_fits_8unorm(const struct 
util_format_description *format_desc)
       switch (format_desc->format) {
       case PIPE_FORMAT_R1_UNORM:
       case PIPE_FORMAT_UYVY:
+      case PIPE_FORMAT_VYUY:
       case PIPE_FORMAT_YUYV:
       case PIPE_FORMAT_YVYU:
       case PIPE_FORMAT_R8G8_B8G8_UNORM:
diff --git a/src/util/format/u_format.csv b/src/util/format/u_format.csv
index e0668cdb1c9..cbb39ba16a2 100644
--- a/src/util/format/u_format.csv
+++ b/src/util/format/u_format.csv
@@ -177,6 +177,7 @@ PIPE_FORMAT_Z24_UNORM_S8_UINT_AS_R8G8B8A8 , plain, 1, 1, 1, 
un8 , un8 , un8 , un
 # YUV formats
 # http://www.fourcc.org/yuv.php#UYVY
 PIPE_FORMAT_UYVY                     , subsampled, 2, 1, 1, un8 , un8 , un8 , 
un8 , xyz1, yuv
+PIPE_FORMAT_VYUY                     , subsampled, 2, 1, 1, un8 , un8 , un8 , 
un8 , xyz1, yuv
 # http://www.fourcc.org/yuv.php#YUYV (a.k.a http://www.fourcc.org/yuv.php#YUY2)
 PIPE_FORMAT_YUYV                     , subsampled, 2, 1, 1, un8 , un8 , un8 , 
un8 , xyz1, yuv
 PIPE_FORMAT_YVYU                     , subsampled, 2, 1, 1, un8 , un8 , un8 , 
un8 , xyz1, yuv
@@ -189,6 +190,7 @@ PIPE_FORMAT_R8G8_B8G8_UNORM         , subsampled, 2, 1, 1, 
x32 ,     ,     ,
 PIPE_FORMAT_G8R8_G8B8_UNORM         , subsampled, 2, 1, 1, x32 ,     ,     ,   
  , xyz1, rgb
 PIPE_FORMAT_G8R8_B8R8_UNORM         , subsampled, 2, 1, 1, x32 ,     ,     ,   
  , zyx1, rgb
 PIPE_FORMAT_R8G8_R8B8_UNORM         , subsampled, 2, 1, 1, x32 ,     ,     ,   
  , zyx1, rgb
+PIPE_FORMAT_B8R8_G8R8_UNORM         , subsampled, 2, 1, 1, x32 ,     ,     ,   
  , yxz1, rgb
 PIPE_FORMAT_R8B8_R8G8_UNORM         , subsampled, 2, 1, 1, x32 ,     ,     ,   
  , yxz1, rgb
 
 # some special formats not fitting anywhere else
diff --git a/src/util/format/u_format_table.py 
b/src/util/format/u_format_table.py
index b14b01c72b5..84d0e21ee95 100644
--- a/src/util/format/u_format_table.py
+++ b/src/util/format/u_format_table.py
@@ -102,6 +102,7 @@ def has_access(format):
         'r8g8_r8b8_unorm',
         'r8b8_r8g8_unorm',
         'g8r8_b8r8_unorm',
+        'b8r8_g8r8_unorm',
         'g8r8_g8b8_unorm',
         'y8_400_unorm',
         'y8_u8_v8_422_unorm',
diff --git a/src/util/format/u_format_tests.c b/src/util/format/u_format_tests.c
index 7a01151762e..e7ae86589d0 100644
--- a/src/util/format/u_format_tests.c
+++ b/src/util/format/u_format_tests.c
@@ -447,6 +447,10 @@ util_format_test_cases[] =
    {PIPE_FORMAT_YVYU, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0xeb, 
0x80, 0x10, 0x80), UNPACKED_2x1(1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0)},
    {PIPE_FORMAT_YVYU, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x10, 
0x80, 0xeb, 0x80), UNPACKED_2x1(0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0)},
 
+   {PIPE_FORMAT_VYUY, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x80, 
0x10, 0x80, 0x10), UNPACKED_2x1(0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0)},
+   {PIPE_FORMAT_VYUY, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x80, 
0xeb, 0x80, 0x10), UNPACKED_2x1(1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0)},
+   {PIPE_FORMAT_VYUY, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x80, 
0x10, 0x80, 0xeb), UNPACKED_2x1(0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0)},
+
    /*
     * Compressed formats
     */
diff --git a/src/util/format/u_format_yuv.c b/src/util/format/u_format_yuv.c
index cbccbc83eb1..b86c8b72372 100644
--- a/src/util/format/u_format_yuv.c
+++ b/src/util/format/u_format_yuv.c
@@ -529,6 +529,52 @@ util_format_uyvy_unpack_rgba_float(void *restrict dst_row, 
unsigned dst_stride,
    }
 }
 
+void
+util_format_vyuy_unpack_rgba_float(void *restrict dst_row, unsigned dst_stride,
+                              const uint8_t *restrict src_row, unsigned 
src_stride,
+                              unsigned width, unsigned height)
+{
+   unsigned x, y;
+
+   for (y = 0; y < height; y += 1) {
+      float *dst = dst_row;
+      const uint32_t *src = (const uint32_t *)src_row;
+      uint32_t value;
+      uint8_t y0, y1, u, v;
+
+      for (x = 0; x + 1 < width; x += 2) {
+         value = util_cpu_to_le32(*src++);
+
+         v  = (value >>  0) & 0xff;
+         y0 = (value >>  8) & 0xff;
+         u  = (value >> 16) & 0xff;
+         y1 = (value >> 24) & 0xff;
+
+         util_format_yuv_to_rgb_float(y0, u, v, &dst[0], &dst[1], &dst[2]);
+         dst[3] = 1.0f; /* a */
+         dst += 4;
+
+         util_format_yuv_to_rgb_float(y1, u, v, &dst[0], &dst[1], &dst[2]);
+         dst[3] = 1.0f; /* a */
+         dst += 4;
+      }
+
+      if (x < width) {
+         value = util_cpu_to_le32(*src);
+
+         v  = (value >>  0) & 0xff;
+         y0 = (value >>  8) & 0xff;
+         u  = (value >> 16) & 0xff;
+         y1 = (value >> 24) & 0xff;
+
+         util_format_yuv_to_rgb_float(y0, u, v, &dst[0], &dst[1], &dst[2]);
+         dst[3] = 1.0f; /* a */
+      }
+
+      src_row = (uint8_t *)src_row + src_stride;
+      dst_row = (uint8_t *)dst_row + dst_stride;
+   }
+}
 
 void
 util_format_uyvy_unpack_rgba_8unorm(uint8_t *restrict dst_row, unsigned 
dst_stride,
@@ -577,6 +623,52 @@ util_format_uyvy_unpack_rgba_8unorm(uint8_t *restrict 
dst_row, unsigned dst_stri
    }
 }
 
+void
+util_format_vyuy_unpack_rgba_8unorm(uint8_t *restrict dst_row, unsigned 
dst_stride,
+                               const uint8_t *restrict src_row, unsigned 
src_stride,
+                               unsigned width, unsigned height)
+{
+   unsigned x, y;
+
+   for (y = 0; y < height; y += 1) {
+      uint8_t *dst = dst_row;
+      const uint32_t *src = (const uint32_t *)src_row;
+      uint32_t value;
+      uint8_t y0, y1, u, v;
+
+      for (x = 0; x + 1 < width; x += 2) {
+         value = util_cpu_to_le32(*src++);
+
+         v  = (value >>  0) & 0xff;
+         y0 = (value >>  8) & 0xff;
+         u  = (value >> 16) & 0xff;
+         y1 = (value >> 24) & 0xff;
+
+         util_format_yuv_to_rgb_8unorm(y0, u, v, &dst[0], &dst[1], &dst[2]);
+         dst[3] = 0xff; /* a */
+         dst += 4;
+
+         util_format_yuv_to_rgb_8unorm(y1, u, v, &dst[0], &dst[1], &dst[2]);
+         dst[3] = 0xff; /* a */
+         dst += 4;
+      }
+
+      if (x < width) {
+         value = util_cpu_to_le32(*src);
+
+         v  = (value >>  0) & 0xff;
+         y0 = (value >>  8) & 0xff;
+         u  = (value >> 16) & 0xff;
+         y1 = (value >> 24) & 0xff;
+
+         util_format_yuv_to_rgb_8unorm(y0, u, v, &dst[0], &dst[1], &dst[2]);
+         dst[3] = 0xff; /* a */
+      }
+
+      src_row += src_stride/sizeof(*src_row);
+      dst_row += dst_stride/sizeof(*dst_row);
+   }
+}
 
 void
 util_format_uyvy_pack_rgba_float(uint8_t *restrict dst_row, unsigned 
dst_stride,
@@ -630,6 +722,58 @@ util_format_uyvy_pack_rgba_float(uint8_t *restrict 
dst_row, unsigned dst_stride,
    }
 }
 
+void
+util_format_vyuy_pack_rgba_float(uint8_t *restrict dst_row, unsigned 
dst_stride,
+                            const float *restrict src_row, unsigned src_stride,
+                            unsigned width, unsigned height)
+{
+   unsigned x, y;
+
+   for (y = 0; y < height; y += 1) {
+      const float *src = src_row;
+      uint32_t *dst = (uint32_t *)dst_row;
+      uint8_t y0, y1, u, v;
+      uint32_t value;
+
+      for (x = 0; x + 1 < width; x += 2) {
+         uint8_t y0, y1, u0, u1, v0, v1, u, v;
+
+         util_format_rgb_float_to_yuv(src[0], src[1], src[2],
+                                      &y0, &u0, &v0);
+         util_format_rgb_float_to_yuv(src[4], src[5], src[6],
+                                      &y1, &u1, &v1);
+
+         u = (u0 + u1 + 1) >> 1;
+         v = (v0 + v1 + 1) >> 1;
+
+         value  = v;
+         value |= (uint32_t)y0 <<  8;
+         value |= (uint32_t)u  << 16;
+         value |= (uint32_t)y1 << 24;
+
+         *dst++ = util_le32_to_cpu(value);
+
+         src += 8;
+      }
+
+      if (x < width) {
+         util_format_rgb_float_to_yuv(src[0], src[1], src[2],
+                                      &y0, &u, &v);
+         y1 = 0;
+
+         value  = v;
+         value |= (uint32_t)y0 <<  8;
+         value |= (uint32_t)u  << 16;
+         value |= (uint32_t)y1 << 24;
+
+         *dst = util_le32_to_cpu(value);
+      }
+
+      dst_row += dst_stride/sizeof(*dst_row);
+      src_row += src_stride/sizeof(*src_row);
+   }
+}
+
 
 void
 util_format_uyvy_pack_rgba_8unorm(uint8_t *restrict dst_row, unsigned 
dst_stride,
@@ -683,6 +827,57 @@ util_format_uyvy_pack_rgba_8unorm(uint8_t *restrict 
dst_row, unsigned dst_stride
    }
 }
 
+void
+util_format_vyuy_pack_rgba_8unorm(uint8_t *restrict dst_row, unsigned 
dst_stride,
+                             const uint8_t *restrict src_row, unsigned 
src_stride,
+                             unsigned width, unsigned height)
+{
+   unsigned x, y;
+
+   for (y = 0; y < height; y += 1) {
+      const uint8_t *src = src_row;
+      uint32_t *dst = (uint32_t *)dst_row;
+      uint8_t y0, y1, u, v;
+      uint32_t value;
+
+      for (x = 0; x + 1 < width; x += 2) {
+         uint8_t y0, y1, u0, u1, v0, v1, u, v;
+
+         util_format_rgb_8unorm_to_yuv(src[0], src[1], src[2],
+                                       &y0, &u0, &v0);
+         util_format_rgb_8unorm_to_yuv(src[4], src[5], src[6],
+                                       &y1, &u1, &v1);
+
+         u = (u0 + u1 + 1) >> 1;
+         v = (v0 + v1 + 1) >> 1;
+
+         value  = v;
+         value |= (uint32_t)y0 <<  8;
+         value |= (uint32_t)u  << 16;
+         value |= (uint32_t)y1 << 24;
+
+         *dst++ = util_le32_to_cpu(value);
+
+         src += 8;
+      }
+
+      if (x < width) {
+         util_format_rgb_8unorm_to_yuv(src[0], src[1], src[2],
+                                       &y0, &u, &v);
+         y1 = 0;
+
+         value  = v;
+         value |= (uint32_t)y0 <<  8;
+         value |= (uint32_t)u  << 16;
+         value |= (uint32_t)y1 << 24;
+
+         *dst = util_le32_to_cpu(value);
+      }
+
+      dst_row += dst_stride/sizeof(*dst_row);
+      src_row += src_stride/sizeof(*src_row);
+   }
+}
 
 void
 util_format_uyvy_fetch_rgba(void *restrict in_dst, const uint8_t *restrict src,
@@ -704,6 +899,26 @@ util_format_uyvy_fetch_rgba(void *restrict in_dst, const 
uint8_t *restrict src,
 }
 
 
+void
+util_format_vyuy_fetch_rgba(void *restrict in_dst, const uint8_t *restrict src,
+                             unsigned i, ASSERTED unsigned j)
+{
+   float *dst = in_dst;
+   uint8_t y, u, v;
+
+   assert(i < 2);
+   assert(j < 1);
+
+   y = src[1 + i*2];
+   v = src[0];
+   u = src[2];
+
+   util_format_yuv_to_rgb_float(y, u, v, &dst[0], &dst[1], &dst[2]);
+
+   dst[3] = 1.0f;
+}
+
+
 void
 util_format_yuyv_unpack_rgba_float(void *restrict dst_row, unsigned dst_stride,
                               const uint8_t *restrict src_row, unsigned 
src_stride,
diff --git a/src/util/format/u_format_yuv.h b/src/util/format/u_format_yuv.h
index 293df1be063..c0d5c9301cd 100644
--- a/src/util/format/u_format_yuv.h
+++ b/src/util/format/u_format_yuv.h
@@ -146,6 +146,30 @@ void
 util_format_uyvy_fetch_rgba(void *restrict dst, const uint8_t *restrict src,
                              unsigned i, unsigned j);
 
+void
+util_format_vyuy_unpack_rgba_float(void *restrict dst_row, unsigned dst_stride,
+                              const uint8_t *restrict src_row, unsigned 
src_stride,
+                              unsigned width, unsigned height);
+
+void
+util_format_vyuy_unpack_rgba_8unorm(uint8_t *restrict dst_row, unsigned 
dst_stride,
+                               const uint8_t *restrict src_row, unsigned 
src_stride,
+                               unsigned width, unsigned height);
+
+void
+util_format_vyuy_pack_rgba_float(uint8_t *restrict dst_row, unsigned 
dst_stride,
+                            const float *restrict src_row, unsigned src_stride,
+                            unsigned width, unsigned height);
+
+void
+util_format_vyuy_pack_rgba_8unorm(uint8_t *restrict dst_row, unsigned 
dst_stride,
+                             const uint8_t *restrict src_row, unsigned 
src_stride,
+                             unsigned width, unsigned height);
+
+void
+util_format_vyuy_fetch_rgba(void *restrict dst, const uint8_t *restrict src,
+                             unsigned i, unsigned j);
+
 void
 util_format_yuyv_unpack_rgba_float(void *restrict dst_row, unsigned dst_stride,
                               const uint8_t *restrict src_row, unsigned 
src_stride,
diff --git a/src/util/format/u_formats.h b/src/util/format/u_formats.h
index 32ea6bc3d7e..35ad0b8477b 100644
--- a/src/util/format/u_formats.h
+++ b/src/util/format/u_formats.h
@@ -188,6 +188,7 @@ enum pipe_format {
    PIPE_FORMAT_L8A8_UNORM,  /**< ubyte alpha, luminance */
    PIPE_FORMAT_L16_UNORM,   /**< ushort luminance */
    PIPE_FORMAT_UYVY,
+   PIPE_FORMAT_VYUY,
    PIPE_FORMAT_YUYV,
    PIPE_FORMAT_YVYU,
    PIPE_FORMAT_Z16_UNORM,
@@ -366,6 +367,7 @@ enum pipe_format {
    PIPE_FORMAT_R8G8_R8B8_UNORM,
    PIPE_FORMAT_R8B8_R8G8_UNORM,
    PIPE_FORMAT_G8R8_B8R8_UNORM,
+   PIPE_FORMAT_B8R8_G8R8_UNORM,
 
    PIPE_FORMAT_R8G8B8X8_SNORM,
    PIPE_FORMAT_R8G8B8X8_SRGB,
@@ -631,6 +633,7 @@ pipe_format_to_chroma_format(enum pipe_format format)
       case PIPE_FORMAT_Y16_U16_V16_420_UNORM:
          return PIPE_VIDEO_CHROMA_FORMAT_420;
       case PIPE_FORMAT_UYVY:
+      case PIPE_FORMAT_VYUY:
       case PIPE_FORMAT_YUYV:
       case PIPE_FORMAT_YVYU:
       case PIPE_FORMAT_YV16:

Reply via email to