[i-g-t 12/15] lib/igt_color: Add support for 3x4 matrices
Bhanuprakash Modem
bhanuprakash.modem at intel.com
Wed Jan 3 18:41:30 UTC 2024
From: Harry Wentland <harry.wentland at amd.com>
Also add a few matrices for testing.
v2: (Bhanu)
- Move few helpers to common place to reuse
Signed-off-by: Harry Wentland <harry.wentland at amd.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem at intel.com>
---
lib/igt_color.c | 106 +++++++++++++++++++++++++++++++++++++++
lib/igt_color.h | 30 +++++++++++
tests/kms_color_helper.c | 76 +++++++++++++++++++++++++---
tests/kms_color_helper.h | 13 ++++-
tests/kms_colorop.c | 26 +++++++---
5 files changed, 237 insertions(+), 14 deletions(-)
diff --git a/lib/igt_color.c b/lib/igt_color.c
index 62249bd70..017b94aa2 100644
--- a/lib/igt_color.c
+++ b/lib/igt_color.c
@@ -9,10 +9,55 @@
#include <errno.h>
#include <math.h>
+#include "drmtest.h"
#include "igt_color.h"
#include "igt_core.h"
#include "igt_x86.h"
+const igt_matrix_3x4_t igt_matrix_3x4_50_desat = { {
+ 0.5, 0.25, 0.25, 0.0,
+ 0.25, 0.5, 0.25, 0.0,
+ 0.25, 0.25, 0.5, 0.0
+} };
+
+const igt_matrix_3x4_t igt_matrix_3x4_overdrive = { {
+ 1.5, 0.0, 0.0, 0.0,
+ 0.0, 1.5, 0.0, 0.0,
+ 0.0, 0.0, 1.5, 0.0
+} };
+
+const igt_matrix_3x4_t igt_matrix_3x4_oversaturate = { {
+ 1.5, -0.25, -0.25, 0.0,
+ -0.25, 1.5, -0.25, 0.0,
+ -0.25, -0.25, 1.5, 0.0
+} };
+
+#if 0
+const igt_matrix_3x4_t igt_matrix_3x4_bt709_enc = { {
+ 0.2126, 0.7152, 0.0722, 0.0,
+ -0.1146, -0.3854, 0.5, 0.0,
+ 0.5, -0.4542, -0.0458, 0.0
+} };
+
+const igt_matrix_3x4_t igt_matrix_3x4_bt709_dec = { {
+ 1.0, 0.0, 1.5748, 0.0,
+ 1.0, -0.1873, -0.4681, 0.0,
+ 1.0, 1.8556, 0.0, 0.0
+} };
+#else
+const igt_matrix_3x4_t igt_matrix_3x4_bt709_enc = { {
+ 0.2126, 0.7152, 0.0722, 0.0,
+ -0.09991, -0.33609, 0.436, 0.0,
+ 0.615, -0.55861, -0.05639, 0.0
+} };
+
+const igt_matrix_3x4_t igt_matrix_3x4_bt709_dec = { {
+ 1.0, 0.0, 1.28033, 0.0,
+ 1.0, -0.21482, -0.38059, 0.0,
+ 1.0, 2.12798, 0.0, 0.0
+} };
+#endif
+
const struct igt_color_tf srgb_tf = {2.4f, (float)(1/1.055), (float)(0.055/1.055), (float)(1/12.92), 0.04045f, 0, 0};
static float clamp(float val, float min, float max)
@@ -69,6 +114,62 @@ void igt_color_srgb_eotf(igt_pixel_t *pixel)
pixel->b = igt_color_tf_eval(&srgb_tf, 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;
@@ -135,6 +236,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);
diff --git a/lib/igt_color.h b/lib/igt_color.h
index 70e159ea0..04545e9b1 100644
--- a/lib/igt_color.h
+++ b/lib/igt_color.h
@@ -26,6 +26,28 @@ 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 |
+ * |1.0|
+ */
+ float m[12];
+} igt_matrix_3x4_t;
+
+extern const igt_matrix_3x4_t igt_matrix_3x4_50_desat;
+extern const igt_matrix_3x4_t igt_matrix_3x4_overdrive;
+extern const igt_matrix_3x4_t igt_matrix_3x4_oversaturate;
+#if 0
+extern const igt_matrix_3x4_t igt_matrix_3x4_bt709_enc;
+extern const igt_matrix_3x4_t igt_matrix_3x4_bt709_dec;
+#else
+extern const igt_matrix_3x4_t igt_matrix_3x4_bt709_enc;
+extern const igt_matrix_3x4_t igt_matrix_3x4_bt709_dec;
+#endif
+
bool igt_cmp_fb_component(uint16_t comp1, uint16_t comp2, uint8_t up, uint8_t down);
bool igt_cmp_fb_pixels(igt_fb_t *fb1, igt_fb_t *fb2, uint8_t up, uint8_t down);
@@ -36,7 +58,15 @@ typedef void (*igt_pixel_transform)(igt_pixel_t *pixel);
int igt_color_transform_pixels(igt_fb_t *fb, igt_pixel_transform transforms[], int num_transforms);
+/* transformations */
+
void igt_color_srgb_inv_eotf(igt_pixel_t *pixel);
void igt_color_srgb_eotf(igt_pixel_t *pixel);
+void igt_color_ctm_3x4_50_desat(igt_pixel_t *pixel);
+void igt_color_ctm_3x4_overdrive(igt_pixel_t *pixel);
+void igt_color_ctm_3x4_oversaturate(igt_pixel_t *pixel);
+void igt_color_ctm_3x4_bt709_dec(igt_pixel_t *pixel);
+void igt_color_ctm_3x4_bt709_enc(igt_pixel_t *pixel);
+
#endif
diff --git a/tests/kms_color_helper.c b/tests/kms_color_helper.c
index d512b085d..895d3fa0a 100644
--- a/tests/kms_color_helper.c
+++ b/tests/kms_color_helper.c
@@ -393,11 +393,10 @@ static bool can_use_colorop(igt_display_t *display, igt_colorop_t *colorop, kms_
{
switch (desired->type) {
case KMS_COLOROP_ENUMERATED_LUT1D:
- if (igt_colorop_get_prop(display, colorop, IGT_COLOROP_TYPE) == DRM_COLOROP_1D_CURVE) {
- return true;
- }
+ return (igt_colorop_get_prop(display, colorop, IGT_COLOROP_TYPE) == DRM_COLOROP_1D_CURVE);
+ case KMS_COLOROP_CTM_3X4:
+ return (igt_colorop_get_prop(display, colorop, IGT_COLOROP_TYPE) == DRM_COLOROP_CTM_3X4);
case KMS_COLOROP_CUSTOM_LUT1D:
- case KMS_COLOROP_CTM:
case KMS_COLOROP_LUT3D:
default:
return false;
@@ -417,13 +416,15 @@ static bool map_to_pipeline(igt_display_t *display,
int i = 0;
int prop_val = 0;
- current_op = colorops[i++];
+ current_op = colorops[i];
+ i++;
igt_require(current_op);
while (next) {
if (can_use_colorop(display, next, current_op)) {
current_op->colorop = next;
- current_op = colorops[i++];
+ current_op = colorops[i];
+ i++;
if (!current_op)
break;
}
@@ -484,8 +485,10 @@ void set_colorop(igt_display_t *display, kms_colorop_t *colorop)
igt_fail(IGT_EXIT_FAILURE);
}
break;
+ case KMS_COLOROP_CTM_3X4:
+ igt_colorop_set_ctm_3x4(display, colorop->colorop, colorop->matrix_3x4);
+ break;
case KMS_COLOROP_CUSTOM_LUT1D:
- case KMS_COLOROP_CTM:
case KMS_COLOROP_LUT3D:
default:
igt_fail(IGT_EXIT_FAILURE);
@@ -521,6 +524,30 @@ void set_color_pipeline(igt_display_t *display,
}
}
+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));
+}
+
kms_colorop_t kms_colorop_srgb_eotf = {
.type = KMS_COLOROP_ENUMERATED_LUT1D,
.enumerated_lut1d_info = {
@@ -538,3 +565,38 @@ kms_colorop_t kms_colorop_srgb_inv_eotf = {
.name = "srgb_inv_eotf",
.transform = &igt_color_srgb_inv_eotf
};
+
+kms_colorop_t kms_colorop_ctm_3x4_50_desat = {
+ .type = KMS_COLOROP_CTM_3X4,
+ .matrix_3x4 = &igt_matrix_3x4_50_desat,
+ .name = "ctm_3x4_50_desat",
+ .transform = &igt_color_ctm_3x4_50_desat
+};
+
+kms_colorop_t kms_colorop_ctm_3x4_overdrive = {
+ .type = KMS_COLOROP_CTM_3X4,
+ .matrix_3x4 = &igt_matrix_3x4_overdrive,
+ .name = "ctm_3x4_overdrive",
+ .transform = &igt_color_ctm_3x4_overdrive
+};
+
+kms_colorop_t kms_colorop_ctm_3x4_oversaturate = {
+ .type = KMS_COLOROP_CTM_3X4,
+ .matrix_3x4 = &igt_matrix_3x4_oversaturate,
+ .name = "ctm_3x4_oversaturate",
+ .transform = &igt_color_ctm_3x4_oversaturate
+};
+
+kms_colorop_t kms_colorop_ctm_3x4_bt709_enc = {
+ .type = KMS_COLOROP_CTM_3X4,
+ .matrix_3x4 = &igt_matrix_3x4_bt709_enc,
+ .name = "ctm_3x4_bt709_enc",
+ .transform = &igt_color_ctm_3x4_bt709_enc
+};
+
+kms_colorop_t kms_colorop_ctm_3x4_bt709_dec = {
+ .type = KMS_COLOROP_CTM_3X4,
+ .matrix_3x4 = &igt_matrix_3x4_bt709_dec,
+ .name = "ctm_3x4_bt709_dec",
+ .transform = &igt_color_ctm_3x4_bt709_dec
+};
diff --git a/tests/kms_color_helper.h b/tests/kms_color_helper.h
index b3a92b24c..e2be3a3a8 100644
--- a/tests/kms_color_helper.h
+++ b/tests/kms_color_helper.h
@@ -125,7 +125,7 @@ void invalid_ctm_matrix_sizes(data_t *data, enum pipe p);
typedef enum kms_colorop_type {
KMS_COLOROP_ENUMERATED_LUT1D,
KMS_COLOROP_CUSTOM_LUT1D,
- KMS_COLOROP_CTM,
+ KMS_COLOROP_CTM_3X4,
KMS_COLOROP_LUT3D
} kms_colorop_type_t;
@@ -145,6 +145,7 @@ typedef struct kms_colorop {
union {
kms_colorop_enumerated_lut1d_info_t enumerated_lut1d_info;
+ const igt_matrix_3x4_t *matrix_3x4;
};
const char *name;
@@ -162,7 +163,17 @@ typedef int (*transform_pixel)(igt_pixel_t *pixel);
extern kms_colorop_t kms_colorop_srgb_eotf;
extern kms_colorop_t kms_colorop_srgb_inv_eotf;
+extern kms_colorop_t kms_colorop_ctm_3x4_50_desat;
+extern kms_colorop_t kms_colorop_ctm_3x4_overdrive;
+extern kms_colorop_t kms_colorop_ctm_3x4_oversaturate;
+extern kms_colorop_t kms_colorop_ctm_3x4_bt709_enc;
+extern kms_colorop_t kms_colorop_ctm_3x4_bt709_dec;
+/* colorop helpers */
+
+void igt_colorop_set_ctm_3x4(igt_display_t *display,
+ igt_colorop_t *colorop,
+ const igt_matrix_3x4_t *matrix);
igt_colorop_t *get_color_pipeline(igt_display_t *display, igt_plane_t *plane,
kms_colorop_t *colorops[]);
void set_colorop(igt_display_t *display, kms_colorop_t *colorop);
diff --git a/tests/kms_colorop.c b/tests/kms_colorop.c
index 4e31439a5..b5f370d87 100644
--- a/tests/kms_colorop.c
+++ b/tests/kms_colorop.c
@@ -37,9 +37,16 @@
*
* arg[1]:
*
- * @srgb_eotf: sRGB EOTF
- * @srgb_inv_eotf: sRGB Inverse EOTF
- * @srgb_eotf-srgb_inv_eotf: sRGB EOTF -> sRGB Inverse EOTF
+ * @srgb_eotf: sRGB EOTF
+ * @srgb_inv_eotf: sRGB Inverse EOTF
+ * @srgb_eotf-srgb_inv_eotf: sRGB EOTF -> sRGB Inverse EOTF
+ * @ctm_3x4_50_desat: 3x4 matrix doing a 50% desaturation
+ * @ctm_3x4_overdrive: 3x4 matrix overdring all values by 50%
+ * @ctm_3x4_oversaturate: 3x4 matrix oversaturating values
+ * @ctm_3x4_bt709_enc: BT709 encoding matrix
+ * @ctm_3x4_bt709_dec: BT709 decoding matrix
+ * @ctm_3x4_bt709_enc_dec: BT709 encoding matrix, followed by decoding matrix
+ * @ctm_3x4_bt709_dec_enc: BT709 decoding matrix, followed by encoding matrix
*
*/
@@ -180,8 +187,8 @@ static bool compare_with_bracket(igt_fb_t *in, igt_fb_t *out)
#define DUMP_FBS 1
-#define MAX_COLOROPS 3
-#define NUM_COLOROP_TESTS 3
+#define MAX_COLOROPS 5
+#define NUM_COLOROP_TESTS 12
#define MAX_NAME_SIZE 256
static void apply_transforms(kms_colorop_t *colorops[], igt_fb_t *sw_transform_fb)
@@ -330,7 +337,14 @@ igt_main
} tests[] = {
{ { &kms_colorop_srgb_eotf, NULL }, "srgb_eotf" },
{ { &kms_colorop_srgb_inv_eotf, NULL }, "srgb_inv_eotf" },
- { { &kms_colorop_srgb_eotf, &kms_colorop_srgb_inv_eotf, NULL }, "srgb_eotf-srgb_inv_eotf" }
+ { { &kms_colorop_srgb_eotf, &kms_colorop_srgb_inv_eotf, NULL }, "srgb_eotf-srgb_inv_eotf" },
+ { { &kms_colorop_ctm_3x4_50_desat, NULL }, "ctm_3x4_50_desat" },
+ { { &kms_colorop_ctm_3x4_overdrive, NULL }, "ctm_3x4_overdrive" },
+ { { &kms_colorop_ctm_3x4_oversaturate, NULL }, "ctm_3x4_oversaturate" },
+ { { &kms_colorop_ctm_3x4_bt709_enc, NULL }, "ctm_3x4_bt709_enc" },
+ { { &kms_colorop_ctm_3x4_bt709_dec, NULL }, "ctm_3x4_bt709_dec" },
+ { { &kms_colorop_ctm_3x4_bt709_enc, &kms_colorop_ctm_3x4_bt709_dec, NULL }, "ctm_3x4_bt709_enc_dec" },
+ { { &kms_colorop_ctm_3x4_bt709_dec, &kms_colorop_ctm_3x4_bt709_enc, NULL }, "ctm_3x4_bt709_dec_enc" },
};
igt_display_t display;
--
2.40.0
More information about the Intel-gfx-trybot
mailing list