From patchwork Mon May 29 05:08:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [RFC] tests/kms_vrr: Add a new subtest to validate different VRR modes From: Nidhi Gupta X-Patchwork-Id: 539769 Message-Id: <20230529050806.30395-1-nidhi1.gupta@intel.com> To: intel-gfx-trybot@lists.freedesktop.org Cc: Nidhi Gupta Date: Mon, 29 May 2023 10:38:06 +0530 Test switch from base VRR mode to various VRR supported modes without triggering modeset. Signed-off-by: Nidhi Gupta --- 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);