[PATCH i-g-t v2 4/4] tests/kms_rotation: Add command line option to reduce the number of tests

Louis Chauvet louis.chauvet at bootlin.com
Wed Mar 13 17:09:43 UTC 2024


As it is often needed to reduce the number of tests (for example during
development), add few command line options to reduce the number of
subtests.

Also add command line option to set a specific plane size.

Signed-off-by: Louis Chauvet <louis.chauvet at bootlin.com>
---
 tests/kms_rotation.c | 116 ++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 111 insertions(+), 5 deletions(-)

diff --git a/tests/kms_rotation.c b/tests/kms_rotation.c
index 333485619541..4d168f66abef 100644
--- a/tests/kms_rotation.c
+++ b/tests/kms_rotation.c
@@ -21,12 +21,19 @@
  * @fd: file descriptor for the current drm device
  * @display: display used for the tests
  * @width, @height: Size of the CRTC used for this test
+ * @format: If not zero, the format to test
+ * @rotation_mask: A mask of IGT_ROTATION_* / IGT_REFLECT_*. This allows running only the subtests where all the values
+ * in this mask are used. So for example:
+ *   IGT_ROTATION_0 | IGT_REFLECT_X will run rot_0, rot_0+reflect_x, rot_0+reflect_x+reflect_y
+ *   IGT_ROTATION_180 | IGT_ROTATION_90 will not run anything, it's not possible to rotate by 90 and 180 simultaneously
  */
 struct data_t {
 	int fd;
 	igt_display_t display;
 	uint32_t width;
 	uint32_t height;
+	uint32_t format;
+	uint32_t rotation_mask;
 };
 
 /**
@@ -66,6 +73,19 @@ static uint32_t tested_rotation[] = {
 	IGT_ROTATION_270 | IGT_REFLECT_X | IGT_REFLECT_Y,
 };
 
+/**
+ * should_skip() - Returns true if a specific rotation must be skipped
+ *
+ * Check if a rotation mus be skipped by comparing it to @data->rotation_mask. See @data->rotation_mask for the expected behavior.
+ *
+ * @data: Test configuration
+ * @rotation: Rotation to check for skipping
+ */
+static bool should_skip(struct data_t *data, uint32_t rotation)
+{
+	return (rotation & data->rotation_mask) != data->rotation_mask;
+}
+
 /**
  * non_equals_crc() - Check if at least one CRC is different
  *
@@ -252,6 +272,8 @@ static void get_ref_crcs(struct data_t *data, igt_output_t *output, enum pipe pi
 
 	for (int r = 0; r < ARRAY_SIZE(tested_rotation); r++) {
 		int rotation = tested_rotation[r];
+		if (should_skip(data, rotation))
+			continue;
 		igt_debug("Computing reference CRC for rotation-%s-reflect-%s\n", igt_plane_rotation_name(rotation),
 			  igt_plane_reflect_name(rotation));
 		/* Configure the pipe for reference frame */
@@ -306,6 +328,8 @@ static void get_crcs(struct data_t *data, igt_output_t *output, enum pipe pipe,
 
 	for (int r = 0; r < ARRAY_SIZE(tested_rotation); r++) {
 		int rotation = tested_rotation[r];
+		if (should_skip(data, rotation))
+			continue;
 		igt_debug("Computing CRC for rotation-%s-reflect-%s\n", igt_plane_rotation_name(rotation),
 			  igt_plane_reflect_name(rotation));
 		/* Configure the pipe for reference frame */
@@ -364,9 +388,36 @@ static void run_test(struct data_t *data, igt_output_t *output, enum pipe pipe,
 	igt_output_set_pipe(output, pipe);
 	/* Check that the rotation is supported */
 	igt_require(igt_plane_has_prop(plane, IGT_PLANE_ROTATION));
+
+	/* Get and ensure that the used crtc sizes are compatible with the current format */
 	format_description = lookup_drm_format(format);
-	width = ARRAY_SIZE(colors) * format_description->hsub * format_description->vsub * 6;
-	height = ARRAY_SIZE(colors) * format_description->hsub * format_description->vsub * 6;
+	if (data->width) {
+		width = data->width;
+		if (format_description->hsub > 1 || format_description->vsub > 1)
+			if (width % ARRAY_SIZE(colors) || width % format_description->hsub ||
+			    width % format_description->vsub) {
+				igt_warn("The requested width (%d) is not compatible with the format %s.\n"
+					 "The test will probably fail because of this.\n"
+					 "To avoid issues with subsampling and rotations, the size must be a multiple of %lu, %d and %d\n",
+					 width, igt_format_str(format), ARRAY_SIZE(colors), format_description->hsub,
+					 format_description->vsub);
+			}
+	} else {
+		width = ARRAY_SIZE(colors) * format_description->hsub * format_description->vsub * 6;
+	}
+	if (data->height) {
+		height = data->height;
+		if (format_description->hsub > 1 || format_description->vsub > 1)
+			if (height % format_description->hsub || height % format_description->vsub) {
+				igt_warn("The requested height (%d) is not compatible with the format %s.\n"
+					 "The test will probably fail because of this.\n"
+					 "To avoid issues with subsampling and rotations, the size must be a multiple of %lu, %d and %d\n",
+					 height, igt_format_str(format), ARRAY_SIZE(colors), format_description->hsub,
+					 format_description->vsub);
+			}
+	} else {
+		height = ARRAY_SIZE(colors) * format_description->hsub * format_description->vsub * 6;
+	}
 
 	/* Generate reference CRC with software rotation */
 	get_ref_crcs(data, output, pipe, plane, width, height, format, modifier, ref_crc);
@@ -377,6 +428,8 @@ static void run_test(struct data_t *data, igt_output_t *output, enum pipe pipe,
 
 	for (int c = 0; c < ARRAY_SIZE(tested_rotation); c++) {
 		int rotation = tested_rotation[c];
+		if (should_skip(data, rotation))
+			continue;
 		igt_dynamic_f("pipe-%s-format-%s-modifier-%s-rotation-%s-reflect-%s", kmstest_pipe_name(pipe),
 			      igt_format_str(format),
 			      igt_fb_modifier_name(modifier), igt_plane_rotation_name(rotation),
@@ -402,6 +455,9 @@ static void test_all_formats(struct data_t *data)
 				uint32_t format = plane->formats[f];
 				uint32_t modifier = plane->modifiers[f];
 
+				if (data->format != 0 && data->format != format)
+					continue;
+
 				if (!igt_fb_supported_format(format))
 					continue;
 				run_test(data, output, pipe, plane, format, modifier);
@@ -412,15 +468,65 @@ static void test_all_formats(struct data_t *data)
 
 static int opt_handler(int opt, int opt_index, void *void_data)
 {
-	return IGT_OPT_HANDLER_SUCCESS;
+	struct data_t *data = void_data;
+	switch (opt) {
+		case 'f': /* --format */
+			data->format = igt_drm_format_str_to_format(optarg);
+			return IGT_OPT_HANDLER_SUCCESS;
+		case 'x': /* --reflect_x */
+			data->rotation_mask |= IGT_REFLECT_X;
+			return IGT_OPT_HANDLER_SUCCESS;
+		case 'y': /* --reflect_y */
+			data->rotation_mask |= IGT_REFLECT_Y;
+			return IGT_OPT_HANDLER_SUCCESS;
+		case '0': /* --rot_0 */
+			data->rotation_mask |= IGT_ROTATION_0;
+			return IGT_OPT_HANDLER_SUCCESS;
+		case '9': /* --rot_90 */
+			data->rotation_mask |= IGT_ROTATION_90;
+			return IGT_OPT_HANDLER_SUCCESS;
+		case '1': /* --rot_180 */
+			data->rotation_mask |= IGT_ROTATION_180;
+			return IGT_OPT_HANDLER_SUCCESS;
+		case '2': /* --rot_270 */
+			data->rotation_mask |= IGT_ROTATION_270;
+			return IGT_OPT_HANDLER_SUCCESS;
+		case 's':  /* --size_x */
+			data->width = strtoul(optarg, NULL, 0);
+			return IGT_OPT_HANDLER_SUCCESS;
+		case 't':  /* --size_y */
+			data->height = strtoul(optarg, NULL, 0);
+			return IGT_OPT_HANDLER_SUCCESS;
+		default:
+			return IGT_OPT_HANDLER_ERROR;
+	}
 }
 
 static const struct option long_opts[] = {
+	{ .name = "format", .has_arg = true, .val = 'f'},
+	{ .name = "reflect_x", .has_arg = false, .val = 'x'},
+	{ .name = "reflect_y", .has_arg = false, .val = 'y'},
+	{ .name = "rot_0", .has_arg = false, .val = '0'},
+	{ .name = "rot_90", .has_arg = false, .val = '9'},
+	{ .name = "rot_180", .has_arg = false, .val = '1'},
+	{ .name = "rot_270", .has_arg = false, .val = '2'},
+	{ .name = "size_x", .has_arg = true, .val = 's'},
+	{ .name = "size_y", .has_arg = true, .val = 't'},
 	{}
 };
 
-static const char help_str[] = "";
-
+static const char help_str[] = ""
+			       "  --format <fmt>\tSet a specific format to test\n"
+			       "  --size_x <x>\tSet a specific x size for the crtc\n"
+			       "  --size_y <y>\tSet a specific y size for the crtc\n"
+			       "All the following options are used to select a specific rotation to test\n"
+			       "For example --reflect_x --rot_0 will test all rotation involving reflect_x AND rot_0\n"
+			       "  --reflect_x\tOnly test cases where X-reflexion is involved\n"
+			       "  --reflect_y\tOnly test cases where Y-reflexion is involved\n"
+			       "  --rot_0\tOnly test cases where a 0° rotation is involved\n"
+			       "  --rot_90\tOnly test cases where a 90° rotation is involved\n"
+			       "  --rot_180\tOnly test cases where a 180° rotation is involved\n"
+			       "  --rot_270\tOnly test cases where a 270° rotation is involved\n";
 static struct data_t global_data;
 
 igt_main_args("", long_opts, help_str, opt_handler, &global_data)

-- 
2.43.0



More information about the igt-dev mailing list