[igt-dev] [RFC, i-g-t] tests/kms_vrr: Add a new subtest to validate different VRR modes

Golani, Mitulkumar Ajitkumar mitulkumar.ajitkumar.golani at intel.com
Wed May 31 11:43:09 UTC 2023


Hi Nidhi,

> -----Original Message-----
> From: Gupta, Nidhi1 <nidhi1.gupta at intel.com>
> Sent: 30 May 2023 22:54
> To: igt-dev at lists.freedesktop.org
> Cc: Golani, Mitulkumar Ajitkumar <mitulkumar.ajitkumar.golani at intel.com>;
> Gupta, Nidhi1 <nidhi1.gupta at intel.com>
> Subject: [RFC, i-g-t] tests/kms_vrr: Add a new subtest to validate different
> VRR modes
> 
> Test switch from base VRR mode to various VRR supported modes without
> triggering modeset.
> 
> Signed-off-by: Nidhi Gupta <nidhi1.gupta at intel.com>
> ---
>  tests/kms_vrr.c | 142 +++++++++++++++++++++++++++++++++++++++++++----
> -
>  1 file changed, 127 insertions(+), 15 deletions(-)
> 
> diff --git a/tests/kms_vrr.c b/tests/kms_vrr.c index d2d79c4e..173d7010
> 100644
> --- a/tests/kms_vrr.c
> +++ b/tests/kms_vrr.c
> @@ -46,6 +46,7 @@ enum {
>  	TEST_SUSPEND = 1 << 2,
>  	TEST_FLIPLINE = 1 << 3,
>  	TEST_NEGATIVE = 1 << 4,
> +	TEST_BASE_MODE_TO_VARIOUS_VRR_MODE = 1 << 5,
>  };
> 
>  typedef struct range {
> @@ -56,10 +57,17 @@ typedef struct range {  typedef struct data {
>  	igt_display_t display;
>  	int drm_fd;
> +	int count_modes;
> +	uint32_t hdisplay;
> +	uint32_t vdisplay;
>  	igt_plane_t *primary;
>  	igt_fb_t fb0;
>  	igt_fb_t fb1;
>  	range_t range;
> +	drmModeConnector *connector;
> +	drmModeModeInfo *modes;
> +	uint32_t base_mode_index;
> +	uint32_t preferred_mode_index;
>  } data_t;
> 
>  typedef struct vtest_ns {
> @@ -168,6 +176,77 @@ get_vrr_range(data_t *data, igt_output_t *output)
>  	return range;
>  }
> 
> +static bool is_variable_video_mode(data_t *data, drmModeModeInfo
> *mode)
> +{
> +	drmModeModeInfo *base_mode = &data->modes[data-
> >base_mode_index];
> +	uint32_t bm_clock = base_mode->clock;
> +
> +	if (mode->hdisplay == data->hdisplay &&
> +	    mode->vdisplay == data->vdisplay &&
> +	    mode->clock == bm_clock &&
> +	    mode->type & DRM_MODE_TYPE_DRIVER) {
> +		return true;
> +	}
> +
> +	return false;
> +}
> +
> +static void init_data(data_t *data, igt_output_t *output) {
> +	int i;
> +	uint32_t pm_hdisplay, pm_vdisplay, max_clk = 0;
> +	drmModeModeInfo *preferred_mode;
> +	drmModeConnector *connector;
> +
> +	connector = data->connector = output->config.connector;
> +	data->count_modes = connector->count_modes;
> +	data->modes = (drmModeModeInfo
> *)malloc(sizeof(drmModeModeInfo) *
> +data->count_modes);
> +
> +	for (i = 0; i < data->count_modes; i++) {
> +		data->modes[i] = connector->modes[i]; #ifdef FSV_DEBUG
> +		igt_info("mode %d:", i);
> +		kmstest_dump_mode(&data->modes[i]);
> +#endif
> +	}
> +
> +	/* searching the preferred mode */
> +	for (i = 0; i < connector->count_modes; i++) {
> +		drmModeModeInfo *mode = &connector->modes[i];
> +
> +		if (mode->type & DRM_MODE_TYPE_PREFERRED) {
> +			data->preferred_mode_index = i;
> +			data->hdisplay = mode->hdisplay;
> +			data->vdisplay = mode->vdisplay;
> +			pm_hdisplay = preferred_mode->hdisplay;
> +			pm_vdisplay = preferred_mode->vdisplay;
> +			break;
> +		}
> +	}
> +
> +	/* searching the base mode; */
> +	for (i = 0; i < connector->count_modes; i++) {
> +		drmModeModeInfo *mode = &connector->modes[i];
> +
> +		if (mode->hdisplay == pm_hdisplay && mode->vdisplay ==
> pm_vdisplay) {
> +			if (mode->clock > max_clk) {
> +				max_clk = mode->clock;
> +				data->base_mode_index = i;
> +			}
> +		}
> +	}
> +	igt_info("preferred=%d, base=%d\n", data->preferred_mode_index,
> +data->base_mode_index);
> +
> +	for (i = 0; i < connector->count_modes; i++) {
> +		drmModeModeInfo *mode = &connector->modes[i];
> +
> +		if (is_variable_video_mode(data, mode))
> +			igt_debug("mode[%d] is variable video mode.\n", i);
> +	}
> +
> +	data->range = get_vrr_range(data, output); }
> +
>  /* Returns vrr test frequency for min, mid & max range. */  static vtest_ns_t
> get_test_rate_ns(range_t range)  { @@ -201,39 +280,42 @@ static void
> set_vrr_on_pipe(data_t *data, enum pipe pipe, bool enabled)  }
> 
>  /* Prepare the display for testing on the given pipe. */ -static void
> prepare_test(data_t *data, igt_output_t *output, enum pipe pipe)
> +static void prepare_test(data_t *data, igt_output_t *output, enum pipe
> +pipe, drmModeModeInfo *mode)
>  {
> -	drmModeModeInfo mode;
>  	cairo_t *cr;
> 
>  	/* Reset output */
>  	igt_display_reset(&data->display);
>  	igt_output_set_pipe(output, pipe);
> 
> +	igt_output_override_mode(output, mode);
> +
>  	/* Capture VRR range */
>  	data->range = get_vrr_range(data, output);
> 
> -	/* Override mode with max vrefresh.
> -	 *   - vrr_min range should be less than the override mode vrefresh.
> -	 *   - Limit the vrr_max range with the override mode vrefresh.
> -	 */
> -	mode = output_mode_with_maxrate(output, data->range.max);
> -	igt_require(mode.vrefresh > data->range.min);
> -	data->range.max = mode.vrefresh;
> -	igt_output_override_mode(output, &mode);
> +	if (mode == NULL) {
> +		/* Override mode with max vrefresh.
> +		 *   - vrr_min range should be less than the override mode
> vrefresh.
> +		 *   - Limit the vrr_max range with the override mode
> vrefresh.
> +		 */
> +		*mode = output_mode_with_maxrate(output, data-
> >range.max);
> +		igt_require(mode->vrefresh > data->range.min);
> +		data->range.max = mode->vrefresh;
> +		igt_output_override_mode(output, mode);
> +	}
> 
>  	/* Prepare resources */
> -	igt_create_color_fb(data->drm_fd, mode.hdisplay, mode.vdisplay,
> +	igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay,
>  			    DRM_FORMAT_XRGB8888,
> DRM_FORMAT_MOD_LINEAR,
>  			    0.50, 0.50, 0.50, &data->fb0);
> 
> -	igt_create_color_fb(data->drm_fd, mode.hdisplay, mode.vdisplay,
> +	igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay,
>  			    DRM_FORMAT_XRGB8888,
> DRM_FORMAT_MOD_LINEAR,
>  			    0.50, 0.50, 0.50, &data->fb1);
> 
>  	cr = igt_get_cairo_ctx(data->drm_fd, &data->fb0);
> 
> -	igt_paint_color(cr, 0, 0, mode.hdisplay / 10, mode.vdisplay / 10,
> +	igt_paint_color(cr, 0, 0, mode->hdisplay / 10, mode->vdisplay / 10,
>  			1.00, 0.00, 0.00);
> 
>  	igt_put_cairo_ctx(cr);
> @@ -353,19 +435,27 @@ flip_and_measure(data_t *data, igt_output_t
> *output, enum pipe pipe,
>  	return total_flip ? ((total_pass * 100) / total_flip) : 0;  }
> 
> +/* Returns the rate duration in nanoseconds for the given refresh rate.
> +*/ static uint64_t nsec_per_frame(uint64_t refresh) {
> +	return NSECS_PER_SEC / refresh;
> +}
> +
>  /* Basic VRR flip functionality test - enable, measure, disable, measure */
> static void  test_basic(data_t *data, enum pipe pipe, igt_output_t *output,
> uint32_t flags)  {
>  	uint32_t result;
> +	int index;
>  	vtest_ns_t vtest_ns;
>  	range_t range;
>  	uint64_t rate;
> +	drmModeModeInfo *mode;
> 
> -	prepare_test(data, output, pipe);
>  	range = data->range;
>  	vtest_ns = get_test_rate_ns(range);
>  	rate = vtest_ns.mid;
> +	mode = NULL;
> 
>  	igt_info("VRR Test execution on %s, PIPE_%s with VRR range: (%u-
> %u) Hz\n",
>  		 output->name, kmstest_pipe_name(pipe), range.min,
> range.max); @@ -380,6 +470,7 @@ test_basic(data_t *data, enum pipe
> pipe, igt_output_t *output, uint32_t flags)
>  	flip_and_measure(data, output, pipe, rate, 250000000ull);
> 
>  	if (flags & TEST_DPMS) {
> +		prepare_test(data, output, pipe, mode);

I think we can drop this change to add mode explicitly as we are intended to initialise to max rate which we are doing in prepare_test function itself. 
As in this current change also passing NULL only, in-turn initializing mode in prepare_test only.

>  		kmstest_set_connector_dpms(output->display->drm_fd,
>  					   output->config.connector,
>  					   DRM_MODE_DPMS_OFF);
> @@ -388,9 +479,11 @@ test_basic(data_t *data, enum pipe pipe,
> igt_output_t *output, uint32_t flags)
>  					   DRM_MODE_DPMS_ON);
>  	}
> 
> -	if (flags & TEST_SUSPEND)
> +	if (flags & TEST_SUSPEND) {
> +		prepare_test(data, output, pipe, mode);

Also, may not be required to this redundant prepare_test calls, rather if we can initialize during test_basic start is also sufficient.

Thanks,
Mitul


More information about the igt-dev mailing list