[RFC v4 22/22] tests/kms_color: Add plane color pipeline tests for Intel hardware
Bhanuprakash Modem
bhanuprakash.modem at intel.com
Wed Feb 14 06:39:53 UTC 2024
For now, Intel plane color pipeline contains 3 colorops:
Pre-csc gamma (1D LUT) --> CTM 3x3 --> 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-ctm3x3
igt at kms_color@plane-lut1d-ctm3x3
igt at kms_color@plane-ctm3x3-lut1d
igt at kms_color@plane-lut1d-lut1d
igt at kms_color@plane-lut1d-ctm3x3-lut1d
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem at intel.com>
---
tests/kms_color.c | 273 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 267 insertions(+), 6 deletions(-)
diff --git a/tests/kms_color.c b/tests/kms_color.c
index bdb80a4ad..5a8bc6eb9 100644
--- a/tests/kms_color.c
+++ b/tests/kms_color.c
@@ -34,6 +34,8 @@
#include "kms_color_helper.h"
+#define MAX_COLOROPS 5
+
/**
* SUBTEST: degamma
* Description: Verify that degamma LUT transformation works correctly
@@ -78,6 +80,20 @@
* @gamma-lut: Gamma LUT
*/
+/**
+ * SUBTEST: plane-%s
+ * Description: Test plane color pipeline with colorops: %arg[1].
+ *
+ * arg[1]:
+ *
+ * @lut1d: 1D LUT
+ * @ctm3x3: 3X3 CTM
+ * @lut1d-ctm3x3: 1D LUT --> 3X3 CTM
+ * @ctm3x3-lut1d: 3X3 CTM --> 1D LUT
+ * @lut1d-lut1d: 1D LUT --> 1D LUT
+ * @lut1d-ctm3x3-lut1d: 1D LUT --> 3X3 CTM --> 1D LUT
+ */
+
IGT_TEST_DESCRIPTION("Test Color Features at Pipe level");
static bool test_pipe_degamma(data_t *data,
@@ -725,6 +741,137 @@ static void test_pipe_limited_range_ctm(data_t *data,
}
#endif
+static void clear_lut_data(kms_colorop_t *colorops[])
+{
+ int i;
+
+ for (i = 0; colorops[i]; i++) {
+ if (colorops[i]->type != KMS_COLOROP_CUSTOM_LUT1D)
+ continue;
+
+ if (colorops[i]->custom_lut1d_info.lut)
+ free(colorops[i]->custom_lut1d_info.lut);
+ }
+}
+
+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_CUSTOM_LUT1D)
+ continue;
+
+ 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]->custom_lut1d_info.lut_size = segment_info->entries_count;
+ colorops[i]->custom_lut1d_info.lut =
+ malloc(sizeof(struct drm_color_lut_ext) * colorops[i]->custom_lut1d_info.lut_size);
+ igt_assert(colorops[i]->custom_lut1d_info.lut);
+
+ switch (colorops[i]->custom_lut1d_info.lut_type) {
+ case KMS_COLOROP_CUSTOM_LUT1D_ZERO:
+ create_zero_lut(segment_info, colorops[i]->custom_lut1d_info.lut);
+ break;
+ case KMS_COLOROP_CUSTOM_LUT1D_LINEAR:
+ create_unity_lut(segment_info, colorops[i]->custom_lut1d_info.lut);
+ break;
+ case KMS_COLOROP_CUSTOM_LUT1D_MAX:
+ default:
+ create_max_lut(segment_info, colorops[i]->custom_lut1d_info.lut);
+ }
+
+ clear_segment_data(segment_info);
+ }
+}
+
+static bool ctm_colorop_only(kms_colorop_t *colorops[])
+{
+ int i;
+
+ for (i = 0; colorops[i]; i++)
+ if (colorops[i]->type != KMS_COLOROP_CTM_3X3)
+ return false;
+ return true;
+}
+
+static bool test_plane_colorops(data_t *data,
+ const color_t *fb_colors,
+ const color_t *exp_colors,
+ kms_colorop_t *colorops[])
+{
+ igt_plane_t *plane = data->primary;
+ igt_output_t *output = data->output;
+ igt_display_t *display = &data->display;
+ drmModeModeInfo *mode = data->mode;
+ struct igt_fb fb;
+ bool ret;
+ igt_colorop_t *color_pipeline = get_color_pipeline(display, plane, colorops);
+ igt_crc_t crc_gamma, crc_fullcolors;
+
+ igt_output_set_pipe(output, plane->pipe->pipe);
+ mode = igt_output_get_mode(output);
+
+ /* Create a framebuffer at the size of the output. */
+ igt_assert(igt_create_fb(data->drm_fd,
+ mode->hdisplay,
+ mode->vdisplay,
+ DRM_FORMAT_XRGB8888,
+ DRM_FORMAT_MOD_LINEAR,
+ &fb));
+ igt_plane_set_fb(plane, &fb);
+
+ /* Disable Pipe color props. */
+ disable_ctm(plane->pipe);
+ disable_degamma(plane->pipe);
+ disable_gamma(plane->pipe);
+ igt_display_commit2(display, COMMIT_ATOMIC);
+
+ set_color_pipeline_bypass(plane);
+ paint_rectangles(data, mode, exp_colors, &fb);
+ igt_plane_set_fb(plane, &fb);
+ igt_display_commit2(display, COMMIT_ATOMIC);
+ igt_wait_for_vblank(data->drm_fd,
+ display->pipes[plane->pipe->pipe].crtc_offset);
+ igt_pipe_crc_collect_crc(data->pipe_crc, &crc_fullcolors);
+
+ /*
+ * Draw gradient colors with LUT to remap all
+ * values to max red/green/blue.
+ */
+ prepare_lut_data(data, colorops);
+ set_color_pipeline(display, plane, colorops, color_pipeline);
+ if (ctm_colorop_only(colorops))
+ paint_rectangles(data, mode, fb_colors, &fb);
+ else
+ paint_gradient_rectangles(data, mode, fb_colors, &fb);
+ igt_plane_set_fb(plane, &fb);
+ igt_display_commit2(display, COMMIT_ATOMIC);
+ igt_wait_for_vblank(data->drm_fd,
+ display->pipes[plane->pipe->pipe].crtc_offset);
+ igt_pipe_crc_collect_crc(data->pipe_crc, &crc_gamma);
+
+ /*
+ * Verify that the CRC of the software computed output is
+ * equal to the CRC of the gamma LUT transformation output.
+ */
+ ret = igt_check_crc_equal(&crc_gamma, &crc_fullcolors);
+
+ clear_lut_data(colorops);
+ clear_color_pipeline(display, plane, colorops, color_pipeline);
+ igt_plane_set_fb(plane, NULL);
+ igt_output_set_pipe(output, PIPE_NONE);
+ igt_display_commit2(display, COMMIT_ATOMIC);
+
+ return ret;
+}
+
static void
prep_pipe(data_t *data, enum pipe p)
{
@@ -861,6 +1008,42 @@ out:
test_cleanup(data);
}
+static void run_plane_color_tests(data_t *data,
+ const color_t *fb_colors,
+ const color_t *exp_colors,
+ kms_colorop_t *colorops[])
+{
+ enum pipe pipe;
+
+ data->color_depth = 8;
+ data->drm_format = DRM_FORMAT_XRGB8888;
+
+ for_each_pipe(&data->display, pipe) {
+ test_setup(data, pipe);
+
+ data->mode = igt_output_get_mode(data->output);
+
+ if (!pipe_output_combo_valid(data, pipe)){
+ test_cleanup(data);
+ continue;
+ }
+
+ /*
+ * TODO: Extend the test to multiple planes?
+ * Since, Intel planes (HDR & SDR) have different capabilities.
+ */
+ if (!igt_plane_has_prop(data->primary, IGT_PLANE_COLOR_PIPELINE))
+ continue;
+
+ igt_dynamic_f("pipe-%s-%s",
+ kmstest_pipe_name(pipe),
+ igt_output_name(data->output))
+ igt_assert(test_plane_colorops(data, fb_colors, exp_colors, colorops));
+ }
+
+ test_cleanup(data);
+}
+
static void
run_deep_color_tests_for_pipe(data_t *data, enum pipe p)
{
@@ -1151,13 +1334,91 @@ run_tests_for_pipe(data_t *data)
}
}
- igt_fixture
- igt_require(data->display.is_atomic);
+ igt_subtest_group {
+ static const color_t colors_red_to_blue[] = {
+ { 0.0, 0.0, 1.0 },
+ { 0.0, 1.0, 0.0 },
+ { 0.0, 0.0, 1.0 },
+ };
+ const struct drm_color_ctm ctm_red_to_blue = { {
+ 0.0, 0.0, 0.0,
+ 0.0, 1.0, 0.0,
+ 1.0, 0.0, 1.0
+ } };
+ kms_colorop_t lut1d_linear = {
+ .type = KMS_COLOROP_CUSTOM_LUT1D,
+ .name = "Pre/Post CSC GAMMA (linear LUT)",
+ .custom_lut1d_info = {
+ .lut_type = KMS_COLOROP_CUSTOM_LUT1D_LINEAR,
+ },
+ };
+ kms_colorop_t lut1d_max = {
+ .type = KMS_COLOROP_CUSTOM_LUT1D,
+ .name = "Pre/Post CSC GAMMA (max LUT)",
+ .custom_lut1d_info = {
+ .lut_type = KMS_COLOROP_CUSTOM_LUT1D_MAX,
+ },
+ };
+ kms_colorop_t ctm_3x3 = {
+ .type = KMS_COLOROP_CTM_3X3,
+ .name = "CTM 3X3 (red to blue)",
+ .matrix_3x3 = &ctm_red_to_blue,
+ };
+ struct {
+ const char *name;
+ const color_t *fb_colors;
+ const color_t *exp_colors;
+ kms_colorop_t *colorops[MAX_COLOROPS];
+ } plane_colorops_tests[] = {
+ { .name = "lut1d",
+ .fb_colors = colors_rgb,
+ .exp_colors = colors_rgb,
+ .colorops = { &lut1d_max, NULL },
+ },
+ { .name = "ctm3x3",
+ .fb_colors = colors_rgb,
+ .exp_colors = colors_red_to_blue,
+ .colorops = { &ctm_3x3, NULL },
+ },
+ { .name = "lut1d-ctm3x3",
+ .fb_colors = colors_rgb,
+ .exp_colors = colors_red_to_blue,
+ .colorops = { &lut1d_max, &ctm_3x3, NULL },
+ },
+ { .name = "ctm3x3-lut1d",
+ .fb_colors = colors_rgb,
+ .exp_colors = colors_red_to_blue,
+ .colorops = { &ctm_3x3, &lut1d_max, NULL },
+ },
+ { .name = "lut1d-lut1d",
+ .fb_colors = colors_rgb,
+ .exp_colors = colors_rgb,
+ .colorops = { &lut1d_linear, &lut1d_max, NULL },
+ },
+ { .name = "lut1d-ctm3x3-lut1d",
+ .fb_colors = colors_rgb,
+ .exp_colors = colors_red_to_blue,
+ .colorops = { &lut1d_linear, &ctm_3x3, &lut1d_max, NULL },
+ },
+ };
- igt_describe("Verify that deep color works correctly");
- igt_subtest_with_dynamic("deep-color") {
- for_each_pipe(&data->display, pipe) {
- run_deep_color_tests_for_pipe(data, pipe);
+ igt_fixture
+ igt_require(data->display.is_atomic);
+
+ for (i = 0; i < ARRAY_SIZE(plane_colorops_tests); i++) {
+ igt_describe_f("Test plane color pipeline with colorops: %s", plane_colorops_tests[i].name);
+ igt_subtest_with_dynamic_f("plane-%s", plane_colorops_tests[i].name)
+ run_plane_color_tests(data,
+ plane_colorops_tests[i].fb_colors,
+ plane_colorops_tests[i].exp_colors,
+ plane_colorops_tests[i].colorops);
+ }
+
+ igt_describe("Verify that deep color works correctly");
+ igt_subtest_with_dynamic("deep-color") {
+ for_each_pipe(&data->display, pipe) {
+ run_deep_color_tests_for_pipe(data, pipe);
+ }
}
}
}
--
2.43.0
More information about the igt-dev
mailing list