[PATCH v5] tests/kms_vrr: Add a subtest for seamless modeset to a virtual LRR mode
Manasi Navare
navaremanasi at chromium.org
Mon Mar 25 23:05:19 UTC 2024
This subtest validates LRR fastset functionality by testing seamless switching
without full modeset to any of the virtual LRR mode within VRR range.
Here we start from highest refresh rate mode and then switch to virtual LRR
modes in the steps of 10Hz within the VRR range.
This is used to test the LRR fastset functionality of the driver.
v4:
- Change the test name to align with drrs/vrr tests (Bhanu)
- Fix some build warnings due to rebase
- Use a local virtual_mode variable
v3:
- Fix build error due to rebase (Manasi)
Cc: Drew Davenport <ddavenport at chromium.org>
Cc: Bhanuprakash Modem <bhanuprakash.modem at intel.com>
Cc: Ville Syrjälä <ville.syrjala at linux.intel.com>
Cc: Sean Paul <seanpaul at chromium.org>
Signed-off-by: Manasi Navare <navaremanasi at chromium.org>
---
tests/kms_vrr.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 68 insertions(+), 4 deletions(-)
diff --git a/tests/kms_vrr.c b/tests/kms_vrr.c
index 15c62b34b..d838647bd 100644
--- a/tests/kms_vrr.c
+++ b/tests/kms_vrr.c
@@ -66,6 +66,11 @@
* Description: Test to switch RR seamlessly without modeset.
* Functionality: adaptive_sync, drrs
*
+ * SUBTEST: seamless-rr-switch-virtual
+ * Description: Test to create a Virtual Mode in VRR range and switch to it
+ * without a full modeset.
+ * Functionality: LRR
+ *
* SUBTEST: max-min
* Description: Oscillates between highest and lowest refresh each frame for
* manual flicker profiling
@@ -89,9 +94,10 @@ enum {
TEST_FLIPLINE = 1 << 3,
TEST_SEAMLESS_VRR = 1 << 4,
TEST_SEAMLESS_DRRS = 1 << 5,
- TEST_FASTSET = 1 << 6,
- TEST_MAXMIN = 1 << 7,
- TEST_NEGATIVE = 1 << 8,
+ TEST_SEAMLESS_VIRTUAL_RR = 1 << 6,
+ TEST_FASTSET = 1 << 7,
+ TEST_MAXMIN = 1 << 8,
+ TEST_NEGATIVE = 1 << 9,
};
enum {
@@ -214,6 +220,18 @@ low_rr_mode_with_same_res(igt_output_t *output, unsigned int vrr_min)
return mode;
}
+static drmModeModeInfo
+virtual_rr_vrr_range_mode(igt_output_t *output, unsigned int virtual_refresh_rate)
+{
+ drmModeModeInfo mode = *igt_output_get_mode(output);
+ uint64_t clock_hz = mode.clock * 1000;
+
+ mode.vtotal = clock_hz / (mode.htotal * virtual_refresh_rate);
+ mode.vrefresh = virtual_refresh_rate;
+
+ 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)
@@ -641,6 +659,48 @@ test_seamless_rr_basic(data_t *data, enum pipe pipe, igt_output_t *output, uint3
vrr ? "on" : "off", vrr ? "not reached" : "exceeded", result);
}
+static void
+test_seamless_virtual_rr_basic(data_t *data, enum pipe pipe, igt_output_t *output, uint32_t flags)
+{
+ uint32_t result;
+ unsigned int vrefresh;
+ uint64_t rate[] = {0};
+
+ igt_info("Use HIGH_RR Mode as default\n");
+ kmstest_dump_mode(&data->switch_modes[HIGH_RR_MODE]);
+
+ prepare_test(data, output, pipe);
+ rate[0] = rate_from_refresh(data->switch_modes[HIGH_RR_MODE].vrefresh);
+
+ /*
+ * Sink with DRR and VRR can be in downclock mode so
+ * switch to highest refresh rate mode.
+ */
+ igt_output_override_mode(output, &data->switch_modes[HIGH_RR_MODE]);
+ igt_assert(igt_display_try_commit_atomic(&data->display, DRM_MODE_PAGE_FLIP_EVENT, NULL) == 0);
+
+ result = flip_and_measure(data, output, pipe, rate, 1, TEST_DURATION_NS);
+ igt_assert_f(result > 75,
+ "Refresh rate (%u Hz) %"PRIu64"ns: Target threshold not reached, result was %u%%\n",
+ data->switch_modes[HIGH_RR_MODE].vrefresh, rate[0], result);
+
+ /* Switch to Virtual RR */
+ for (vrefresh = data->range.min + 10; vrefresh < data->range.max; vrefresh += 10) {
+ drmModeModeInfo virtual_mode = virtual_rr_vrr_range_mode(output, vrefresh);
+ igt_info("Requesting Virtual Mode with Refresh Rate (%u Hz): \n", vrefresh);
+ kmstest_dump_mode(&virtual_mode);
+
+ igt_output_override_mode(output, &virtual_mode);
+ igt_assert(igt_display_try_commit_atomic(&data->display, 0, NULL) == 0);
+
+ rate[0] = rate_from_refresh(vrefresh);
+ result = flip_and_measure(data, output, pipe, rate[0], 1, TEST_DURATION_NS);
+ igt_assert_f(result > 75,
+ "Refresh rate (%u Hz) %"PRIu64"ns: Target threshold not reached, result was %u%%\n",
+ vrefresh, rate[0], result);
+ }
+}
+
static void test_cleanup(data_t *data, enum pipe pipe, igt_output_t *output)
{
if (vrr_capable(output))
@@ -686,7 +746,7 @@ static bool output_constraint(data_t *data, igt_output_t *output, uint32_t flags
igt_output_override_mode(output, &data->switch_modes[HIGH_RR_MODE]);
/* Search for a low refresh rate mode. */
- if (!(flags & (TEST_SEAMLESS_VRR | TEST_SEAMLESS_DRRS)))
+ if (!(flags & (TEST_SEAMLESS_VRR | TEST_SEAMLESS_DRRS | TEST_SEAMLESS_VIRTUAL_RR)))
return true;
data->switch_modes[LOW_RR_MODE] = low_rr_mode_with_same_res(output, data->range.min);
@@ -841,6 +901,10 @@ igt_main_args("drs:", long_opts, help_str, opt_handler, &data)
"between flip timestamps converges to the requested rate");
igt_subtest_with_dynamic("flip-basic-fastset")
run_vrr_test(&data, test_basic, TEST_FASTSET);
+
+ igt_describe("Test to switch to any custom virtual mode in VRR range without modeset.");
+ igt_subtest_with_dynamic("seamless-rr-switch-virtual")
+ run_vrr_test(&data, test_seamless_virtual_rr_basic, TEST_SEAMLESS_VIRTUAL_RR);
}
igt_fixture {
--
2.44.0.396.g6e790dbe36-goog
More information about the igt-dev
mailing list