[RFC] tests/kms_vrr: Add a new subtest to validate different VRR modes
Nidhi Gupta
nidhi1.gupta at intel.com
Mon May 29 05:08:06 UTC 2023
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 | 102 +++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 100 insertions(+), 2 deletions(-)
diff --git a/tests/kms_vrr.c b/tests/kms_vrr.c
index d2d79c4e..2084c833 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,16 @@ 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;
} data_t;
typedef struct vtest_ns {
@@ -168,6 +175,59 @@ get_vrr_range(data_t *data, igt_output_t *output)
return range;
}
+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_freesync_video_mode(data, mode))
+ igt_debug("mode[%d] is freesync 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,7 +261,7 @@ 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;
@@ -213,6 +273,8 @@ static void prepare_test(data_t *data, igt_output_t *output, enum pipe pipe)
/* Capture VRR range */
data->range = get_vrr_range(data, output);
+ 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.
@@ -222,6 +284,8 @@ static void prepare_test(data_t *data, igt_output_t *output, enum pipe pipe)
data->range.max = mode.vrefresh;
igt_output_override_mode(output, &mode);
+ }
+
/* Prepare resources */
igt_create_color_fb(data->drm_fd, mode.hdisplay, mode.vdisplay,
DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_LINEAR,
@@ -353,6 +417,12 @@ 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)
@@ -362,7 +432,7 @@ test_basic(data_t *data, enum pipe pipe, igt_output_t *output, uint32_t flags)
range_t range;
uint64_t rate;
- prepare_test(data, output, pipe);
+ prepare_test(data, output, pipe, NULL);
range = data->range;
vtest_ns = get_test_rate_ns(range);
rate = vtest_ns.mid;
@@ -380,6 +450,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, NULL);
kmstest_set_connector_dpms(output->display->drm_fd,
output->config.connector,
DRM_MODE_DPMS_OFF);
@@ -389,6 +460,7 @@ test_basic(data_t *data, enum pipe pipe, igt_output_t *output, uint32_t flags)
}
if (flags & TEST_SUSPEND)
+ prepare_test(data, output, pipe, NULL);
igt_system_suspend_autoresume(SUSPEND_STATE_MEM,
SUSPEND_TEST_NONE);
@@ -408,6 +480,7 @@ test_basic(data_t *data, enum pipe pipe, igt_output_t *output, uint32_t flags)
* next Vmin.
*/
if (flags & TEST_FLIPLINE) {
+ prepare_test(data, output, pipe, NULL);
rate = rate_from_refresh(range.max + 5);
result = flip_and_measure(data, output, pipe, rate, TEST_DURATION_NS);
igt_assert_f(result > 75,
@@ -416,6 +489,7 @@ test_basic(data_t *data, enum pipe pipe, igt_output_t *output, uint32_t flags)
}
if (flags & ~TEST_NEGATIVE) {
+ prepare_test(data, output, pipe, NULL);
rate = vtest_ns.mid;
result = flip_and_measure(data, output, pipe, rate, TEST_DURATION_NS);
igt_assert_f(result > 75,
@@ -423,7 +497,25 @@ test_basic(data_t *data, enum pipe pipe, igt_output_t *output, uint32_t flags)
((range.max + range.min) / 2), rate, result);
}
+ if (flags & TEST_BASE_MODE_TO_VARIOUS_VRR_MODE) {
+ uint32_t result;
+ uint64_t interval;
+ int index;
+
+ init_data(data, output);
+ drmModeModeInfo *mode_start = NULL;
+ index = data->base_mode_index;
+ mode_start = &data->modes[index];
+ prepare_test(data, output, pipe, mode_start);
+ rate = nsec_per_frame(mode_start->vrefresh);
+ 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",
+ ((range.max + range.min) / 2), rate, result);
+ }
+
if (flags & TEST_FLIPLINE) {
+ prepare_test(data, output, pipe, NULL);
rate = rate_from_refresh(range.min - 5);
result = flip_and_measure(data, output, pipe, rate, TEST_DURATION_NS);
igt_assert_f(result < 50,
@@ -525,6 +617,12 @@ igt_main
igt_describe("Make sure that VRR should not be enabled on the Non-VRR panel.");
igt_subtest_with_dynamic("negative-basic")
run_vrr_test(&data, test_basic, TEST_NEGATIVE);
+ igt_describe("Test switch from base freesync mode to " \
+ "various freesync video modes");
+
+ igt_describe("Test switch from base VRR mode to various VRR modes");
+ igt_subtest("vrr-base-to-various")
+ run_vrr_test(&data, test_basic, TEST_BASE_MODE_TO_VARIOUS_VRR_MODE);
igt_fixture {
igt_display_fini(&data.display);
--
2.39.0
More information about the Intel-gfx-trybot
mailing list