[igt-dev] [RFC PATCH 4/4][i-g-t] tests/kms_color: add 3D LUT tests

Alex Hung alex.hung at amd.com
Tue Oct 4 21:16:26 UTC 2022


This is a sample test that passes a dummy 3D LUT to a proposed 3DLUT
API and verifies 3D LUT functionalities by the hardware.

Note: The kernel 3DLUT API proposal "Proposal for Pre-blending 3D LUT
interfaces" is sent to dri-devel mailing list.

Signed-off-by: Alex Hung <alex.hung at amd.com>
---
 tests/kms_color.c        | 96 ++++++++++++++++++++++++++++++++++++++++
 tests/kms_color_helper.c | 35 +++++++++++++++
 tests/kms_color_helper.h |  1 +
 3 files changed, 132 insertions(+)

diff --git a/tests/kms_color.c b/tests/kms_color.c
index 1539c750..20bd56e2 100644
--- a/tests/kms_color.c
+++ b/tests/kms_color.c
@@ -859,6 +859,97 @@ static bool invalid_plane_ctm_test(data_t *data, igt_plane_t *plane)
 	return true;
 }
 
+static bool plane_3dlut_test(data_t *data, igt_plane_t *plane)
+{
+	igt_display_t *display = &data->display;
+	drmModeModeInfo *mode;
+	igt_output_t *output;
+	struct igt_fb fb;
+	drmModePropertyPtr lut_3d_mode = NULL;
+	igt_pipe_crc_t *pipe_crc = NULL;
+	bool ret = true;
+	uint32_t i;
+	color_t red_green_blue[] = {
+		{ 1.0, 0.0, 0.0 },
+		{ 0.0, 1.0, 0.0 },
+		{ 0.0, 0.0, 1.0 }
+	};
+
+	igt_info("Plane 3D LUT test is running on pipe-%s plane-%s(%s)\n",
+			kmstest_pipe_name(plane->pipe->pipe),
+			kmstest_plane_type_name(plane->type),
+			is_hdr_plane(plane) ? "hdr":"sdr");
+
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_3D_LUT_MODE));
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_3D_LUT));
+
+	pipe_crc = igt_pipe_crc_new(data->drm_fd, plane->pipe->pipe, "auto");
+	output = igt_get_single_output_for_pipe(display, plane->pipe->pipe);
+	igt_assert(output);
+
+	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_XRGB16161616,
+			      DRM_FORMAT_MOD_LINEAR,
+			      &fb));
+
+	igt_plane_set_fb(plane, &fb);
+
+	lut_3d_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_3D_LUT_MODE);
+	for (i = 0; i < lut_3d_mode->count_enums; i++) {
+		igt_crc_t crc_3dlut, crc_fullcolors;
+		void *lut = NULL;
+		uint32_t lut_size = 0;
+
+		igt_info("Teseting with 3D LUT mode: \'%s\'\n", lut_3d_mode->enums[i].name);
+
+		lut = create_max_3dlut(data, lut_3d_mode->enums[i].value, &lut_size);
+
+		/* Draw solid colors without 3D LUT. */
+		disable_plane_prop(plane, IGT_PLANE_3D_LUT);
+		paint_rectangles(data, mode, red_green_blue, &fb);
+		igt_plane_set_fb(plane, &fb);
+		igt_display_commit2(display, display->is_atomic ?
+				COMMIT_ATOMIC : COMMIT_LEGACY);
+		igt_wait_for_vblank(data->drm_fd,
+				display->pipes[plane->pipe->pipe].crtc_offset);
+		igt_pipe_crc_collect_crc(pipe_crc, &crc_fullcolors);
+
+		/* Draw with dummy 3D LUT */
+		paint_gradient_rectangles(data, mode, red_green_blue, &fb);
+		igt_plane_set_fb(plane, &fb);
+		igt_plane_set_prop_enum(plane, IGT_PLANE_3D_LUT_MODE, lut_3d_mode->enums[i].name);
+		igt_plane_replace_prop_blob(plane, IGT_PLANE_3D_LUT, lut, lut_size);
+		igt_assert(igt_display_commit2(display, display->is_atomic ?
+				COMMIT_ATOMIC : COMMIT_LEGACY) == 0);
+		igt_wait_for_vblank(data->drm_fd,
+				display->pipes[plane->pipe->pipe].crtc_offset);
+		igt_pipe_crc_collect_crc(pipe_crc, &crc_3dlut);
+
+		/* TODO Verify CRC values - is checking CRC reasonable? */
+
+		/* TODO Draw with a real 3D LUT that can be verified by eyes */
+
+		/* Draw without 3D LUT again */
+		paint_gradient_rectangles(data, mode, red_green_blue, &fb);
+		igt_plane_set_fb(plane, &fb);
+		disable_plane_prop(plane, IGT_PLANE_3D_LUT);
+		igt_display_commit2(display, display->is_atomic ?
+			COMMIT_ATOMIC : COMMIT_LEGACY);
+
+		free(lut);
+	}
+
+	drmModeFreeProperty(lut_3d_mode);
+	return ret;
+}
+
+
 static bool plane_3dlut_mode_test(data_t *data, igt_plane_t *plane)
 {
 	igt_display_t *display = &data->display;
@@ -1583,6 +1674,11 @@ static void run_tests_for_plane(data_t *data, enum pipe pipe)
 	igt_describe("Verify for plane 3dlut modes");
 	igt_subtest_f("pipe-%s-plane-3dlut-modes", kmstest_pipe_name(pipe))
 		run_plane_color_test(data, pipe, plane_3dlut_mode_test);
+
+	igt_describe("Compare out plane with 3dlut");
+	igt_subtest_f("pipe-%s-plane-3dlut", kmstest_pipe_name(pipe))
+		run_plane_color_test(data, pipe, plane_3dlut_test);
+
 }
 
 igt_main
diff --git a/tests/kms_color_helper.c b/tests/kms_color_helper.c
index 5ed313e9..c84ec7fa 100644
--- a/tests/kms_color_helper.c
+++ b/tests/kms_color_helper.c
@@ -423,6 +423,41 @@ segment_data_t *get_segment_data(data_t *data,
 	return info;
 }
 
+void *create_max_3dlut(data_t *data, uint64_t blob_id, uint32_t *lut_size)
+{
+	struct drm_mode_3dlut_mode *mode_3dlut = NULL;
+	drmModePropertyBlobPtr blob;
+	uint32_t fmt = 0;
+	void *lut = NULL;
+
+	blob = drmModeGetPropertyBlob(data->drm_fd, blob_id);
+	igt_assert(blob);
+	igt_assert(blob->length);
+
+	/* test with the first 3dlut */
+	mode_3dlut = (struct drm_mode_3dlut_mode *) blob->data;
+	fmt = mode_3dlut->color_format;
+	if (fmt == DRM_FORMAT_XRGB16161616 || fmt == DRM_FORMAT_XBGR16161616)
+		*lut_size = pow(mode_3dlut->lut_size, 3) * sizeof(uint64_t);
+	else if (fmt == DRM_FORMAT_XRGB8888 || fmt == DRM_FORMAT_XBGR8888)
+		*lut_size = pow(mode_3dlut->lut_size, 3) * sizeof(uint32_t);
+	else
+		return lut;
+
+	lut = malloc(sizeof(struct drm_mode_3dlut_mode) * (*lut_size));
+	igt_assert(lut);
+
+	/* TODO create 3dlut - fill with dummy values for now */
+	if (mode_3dlut->color_format == DRM_FORMAT_XRGB16161616)
+		memset(lut, 0x5A, *lut_size);
+	else if (mode_3dlut->color_format == DRM_FORMAT_XBGR16161616)
+		memset(lut, 0xA5, *lut_size);
+	else
+		memset(lut, 0, *lut_size);
+
+	return lut;
+}
+
 void verify_3dlut_mode(data_t *data, uint64_t blob_id)
 {
 	struct drm_mode_3dlut_mode *mode_3dlut = NULL;
diff --git a/tests/kms_color_helper.h b/tests/kms_color_helper.h
index 994ba2be..b097b77a 100644
--- a/tests/kms_color_helper.h
+++ b/tests/kms_color_helper.h
@@ -117,6 +117,7 @@ gamma_lut_t *pipe_create_linear_lut(segment_data_t *info);
 struct drm_color_lut_ext *create_linear_lut(segment_data_t *info);
 struct drm_color_lut_ext *create_max_lut(segment_data_t *info);
 segment_data_t *get_segment_data(data_t *data, uint64_t blob_id, char *mode);
+void *create_max_3dlut(data_t *data, uint64_t blob_id, uint32_t *lut_size);
 void verify_3dlut_mode(data_t *data, uint64_t blob_id);
 void set_pipe_gamma(igt_pipe_t *pipe, uint64_t value,
 		    struct drm_color_lut *lut, uint32_t size);
-- 
2.25.1



More information about the igt-dev mailing list