Module: Mesa Branch: amber Commit: 54a564e679e1f01e22c1bdc50e4040c946281349 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=54a564e679e1f01e22c1bdc50e4040c946281349
Author: Andres Calderon Jaramillo <[email protected]> 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 <[email protected]> Reviewed-by: Rob Clark <[email protected]> (cherry picked from commit a5d09d7a0ac73ec1626be139a482f901c521a466) Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17114> --- 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 aff1289892c..8fac9293098 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -5108,6 +5108,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 30aa1e75249..d2f603430fb 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);
