[PATCH V10 11/30] lib/igt_color: Add support for 3x4 matrices

Aurabindo Pillai aurabindo.pillai at amd.com
Tue Aug 26 16:29:42 UTC 2025



On 8/15/25 12:06 AM, Alex Hung wrote:
> From: Harry Wentland <harry.wentland at amd.com>
> 
> Support 3x4 matrices in color pipeline API.
> 
> Also add a few matrices for testing.
> 
> Signed-off-by: Alex Hung <alex.hung at amd.com>
> Signed-off-by: Harry Wentland <harry.wentland at amd.com>
> ---
>   lib/igt_color.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++
>   lib/igt_color.h | 54 +++++++++++++++++++++++++++++++
>   2 files changed, 140 insertions(+)
> 
> diff --git a/lib/igt_color.c b/lib/igt_color.c
> index 0e5f391db..bc90fbdca 100644
> --- a/lib/igt_color.c
> +++ b/lib/igt_color.c
> @@ -11,6 +11,7 @@
>   #include <errno.h>
>   #include <math.h>
>   
> +#include "drmtest.h"
>   #include "igt_color.h"
>   #include "igt_core.h"
>   #include "igt_x86.h"
> @@ -76,6 +77,62 @@ void igt_color_srgb_eotf(igt_pixel_t *pixel)
>   	pixel->b = igt_color_tf_eval(&srgb_eotf, pixel->b);
>   }
>   
> +static void igt_color_apply_3x4_ctm(igt_pixel_t *pixel, const igt_matrix_3x4_t *matrix)
> +{
> +	igt_pixel_t result;
> +
> +	memcpy(&result, pixel, sizeof(result));
> +
> +	result.r = matrix->m[0] * pixel->r +
> +		   matrix->m[1] * pixel->g +
> +		   matrix->m[2] * pixel->b +
> +		   matrix->m[3];
> +
> +	result.g = matrix->m[4] * pixel->r +
> +		   matrix->m[5] * pixel->g +
> +		   matrix->m[6] * pixel->b +
> +		   matrix->m[7];
> +
> +	result.b = matrix->m[8] * pixel->r +
> +		   matrix->m[9] * pixel->g +
> +		   matrix->m[10] * pixel->b +
> +		   matrix->m[11];
> +
> +	memcpy(pixel, &result, sizeof(result));
> +
> +}
> +
> +void igt_color_ctm_3x4_50_desat(igt_pixel_t *pixel)
> +{
> +	/* apply a 50% desat matrix */
> +	igt_color_apply_3x4_ctm(pixel, &igt_matrix_3x4_50_desat);
> +}
> +
> +void igt_color_ctm_3x4_overdrive(igt_pixel_t *pixel)
> +{
> +	/* apply a 50% desat matrix */
> +	igt_color_apply_3x4_ctm(pixel, &igt_matrix_3x4_overdrive);
> +}
> +
> +void igt_color_ctm_3x4_oversaturate(igt_pixel_t *pixel)
> +{
> +	/* apply a 50% desat matrix */
> +	igt_color_apply_3x4_ctm(pixel, &igt_matrix_3x4_oversaturate);
> +}
> +
> +void igt_color_ctm_3x4_bt709_enc(igt_pixel_t *pixel)
> +{
> +	/* apply a 50% desat matrix */
> +	igt_color_apply_3x4_ctm(pixel, &igt_matrix_3x4_bt709_enc);
> +}
> +
> +void igt_color_ctm_3x4_bt709_dec(igt_pixel_t *pixel)
> +{
> +	/* apply a 50% desat matrix */
> +	igt_color_apply_3x4_ctm(pixel, &igt_matrix_3x4_bt709_dec);
> +}
> +
> +
>   int igt_color_transform_pixels(igt_fb_t *fb, igt_pixel_transform transforms[], int num_transforms)
>   {
>   	uint32_t *line = NULL;
> @@ -142,6 +199,11 @@ int igt_color_transform_pixels(igt_fb_t *fb, igt_pixel_transform transforms[], i
>   			for (i = 0; i < num_transforms; i++)
>   				transforms[i](&pixel);
>   
> +			/* clip */
> +			pixel.r = fmax(fmin(pixel.r, 1.0), 0.0);
> +			pixel.g = fmax(fmin(pixel.g, 1.0), 0.0);
> +			pixel.b = fmax(fmin(pixel.b, 1.0), 0.0);
> +
>   			/* de-normalize back to 8-bit */
>   			pixel.r *= (0xff);
>   			pixel.g *= (0xff);
> @@ -244,3 +306,27 @@ void igt_dump_fb(igt_display_t *display, igt_fb_t *fb,
>   	igt_assert_eq(status, CAIRO_STATUS_SUCCESS);
>   	cairo_surface_destroy(fb_surface_out);
>   }
> +
> +void igt_colorop_set_ctm_3x4(igt_display_t *display,
> +			     igt_colorop_t *colorop,
> +			     const igt_matrix_3x4_t *matrix)
> +{
> +	struct drm_color_ctm_3x4 ctm;
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(ctm.matrix); i++) {
> +		if (matrix->m[i] < 0) {
> +			ctm.matrix[i] =
> +				(int64_t) (-matrix->m[i] *
> +				((int64_t) 1L << 32));
> +			ctm.matrix[i] |= 1ULL << 63;
> +		} else {
> +			ctm.matrix[i] =
> +				(int64_t) (matrix->m[i] *
> +				((int64_t) 1L << 32));
> +		}
> +	}
> +
> +	/* set blob property */
> +	igt_colorop_replace_prop_blob(colorop, IGT_COLOROP_DATA, &ctm, sizeof(ctm));
> +}
> diff --git a/lib/igt_color.h b/lib/igt_color.h
> index 4f34a1b0d..fe0037ae5 100644
> --- a/lib/igt_color.h
> +++ b/lib/igt_color.h
> @@ -29,6 +29,47 @@ typedef struct igt_pixel {
>   	float b;
>   } igt_pixel_t;
>   
> +typedef struct igt_matrix_3x4 {
> +	/*
> +	 * out   matrix          in
> +	 * |R|   |0  1  2  3 |   | R |
> +	 * |G| = |4  5  6  7 | x | G |
> +	 * |B|   |8  9  10 12|   | B |

Typo here? 11 instead of 12 above




More information about the igt-dev mailing list