[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