From: Lee Shawn C <shawn.c.lee@intel.com>
To: igt-dev@lists.freedesktop.org
Cc: Lee Shawn C <shawn.c.lee@intel.com>,
Naladala Ramanaidu <ramanaidu.naladala@intel.com>
Subject: [v4] tests/kms_vrr: add support for full range refresh rate testing
Date: Thu, 7 May 2026 13:53:40 +0000 [thread overview]
Message-ID: <20260507135340.685188-1-shawn.c.lee@intel.com> (raw)
In-Reply-To: <20260427120955.3537070-1-shawn.c.lee@intel.com>
Currently, kms_vrr tests fixed step increments within the VRR range.
To better validate hardware stability and potential issues across the
entire spectrum, this patch adds a 'full-range' testing mode.
When the full-range flag is enabled, the test will:
1. Iterate from the maximum to the minimum refresh rate (stepping by 1).
2. For standard testing, maintain the existing behavior of incrementing
from minimum to maximum using the defined step size.
v2: Fix build failure by adding documentation for the new subtest.
v3: Remove unnecessary '!!' operator when assigning to bool.
v4: Add full-range (top-down/bottom-up) subtests to verify all supported
RR within VRR range.
Cc: Naladala Ramanaidu <ramanaidu.naladala@intel.com>
Signed-off-by: Lee Shawn C <shawn.c.lee@intel.com>
---
tests/kms_vrr.c | 118 ++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 100 insertions(+), 18 deletions(-)
diff --git a/tests/kms_vrr.c b/tests/kms_vrr.c
index 6043d40f1d74..7cb37e14ab02 100644
--- a/tests/kms_vrr.c
+++ b/tests/kms_vrr.c
@@ -65,6 +65,11 @@
* SUBTEST: seamless-rr-switch-virtual
* Description: Test to create a Virtual Mode in VRR range and switch to it
* without a full modeset.
+ * SUBTEST: seamless-rr-switch-virtual-full-top-down
+ * Description: Vrr seamless refresh rate switch for virtual modes using full range
+ *
+ * SUBTEST: seamless-rr-switch-virtual-full-bottom-up
+ * Description: Vrr seamless refresh rate switch for virtual modes using full range
*
* SUBTEST: lobf
* Description: Test to validate link-off between active frames in non-psr
@@ -94,11 +99,13 @@ enum {
TEST_SEAMLESS_VRR = 1 << 4,
TEST_SEAMLESS_DRRS = 1 << 5,
TEST_SEAMLESS_VIRTUAL_RR = 1 << 6,
- TEST_FASTSET = 1 << 7,
- TEST_MAXMIN = 1 << 8,
- TEST_LINK_OFF = 1 << 10,
- TEST_NEGATIVE = 1 << 11,
- TEST_FORCE_RR = 1 << 12,
+ TEST_SEAMLESS_VIRTUAL_RR_TOP_DOWN = 1 << 7,
+ TEST_SEAMLESS_VIRTUAL_RR_BOTTOM_UP = 1 << 8,
+ TEST_FASTSET = 1 << 9,
+ TEST_MAXMIN = 1 << 10,
+ TEST_LINK_OFF = 1 << 11,
+ TEST_NEGATIVE = 1 << 12,
+ TEST_FORCE_RR = 1 << 13,
};
enum {
@@ -235,13 +242,58 @@ low_rr_mode_with_same_res(igt_output_t *output, unsigned int vrr_min)
return mode;
}
-static void
-virtual_rr_vrr_range_mode(drmModeModeInfo *mode, float virtual_refresh_rate)
+static bool
+virtual_rr_vrr_range_mode(data_t *data, drmModeModeInfo *mode, float virtual_refresh_rate)
{
uint64_t clock_hz = mode->clock * 1000;
+ uint16_t virtual_vtotal;
+
+ virtual_vtotal = clock_hz / (mode->htotal * virtual_refresh_rate);
+ if (is_intel_device(data->drm_fd) && virtual_vtotal > 8192) {
+ igt_info("VTotal (%d) already exceed 8192 at %fHz\n", virtual_vtotal, virtual_refresh_rate);
+ return false;
+ }
- mode->vtotal = clock_hz / (mode->htotal * virtual_refresh_rate);
+ mode->vsync_start = virtual_vtotal - (mode->vtotal - mode->vsync_start);
+ mode->vsync_end = virtual_vtotal - (mode->vtotal - mode->vsync_end);
+ mode->vtotal = virtual_vtotal;
mode->vrefresh = virtual_refresh_rate;
+
+ return true;
+}
+
+static drmModeModeInfo*
+get_selected_fixed_mode(igt_output_t *output, bool lowest)
+{
+ drmModeConnectorPtr connector = output->config.connector;
+ drmModeModeInfo *selected_mode = NULL;
+
+ for (int i = 0; i < connector->count_modes; i++) {
+ drmModeModeInfo *m = &connector->modes[i];
+
+ if (m->type & (DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER)) {
+ if (!selected_mode) {
+ selected_mode = m;
+ continue;
+ }
+
+ if (lowest) {
+ if (m->vrefresh < selected_mode->vrefresh)
+ selected_mode = m;
+ } else {
+ if (m->vrefresh > selected_mode->vrefresh)
+ selected_mode = m;
+ }
+ }
+ }
+
+ if (selected_mode) {
+ igt_info("Found Target Fixed Mode: \"%s\" %dHz (vtotal: %d)\n",
+ selected_mode->name, selected_mode->vrefresh, selected_mode->vtotal);
+ return selected_mode;
+ }
+
+ return NULL;
}
/* Read min and max vrr range from the connector debugfs. */
@@ -757,19 +809,25 @@ test_seamless_virtual_rr_basic(data_t *data, igt_crtc_t *crtc,
unsigned int vrefresh;
uint64_t rate[] = {0};
uint32_t step_size;
- drmModeModeInfo virtual_mode;
+ drmModeModeInfo *virtual_mode = NULL;
+ int start, end, step;
+ bool need_low_rr = flags & TEST_SEAMLESS_VIRTUAL_RR_BOTTOM_UP;
- igt_info("Use HIGH_RR Mode as default\n");
- kmstest_dump_mode(&data->switch_modes[HIGH_RR_MODE]);
+ virtual_mode = get_selected_fixed_mode(output, need_low_rr);
+ if (!virtual_mode)
+ return;
+
+ igt_info("Use %s_RR Mode as default\n", need_low_rr ? "LOW" : "HIGH");
+ kmstest_dump_mode(virtual_mode);
prepare_test(data, output, crtc);
- rate[0] = igt_kms_frame_time_from_vrefresh(data->switch_modes[HIGH_RR_MODE].vrefresh);
+ rate[0] = igt_kms_frame_time_from_vrefresh(virtual_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_output_override_mode(output, virtual_mode);
igt_assert(igt_display_try_commit_atomic(&data->display, DRM_MODE_PAGE_FLIP_EVENT, NULL) == 0);
result = flip_and_measure(data, output, rate, 1, TEST_DURATION_NS);
@@ -784,7 +842,7 @@ test_seamless_virtual_rr_basic(data_t *data, igt_crtc_t *crtc,
step_size = (data->range.max - data->range.min) / 5;
/* Switch to Virtual RR */
- virtual_mode = *igt_output_get_mode(output);
+ virtual_mode = igt_output_get_mode(output);
/*
* Start virtual RR testing from above the midpoint of the VRR range when multiple
@@ -795,13 +853,29 @@ test_seamless_virtual_rr_basic(data_t *data, igt_crtc_t *crtc,
(((data->range.max + data->range.min) / 2) + step_size) :
data->range.min + step_size;
- for ( ; vrefresh < data->range.max; vrefresh += step_size) {
- virtual_rr_vrr_range_mode(&virtual_mode, vrefresh);
+ if (flags & TEST_SEAMLESS_VIRTUAL_RR_TOP_DOWN) {
+ start = data->range.max;
+ end = data->range.min;
+ step = -1;
+ } else if (flags & TEST_SEAMLESS_VIRTUAL_RR_BOTTOM_UP) {
+ start = data->range.min;
+ end = data->range.max;
+ step = 1;
+ } else {
+ start = data->range.min;
+ end = data->range.max;
+ step = step_size;
+ }
+
+ for (vrefresh = start; (step > 0) ? (vrefresh <= end) : (vrefresh >= end); vrefresh += step) {
+ if (!virtual_rr_vrr_range_mode(data, virtual_mode, vrefresh))
+ continue;
igt_info("Requesting Virtual Mode with Refresh Rate (%u Hz): \n", vrefresh);
- kmstest_dump_mode(&virtual_mode);
+ kmstest_dump_mode(virtual_mode);
- igt_output_override_mode(output, &virtual_mode);
+ igt_output_override_mode(output, virtual_mode);
+ igt_assert(igt_display_try_commit_atomic(&data->display, DRM_MODE_ATOMIC_TEST_ONLY, NULL) == 0);
igt_assert(igt_display_try_commit_atomic(&data->display, 0, NULL) == 0);
rate[0] = igt_kms_frame_time_from_vrefresh(vrefresh);
@@ -1105,6 +1179,14 @@ int igt_main_args("drs:", long_opts, help_str, opt_handler, &data)
igt_subtest_with_dynamic("seamless-rr-switch-virtual")
run_vrr_test(&data, test_seamless_virtual_rr_basic, TEST_SEAMLESS_VIRTUAL_RR);
+ igt_describe("Test to switch to all virtual modes in VRR range without modeset.");
+ igt_subtest_with_dynamic("seamless-rr-switch-virtual-top-down")
+ run_vrr_test(&data, test_seamless_virtual_rr_basic, TEST_SEAMLESS_VIRTUAL_RR_TOP_DOWN);
+
+ igt_describe("Test to switch to all virtual modes in VRR range without modeset.");
+ igt_subtest_with_dynamic("seamless-rr-switch-virtual-bottom-up")
+ run_vrr_test(&data, test_seamless_virtual_rr_basic, TEST_SEAMLESS_VIRTUAL_RR_BOTTOM_UP);
+
igt_describe("Test to validate the link-off between active frames in "
"non-PSR operation.");
igt_subtest_with_dynamic("lobf") {
--
2.34.1
prev parent reply other threads:[~2026-05-07 14:02 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-27 12:09 [PATCH i-g-t] tests/kms_vrr: add support for full range refresh rate testing Lee Shawn C
2026-04-28 6:12 ` [v2] " Lee Shawn C
2026-04-28 7:10 ` Jani Nikula
2026-04-28 7:30 ` Lee, Shawn C
2026-04-28 7:29 ` ✓ i915.CI.BAT: success for tests/kms_vrr: add support for full range refresh rate testing (rev2) Patchwork
2026-04-28 7:34 ` [v3] tests/kms_vrr: add support for full range refresh rate testing Lee Shawn C
2026-04-28 7:43 ` ✓ Xe.CI.BAT: success for tests/kms_vrr: add support for full range refresh rate testing (rev2) Patchwork
2026-04-28 8:49 ` ✓ i915.CI.BAT: success for tests/kms_vrr: add support for full range refresh rate testing (rev3) Patchwork
2026-04-28 9:18 ` ✓ Xe.CI.BAT: " Patchwork
2026-04-28 13:53 ` ✗ i915.CI.Full: failure for tests/kms_vrr: add support for full range refresh rate testing (rev2) Patchwork
2026-04-28 14:45 ` ✗ Xe.CI.FULL: " Patchwork
2026-04-28 15:00 ` ✗ i915.CI.Full: failure for tests/kms_vrr: add support for full range refresh rate testing (rev3) Patchwork
2026-04-28 16:43 ` ✓ Xe.CI.FULL: success " Patchwork
2026-05-07 13:53 ` Lee Shawn C [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260507135340.685188-1-shawn.c.lee@intel.com \
--to=shawn.c.lee@intel.com \
--cc=igt-dev@lists.freedesktop.org \
--cc=ramanaidu.naladala@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox