[PATCH i-g-t V3] tests/kms_setmode: Fix mode selection for Nx tests

Bhanuprakash Modem bhanuprakash.modem at intel.com
Tue Aug 3 09:20:15 UTC 2021


This patch will find the connector/mode combination that fits
into the bandwidth when more than one monitor is connected.

Example:
  When two monitors connected through MST, the second monitor
  also tries to use the same mode. So two such modes may not
  fit into the link bandwidth. So, iterate through connected
  outputs & modes and find a combination of modes those fit
  into the link BW.

V2:
* Addressed comments from Ankit

Cc: Imre Deak <imre.deak at intel.com>
Cc: Ankit Nautiyal <ankit.k.nautiyal at intel.com>
Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem at intel.com>
---
 tests/kms_setmode.c | 100 ++++++++++++++++++++++++++++++++------------
 1 file changed, 73 insertions(+), 27 deletions(-)

diff --git a/tests/kms_setmode.c b/tests/kms_setmode.c
index 05084c3a7..9d0ba6c70 100644
--- a/tests/kms_setmode.c
+++ b/tests/kms_setmode.c
@@ -46,6 +46,9 @@ static int filter_test_id;
 static bool dry_run;
 static bool all_pipes = false;

+static char str_buf[MAX_CRTCS][1024];
+static const char *crtc_strs[MAX_CRTCS];
+
 const drmModeModeInfo mode_640_480 = {
 	.name		= "640x480",
 	.vrefresh	= 60,
@@ -540,44 +543,48 @@ static void check_timings(int crtc_idx, const drmModeModeInfo *kmode)
 		     fabs(mean - expected) / line_time(kmode));
 }

-static void test_crtc_config(const struct test_config *tconf,
-			     struct crtc_config *crtcs, int crtc_count)
+static int sort_drm_modes(const void *a, const void *b)
 {
-	char str_buf[MAX_CRTCS][1024];
-	const char *crtc_strs[MAX_CRTCS];
-	struct crtc_config *crtc;
-	static int test_id;
-	bool config_failed = false;
-	int ret = 0;
-	int i;
+	const drmModeModeInfo *mode1 = a, *mode2 = b;

-	test_id++;
+	return (mode1->clock < mode2->clock) - (mode2->clock < mode1->clock);
+}

-	if (filter_test_id && filter_test_id != test_id)
-		return;
+static
+int __test_crtc_config(struct crtc_config *crtcs, int crtc_count,
+		       const struct test_config *tconf, bool *config_failed,
+		       int base, int ret)
+{
+	struct crtc_config *crtc = NULL;

-	igt_info("  Test id#%d CRTC count %d\n", test_id, crtc_count);
+	if (base >= crtc_count)
+		return ret;

-	for (i = 0; i < crtc_count; i++) {
-		get_crtc_config_str(&crtcs[i], str_buf[i], sizeof(str_buf[i]));
-		crtc_strs[i] = &str_buf[i][0];
-	}
+	crtc = &crtcs[base];

-	if (dry_run) {
-		for (i = 0; i < crtc_count; i++)
-			igt_info("    %s\n", crtc_strs[i]);
-		return;
-	}
+	/* Sort the modes in descending order by clock freq. */
+	qsort(crtc->cconfs->connector->modes,
+		crtc->cconfs->connector->count_modes,
+		sizeof(drmModeModeInfo),
+		sort_drm_modes);

-	for (i = 0; i < crtc_count; i++) {
+	for (int i = 0; i < crtc->cconfs->connector->count_modes; i++) {
 		uint32_t *ids;

-		crtc = &crtcs[i];
+		if ((ret == 0 || ret == -EINVAL) && base == (crtc_count - 1))
+			return ret;
+
+		if (!crtc_supports_mode(crtc, &crtc->cconfs->connector->modes[i]))
+			continue;

-		igt_info("    %s\n", crtc_strs[i]);
+		crtc->mode = crtc->cconfs->connector->modes[i];
+
+		get_crtc_config_str(crtc, str_buf[base], sizeof(str_buf[base]));
+		crtc_strs[base] = &str_buf[base][0];
+		igt_info("    %s\n", crtc_strs[base]);

 		create_fb_for_crtc(crtc, &crtc->fb_info);
-		paint_fb(&crtc->fb_info, tconf->name, crtc_strs, crtc_count, i);
+		paint_fb(&crtc->fb_info, tconf->name, crtc_strs, crtc_count, base);

 		ids = get_connector_ids(crtc);
 		if (tconf->flags & TEST_STEALING)
@@ -589,12 +596,51 @@ static void test_crtc_config(const struct test_config *tconf,

 		free(ids);

+		if (ret < 0 && errno == ENOSPC)
+			continue;
+
 		if (ret < 0) {
 			igt_assert_eq(errno, EINVAL);
-			config_failed = true;
+			*config_failed = true;
+
+			return ret;
 		}
+
+		ret = __test_crtc_config(crtcs, crtc_count, tconf, config_failed, base + 1, ret);
 	}

+	return ret;
+}
+
+static void test_crtc_config(const struct test_config *tconf,
+			     struct crtc_config *crtcs, int crtc_count)
+{
+	static int test_id;
+	bool config_failed = false;
+	int ret = 0;
+	int i;
+
+	test_id++;
+
+	if (filter_test_id && filter_test_id != test_id)
+		return;
+
+	igt_info("  Test id#%d CRTC count %d\n", test_id, crtc_count);
+
+	for (i = 0; i < crtc_count; i++) {
+		get_crtc_config_str(&crtcs[i], str_buf[i], sizeof(str_buf[i]));
+		crtc_strs[i] = &str_buf[i][0];
+	}
+
+	if (dry_run) {
+		for (i = 0; i < crtc_count; i++)
+			igt_info("    %s\n", crtc_strs[i]);
+		return;
+	}
+
+	ret = __test_crtc_config(crtcs, crtc_count, tconf, &config_failed, 0, -1);
+
+	igt_assert((ret == 0 || ret == -EINVAL));
 	igt_assert(config_failed == !!(tconf->flags & TEST_INVALID));

 	if (ret == 0 && tconf->flags & TEST_TIMINGS)
--
2.32.0



More information about the Intel-gfx-trybot mailing list