[PATCH i-g-t, v10 3/9] tests/kms_sharpness_filter: Add adaptive sharpness basic filter tests

Swati Sharma swati2.sharma at intel.com
Tue Dec 31 13:02:35 UTC 2024


Add new test to validate adaptive sharpness filter on LNL platform.
Add various test cases to validate this feature. Mark these as
non-CRC based tests requiring manual verification.

Pipe scaler is repurposed to perform a portion of this work.
This means pipe scaling will be disabled while the sharpening
function is in use. Use the other scaler for plane scaling.

Add 5 subtests:
	-basic: verify basic functionality
	-modifiers: verify casf with different modifiers
	-rotation: verify casf with different rotation
	-formats: verify casf with different formats
	-strength: vary strength and check difference in sharpness

TODO: -Enable casf with varying output formats (YCBCR/RGB)

v2: -Updated modifier type to uint64_t.
    -Replaced IGT_CRTC_SHARPENESS_STRENGTH with IGT_CRTC_SHARPNESS_STRENGTH.
v3: -Updated setup_fb with height and width.
v4: -Renamed tests/intel/kms_sharpness_filter.c -> tests/kms_sharpness_filter.c (Ankit)
    -Added subtest invalid filter with connector. (Ankit)
    -Updated documentation. (Bhanu)
    -Used driver_close_driver instead close. (Bhanu)
    -Added check to avoid debug print for invalid tests and filter strength = 0. (Ankit)
v5: -Instead of using default strength as MAX, use MID value strength.
    -Add relevant debug print for test skip.
    -Fix indentation.
    -Renamed invalid-filter-with-connector -> invalid-filter-with-scaling-mode
    -Reworked on invalid-filter-with-scaling-mode(), added provision to
     validate other scaling modes.
v6: -Skip test if ret=-EINVAL for downscaling test.
    -Change if() for tap subtest.
v8: -Optimize tap-filter subtest (Ankit)
v9: -Logically split tests (Ankit)
    -Fix alignment (Ankit)
v10: -Use imperative mood for commit message (Ankit)
     -Fix condition for rotation test (Ankit)
     -Change iterator from k to i (Ankit)

Signed-off-by: Swati Sharma <swati2.sharma at intel.com>
Signed-off-by: Mohammed Thasleem <mohammed.thasleem at intel.com>
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal at intel.com>
---
 tests/kms_sharpness_filter.c | 348 +++++++++++++++++++++++++++++++++++
 tests/meson.build            |   1 +
 2 files changed, 349 insertions(+)
 create mode 100644 tests/kms_sharpness_filter.c

diff --git a/tests/kms_sharpness_filter.c b/tests/kms_sharpness_filter.c
new file mode 100644
index 000000000..92981c2ae
--- /dev/null
+++ b/tests/kms_sharpness_filter.c
@@ -0,0 +1,348 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+/**
+ * TEST: kms sharpness filter
+ * Category: Display
+ * Description: Test to validate content adaptive sharpness filter
+ * Driver requirement: xe
+ * Functionality: casf
+ * Mega feature: General Display Features
+ * Test category: functionality test
+ */
+
+#include "igt.h"
+#include "igt_kms.h"
+
+/**
+ * SUBTEST: filter-basic
+ * Description: Verify basic content adaptive sharpness filter.
+ *
+ * SUBTEST: filter-strength
+ * Description: Verify that varying strength (0-255), affects the degree of sharpeness applied.
+ *
+ * SUBTEST: filter-modifiers
+ * Description: Verify content adaptive sharpness filter with varying modifiers.
+ * Functionality: casf, tiling
+ *
+ * SUBTEST: filter-rotations
+ * Description: Verify content adaptive sharpness filter with varying rotations.
+ * Functionality: casf, rotation
+ *
+ * SUBTEST: filter-formats
+ * Description: Verify content adaptive sharpness filter with varying formats.
+ * Functionality: casf, pixel-format
+*/
+
+IGT_TEST_DESCRIPTION("Test to validate content adaptive sharpness filter");
+
+/*
+ * Until the CRC support is added test needs to be invoked with
+ * --interactive|--i to manually verify if "sharpened" image
+ * is seen without corruption for each subtest.
+ */
+
+#define MIN_FILTER_STRENGTH		1
+#define MID_FILTER_STRENGTH		128
+#define MAX_FILTER_STRENGTH		255
+
+enum test_type {
+	TEST_FILTER_BASIC,
+	TEST_FILTER_MODIFIERS,
+	TEST_FILTER_ROTATION,
+	TEST_FILTER_FORMATS,
+	TEST_FILTER_STRENGTH,
+};
+
+const int filter_strength_list[] = {
+	MIN_FILTER_STRENGTH,
+	(MIN_FILTER_STRENGTH + MID_FILTER_STRENGTH) / 2,
+	MID_FILTER_STRENGTH,
+	(MID_FILTER_STRENGTH + MAX_FILTER_STRENGTH) / 2,
+	MAX_FILTER_STRENGTH,
+};
+static const struct {
+	uint64_t modifier;
+	const char *name;
+} modifiers[] = {
+	{ DRM_FORMAT_MOD_LINEAR, "linear", },
+	{ I915_FORMAT_MOD_X_TILED, "x-tiled", },
+	{ I915_FORMAT_MOD_4_TILED, "4-tiled", },
+};
+static const int formats[] = {
+	DRM_FORMAT_NV12,
+	DRM_FORMAT_RGB565,
+	DRM_FORMAT_XRGB8888,
+	DRM_FORMAT_XBGR16161616F,
+};
+static const igt_rotation_t rotations[] = {
+	IGT_ROTATION_0,
+	IGT_ROTATION_180,
+};
+
+typedef struct {
+	int drm_fd;
+	bool limited;
+	enum pipe pipe_id;
+	struct igt_fb fb[4];
+	igt_pipe_t *pipe;
+	igt_display_t display;
+	igt_output_t *output;
+	igt_plane_t *plane[4];
+	drmModeModeInfo *mode;
+	int filter_strength;
+	uint64_t modifier;
+	const char *modifier_name;
+	uint32_t format;
+	igt_rotation_t rotation;
+} data_t;
+
+static void set_filter_strength_on_pipe(data_t *data)
+{
+	igt_pipe_set_prop_value(&data->display, data->pipe_id,
+				IGT_CRTC_SHARPNESS_STRENGTH,
+				data->filter_strength);
+}
+
+static void paint_image(igt_fb_t *fb)
+{
+	cairo_t *cr = igt_get_cairo_ctx(fb->fd, fb);
+	int img_x, img_y, img_w, img_h;
+	const char *file = "1080p-left.png";
+
+	img_x = img_y = 0;
+	img_w = fb->width;
+	img_h = fb->height;
+
+	igt_paint_image(cr, file, img_x, img_y, img_w, img_h);
+
+	igt_put_cairo_ctx(cr);
+}
+
+static void setup_fb(int fd, int width, int height, uint32_t format,
+		     uint64_t modifier, struct igt_fb *fb)
+{
+	int fb_id;
+
+	fb_id = igt_create_fb(fd, width, height, format, modifier, fb);
+	igt_assert(fb_id);
+
+	paint_image(fb);
+}
+
+static void cleanup_fbs(data_t *data)
+{
+	for (int i = 0; i < ARRAY_SIZE(data->fb); i++)
+		igt_remove_fb(data->drm_fd, &data->fb[i]);
+}
+
+static void cleanup(data_t *data)
+{
+	igt_display_reset(&data->display);
+
+	cleanup_fbs(data);
+}
+
+static void test_sharpness_filter(data_t *data,  enum test_type type)
+{
+	drmModeModeInfo *mode = data->mode;
+	int height = mode->hdisplay;
+	int width =  mode->vdisplay;
+	int ret;
+
+	data->plane[0] = igt_pipe_get_plane_type(data->pipe, DRM_PLANE_TYPE_PRIMARY);
+	igt_skip_on_f(!igt_plane_has_format_mod(data->plane[0], data->format, data->modifier),
+		      "No requested format/modifier on pipe %s\n", kmstest_pipe_name(data->pipe_id));
+
+	setup_fb(data->drm_fd, height, width, data->format, data->modifier, &data->fb[0]);
+	igt_plane_set_fb(data->plane[0], &data->fb[0]);
+
+	if (type == TEST_FILTER_ROTATION) {
+		if (igt_plane_has_rotation(data->plane[0], data->rotation))
+			igt_plane_set_rotation(data->plane[0], data->rotation);
+		else
+			igt_skip("No requested rotation on pipe %s\n", kmstest_pipe_name(data->pipe_id));
+	}
+
+	set_filter_strength_on_pipe(data);
+
+	if (data->filter_strength != 0)
+		igt_debug("Sharpened image should be observed for filter strength > 0\n");
+
+	ret = igt_display_try_commit2(&data->display, COMMIT_ATOMIC);
+
+	igt_assert_eq(ret, 0);
+
+	cleanup(data);
+}
+
+static bool has_sharpness_filter(igt_pipe_t *pipe)
+{
+	return igt_pipe_obj_has_prop(pipe, IGT_CRTC_SHARPNESS_STRENGTH);
+}
+
+static void
+run_sharpness_filter_test(data_t *data, enum test_type type)
+{
+	igt_display_t *display = &data->display;
+	igt_output_t *output;
+	enum pipe pipe;
+	char name[40];
+
+	for_each_connected_output(display, output) {
+		for_each_pipe(display, pipe) {
+			igt_display_reset(display);
+
+			data->output = output;
+			data->pipe_id = pipe;
+			data->pipe = &display->pipes[data->pipe_id];
+			data->mode = igt_output_get_mode(data->output);
+
+			if (!has_sharpness_filter(data->pipe)) {
+				igt_info("%s: Doesn't support IGT_CRTC_SHARPNESS_STRENGTH.\n",
+				kmstest_pipe_name(data->pipe_id));
+				continue;
+			}
+
+			igt_output_set_pipe(data->output, data->pipe_id);
+
+			if (!intel_pipe_output_combo_valid(display)) {
+				igt_output_set_pipe(data->output, PIPE_NONE);
+				continue;
+			}
+
+			switch (type) {
+			case TEST_FILTER_BASIC:
+				snprintf(name, sizeof(name), "-basic");
+				break;
+			case TEST_FILTER_MODIFIERS:
+				snprintf(name, sizeof(name), "-%s", data->modifier_name);
+				break;
+			case TEST_FILTER_ROTATION:
+				snprintf(name, sizeof(name), "-%srot", igt_plane_rotation_name(data->rotation));
+				break;
+			case TEST_FILTER_FORMATS:
+				snprintf(name, sizeof(name), "-%s", igt_format_str(data->format));
+				break;
+			case TEST_FILTER_STRENGTH:
+				snprintf(name, sizeof(name), "-strength-%d", data->filter_strength);
+				break;
+			default:
+				igt_assert(0);
+			}
+
+			igt_dynamic_f("pipe-%s-%s%s",  kmstest_pipe_name(data->pipe_id), data->output->name, name)
+				test_sharpness_filter(data, type);
+
+			if (data->limited)
+				break;
+		}
+	}
+}
+
+static int opt_handler(int opt, int opt_index, void *_data)
+{
+	data_t *data = _data;
+
+	switch (opt) {
+	case 'l':
+		data->limited = true;
+		break;
+	default:
+		return IGT_OPT_HANDLER_ERROR;
+	}
+
+	return IGT_OPT_HANDLER_SUCCESS;
+}
+
+static const char help_str[] =
+	"  --limited|-l\t\tLimit execution to 1 valid pipe-output combo\n";
+
+data_t data = {};
+
+igt_main_args("l", NULL, help_str, opt_handler, &data)
+{
+	igt_fixture {
+		data.drm_fd = drm_open_driver_master(DRIVER_ANY);
+
+		kmstest_set_vt_graphics_mode();
+
+		igt_display_require(&data.display, data.drm_fd);
+		igt_require(data.display.is_atomic);
+		igt_display_require_output(&data.display);
+	}
+
+	igt_describe("Verify basic content adaptive sharpness filter.");
+	igt_subtest_with_dynamic("filter-basic") {
+		data.modifier = DRM_FORMAT_MOD_LINEAR;
+		data.rotation = IGT_ROTATION_0;
+		data.format = DRM_FORMAT_XRGB8888;
+		data.filter_strength = MID_FILTER_STRENGTH;
+
+		run_sharpness_filter_test(&data, TEST_FILTER_BASIC);
+	}
+
+	igt_describe("Verify that varying strength(0-255), affects "
+		     "the degree of sharpeness applied.");
+	igt_subtest_with_dynamic("filter-strength") {
+		data.modifier = DRM_FORMAT_MOD_LINEAR;
+		data.rotation = IGT_ROTATION_0;
+		data.format = DRM_FORMAT_XRGB8888;
+
+		for (int i = 0; i < ARRAY_SIZE(filter_strength_list); i++) {
+			data.filter_strength = filter_strength_list[i];
+
+			run_sharpness_filter_test(&data, TEST_FILTER_STRENGTH);
+		}
+	}
+
+	igt_describe("Verify content adaptive sharpness filter with "
+		     "varying modifiers.");
+	igt_subtest_with_dynamic("filter-modifiers") {
+		data.rotation = IGT_ROTATION_0;
+		data.format = DRM_FORMAT_XRGB8888;
+		data.filter_strength = MID_FILTER_STRENGTH;
+
+		for (int i = 0; i < ARRAY_SIZE(modifiers); i++) {
+			data.modifier = modifiers[i].modifier;
+			data.modifier_name = modifiers[i].name;
+
+			run_sharpness_filter_test(&data, TEST_FILTER_MODIFIERS);
+		}
+	}
+
+	igt_describe("Verify content adaptive sharpness filter with "
+		     "varying rotations.");
+	igt_subtest_with_dynamic("filter-rotations") {
+		data.modifier = DRM_FORMAT_MOD_LINEAR;
+		data.format = DRM_FORMAT_XRGB8888;
+		data.filter_strength = MID_FILTER_STRENGTH;
+
+		for (int i = 0; i < ARRAY_SIZE(rotations); i++) {
+			data.rotation = rotations[i];
+
+			run_sharpness_filter_test(&data, TEST_FILTER_ROTATION);
+		}
+	}
+
+	igt_describe("Verify content adaptive sharpness filter with "
+		     "varying formats.");
+	igt_subtest_with_dynamic("filter-formats") {
+		data.modifier = DRM_FORMAT_MOD_LINEAR;
+		data.rotation = IGT_ROTATION_0;
+		data.filter_strength = MID_FILTER_STRENGTH;
+
+		for (int i = 0; i < ARRAY_SIZE(formats); i++) {
+			data.format = formats[i];
+
+			run_sharpness_filter_test(&data, TEST_FILTER_FORMATS);
+		}
+	}
+
+	igt_fixture {
+		igt_display_fini(&data.display);
+		drm_close_driver(data.drm_fd);
+	}
+}
diff --git a/tests/meson.build b/tests/meson.build
index 89bba6454..f5c268b81 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -59,6 +59,7 @@ test_progs = [
 	'kms_sequence',
 	'kms_setmode',
 	'kms_sysfs_edid_timing',
+	'kms_sharpness_filter',
 	'kms_tiled_display',
 	'kms_tv_load_detect',
 	'kms_universal_plane',
-- 
2.25.1



More information about the igt-dev mailing list