Mesa (main): nir: Account for YUV range.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Jun 17 18:12:39 UTC 2022


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

Author: Andres Calderon Jaramillo <andrescj at chromium.org>
Date:   Sat May 21 23:25:02 2022 +0000

nir: Account for YUV range.

This patch expands on what commit
d8fdb8dab4658de2d255718627ee671e84fedf2d did. It adds support for
YUV-to-RGB conversions depending on the range of the YUV samples.

The conversion matrices and offsets are derived from
https://gist.github.com/yohhoy/dafa5a47dade85d8b40625261af3776a.

Tested-by: Andres Calderon Jaramillo <andrescj at chromium.org>
Reviewed-by: Rob Clark <robdclark at chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16651>

---

 src/compiler/nir/nir.h           |  1 +
 src/compiler/nir/nir_lower_tex.c | 71 +++++++++++++++++++++++++++++++---------
 2 files changed, 56 insertions(+), 16 deletions(-)

diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index b6387fd398e..191c9e7e825 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -4947,6 +4947,7 @@ typedef struct nir_lower_tex_options {
    unsigned lower_y41x_external;
    unsigned bt709_external;
    unsigned bt2020_external;
+   unsigned yuv_full_range_external;
 
    /**
     * To emulate certain texture wrap modes, this can be used
diff --git a/src/compiler/nir/nir_lower_tex.c b/src/compiler/nir/nir_lower_tex.c
index ec48d9a4ac9..9add854736a 100644
--- a/src/compiler/nir/nir_lower_tex.c
+++ b/src/compiler/nir/nir_lower_tex.c
@@ -33,6 +33,8 @@
  *     inserts instructions to clamp specified coordinates to [0.0, 1.0].
  *     Note that this automatically triggers texture projector lowering if
  *     needed, since clamping must happen after projector lowering.
+ *   + YUV-to-RGB conversion: to allow sampling YUV values as RGB values
+ *     according to a specific YUV color space and range.
  */
 
 #include "nir.h"
@@ -44,30 +46,54 @@ typedef struct nir_const_value_3_4 {
    nir_const_value v[3][4];
 } nir_const_value_3_4;
 
-static const nir_const_value_3_4 bt601_csc_coeffs = { {
+static const nir_const_value_3_4 bt601_limited_range_csc_coeffs = { {
    { { .f32 = 1.16438356f }, { .f32 =  1.16438356f }, { .f32 = 1.16438356f } },
    { { .f32 = 0.0f        }, { .f32 = -0.39176229f }, { .f32 = 2.01723214f } },
    { { .f32 = 1.59602678f }, { .f32 = -0.81296764f }, { .f32 = 0.0f        } },
 } };
-static const nir_const_value_3_4 bt709_csc_coeffs = { {
+static const nir_const_value_3_4 bt601_full_range_csc_coeffs = { {
+   { { .f32 = 1.0f        }, { .f32 =  1.0f        }, { .f32 = 1.0f        } },
+   { { .f32 = 0.0f        }, { .f32 = -0.34413629f }, { .f32 = 1.772f      } },
+   { { .f32 = 1.402f      }, { .f32 = -0.71413629f }, { .f32 = 0.0f        } },
+} };
+static const nir_const_value_3_4 bt709_limited_range_csc_coeffs = { {
    { { .f32 = 1.16438356f }, { .f32 =  1.16438356f }, { .f32 = 1.16438356f } },
    { { .f32 = 0.0f        }, { .f32 = -0.21324861f }, { .f32 = 2.11240179f } },
    { { .f32 = 1.79274107f }, { .f32 = -0.53290933f }, { .f32 = 0.0f        } },
 } };
-static const nir_const_value_3_4 bt2020_csc_coeffs = { {
+static const nir_const_value_3_4 bt709_full_range_csc_coeffs = { {
+   { { .f32 = 1.0f        }, { .f32 =  1.0f        }, { .f32 = 1.0f        } },
+   { { .f32 = 0.0f        }, { .f32 = -0.18732427f }, { .f32 = 1.8556f     } },
+   { { .f32 = 1.5748f     }, { .f32 = -0.46812427f }, { .f32 = 0.0f        } },
+} };
+static const nir_const_value_3_4 bt2020_limited_range_csc_coeffs = { {
    { { .f32 = 1.16438356f }, { .f32 =  1.16438356f }, { .f32 = 1.16438356f } },
    { { .f32 = 0.0f        }, { .f32 = -0.18732610f }, { .f32 = 2.14177232f } },
-   { { .f32 = 1.67867411f }, { .f32 = -0.65042432f }, { .f32 = 0.0f        } },
+   { { .f32 = 1.67878795f }, { .f32 = -0.65046843f }, { .f32 = 0.0f        } },
+} };
+static const nir_const_value_3_4 bt2020_full_range_csc_coeffs = { {
+   { { .f32 = 1.0f        }, { .f32 =  1.0f        }, { .f32 = 1.0f        } },
+   { { .f32 = 0.0f        }, { .f32 = -0.16455313f }, { .f32 = 1.88140000f } },
+   { { .f32 = 1.4747f     }, { .f32 = -0.57139187f }, { .f32 = 0.0f        } },
 } };
 
-static const float bt601_csc_offsets[3] = {
+static const float bt601_limited_range_csc_offsets[3] = {
    -0.874202218f, 0.531667823f, -1.085630789f
 };
-static const float bt709_csc_offsets[3] = {
+static const float bt601_full_range_csc_offsets[3] = {
+   -0.701000000f, 0.529136286f, -0.886000000f
+};
+static const float bt709_limited_range_csc_offsets[3] = {
    -0.972945075f, 0.301482665f, -1.133402218f
 };
-static const float bt2020_csc_offsets[3] = {
-   -0.915687932f, 0.347458499f, -1.148145075f
+static const float bt709_full_range_csc_offsets[3] = {
+   -0.787400000f, 0.327724273f, -0.927800000f
+};
+static const float bt2020_limited_range_csc_offsets[3] = {
+   -0.915745075f, 0.347480639f, -1.148145075f
+};
+static const float bt2020_full_range_csc_offsets[3] = {
+   -0.737350000f, 0.367972500f, -0.940700000f
 };
 
 static bool
@@ -326,15 +352,28 @@ convert_yuv_to_rgb(nir_builder *b, nir_tex_instr *tex,
    const float *offset_vals;
    const nir_const_value_3_4 *m;
    assert((options->bt709_external & options->bt2020_external) == 0);
-   if (options->bt709_external & (1u << texture_index)) {
-      m = &bt709_csc_coeffs;
-      offset_vals = bt709_csc_offsets;
-   } else if (options->bt2020_external & (1u << texture_index)) {
-      m = &bt2020_csc_coeffs;
-      offset_vals = bt2020_csc_offsets;
+   if (options->yuv_full_range_external & (1u << texture_index)) {
+      if (options->bt709_external & (1u << texture_index)) {
+         m = &bt709_full_range_csc_coeffs;
+         offset_vals = bt709_full_range_csc_offsets;
+      } else if (options->bt2020_external & (1u << texture_index)) {
+         m = &bt2020_full_range_csc_coeffs;
+         offset_vals = bt2020_full_range_csc_offsets;
+      } else {
+         m = &bt601_full_range_csc_coeffs;
+         offset_vals = bt601_full_range_csc_offsets;
+      }
    } else {
-      m = &bt601_csc_coeffs;
-      offset_vals = bt601_csc_offsets;
+      if (options->bt709_external & (1u << texture_index)) {
+         m = &bt709_limited_range_csc_coeffs;
+         offset_vals = bt709_limited_range_csc_offsets;
+      } else if (options->bt2020_external & (1u << texture_index)) {
+         m = &bt2020_limited_range_csc_coeffs;
+         offset_vals = bt2020_limited_range_csc_offsets;
+      } else {
+         m = &bt601_limited_range_csc_coeffs;
+         offset_vals = bt601_limited_range_csc_offsets;
+      }
    }
 
    unsigned bit_size = nir_dest_bit_size(tex->dest);



More information about the mesa-commit mailing list