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

Nautiyal, Ankit K ankit.k.nautiyal at intel.com
Fri Aug 6 09:07:41 UTC 2021


LGTM.

Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal at intel.com>

On 8/5/2021 10:47 AM, Bhanuprakash Modem wrote:
> 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 | 116 +++++++++++++++++++++++++++++++++-----------
>   1 file changed, 88 insertions(+), 28 deletions(-)
>
> diff --git a/tests/kms_setmode.c b/tests/kms_setmode.c
> index 05084c3a7..89220b83e 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,43 @@ 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++;
> -
> -	if (filter_test_id && filter_test_id != test_id)
> -		return;
> +	return (mode1->clock < mode2->clock) - (mode2->clock < mode1->clock);
> +}
>
> -	igt_info("  Test id#%d CRTC count %d\n", test_id, crtc_count);
> +static
> +int __test_crtc_config(struct crtc_config *crtcs, int crtc_count,
> +		       const struct test_config *tconf, bool *config_failed,
> +		       int base)
> +{
> +	struct crtc_config *crtc = NULL;
> +	int ret = 0;
>
> -	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 (!crtc_supports_mode(crtc, &crtc->cconfs->connector->modes[i]))
> +			continue;
> +
> +		crtc->mode = crtc->cconfs->connector->modes[i];
>
> -		igt_info("    %s\n", crtc_strs[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 +591,70 @@ static void test_crtc_config(const struct test_config *tconf,
>
>   		free(ids);
>
> +		/* crtcs[base].modes[i] don't fit, try next mode. */
> +		if (ret < 0 && errno == ENOSPC)
> +			continue;
> +
>   		if (ret < 0) {
>   			igt_assert_eq(errno, EINVAL);
> -			config_failed = true;
> +			*config_failed = true;
> +
> +			return ret;
>   		}
> +
> +		/* Try all crtcs recursively. */
> +		if (base + 1 < crtc_count)
> +			ret = __test_crtc_config(crtcs, crtc_count, tconf, config_failed, base + 1);
> +
> +		/*
> +		 * With crtcs[base].modes[i], None of the crtc[base+1] modes fits
> +		 * into the link BW.
> +		 *
> +		 * Lets try with crtcs[base].modes[i+1]
> +		 */
> +		if (ret < 0 && errno == ENOSPC)
> +			continue;
> +
> +		/*
> +		 * ret == 0, (or) ret < 0 && errno == EINVAL
> +		 * No need to try other modes of crtcs[base].
> +		 */
> +		return ret;
> +	}
> +
> +	/* When all crtcs[base].modes are tried & failed to fit into link BW. */
> +	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);
> +	igt_skip_on_f((ret < 0 && errno == ENOSPC),
> +			"No suitable mode(s) found to fit into the link BW\n");
>   	igt_assert(config_failed == !!(tconf->flags & TEST_INVALID));
>
>   	if (ret == 0 && tconf->flags & TEST_TIMINGS)
> --
> 2.32.0
>


More information about the igt-dev mailing list