[igt-dev] [PATCH i-g-t] tests/kms_display_modes: Add negative test for extended display

B, Jeevan jeevan.b at intel.com
Fri Apr 14 11:41:25 UTC 2023


> -----Original Message-----
> From: igt-dev <igt-dev-bounces at lists.freedesktop.org> On Behalf Of
> Mohammed Thasleem
> Sent: Tuesday, April 11, 2023 11:03 PM
> To: igt-dev at lists.freedesktop.org
> Subject: [igt-dev] [PATCH i-g-t] tests/kms_display_modes: Add negative test for
> extended display
> 
> Added negative test to validte ENOSPC when two 2k-4k or 4k-4k moniters
> connected through MST.
> This test added to prvode bandwidth issue in MST config.
> 
> 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: Rebased on tip.
> v3: Code cleanup and updated description.
> 
> Signed-off-by: Mohammed Thasleem <mohammed.thasleem at intel.com>
> ---
>  tests/kms_display_modes.c | 161
> ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 161 insertions(+)
> 
> diff --git a/tests/kms_display_modes.c b/tests/kms_display_modes.c index
> d69c7b931..1fe1be1ac 100644
> --- a/tests/kms_display_modes.c
> +++ b/tests/kms_display_modes.c
> @@ -26,14 +26,107 @@
> 
>  #include "igt.h"
> 
> +#define HDISPLAY_2K	2560
> +#define VDISPLAY_2K	1440
> +
> +#define HDISPLAY_4K	3840
> +#define VDISPLAY_4K	2160
> +
>  IGT_TEST_DESCRIPTION("Test Display Modes");
> 
>  typedef struct {
>  	int drm_fd;
>  	igt_display_t display;
> +	drmModeModeInfo mode_mst[2];
> +	igt_output_t *mst_output[2];
>  	int n_pipes;
>  } data_t;
> 

Add comments to describe the function. 
> +static drmModeModeInfo *get_highres_mode(igt_output_t *output) {
> +	drmModeConnector *connector = output->config.connector;
> +	drmModeModeInfo *highest_mode = NULL;
> +
> +	igt_sort_connector_modes(connector, sort_drm_modes_by_res_dsc);
> +
> +	highest_mode = &connector->modes[0];
> +
> +	return highest_mode;
> +}
> +
Same here, Also check for formatting of code its not consistent.  
> +static drmModeModeInfo *get_mode(igt_output_t *output) {
> +	drmModeModeInfo *required_mode = NULL;
> +	drmModeConnector *connector = output->config.connector;
> +	int j;
> +
> +	igt_sort_connector_modes(connector, sort_drm_modes_by_res_dsc);
> +	for (j = 0; j < connector->count_modes; j++) {
> +
> +		if (connector->modes[j].vdisplay <= VDISPLAY_4K &&
> +		    connector->modes[j].hdisplay <= HDISPLAY_4K) {
> +			required_mode = &connector->modes[j];
> +			break;
> +		}
> +	}
> +
> +	return required_mode;
> +}
> +

Error handling is not done if blob property is not found. 
> +static int parse_path_blob(char *blob_data) {
> +	int connector_id;
> +	char *encoder;
> +
> +	encoder = strtok(blob_data, ":");
> +	igt_assert_f(!strcmp(encoder, "mst"), "PATH connector property
> +expected to have 'mst'\n");
> +
> +	connector_id = atoi(strtok(NULL, "-"));
> +
> +	return connector_id;
> +}
> +
> +static bool output_is_dp_mst(data_t *data, igt_output_t *output, int i)
> +{
> +	drmModePropertyBlobPtr path_blob = NULL;
> +	uint64_t path_blob_id;
> +	drmModeConnector *connector = output->config.connector;
> +	struct kmstest_connector_config config;
> +	const char *encoder;
> +	int connector_id;
> +	static int prev_connector_id;
> +
> +	kmstest_get_connector_config(data->drm_fd, output-
> >config.connector->connector_id,
> +				     -1, &config);
> +	encoder = kmstest_encoder_type_str(config.encoder->encoder_type);
> +
> +	if (strcmp(encoder, "DP MST"))
> +		return false;
> +
> +	igt_assert(kmstest_get_property(data->drm_fd, connector-
> >connector_id,
> +		   DRM_MODE_OBJECT_CONNECTOR, "PATH", NULL,
> +		   &path_blob_id, NULL));
> +
> +	igt_assert(path_blob = drmModeGetPropertyBlob(data->drm_fd,
> +path_blob_id));
> +
> +	connector_id = parse_path_blob((char *) path_blob->data);
> +
> +	drmModeFreePropertyBlob(path_blob);
> +
> +	/*
> +	 * Discarding outputs of other DP MST topology.
> +	 * Testing only on outputs on the topology we got previously
> +	 */
> +	if (i == 0) {
> +		prev_connector_id = connector_id;
> +	} else {
> +		if (connector_id != prev_connector_id)
> +			return false;
> +	}
> +
> +	return true;
> +}
> +
>  static void run_extendedmode_basic(data_t *data,
>  				   enum pipe pipe1, igt_output_t *output1,
>  				   enum pipe pipe2, igt_output_t *output2) @@
> -173,8 +266,46 @@ static void run_extendedmode_test(data_t *data) {
>  	}
>  }
> 
> +static void run_extendedmode_negative(data_t *data, int pipe1, int
> +pipe2) {
> +	struct igt_fb fbs[2];
> +	igt_display_t *display = &data->display;
> +	igt_plane_t *plane[2];
> +	int ret;
> +
> +	igt_display_reset(display);
> +
> +	igt_output_set_pipe(data->mst_output[0], pipe1);
> +	igt_output_set_pipe(data->mst_output[1], pipe2);
> +
> +	igt_create_color_fb(data->drm_fd, data->mode_mst[0].hdisplay, data-
> >mode_mst[0].vdisplay,
> +			    DRM_FORMAT_XRGB8888,
> DRM_FORMAT_MOD_LINEAR, 1, 0, 0, &fbs[0]);
> +	igt_create_color_fb(data->drm_fd, data->mode_mst[1].hdisplay, data-
> >mode_mst[1].vdisplay,
> +			    DRM_FORMAT_XRGB8888,
> DRM_FORMAT_MOD_LINEAR, 0, 0, 1, &fbs[1]);
> +
> +	plane[0] = igt_pipe_get_plane_type(&display->pipes[pipe1],
> DRM_PLANE_TYPE_PRIMARY);
> +	plane[1] = igt_pipe_get_plane_type(&display->pipes[pipe2],
> +DRM_PLANE_TYPE_PRIMARY);
> +
> +	igt_plane_set_fb(plane[0], &fbs[0]);
> +	igt_fb_set_size(&fbs[0], plane[0], data->mode_mst[0].hdisplay, data-
> >mode_mst[0].vdisplay);
> +	igt_plane_set_size(plane[0], data->mode_mst[0].hdisplay,
> +data->mode_mst[0].vdisplay);
> +
> +	igt_plane_set_fb(plane[1], &fbs[1]);
> +	igt_fb_set_size(&fbs[1], plane[1], data->mode_mst[1].hdisplay, data-
> >mode_mst[1].vdisplay);
> +	igt_plane_set_size(plane[1], data->mode_mst[1].hdisplay,
> +data->mode_mst[1].vdisplay);
> +
> +	igt_output_override_mode(data->mst_output[0], &data-
> >mode_mst[0]);
> +	igt_output_override_mode(data->mst_output[1], &data-
> >mode_mst[1]);
> +
> +	ret = igt_display_try_commit2(display, COMMIT_ATOMIC);
> +	igt_assert(ret != 0 && errno == ENOSPC); }
> +
>  igt_main
>  {
> +	int dp_mst_outputs = 0, count = 0;
> +	enum pipe pipe1, pipe2;
> +	igt_output_t *output;
>  	data_t data;
> 
>  	igt_fixture {
> @@ -182,12 +313,42 @@ igt_main
>  		kmstest_set_vt_graphics_mode();
>  		igt_display_require(&data.display, data.drm_fd);
>  		igt_display_require_output(&data.display);
> +
> +		for_each_connected_output(&data.display, output) {
> +			data.mst_output[count++] = output;
> +			if (output_is_dp_mst(&data, output, dp_mst_outputs))
> +				dp_mst_outputs++;
> +		}
>  	}
> 
>  	igt_describe("Test for validating display extended mode with a pair of
> connected displays");
>  	igt_subtest_with_dynamic("extended-mode-basic")
>  		run_extendedmode_test(&data);
> 
> +	igt_describe("Negative test for validating display extended mode with a
> pair of connected "
> +		     "2k-4k or 4k-4k displays");
> +	igt_subtest_with_dynamic("mst-extended-mode-negative") {
> +		igt_require_f(dp_mst_outputs > 1, "MST not found more then
> one\n");
> +
> +		 memcpy(&data.mode_mst[0], get_mode(data.mst_output[0]),
> sizeof(drmModeModeInfo));
> +		 memcpy(&data.mode_mst[1],
> get_highres_mode(data.mst_output[1]),
> +				 sizeof(drmModeModeInfo));
> +
> +		igt_require_f((data.mode_mst[1].hdisplay >= HDISPLAY_4K &&
> +			       data.mode_mst[1].vdisplay >= VDISPLAY_4K), "4k
> panel not
> +found\n");
> +
> +		for_each_pipe(&data.display, pipe1) {
> +			for_each_pipe(&data.display, pipe2) {
> +				if (pipe1 == pipe2)
> +					continue;
> +
> +				igt_dynamic_f("pipe-%s-%s",
> kmstest_pipe_name(pipe1),
> +					      kmstest_pipe_name(pipe2))
> +					run_extendedmode_negative(&data,
> pipe1, pipe2);
> +			}
> +		}
> +	}
> +
>  	igt_fixture {
>  		igt_display_fini(&data.display);
>  	}
> --
> 2.25.1



More information about the igt-dev mailing list