[PATCH v6 21/44] drm/vkms: Add tests for CTM handling
Louis Chauvet
louis.chauvet at bootlin.com
Fri Oct 4 11:43:27 UTC 2024
On 03/10/24 - 16:01, Harry Wentland wrote:
> A whole slew of tests for CTM handling that greatly helped in
> debugging the CTM code. The extent of tests might seem a bit
> silly but they're fast and might someday help save someone
> else's day when debugging this.
>
> Signed-off-by: Harry Wentland <harry.wentland at amd.com>
Reviewed-by: Louis Chauvet <louis.chauvet at bootlin.com>
> ---
>
> v6:
> - update reference values since we're now rounding
>
> v5:
> - Make apply_3x4_matrix static
>
> v4:
> - Comment on origin of bt709_enc matrix (Pekka)
> - Use full opaque alpha (Pekka)
> - Add additional check for Y < 0xffff (Pekka)
> - Remove unused code (Pekka)
> - Rename red, green, blue to Y, U, V where applicable
>
> drivers/gpu/drm/vkms/tests/vkms_color_test.c | 250 +++++++++++++++++++
> drivers/gpu/drm/vkms/vkms_composer.c | 3 +-
> drivers/gpu/drm/vkms/vkms_composer.h | 1 +
> 3 files changed, 253 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/vkms/tests/vkms_color_test.c b/drivers/gpu/drm/vkms/tests/vkms_color_test.c
> index c36e67c7909e..d5eb1e4e9b67 100644
> --- a/drivers/gpu/drm/vkms/tests/vkms_color_test.c
> +++ b/drivers/gpu/drm/vkms/tests/vkms_color_test.c
> @@ -187,11 +187,261 @@ static void vkms_color_srgb_inv_srgb(struct kunit *test)
> }
> }
>
> +#define FIXPT_HALF (DRM_FIXED_ONE >> 1)
> +#define FIXPT_QUARTER (DRM_FIXED_ONE >> 2)
> +
> +const struct drm_color_ctm_3x4 test_matrix_3x4_50_desat = { {
> + FIXPT_HALF, FIXPT_QUARTER, FIXPT_QUARTER, 0,
> + FIXPT_QUARTER, FIXPT_HALF, FIXPT_QUARTER, 0,
> + FIXPT_QUARTER, FIXPT_QUARTER, FIXPT_HALF, 0
> +} };
> +
> +static void vkms_color_ctm_3x4_50_desat(struct kunit *test)
> +{
> + struct pixel_argb_s32 ref, out;
> +
> + /* full white */
> + ref.a = 0xffff;
> + ref.r = 0xffff;
> + ref.g = 0xffff;
> + ref.b = 0xffff;
> +
> + memcpy(&out, &ref, sizeof(out));
> + apply_3x4_matrix(&out, &test_matrix_3x4_50_desat);
> +
> + KUNIT_EXPECT_MEMEQ(test, &ref, &out, sizeof(out));
> +
> + /* full black */
> + ref.a = 0xffff;
> + ref.r = 0x0;
> + ref.g = 0x0;
> + ref.b = 0x0;
> +
> + memcpy(&out, &ref, sizeof(out));
> + apply_3x4_matrix(&out, &test_matrix_3x4_50_desat);
> +
> + KUNIT_EXPECT_MEMEQ(test, &ref, &out, sizeof(out));
> +
> + /* 50% grey */
> + ref.a = 0xffff;
> + ref.r = 0x8000;
> + ref.g = 0x8000;
> + ref.b = 0x8000;
> +
> + memcpy(&out, &ref, sizeof(out));
> + apply_3x4_matrix(&out, &test_matrix_3x4_50_desat);
> +
> + KUNIT_EXPECT_MEMEQ(test, &ref, &out, sizeof(out));
> +
> + /* full red to 50% desat */
> + ref.a = 0xffff;
> + ref.r = 0x8000;
> + ref.g = 0x4000;
> + ref.b = 0x4000;
> +
> + out.a = 0xffff;
> + out.r = 0xffff;
> + out.g = 0x0;
> + out.b = 0x0;
> +
> + apply_3x4_matrix(&out, &test_matrix_3x4_50_desat);
> +
> + KUNIT_EXPECT_MEMEQ(test, &ref, &out, sizeof(out));
> +}
> +
> +/*
> + * BT.709 encoding matrix
> + *
> + * Values printed from within IGT when converting
> + * igt_matrix_3x4_bt709_enc to the fixed-point format expected
> + * by DRM/KMS.
> + */
> +const struct drm_color_ctm_3x4 test_matrix_3x4_bt709_enc = { {
> + 0x00000000366cf400ull, 0x00000000b7175900ull, 0x0000000127bb300ull, 0,
> + 0x800000001993b3a0ull, 0x800000005609fe80ull, 0x000000006f9db200ull, 0,
> + 0x000000009d70a400ull, 0x800000008f011100ull, 0x800000000e6f9330ull, 0
> +} };
> +
> +static void vkms_color_ctm_3x4_bt709(struct kunit *test)
> +{
> + struct pixel_argb_s32 out;
> +
> + /* full white to bt709 */
> + out.a = 0xffff;
> + out.r = 0xffff;
> + out.g = 0xffff;
> + out.b = 0xffff;
> +
> + apply_3x4_matrix(&out, &test_matrix_3x4_bt709_enc);
> +
> + /* Y 255 */
> + KUNIT_EXPECT_GT(test, out.r, 0xfe00);
> + KUNIT_EXPECT_LT(test, out.r, 0x10000);
> +
> + /* U 0 */
> + KUNIT_EXPECT_LT(test, out.g, 0x0100);
> +
> + /* V 0 */
> + KUNIT_EXPECT_LT(test, out.b, 0x0100);
> +
> + /* full black to bt709 */
> + out.a = 0xffff;
> + out.r = 0x0;
> + out.g = 0x0;
> + out.b = 0x0;
> +
> + apply_3x4_matrix(&out, &test_matrix_3x4_bt709_enc);
> +
> + /* Y 0 */
> + KUNIT_EXPECT_LT(test, out.r, 0x100);
> +
> + /* U 0 */
> + KUNIT_EXPECT_LT(test, out.g, 0x0100);
> +
> + /* V 0 */
> + KUNIT_EXPECT_LT(test, out.b, 0x0100);
> +
> + /* gray to bt709 */
> + out.a = 0xffff;
> + out.r = 0x7fff;
> + out.g = 0x7fff;
> + out.b = 0x7fff;
> +
> + apply_3x4_matrix(&out, &test_matrix_3x4_bt709_enc);
> +
> + /* Y 127 */
> + KUNIT_EXPECT_GT(test, out.r, 0x7e00);
> + KUNIT_EXPECT_LT(test, out.r, 0x8000);
> +
> + /* U 0 */
> + KUNIT_EXPECT_LT(test, out.g, 0x0100);
> +
> + /* V 0 */
> + KUNIT_EXPECT_LT(test, out.b, 0x0100);
> +
> + /* == red 255 - bt709 enc == */
> + out.a = 0xffff;
> + out.r = 0xffff;
> + out.g = 0x0;
> + out.b = 0x0;
> +
> + apply_3x4_matrix(&out, &test_matrix_3x4_bt709_enc);
> +
> + /* Y 54 */
> + KUNIT_EXPECT_GT(test, out.r, 0x3500);
> + KUNIT_EXPECT_LT(test, out.r, 0x3700);
> +
> + /* U 0 */
> + KUNIT_EXPECT_LT(test, out.g, 0x0100);
> +
> + /* V 157 */
> + KUNIT_EXPECT_GT(test, out.b, 0x9C00);
> + KUNIT_EXPECT_LT(test, out.b, 0x9E00);
> +
> +
> + /* == green 255 - bt709 enc == */
> + out.a = 0xffff;
> + out.r = 0x0;
> + out.g = 0xffff;
> + out.b = 0x0;
> +
> + apply_3x4_matrix(&out, &test_matrix_3x4_bt709_enc);
> +
> + /* Y 182 */
> + KUNIT_EXPECT_GT(test, out.r, 0xB500);
> + KUNIT_EXPECT_LT(test, out.r, 0xB780); /* laxed by half*/
> +
> + /* U 0 */
> + KUNIT_EXPECT_LT(test, out.g, 0x0100);
> +
> + /* V 0 */
> + KUNIT_EXPECT_LT(test, out.b, 0x0100);
> +
> + /* == blue 255 - bt709 enc == */
> + out.a = 0xffff;
> + out.r = 0x0;
> + out.g = 0x0;
> + out.b = 0xffff;
> +
> + apply_3x4_matrix(&out, &test_matrix_3x4_bt709_enc);
> +
> + /* Y 18 */
> + KUNIT_EXPECT_GT(test, out.r, 0x1100);
> + KUNIT_EXPECT_LT(test, out.r, 0x1300);
> +
> + /* U 111 */
> + KUNIT_EXPECT_GT(test, out.g, 0x6E00);
> + KUNIT_EXPECT_LT(test, out.g, 0x7000);
> +
> + /* V 0 */
> + KUNIT_EXPECT_LT(test, out.b, 0x0100);
> +
> + /* == red 140 - bt709 enc == */
> + out.a = 0xffff;
> + out.r = 0x8c8c;
> + out.g = 0x0;
> + out.b = 0x0;
> +
> + apply_3x4_matrix(&out, &test_matrix_3x4_bt709_enc);
> +
> + /* Y 30 */
> + KUNIT_EXPECT_GT(test, out.r, 0x1D00);
> + KUNIT_EXPECT_LT(test, out.r, 0x1F00);
> +
> + /* U 0 */
> + KUNIT_EXPECT_LT(test, out.g, 0x100);
> +
> + /* V 87 */
> + KUNIT_EXPECT_GT(test, out.b, 0x5600);
> + KUNIT_EXPECT_LT(test, out.b, 0x5800);
> +
> + /* == green 140 - bt709 enc == */
> + out.a = 0xffff;
> + out.r = 0x0;
> + out.g = 0x8c8c;
> + out.b = 0x0;
> +
> + apply_3x4_matrix(&out, &test_matrix_3x4_bt709_enc);
> +
> + /* Y 30 */
> + KUNIT_EXPECT_GT(test, out.r, 0x6400);
> + KUNIT_EXPECT_LT(test, out.r, 0x6600);
> +
> + /* U 0 */
> + KUNIT_EXPECT_LT(test, out.g, 0x100);
> +
> + /* V 0 */
> + KUNIT_EXPECT_LT(test, out.b, 0x100);
> +
> +
> + /* == blue 140 - bt709 enc == */
> + out.a = 0xffff;
> + out.r = 0x0;
> + out.g = 0x0;
> + out.b = 0x8c8c;
> +
> + apply_3x4_matrix(&out, &test_matrix_3x4_bt709_enc);
> +
> + /* Y 30 */
> + KUNIT_EXPECT_GT(test, out.r, 0x900);
> + KUNIT_EXPECT_LT(test, out.r, 0xB00);
> +
> + /* U 61 */
> + KUNIT_EXPECT_GT(test, out.g, 0x3C00);
> + KUNIT_EXPECT_LT(test, out.g, 0x3E00);
> +
> + /* V 0 */
> + KUNIT_EXPECT_LT(test, out.b, 0x100);
> +
> +}
> +
> static struct kunit_case vkms_color_test_cases[] = {
> KUNIT_CASE(vkms_color_test_get_lut_index),
> KUNIT_CASE(vkms_color_test_lerp),
> KUNIT_CASE(vkms_color_test_linear),
> KUNIT_CASE(vkms_color_srgb_inv_srgb),
> + KUNIT_CASE(vkms_color_ctm_3x4_50_desat),
> + KUNIT_CASE(vkms_color_ctm_3x4_bt709),
> {}
> };
>
> diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c
> index c8b9b9d7f78f..daee7d56abb7 100644
> --- a/drivers/gpu/drm/vkms/vkms_composer.c
> +++ b/drivers/gpu/drm/vkms/vkms_composer.c
> @@ -159,7 +159,7 @@ static void apply_lut(const struct vkms_crtc_state *crtc_state, struct line_buff
> }
> }
>
> -static void apply_3x4_matrix(struct pixel_argb_s32 *pixel, const struct drm_color_ctm_3x4 *matrix)
> +VISIBLE_IF_KUNIT void apply_3x4_matrix(struct pixel_argb_s32 *pixel, const struct drm_color_ctm_3x4 *matrix)
> {
> s64 rf, gf, bf;
> s64 r, g, b;
> @@ -187,6 +187,7 @@ static void apply_3x4_matrix(struct pixel_argb_s32 *pixel, const struct drm_colo
> pixel->g = drm_fixp2int_round(gf);
> pixel->b = drm_fixp2int_round(bf);
> }
> +EXPORT_SYMBOL_IF_KUNIT(apply_3x4_matrix);
>
> static void apply_colorop(struct pixel_argb_s32 *pixel, struct drm_colorop *colorop)
> {
> diff --git a/drivers/gpu/drm/vkms/vkms_composer.h b/drivers/gpu/drm/vkms/vkms_composer.h
> index 67ae09913460..afef65a5c3ba 100644
> --- a/drivers/gpu/drm/vkms/vkms_composer.h
> +++ b/drivers/gpu/drm/vkms/vkms_composer.h
> @@ -21,6 +21,7 @@ u16 lerp_u16(u16 a, u16 b, s64 t);
> s64 get_lut_index(const struct vkms_color_lut *lut, u16 channel_value);
> u16 apply_lut_to_channel_value(const struct vkms_color_lut *lut, u16 channel_value,
> enum lut_channel channel);
> +void apply_3x4_matrix(struct pixel_argb_s32 *pixel, const struct drm_color_ctm_3x4 *matrix);
> #endif
>
> #endif /* _VKMS_COMPOSER_H_ */
> --
> 2.46.2
>
More information about the amd-gfx
mailing list