[PATCH i-g-t 9/9] tests/kms_color: Add Intel plane pipeline tests with LUT1D and CTM
Swati Sharma
swati2.sharma at intel.com
Sun Jul 6 20:01:25 UTC 2025
For now, Intel plane color pipeline contains 3 colorops:
Pre-csc gamma (1D LUT) --> CTM 3x4 --> Post-csc gamma (1D LUT)
Create subtests to cover different combinations of available
colorops:
igt at kms_color@plane-lut1d
igt at kms_color@plane-lut1d-ctm3x4
igt at kms_color@plane-ctm3x4-lut1d
igt at kms_color@plane-lut1d-lut1d
igt at kms_color@plane-lut1d-ctm3x4-lut1d
Signed-off-by: Swati Sharma <swati2.sharma at intel.com>
---
tests/kms_color.c | 131 ++++++++++++++++++++++++++++++---------
tests/kms_color_helper.c | 55 +++++++++++++++-
tests/kms_color_helper.h | 11 ++++
3 files changed, 164 insertions(+), 33 deletions(-)
diff --git a/tests/kms_color.c b/tests/kms_color.c
index 1c61fac71..02c43901e 100644
--- a/tests/kms_color.c
+++ b/tests/kms_color.c
@@ -90,6 +90,11 @@
* @ctm3x4-lut1d-multseg: 3X4 CTM --> 1D LUT MULTSEG
* @lut1d-multseg-lut1d-multseg: 1D LUT MULTSEG --> 1D LUT MULTSEG
* @lut1d-multseg-ctm3x4-lut1d-multseg: 1D LUT MULTSEG --> 3X4 CTM --> 1D LUT MULTSEG
+ * @lut1d: 1D LUT
+ * @lut1d-ctm3x4: 1D LUT --> 3X4 CTM
+ * @ctm3x4-lut1d: 3X4 CTM --> 1D LUT
+ * @lut1d-lut1d: 1D LUT --> 1D LUT
+ * @lut1d-ctm3x4-lut1d: 1D LUT --> 3X4 CTM --> 1D LUT
*/
IGT_TEST_DESCRIPTION("Test Color Features at Pipe level");
@@ -745,11 +750,13 @@ static void clear_lut_data(kms_colorop_t *colorops[])
int i;
for (i = 0; colorops[i]; i++) {
- if (colorops[i]->type != KMS_COLOROP_MULTSEG_LUT1D)
- continue;
-
- if (colorops[i]->multseg_lut1d_info.lut)
- free(colorops[i]->multseg_lut1d_info.lut);
+ if (colorops[i]->type == KMS_COLOROP_MULTSEG_LUT1D) {
+ if (colorops[i]->multseg_lut1d_info.lut)
+ free(colorops[i]->multseg_lut1d_info.lut);
+ } else if (colorops[i]->type == KMS_COLOROP_CUSTOM_LUT1D) {
+ if (colorops[i]->lut1d->lut)
+ free(colorops[i]->lut1d->lut);
+ }
}
}
@@ -758,35 +765,62 @@ static void prepare_lut_data(data_t *data, kms_colorop_t *colorops[])
int i;
for (i = 0; colorops[i]; i++) {
- uint64_t hwlut_caps = 0;
- segment_data_t *segment_info;
+ if (colorops[i]->type == KMS_COLOROP_MULTSEG_LUT1D) {
+ uint64_t hwlut_caps = 0;
+ segment_data_t *segment_info;
+
+ hwlut_caps = igt_colorop_get_prop(&data->display, colorops[i]->colorop, IGT_COLOROP_HW_CAPS);
+ segment_info = get_segment_data(data->drm_fd, hwlut_caps);
+
+ igt_info("Lut size (%s): %d\n", colorops[i]->name, segment_info->entries_count);
+
+ colorops[i]->multseg_lut1d_info.lut_size = segment_info->entries_count;
+ colorops[i]->multseg_lut1d_info.lut =
+ malloc(sizeof(struct drm_color_lut_32) * colorops[i]->multseg_lut1d_info.lut_size);
+ igt_assert(colorops[i]->multseg_lut1d_info.lut);
+
+ switch (colorops[i]->multseg_lut1d_info.lut_type) {
+ case KMS_COLOROP_MULTSEG_LUT1D_ZERO:
+ create_zero_lut(segment_info, colorops[i]->multseg_lut1d_info.lut);
+ break;
+ case KMS_COLOROP_MULTSEG_LUT1D_LINEAR:
+ create_unity_lut(segment_info, colorops[i]->multseg_lut1d_info.lut);
+ break;
+ case KMS_COLOROP_MULTSEG_LUT1D_MAX:
+ default:
+ create_max_lut(segment_info, colorops[i]->multseg_lut1d_info.lut);
+ }
+ clear_segment_data(segment_info);
+ } else if (colorops[i]->type == KMS_COLOROP_CUSTOM_LUT1D) {
+ unsigned int size;
+ gamma_lut_t *lut;
+ struct drm_color_lut_32 *lut_32;
+
+ size = igt_colorop_get_prop(&data->display, colorops[i]->colorop, IGT_COLOROP_SIZE);
+ igt_assert_f(size <= MAX_COLOR_LUT_ENTRIES,
+ "LUT size %u exceeds max %u\n", size, MAX_COLOR_LUT_ENTRIES);
+
+ switch (colorops[i]->lut_type) {
+ case KMS_COLOROP_LUT1D_ZERO:
+ lut = generate_table(size, 0.0);
+ break;
+ case KMS_COLOROP_LUT1D_LINEAR:
+ lut = generate_table(size, 1.0);
+ break;
+ case KMS_COLOROP_LUT1D_MAX:
+ default:
+ lut = generate_table_max(size);
+ }
- if (colorops[i]->type != KMS_COLOROP_MULTSEG_LUT1D)
- continue;
+ lut_32 = coeffs_to_lut_32(data, lut, 32, 0);
+ igt_assert(lut_32);
- hwlut_caps = igt_colorop_get_prop(&data->display, colorops[i]->colorop, IGT_COLOROP_HW_CAPS);
- segment_info = get_segment_data(data->drm_fd, hwlut_caps);
-
- igt_info("Lut size (%s): %d\n", colorops[i]->name, segment_info->entries_count);
-
- colorops[i]->multseg_lut1d_info.lut_size = segment_info->entries_count;
- colorops[i]->multseg_lut1d_info.lut =
- malloc(sizeof(struct drm_color_lut_32) * colorops[i]->multseg_lut1d_info.lut_size);
- igt_assert(colorops[i]->multseg_lut1d_info.lut);
-
- switch (colorops[i]->multseg_lut1d_info.lut_type) {
- case KMS_COLOROP_MULTSEG_LUT1D_ZERO:
- create_zero_lut(segment_info, colorops[i]->multseg_lut1d_info.lut);
- break;
- case KMS_COLOROP_MULTSEG_LUT1D_LINEAR:
- create_unity_lut(segment_info, colorops[i]->multseg_lut1d_info.lut);
- break;
- case KMS_COLOROP_MULTSEG_LUT1D_MAX:
- default:
- create_max_lut(segment_info, colorops[i]->multseg_lut1d_info.lut);
- }
+ colorops[i]->lut1d = calloc(1, sizeof(struct igt_1dlut));
+ igt_assert(colorops[i]->lut1d);
- clear_segment_data(segment_info);
+ memcpy(colorops[i]->lut1d->lut, lut_32, size * sizeof(struct drm_color_lut_32));
+ free_lut(lut);
+ }
}
}
@@ -1367,6 +1401,16 @@ run_tests_for_pipe(data_t *data)
.lut_type = KMS_COLOROP_MULTSEG_LUT1D_MAX,
},
};
+ kms_colorop_t lut1d_linear = {
+ .type = KMS_COLOROP_CUSTOM_LUT1D,
+ .name = "Pre/Post CSC GAMMA (linear LUT)",
+ .lut_type = KMS_COLOROP_LUT1D_LINEAR,
+ };
+ kms_colorop_t lut1d_max = {
+ .type = KMS_COLOROP_CUSTOM_LUT1D,
+ .name = "Pre/Post CSC GAMMA (max LUT)",
+ .lut_type = KMS_COLOROP_LUT1D_MAX,
+ };
kms_colorop_t ctm_3x4 = {
.type = KMS_COLOROP_CTM_3X4,
.name = "CTM 3X4 (red to blue)",
@@ -1408,6 +1452,31 @@ run_tests_for_pipe(data_t *data)
.exp_colors = colors_red_to_blue,
.colorops = { &lut1d_multseg_linear, &ctm_3x4, &lut1d_multseg_max, NULL },
},
+ { .name = "lut1d",
+ .fb_colors = colors_rgb,
+ .exp_colors = colors_rgb,
+ .colorops = { &lut1d_max, NULL },
+ },
+ { .name = "lut1d-ctm3x4",
+ .fb_colors = colors_rgb,
+ .exp_colors = colors_red_to_blue,
+ .colorops = { &lut1d_max, &ctm_3x4, NULL },
+ },
+ { .name = "ctm3x4-lut1d",
+ .fb_colors = colors_rgb,
+ .exp_colors = colors_red_to_blue,
+ .colorops = { &ctm_3x4, &lut1d_max, NULL },
+ },
+ { .name = "lut1d-lut1d",
+ .fb_colors = colors_rgb,
+ .exp_colors = colors_rgb,
+ .colorops = { &lut1d_linear, &lut1d_max, NULL },
+ },
+ { .name = "lut1d-ctm3x4-lut1d",
+ .fb_colors = colors_rgb,
+ .exp_colors = colors_red_to_blue,
+ .colorops = { &lut1d_linear, &ctm_3x4, &lut1d_max, NULL },
+ },
};
igt_fixture {
diff --git a/tests/kms_color_helper.c b/tests/kms_color_helper.c
index ba6890c86..e170202c2 100644
--- a/tests/kms_color_helper.c
+++ b/tests/kms_color_helper.c
@@ -220,6 +220,53 @@ struct drm_color_lut *coeffs_to_lut(data_t *data,
return lut;
}
+struct drm_color_lut_32 *coeffs_to_lut_32(data_t *data,
+ const gamma_lut_t *gamma,
+ uint32_t color_depth,
+ int off)
+{
+ struct drm_color_lut_32 *lut;
+ int i, lut_size = gamma->size;
+ uint64_t max_value = (1ULL << 32) - 1;
+ uint32_t mask;
+
+ if (is_intel_device(data->drm_fd))
+ mask = ((1ULL << color_depth) - 1) << (32 - color_depth);
+ else
+ mask = max_value;
+
+ lut = malloc(sizeof(struct drm_color_lut_32) * lut_size);
+
+ if (IS_CHERRYVIEW(data->devid))
+ lut_size -= 1;
+ for (i = 0; i < lut_size; i++) {
+ uint32_t r = gamma->coeffs[i].r * max_value;
+ uint32_t g = gamma->coeffs[i].g * max_value;
+ uint32_t b = gamma->coeffs[i].b * max_value;
+
+ /*
+ * Hardware might encode colors on a different number of bits
+ * than what is in our framebuffer (10 or 12bits for example).
+ * Mask the lower bits not provided by the framebuffer so we
+ * can do CRC comparisons.
+ */
+ r &= mask;
+ g &= mask;
+ b &= mask;
+
+ lut[i].red = r;
+ lut[i].green = g;
+ lut[i].blue = b;
+ }
+
+ if (IS_CHERRYVIEW(data->devid))
+ lut[lut_size].red =
+ lut[lut_size].green =
+ lut[lut_size].blue = lut[lut_size - 1].red;
+
+ return lut;
+}
+
void set_degamma(data_t *data,
igt_pipe_t *pipe,
const gamma_lut_t *gamma)
@@ -537,9 +584,13 @@ void set_colorop(igt_display_t *display, kms_colorop_t *colorop)
igt_colorop_set_ctm_3x4(display, colorop->colorop, colorop->matrix_3x4);
break;
case KMS_COLOROP_CUSTOM_LUT1D:
- fill_custom_1dlut(display, colorop);
+ if (!is_intel_device(display->drm_fd))
+ fill_custom_1dlut(display, colorop);
lut_size = igt_colorop_get_prop(display, colorop->colorop, IGT_COLOROP_SIZE);
- igt_colorop_set_custom_1dlut(display, colorop->colorop, colorop->lut1d, lut_size * sizeof(struct drm_color_lut));
+ if (is_intel_device(display->drm_fd))
+ igt_colorop_set_custom_1dlut(display, colorop->colorop, colorop->lut1d, lut_size * sizeof(struct drm_color_lut_32));
+ else
+ igt_colorop_set_custom_1dlut(display, colorop->colorop, colorop->lut1d, lut_size * sizeof(struct drm_color_lut));
break;
case KMS_COLOROP_MULTSEG_LUT1D:
igt_colorop_set_multseg_1dlut(display, colorop->colorop, colorop->multseg_lut1d_info);
diff --git a/tests/kms_color_helper.h b/tests/kms_color_helper.h
index c384de8a2..86f0a0e11 100644
--- a/tests/kms_color_helper.h
+++ b/tests/kms_color_helper.h
@@ -96,6 +96,10 @@ struct drm_color_lut *coeffs_to_lut(data_t *data,
const gamma_lut_t *gamma,
uint32_t color_depth,
int off);
+struct drm_color_lut_32 *coeffs_to_lut_32(data_t *data,
+ const gamma_lut_t *gamma,
+ uint32_t color_depth,
+ int off);
void set_degamma(data_t *data,
igt_pipe_t *pipe,
const gamma_lut_t *gamma);
@@ -159,6 +163,12 @@ typedef enum kms_colorop_multseg_lut1d_tf {
KMS_COLOROP_MULTSEG_LUT1D_MAX,
} kms_colorop_multseg_lut1d_tf_t;
+typedef enum kms_colorop_lut1d_tf_v2 {
+ KMS_COLOROP_LUT1D_ZERO,
+ KMS_COLOROP_LUT1D_LINEAR,
+ KMS_COLOROP_LUT1D_MAX,
+} kms_colorop_lut1d_tf_v2_t;
+
typedef struct kms_colorop_multseg_lut1d_info {
uint32_t lut_size;
kms_colorop_multseg_lut1d_tf_t lut_type;
@@ -177,6 +187,7 @@ typedef struct kms_colorop {
double multiplier;
};
+ kms_colorop_lut1d_tf_v2_t lut_type;
kms_colorop_lut3d_info_t lut3d_info;
const char *name;
--
2.25.1
More information about the igt-dev
mailing list