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

Nautiyal, Ankit K ankit.k.nautiyal at intel.com
Mon May 23 09:44:16 UTC 2022


LGTM.

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

On 5/23/2022 1:43 PM, 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:
> * Exit if suitable modes not found in retry.
> * New function to re-use the code.
>
> Cc: Karthik B S <karthik.b.s at intel.com>
> Cc: Ankit Nautiyal <ankit.k.nautiyal at intel.com>
> Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem at intel.com>
> ---
>   tests/kms_flip.c | 109 ++++++++++++++++++++++++++++++++++++-----------
>   1 file changed, 84 insertions(+), 25 deletions(-)
>
> diff --git a/tests/kms_flip.c b/tests/kms_flip.c
> index 773e6597..5985e012 100755
> --- a/tests/kms_flip.c
> +++ b/tests/kms_flip.c
> @@ -932,12 +932,36 @@ static bool mode_compatible(const drmModeModeInfo *a, const drmModeModeInfo *b)
>   	return true;
>   }
>   
> +static void get_compatible_modes(drmModeModeInfo *a, drmModeModeInfo *b,
> +				 drmModeConnector *c1, drmModeConnector *c2)
> +{
> +	int n, m;
> +
> +	*a = c1->modes[0];
> +	*b = c2->modes[0];
> +
> +	if (!mode_compatible(a, b)) {
> +		for (n = 0; n < c1->count_modes; n++) {
> +			*a = c1->modes[n];
> +			for (m = 0; m < c2->count_modes; m++) {
> +				*b = c2->modes[m];
> +				if (mode_compatible(a, b))
> +					return;
> +			}
> +		}
> +
> +		/* hope for the best! */
> +		*a = *b = c1->modes[0];
> +	}
> +
> +	return;
> +}
> +
>   static void connector_find_compatible_mode(int crtc_idx0, int crtc_idx1,
>   					   struct test_output *o)
>   {
>   	struct kmstest_connector_config config[2];
> -	drmModeModeInfo *mode[2];
> -	int n, m;
> +	drmModeModeInfo mode[2];
>   
>   	if (!kmstest_get_connector_config(drm_fd, o->_connector[0],
>   					  1 << crtc_idx0, &config[0]))
> @@ -949,39 +973,25 @@ static void connector_find_compatible_mode(int crtc_idx0, int crtc_idx1,
>   		return;
>   	}
>   
> -	mode[0] = &config[0].default_mode;
> -	mode[1] = &config[1].default_mode;
> -	if (!mode_compatible(mode[0], mode[1])) {
> -		for (n = 0; n < config[0].connector->count_modes; n++) {
> -			mode[0] = &config[0].connector->modes[n];
> -			for (m = 0; m < config[1].connector->count_modes; m++) {
> -				mode[1] = &config[1].connector->modes[m];
> -				if (mode_compatible(mode[0], mode[1]))
> -					goto found;
> -			}
> -		}
> -
> -		/* hope for the best! */
> -		mode[1] = mode[0] = &config[0].default_mode;
> -	}
> +	get_compatible_modes(&mode[0], &mode[1],
> +			     config[0].connector, config[1].connector);
>   
> -found:
>   	o->pipe = config[0].pipe;
> -	o->fb_width = mode[0]->hdisplay;
> -	o->fb_height = mode[0]->vdisplay;
> +	o->fb_width = mode[0].hdisplay;
> +	o->fb_height = mode[0].vdisplay;
>   	o->mode_valid = 1;
>   
>   	o->kconnector[0] = config[0].connector;
>   	o->kencoder[0] = config[0].encoder;
>   	o->_crtc[0] = config[0].crtc->crtc_id;
>   	o->_pipe[0] = config[0].pipe;
> -	o->kmode[0] = *mode[0];
> +	o->kmode[0] = mode[0];
>   
>   	o->kconnector[1] = config[1].connector;
>   	o->kencoder[1] = config[1].encoder;
>   	o->_crtc[1] = config[1].crtc->crtc_id;
>   	o->_pipe[1] = config[1].pipe;
> -	o->kmode[1] = *mode[1];
> +	o->kmode[1] = mode[1];
>   
>   	drmModeFreeCrtc(config[0].crtc);
>   	drmModeFreeCrtc(config[1].crtc);
> @@ -1302,6 +1312,33 @@ static void discard_any_stale_events(void) {
>   	}
>   }
>   
> +static int sort_drm_modes(const void *a, const void *b)
> +{
> +	const drmModeModeInfo *mode1 = a, *mode2 = b;
> +
> +	return (mode2->clock < mode1->clock) - (mode1->clock < mode2->clock);
> +}
> +
> +static void get_suitable_modes(struct test_output *o)
> +{
> +	drmModeModeInfo mode[2];
> +	int i;
> +
> +	for (i = 0; i < RUN_PAIR; i++) {
> +		qsort(o->kconnector[i]->modes,
> +		      o->kconnector[i]->count_modes,
> +		      sizeof(drmModeModeInfo),
> +		      sort_drm_modes);
> +	}
> +
> +	get_compatible_modes(&mode[0], &mode[1],
> +			     o->kconnector[0], o->kconnector[1]);
> +
> +	o->fb_width = mode[0].hdisplay;
> +	o->fb_height = mode[0].vdisplay;
> +	o->kmode[0] = mode[0];
> +	o->kmode[1] = mode[1];
> +}
>   
>   static void __run_test_on_crtc_set(struct test_output *o, int *crtc_idxs,
>   				   int crtc_count, int duration_ms)
> @@ -1309,12 +1346,13 @@ static void __run_test_on_crtc_set(struct test_output *o, int *crtc_idxs,
>   	struct udev_monitor *mon = igt_watch_uevents();
>   	unsigned bo_size = 0;
>   	bool vblank = true;
> -	bool retried = false;
> +	bool retried = false, restart = false;
>   	bool state_ok;
>   	unsigned elapsed;
>   	uint64_t modifier;
> -	int i;
> +	int i, ret;
>   
> +restart:
>   	last_connector = o->kconnector[0];
>   
>   	if (o->flags & TEST_PAN)
> @@ -1366,7 +1404,28 @@ retry:
>   
>   	igt_flush_uevents(mon);
>   
> -	igt_assert(!set_mode(o, o->fb_ids[0], 0, 0));
> +	ret = set_mode(o, o->fb_ids[0], 0, 0);
> +
> +	/* In case of DP-MST find suitable mode(s) to fit into the link BW. */
> +	if (ret < 0 && errno == ENOSPC &&
> +	    crtc_count == RUN_PAIR) {
> +
> +		if (restart) {
> +			igt_info("No suitable modes found to fit into the link BW.\n");
> +			goto out;
> +		}
> +
> +		get_suitable_modes(o);
> +
> +		igt_remove_fb(drm_fd, &o->fb_info[2]);
> +		igt_remove_fb(drm_fd, &o->fb_info[1]);
> +		igt_remove_fb(drm_fd, &o->fb_info[0]);
> +
> +		restart = true;
> +		goto restart;
> +	}
> +
> +	igt_assert(!ret);
>   	igt_assert(fb_is_bound(o, o->fb_ids[0]));
>   
>   	vblank = kms_has_vblank(drm_fd);


More information about the igt-dev mailing list