[i-g-t V7 5/8] tests/kms_vrr: Add new subtest to switch RR without modeset

Golani, Mitulkumar Ajitkumar mitulkumar.ajitkumar.golani at intel.com
Wed Dec 13 03:03:47 UTC 2023



> -----Original Message-----
> From: Modem, Bhanuprakash <bhanuprakash.modem at intel.com>
> Sent: Monday, December 11, 2023 5:07 PM
> To: igt-dev at lists.freedesktop.org; Golani, Mitulkumar Ajitkumar
> <mitulkumar.ajitkumar.golani at intel.com>
> Cc: Modem, Bhanuprakash <bhanuprakash.modem at intel.com>; Srinivas,
> Vidya <vidya.srinivas at intel.com>
> Subject: [i-g-t V7 5/8] tests/kms_vrr: Add new subtest to switch RR without
> modeset
> 
> Add new subtest to switch between low refresh rate to high refresh rate and
> vice versa seamlessly without modeset.
> 
> Below are the sequence of operations to perform:
> 
> 1. Use High RR mode + VRR On  -> Measure vblank timings 2. Switch to Low
> RR mode -> Measure vblank timings 3. Switch back to High RR mode ->
> Measure vblank timings
> 
> V2: Squash other required patches
> 
> Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem at intel.com>
> Tested-by: Vidya Srinivas <vidya.srinivas at intel.com>
> ---
>  tests/kms_vrr.c | 115 +++++++++++++++++++++++++++++++++++++++++++----
> -
>  1 file changed, 104 insertions(+), 11 deletions(-)
> 
> diff --git a/tests/kms_vrr.c b/tests/kms_vrr.c index 4540d8b4b..6cb5a9b10
> 100644
> --- a/tests/kms_vrr.c
> +++ b/tests/kms_vrr.c
> @@ -53,6 +53,10 @@
>   * SUBTEST: flipline
>   * Description: Make sure that flips happen at flipline decision boundary.
>   *
> + * SUBTEST: seamless-rr-switch-vrr
> + * Description: Test to switch RR seamlessly without modeset.
> + * Functionality: adaptive_sync, lrr
> + *
>   * SUBTEST: negative-basic
>   * Description: Make sure that VRR should not be enabled on the Non-VRR
> panel.
>   */
> @@ -70,7 +74,14 @@ enum {
>  	TEST_DPMS = 1 << 1,
>  	TEST_SUSPEND = 1 << 2,
>  	TEST_FLIPLINE = 1 << 3,
> -	TEST_NEGATIVE = 1 << 4,
> +	TEST_SEAMLESS_VRR = 1 << 4,
> +	TEST_NEGATIVE = 1 << 5,
> +};
> +
> +enum {
> +	HIGH_RR_MODE,
> +	LOW_RR_MODE,
> +	RR_MODES_COUNT,
>  };
> 
>  typedef struct range {
> @@ -85,6 +96,7 @@ typedef struct data {
>  	igt_fb_t fb0;
>  	igt_fb_t fb1;
>  	range_t range;
> +	drmModeModeInfo switch_modes[RR_MODES_COUNT];
>  } data_t;
> 
>  typedef struct vtest_ns {
> @@ -166,6 +178,24 @@ output_mode_with_maxrate(igt_output_t *output,
> unsigned int vrr_max)
>  	return mode;
>  }
> 
> +static drmModeModeInfo
> +low_rr_mode_with_same_res(igt_output_t *output, unsigned int vrr_min) {
> +	int i;
> +	drmModeConnectorPtr connector = output->config.connector;
> +	drmModeModeInfo mode = *igt_output_get_mode(output);
> +
> +	for (i = 0; i < connector->count_modes; i++)
> +		if (connector->modes[i].hdisplay == mode.hdisplay &&
> +		    connector->modes[i].vdisplay == mode.vdisplay &&
> +		    connector->modes[i].clock < mode.clock &&
> +		    connector->modes[i].vrefresh < mode.vrefresh &&
> +		    connector->modes[i].vrefresh >= vrr_min)
> +			mode = connector->modes[i];
> +
> +	return mode;
> +}
> +
>  /* Read min and max vrr range from the connector debugfs. */  static
> range_t  get_vrr_range(data_t *data, igt_output_t *output) @@ -329,7
> +359,7 @@ flip_and_measure(data_t *data, igt_output_t *output, enum
> pipe pipe,
>  		 * difference between 144Hz and 143Hz which should give
> this
>  		 * enough accuracy for most use cases.
>  		 */
> -		if ((rate_ns < vtest_ns.min) && (rate_ns >= vtest_ns.max))
> +		if ((rate_ns <= vtest_ns.min) && (rate_ns >= vtest_ns.max))
>  			diff_ns = rate_ns;
>  		else
>  			diff_ns = vtest_ns.max;
> @@ -379,6 +409,8 @@ test_basic(data_t *data, enum pipe pipe,
> igt_output_t *output, uint32_t flags)
> 
>  	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);
> +	igt_info("Override Mode: ");
> +	kmstest_dump_mode(&data->switch_modes[HIGH_RR_MODE]);
> 
>  	set_vrr_on_pipe(data, pipe, true);
> 
> @@ -454,6 +486,53 @@ test_basic(data_t *data, enum pipe pipe,
> igt_output_t *output, uint32_t flags)
>  		     ((range.max + range.min) / 2), rate, (flags &
> TEST_NEGATIVE)? "on" : "off", result);  }
> 
> +static void
> +test_seamless_rr_basic(data_t *data, enum pipe pipe, igt_output_t
> +*output, uint32_t flags) {
> +	uint32_t result;
> +	vtest_ns_t vtest_ns;
> +	uint64_t rate;
> +
> +	igt_info("Use HIGH_RR Mode as default: ");
> +	kmstest_dump_mode(&data->switch_modes[HIGH_RR_MODE]);
> +
> +	prepare_test(data, output, pipe);
> +	vtest_ns = get_test_rate_ns(data->range);
> +
> +	igt_pipe_set_prop_value(&data->display, pipe,
> IGT_CRTC_VRR_ENABLED, true);
> +	igt_assert(igt_display_try_commit_atomic(&data->display, 0, NULL)
> ==
> +0);
> +
> +	rate = vtest_ns.max;
> +	result = flip_and_measure(data, output, pipe, rate,
> TEST_DURATION_NS);
> +	igt_assert_f(result > 75,
> +		     "Refresh rate (%u Hz) %"PRIu64"ns: Target VRR on
> threshold not reached, result was %u%%\n",
> +		     data->range.max, rate, result);
> +
> +	/* Switch to low rr mode without modeset. */
> +	igt_info("Switch to LOW_RR Mode: ");
> +	kmstest_dump_mode(&data->switch_modes[LOW_RR_MODE]);
> +	igt_output_override_mode(output, &data-
> >switch_modes[LOW_RR_MODE]);
> +	igt_assert(igt_display_try_commit_atomic(&data->display, 0, NULL)
> ==
> +0);
> +
> +	rate = vtest_ns.min;
> +	result = flip_and_measure(data, output, pipe, rate,
> TEST_DURATION_NS);
> +	igt_assert_f(result > 75,
> +		     "Refresh rate (%u Hz) %"PRIu64"ns: Target VRR on
> threshold not reached, result was %u%%\n",
> +		     data->range.min, rate, result);
> +
> +	/* Switch back to high rr mode without modeset. */
> +	igt_info("Switch back to HIGH_RR Mode: ");
> +	kmstest_dump_mode(&data->switch_modes[HIGH_RR_MODE]);
> +	igt_output_override_mode(output, &data-
> >switch_modes[HIGH_RR_MODE]);
> +	igt_assert(igt_display_try_commit_atomic(&data->display, 0, NULL)
> ==
> +0);
> +
> +	rate = vtest_ns.mid;
> +	result = flip_and_measure(data, output, pipe, rate,
> TEST_DURATION_NS);
> +	igt_assert_f(result > 75,
> +		     "Refresh rate (%u Hz) %"PRIu64"ns: Target VRR on
> threshold not reached, result was %u%%\n",
> +		     ((data->range.max + data->range.min) / 2), rate, result); }
> +
>  static void test_cleanup(data_t *data, enum pipe pipe, igt_output_t *output)
> {
>  	igt_pipe_set_prop_value(&data->display, pipe,
> IGT_CRTC_VRR_ENABLED, false); @@ -466,9 +545,11 @@ static void
> test_cleanup(data_t *data, enum pipe pipe, igt_output_t *output)
>  	igt_remove_fb(data->drm_fd, &data->fb0);  }
> 
> -static bool output_constraint(data_t *data, igt_output_t *output)
> +static bool output_constraint(data_t *data, igt_output_t *output,
> +uint32_t flags)
>  {
> -	drmModeModeInfo mode;
> +	if ((flags & TEST_SEAMLESS_VRR) &&
> +	    output->config.connector->connector_type !=
> DRM_MODE_CONNECTOR_eDP)
> +		return false;
> 
>  	/* Reset output */
>  	igt_display_reset(&data->display);
> @@ -481,16 +562,22 @@ static bool output_constraint(data_t *data,
> igt_output_t *output)
>  	 *   - 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);
> -	if (mode.vrefresh < data->range.min)
> +	data->switch_modes[HIGH_RR_MODE] =
> output_mode_with_maxrate(output, data->range.max);
> +	if (data->switch_modes[HIGH_RR_MODE].vrefresh < data-
> >range.min)
>  		return false;
> 
> -	data->range.max = mode.vrefresh;
> +	data->range.max = data->switch_modes[HIGH_RR_MODE].vrefresh;
> +	igt_output_override_mode(output, &data-
> >switch_modes[HIGH_RR_MODE]);
> 
> -	igt_info("Override Mode: ");
> -	kmstest_dump_mode(&mode);
> +	/* Search for a low refresh rate mode. */
> +	if (!(flags & TEST_SEAMLESS_VRR))
> +		return true;
> +
> +	data->switch_modes[LOW_RR_MODE] =
> low_rr_mode_with_same_res(output, data->range.min);
> +	if (data->switch_modes[LOW_RR_MODE].vrefresh == data-
> >switch_modes[HIGH_RR_MODE].vrefresh)
> +		return false;
> 
> -	igt_output_override_mode(output, &mode);
> +	data->range.min = data->switch_modes[LOW_RR_MODE].vrefresh;
> 
>  	return true;
>  }
> @@ -507,7 +594,7 @@ static bool config_constraint(data_t *data,
> igt_output_t *output, uint32_t flags
>  	if ((flags & ~TEST_NEGATIVE) && !vrr_capable(output))
>  		return false;
> 
> -	if (!output_constraint(data, output))
> +	if (!output_constraint(data, output, flags))
>  		return false;
> 
>  	return true;
> @@ -583,6 +670,12 @@ igt_main
>  	igt_subtest_with_dynamic("negative-basic")
>  		run_vrr_test(&data, test_basic, TEST_NEGATIVE);
> 
> +	igt_describe("Test to switch RR seamlessly without modeset.");
> +	igt_subtest_with_dynamic("seamless-rr-switch-vrr"){
> +		igt_require_intel(data.drm_fd);
> +		run_vrr_test(&data, test_seamless_rr_basic,
> TEST_SEAMLESS_VRR);
> +	}
> +

Change LGTM
Reviewed-by: Mitul Golani <mitulkumar.ajitkumar.golani at intel.com>

>  	igt_fixture {
>  		igt_display_fini(&data.display);
>  		drm_close_driver(data.drm_fd);
> --
> 2.40.0



More information about the igt-dev mailing list