[Intel-gfx] [PATCH igt] igt/kms_setmode: Test that the vblank interval matches the dotclock
Daniel Vetter
daniel at ffwll.ch
Wed Oct 26 06:21:40 UTC 2016
On Mon, Oct 24, 2016 at 11:08:31AM +0100, Chris Wilson wrote:
> As we allow userspace to set the dotclock, we should try to respect it!
> Userpsace will try to set its frametimings based upon the dotclock, so
> ideally it should match the measured vblank interval.
>
> Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
Ack on the testcase. And I think with this one we can make the kms_flip
ones a bit more lenient in what they accept. At least I think it'd be
useful to afford a bit more imprecision in exchange for more test coverage
on shittier hw.
-Daniel
> ---
> tests/kms_setmode.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 73 insertions(+), 2 deletions(-)
>
> diff --git a/tests/kms_setmode.c b/tests/kms_setmode.c
> index df958f0..966ad93 100644
> --- a/tests/kms_setmode.c
> +++ b/tests/kms_setmode.c
> @@ -71,6 +71,7 @@ enum test_flags {
> TEST_SINGLE_CRTC_CLONE = 0x04,
> TEST_EXCLUSIVE_CRTC_CLONE = 0x08,
> TEST_STEALING = 0x10,
> + TEST_TIMINGS = 0x20,
> };
>
> struct test_config {
> @@ -413,6 +414,75 @@ static int test_stealing(int fd, struct crtc_config *crtc, uint32_t *ids)
> return ret;
> }
>
> +static double frame_time(const drmModeModeInfo *kmode)
> +{
> + return 1000.0 * kmode->htotal * kmode->vtotal / kmode->clock;
> +}
> +
> +static void check_timings(int crtc_idx, const drmModeModeInfo *kmode)
> +{
> +#define CALIBRATE_TS_STEPS 120 /* ~2s has to be less than 128! */
Because speed matters, maybe just 50?
> + drmVBlank wait;
> + igt_stats_t stats;
> + uint32_t last_seq;
> + uint64_t last_timestamp;
> + double expected;
> + double mean;
> + double stddev;
> + int n;
> +
> + memset(&wait, 0, sizeof(wait));
> + wait.request.type = kmstest_get_vbl_flag(crtc_idx);
> + wait.request.type |= DRM_VBLANK_ABSOLUTE | DRM_VBLANK_NEXTONMISS;
> + do_or_die(drmWaitVBlank(drm_fd, &wait));
> +
> + last_seq = wait.reply.sequence;
> + last_timestamp = wait.reply.tval_sec;
> + last_timestamp *= 1000000;
> + last_timestamp += wait.reply.tval_usec;
> +
> + memset(&wait, 0, sizeof(wait));
> + wait.request.type = kmstest_get_vbl_flag(crtc_idx);
> + wait.request.type |= DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT;
> + wait.request.sequence = last_seq;
> + for (n = 0; n < CALIBRATE_TS_STEPS; n++) {
> + ++wait.request.sequence;
> + do_or_die(drmWaitVBlank(drm_fd, &wait));
> + }
> +
> + igt_stats_init_with_size(&stats, CALIBRATE_TS_STEPS);
> + for (n = 0; n < CALIBRATE_TS_STEPS; n++) {
> + struct drm_event_vblank ev;
> + uint64_t now;
> +
> + igt_assert(read(drm_fd, &ev, sizeof(ev)) == sizeof(ev));
> + igt_assert_eq(ev.sequence, last_seq + 1);
> +
> + now = ev.tv_sec;
> + now *= 1000000;
> + now += ev.tv_usec;
> +
> + igt_stats_push(&stats, now - last_timestamp);
> +
> + last_timestamp = now;
> + last_seq = ev.sequence;
> + }
> +
> + expected = frame_time(kmode);
> +
> + mean = igt_stats_get_mean(&stats);
> + stddev = igt_stats_get_std_deviation(&stats);
> +
> + igt_info("Expected frametime: %.0fus; measured %.1fus +- %.3fus accuracy %.2f%%\n",
> + expected, mean, stddev, 100 * 6 * stddev / mean);
> + igt_assert(6 * stddev / mean < 0.005); /* 99% accuracy within 0.5% */
> +
> + igt_assert_f(fabs(mean - expected) < 2*stddev,
> + "vblank interval differs from modeline! expected %.1fus, measured %1.fus +- %.3fus, difference %.1fus (%.1f sigma)\n",
> + expected, mean, stddev,
> + fabs(mean - expected), fabs(mean - expected) / stddev);
> +}
> +
> static void test_crtc_config(const struct test_config *tconf,
> struct crtc_config *crtcs, int crtc_count)
> {
> @@ -475,8 +545,8 @@ static void test_crtc_config(const struct test_config *tconf,
>
> igt_assert(config_failed == !!(tconf->flags & TEST_INVALID));
>
> - if (ret == 0 && connector_connected && !(tconf->flags & TEST_INVALID))
> - sleep(5);
> + if (ret == 0 && connector_connected && tconf->flags & TEST_TIMINGS)
> + check_timings(crtcs[0].crtc_idx, &crtcs[0].mode);
>
> for (i = 0; i < crtc_count; i++) {
> if (crtcs[i].fb_info.fb_id) {
> @@ -732,6 +802,7 @@ int main(int argc, char **argv)
> enum test_flags flags;
> const char *name;
> } tests[] = {
> + { TEST_TIMINGS, "basic" },
If you want this in BAT, it needs to be manually added to the list. And
maybe give it a better name, like timings or basic-timings.
-Daniel
> { TEST_CLONE | TEST_SINGLE_CRTC_CLONE,
> "basic-clone-single-crtc" },
> { TEST_INVALID | TEST_CLONE | TEST_SINGLE_CRTC_CLONE,
> --
> 2.10.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
More information about the Intel-gfx
mailing list