nir: add options to lower y_vu, yv_yu, yx_xvxu and xy_vxux
authorItalo Nicola <italonicola@collabora.com>
Thu, 9 Feb 2023 12:39:33 +0000 (12:39 +0000)
committerMarge Bot <emma+marge@anholt.net>
Mon, 10 Jul 2023 16:29:13 +0000 (16:29 +0000)
`y_vu` will be used to convert NV21 to RGB.
`yv_yu` will be used to convert YVYU and VYUY to RGB when the
subsampling formats PIPE_FORMAT_R8B8_R8G8 and PIPE_FORMAT_B8R8_G8R8
are supported.
`yx_xvxu` and `xy_vxux` will be used to convert YVYU and VYUY to RGB
when those subsampling formats are not supported.

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/21219>

src/compiler/nir/nir.h
src/compiler/nir/nir_lower_tex.c

index 48b414c..aa86d2f 100644 (file)
@@ -5504,13 +5504,17 @@ typedef struct nir_lower_tex_options {
     * If true, convert yuv to rgb.
     */
    unsigned lower_y_uv_external;
+   unsigned lower_y_vu_external;
    unsigned lower_y_u_v_external;
    unsigned lower_yx_xuxv_external;
+   unsigned lower_yx_xvxu_external;
    unsigned lower_xy_uxvx_external;
+   unsigned lower_xy_vxux_external;
    unsigned lower_ayuv_external;
    unsigned lower_xyuv_external;
    unsigned lower_yuv_external;
    unsigned lower_yu_yv_external;
+   unsigned lower_yv_yu_external;
    unsigned lower_y41x_external;
    unsigned bt709_external;
    unsigned bt2020_external;
index 2df08d2..0b24271 100644 (file)
@@ -405,6 +405,25 @@ lower_y_uv_external(nir_builder *b, nir_tex_instr *tex,
 }
 
 static void
+lower_y_vu_external(nir_builder *b, nir_tex_instr *tex,
+                    const nir_lower_tex_options *options,
+                    unsigned texture_index)
+{
+   b->cursor = nir_after_instr(&tex->instr);
+
+   nir_ssa_def *y = sample_plane(b, tex, 0, options);
+   nir_ssa_def *vu = sample_plane(b, tex, 1, options);
+
+   convert_yuv_to_rgb(b, tex,
+                      nir_channel(b, y, 0),
+                      nir_channel(b, vu, 1),
+                      nir_channel(b, vu, 0),
+                      nir_imm_float(b, 1.0f),
+                      options,
+                      texture_index);
+}
+
+static void
 lower_y_u_v_external(nir_builder *b, nir_tex_instr *tex,
                      const nir_lower_tex_options *options,
                      unsigned texture_index)
@@ -444,6 +463,25 @@ lower_yx_xuxv_external(nir_builder *b, nir_tex_instr *tex,
 }
 
 static void
+lower_yx_xvxu_external(nir_builder *b, nir_tex_instr *tex,
+                       const nir_lower_tex_options *options,
+                       unsigned texture_index)
+{
+   b->cursor = nir_after_instr(&tex->instr);
+
+   nir_ssa_def *y = sample_plane(b, tex, 0, options);
+   nir_ssa_def *xvxu = sample_plane(b, tex, 1, options);
+
+   convert_yuv_to_rgb(b, tex,
+                      nir_channel(b, y, 0),
+                      nir_channel(b, xvxu, 3),
+                      nir_channel(b, xvxu, 1),
+                      nir_imm_float(b, 1.0f),
+                      options,
+                      texture_index);
+}
+
+static void
 lower_xy_uxvx_external(nir_builder *b, nir_tex_instr *tex,
                        const nir_lower_tex_options *options,
                        unsigned texture_index)
@@ -463,6 +501,25 @@ lower_xy_uxvx_external(nir_builder *b, nir_tex_instr *tex,
 }
 
 static void
+lower_xy_vxux_external(nir_builder *b, nir_tex_instr *tex,
+                       const nir_lower_tex_options *options,
+                       unsigned texture_index)
+{
+  b->cursor = nir_after_instr(&tex->instr);
+
+  nir_ssa_def *y = sample_plane(b, tex, 0, options);
+  nir_ssa_def *vxux = sample_plane(b, tex, 1, options);
+
+  convert_yuv_to_rgb(b, tex,
+                     nir_channel(b, y, 1),
+                     nir_channel(b, vxux, 2),
+                     nir_channel(b, vxux, 0),
+                     nir_imm_float(b, 1.0f),
+                     options,
+                     texture_index);
+}
+
+static void
 lower_ayuv_external(nir_builder *b, nir_tex_instr *tex,
                     const nir_lower_tex_options *options,
                     unsigned texture_index)
@@ -552,6 +609,24 @@ lower_yu_yv_external(nir_builder *b, nir_tex_instr *tex,
                      texture_index);
 }
 
+static void
+lower_yv_yu_external(nir_builder *b, nir_tex_instr *tex,
+                     const nir_lower_tex_options *options,
+                     unsigned texture_index)
+{
+  b->cursor = nir_after_instr(&tex->instr);
+
+  nir_ssa_def *yuv = sample_plane(b, tex, 0, options);
+
+  convert_yuv_to_rgb(b, tex,
+                     nir_channel(b, yuv, 2),
+                     nir_channel(b, yuv, 1),
+                     nir_channel(b, yuv, 0),
+                     nir_imm_float(b, 1.0f),
+                     options,
+                     texture_index);
+}
+
 /*
  * Converts a nir_texop_txd instruction to nir_texop_txl with the given lod
  * computed from the gradients.
@@ -1442,6 +1517,11 @@ nir_lower_tex_block(nir_block *block, nir_builder *b,
          progress = true;
       }
 
+      if (texture_mask & options->lower_y_vu_external) {
+         lower_y_vu_external(b, tex, options, texture_index);
+         progress = true;
+      }
+
       if (texture_mask & options->lower_y_u_v_external) {
          lower_y_u_v_external(b, tex, options, texture_index);
          progress = true;
@@ -1452,11 +1532,21 @@ nir_lower_tex_block(nir_block *block, nir_builder *b,
          progress = true;
       }
 
+      if (texture_mask & options->lower_yx_xvxu_external) {
+         lower_yx_xvxu_external(b, tex, options, texture_index);
+         progress = true;
+      }
+
       if (texture_mask & options->lower_xy_uxvx_external) {
          lower_xy_uxvx_external(b, tex, options, texture_index);
          progress = true;
       }
 
+      if (texture_mask & options->lower_xy_vxux_external) {
+         lower_xy_vxux_external(b, tex, options, texture_index);
+         progress = true;
+      }
+
       if (texture_mask & options->lower_ayuv_external) {
          lower_ayuv_external(b, tex, options, texture_index);
          progress = true;
@@ -1477,6 +1567,11 @@ nir_lower_tex_block(nir_block *block, nir_builder *b,
          progress = true;
       }
 
+      if ((1 << tex->texture_index) & options->lower_yv_yu_external) {
+         lower_yv_yu_external(b, tex, options, texture_index);
+         progress = true;
+      }
+
       if ((1 << tex->texture_index) & options->lower_y41x_external) {
          lower_y41x_external(b, tex, options, texture_index);
          progress = true;