[i-g-t 15/15] tests/kms_color: Add tests for 3x3 CTM matrices
Bhanuprakash Modem
bhanuprakash.modem at intel.com
Wed Jan 3 18:41:33 UTC 2024
Add tests for 3x3 CTM matrices
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem at intel.com>
---
tests/kms_color.c | 176 ++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 170 insertions(+), 6 deletions(-)
diff --git a/tests/kms_color.c b/tests/kms_color.c
index bdb80a4ad..4dd465653 100644
--- a/tests/kms_color.c
+++ b/tests/kms_color.c
@@ -51,6 +51,9 @@
* SUBTEST: ctm-%s
* Description: Check the color transformation %arg[1]
*
+ * SUBTEST: plane-ctm-%s
+ * Description: Check the Plane color transformation %arg[1]
+ *
* arg[1]:
*
* @0-25: for 0.25 transparency
@@ -611,6 +614,71 @@ static bool test_pipe_ctm(data_t *data,
return ret;
}
+static bool test_plane_ctm(data_t *data,
+ igt_plane_t *plane,
+ const color_t *before,
+ const color_t *after,
+ igt_colorop_t *color_pipeline,
+ kms_colorop_t *colorops[])
+{
+ igt_output_t *output = data->output;
+ igt_display_t *display = &data->display;
+ drmModeModeInfo *mode = data->mode;
+ struct igt_fb fb;
+ igt_crc_t crc_software, crc_hardware;
+ bool ret = true;
+
+ igt_info("Plane CTM test is running on pipe-%s plane-%d(%s)\n",
+ kmstest_pipe_name(plane->pipe->pipe), plane->index,
+ kmstest_plane_type_name(plane->type));
+
+ igt_output_set_pipe(output, plane->pipe->pipe);
+
+ /* Create a framebuffer at the size of the output. */
+ igt_assert(igt_create_fb(data->drm_fd,
+ mode->hdisplay,
+ mode->vdisplay,
+ data->drm_format,
+ DRM_FORMAT_MOD_LINEAR,
+ &fb));
+
+ igt_plane_set_fb(plane, &fb);
+
+ disable_degamma(plane->pipe);
+ disable_gamma(plane->pipe);
+ disable_ctm(plane->pipe);
+
+ /* Bypass the pipeline */
+ paint_rectangles(data, mode, after, &fb);
+ set_color_pipeline_bypass(plane);
+ 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_software);
+
+ /* Apply CTM matrix */
+ set_color_pipeline(display, plane, colorops, color_pipeline);
+ paint_rectangles(data, mode, before, &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_hardware);
+
+ /*
+ * Verify that the CRC of the software computed output is
+ * equal to the CRC of the CTM matrix transformation output.
+ */
+ ret &= igt_skip_crc_compare || igt_check_crc_equal(&crc_software, &crc_hardware);
+
+ set_color_pipeline_bypass(plane);
+ igt_plane_set_fb(plane, NULL);
+ igt_output_set_pipe(output, PIPE_NONE);
+ igt_display_commit2(display, COMMIT_ATOMIC);
+ igt_remove_fb(data->drm_fd, &fb);
+
+ return ret;
+}
+
/*
* Hardware computes CRC based on the number of bits it is working with (8,
* 10, 12, 16 bits), meaning with a framebuffer of 8bits per color will
@@ -861,6 +929,88 @@ out:
test_cleanup(data);
}
+static void run_ctm_tests_for_plane(data_t *data,
+ enum pipe pipe,
+ const color_t *fb_colors,
+ const double *ctm,
+ int iter)
+{
+ igt_plane_t *plane;
+ double delta;
+
+ test_setup(data, pipe);
+
+ data->color_depth = 8;
+ delta = 1.0 / (1 << data->color_depth);
+ data->drm_format = DRM_FORMAT_XRGB8888;
+ data->mode = igt_output_get_mode(data->output);
+
+ if (!pipe_output_combo_valid(data, pipe))
+ goto out;
+
+ if (!iter)
+ iter = 1;
+
+ igt_dynamic_f("pipe-%s-%s", kmstest_pipe_name(pipe), igt_output_name(data->output)) {
+ int first_plane = -1;
+ int last_plane = -1;
+ kms_colorop_t colorop_ctm_3x3 = {
+ .type = KMS_COLOROP_CTM_3X3,
+ .matrix_3x3 = (const igt_matrix_3x3_t *) ctm,
+ .transform = NULL
+ };
+ kms_colorop_t *colorops[] = { &colorop_ctm_3x3, NULL };
+
+ /* Run only for two planes */
+ for_each_plane_on_pipe(&data->display, pipe, plane) {
+ if (!igt_plane_has_prop(plane, IGT_PLANE_COLOR_PIPELINE))
+ continue;
+
+ /* Get first & last valid planes. */
+ if (first_plane < 0)
+ first_plane = j__;
+
+ last_plane = j__;
+ }
+
+ if (first_plane < 0)
+ igt_skip("No valid planes found.\n");
+
+ for_each_plane_on_pipe(&data->display, pipe, plane) {
+ igt_colorop_t *color_pipeline = NULL;
+ bool success = false;
+ int i;
+
+ if (j__ != first_plane && j__ != last_plane)
+ continue;
+
+ color_pipeline = get_color_pipeline(&data->display, plane, colorops);
+
+ for (i = 0; i < iter; i++) {
+ color_t expected_colors[3] = {
+ fb_colors[0],
+ fb_colors[1],
+ fb_colors[2],
+ };
+
+ transform_color(&expected_colors[0], ctm, delta * (i - (iter / 2)));
+ transform_color(&expected_colors[1], ctm, delta * (i - (iter / 2)));
+ transform_color(&expected_colors[2], ctm, delta * (i - (iter / 2)));
+
+ if (test_plane_ctm(data, plane, fb_colors,
+ expected_colors,
+ color_pipeline, colorops)) {
+ success = true;
+ break;
+ }
+ }
+ igt_assert(success);
+ }
+ }
+out:
+ test_cleanup(data);
+}
+
static void
run_deep_color_tests_for_pipe(data_t *data, enum pipe p)
{
@@ -1151,13 +1301,27 @@ run_tests_for_pipe(data_t *data)
}
}
- igt_fixture
- igt_require(data->display.is_atomic);
+ igt_subtest_group {
+ igt_fixture
+ igt_require(data->display.is_atomic);
+
+ for (i = 0; i < ARRAY_SIZE(ctm_tests); i++) {
+ igt_describe_f("%s", ctm_tests[i].desc);
+ igt_subtest_with_dynamic_f("plane-%s", ctm_tests[i].name) {
+ for_each_pipe(&data->display, pipe) {
+ run_ctm_tests_for_plane(data, pipe,
+ ctm_tests[i].fb_colors,
+ ctm_tests[i].ctm,
+ ctm_tests[i].iter);
+ }
+ }
+ }
- 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_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.40.0
More information about the Intel-gfx-trybot
mailing list