All of lore.kernel.org
 help / color / mirror / Atom feed
From: Daniel Vetter <daniel@ffwll.ch>
To: Chris Wilson <chris@chris-wilson.co.uk>
Cc: intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH igt] igt/kms_flip: Calibrate timestamp errors
Date: Mon, 24 Oct 2016 11:14:31 +0200	[thread overview]
Message-ID: <20161024091431.GP20761@phenom.ffwll.local> (raw)
In-Reply-To: <20161024085452.28315-1-chris@chris-wilson.co.uk>

On Mon, Oct 24, 2016 at 09:54:52AM +0100, Chris Wilson wrote:
> We assert that the interval between a vblank and a flip corresponds with
> the computed frametime derived from the modeline. However, historically
> the dotclock is unreliable (in error of about 1%) for VBT supplied data
> about LVDS panels - the situation looks to be much improved with eDP at
> least. The simple fact that we cannot rely on the manufacturer's supplied
> modeline causes us to fail the test. So before we claim a driver failure,
> do a calibration pass and check for inconsistencies with the modeline.
> 
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

Yeah, throwing some decent stats at this makes sense.

> ---
>  tests/kms_flip.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 71 insertions(+), 2 deletions(-)
> 
> diff --git a/tests/kms_flip.c b/tests/kms_flip.c
> index b30e07c..44aec75 100644
> --- a/tests/kms_flip.c
> +++ b/tests/kms_flip.c
> @@ -26,6 +26,7 @@
>  #endif
>  
>  #include "igt.h"
> +
>  #include <cairo.h>
>  #include <errno.h>
>  #include <fcntl.h>
> @@ -43,6 +44,7 @@
>  #include <time.h>
>  #include <pthread.h>
>  
> +#include "igt_stats.h"
>  
>  #define TEST_DPMS		(1 << 0)
>  #define TEST_WITH_DUMMY_BCS	(1 << 1)
> @@ -175,6 +177,8 @@ struct test_output {
>  	int seq_step;
>  	unsigned int pending_events;
>  	int flip_count;
> +
> +	double ts_error;
>  };
>  
>  
> @@ -698,7 +702,7 @@ static void check_state(const struct test_output *o, const struct event_state *e
>  			  elapsed, expected, expected * 0.005,
>  			  fabs((elapsed - expected) / expected) * 100);
>  
> -		igt_assert_f(fabs((elapsed - expected) / expected) <= 0.005,
> +		igt_assert_f(fabs(elapsed - expected) / expected <= o->ts_error,
>  			     "inconsistent %s ts/seq: last %ld.%06ld/%u, current %ld.%06ld/%u: elapsed=%.1fus expected=%.1fus\n",
>  			     es->name, es->last_ts.tv_sec, es->last_ts.tv_usec, es->last_seq,
>  			     es->current_ts.tv_sec, es->current_ts.tv_usec, es->current_seq,
> @@ -1301,6 +1305,71 @@ static void free_test_output(struct test_output *o)
>  	}
>  }
>  
> +static double calibrate_ts(struct test_output *o, int crtc_idx)
> +{
> +#define CALIBRATE_TS_STEPS 16
> +	drmVBlank wait;
> +	igt_stats_t stats;
> +	uint32_t last_seq;
> +	uint64_t last_timestamp;
> +	double expected;
> +	double mean;
> +	double stddev;
> +	double median;
> +	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(o);
> +
> +	mean = igt_stats_get_mean(&stats);
> +	stddev = igt_stats_get_std_deviation(&stats);
> +	median = igt_stats_get_median(&stats);
> +
> +	igt_info("Expected frametime: %.0fus; measured %.1fus +- %.3fus accuracy %.2f%%; median %.1fus error=%.1f%%\n",
> +		 expected, mean, stddev, 100 * 6 * stddev / mean,
> +		 median, 100* fabs(median - expected) / expected);
> +	igt_assert(6 * stddev / mean < 0.005); /* 99% accuracy within 0.5% */
> +	igt_require(fabs(mean - expected) < 2*stddev);

I think an igt_require_f here with an explanation of what's going on would
be good here.

Also with this patch we should be able to throw out the hacks for tv-out.
I only added those because the reported mode-timings are massively off
(due to the magic tv scaler thing) from the real timestamps we receive.
Auto-detecting this is much better.

And another issue: Failing to match the reported mode timings is a driver
bug. I think a separate testcase which _only_ does the ts calibration (and
makes it a fail/pass instead of require/pass) would be great. I think
having an expectation that the timings userspace asks for is the timing it
gets would be great for kms ;-)

Ack on the patch.
-Daniel

> +
> +	return 2*fabs(median - expected) / expected;
> +}
> +
>  static void run_test_on_crtc_set(struct test_output *o, int *crtc_idxs,
>  				 int crtc_count, int duration_ms)
>  {
> @@ -1404,7 +1473,7 @@ static void run_test_on_crtc_set(struct test_output *o, int *crtc_idxs,
>  
>  	/* quiescent the hw a bit so ensure we don't miss a single frame */
>  	if (o->flags & TEST_CHECK_TS)
> -		sleep(1);
> +		o->ts_error = calibrate_ts(o, crtc_idxs[0]);
>  
>  	igt_assert_eq(do_page_flip(o, o->fb_ids[1], true), 0);
>  	wait_for_events(o);
> -- 
> 2.10.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  reply	other threads:[~2016-10-24  9:14 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-10-24  8:54 [PATCH igt] igt/kms_flip: Calibrate timestamp errors Chris Wilson
2016-10-24  9:14 ` Daniel Vetter [this message]
2016-10-24  9:38   ` Chris Wilson
2016-10-26  6:18     ` Daniel Vetter
2016-10-26  9:10       ` Chris Wilson
2016-10-26  9:17       ` Ville Syrjälä
2016-10-27  6:43         ` Daniel Vetter
2016-10-27 10:13           ` Ville Syrjälä
2016-10-27 10:29             ` Chris Wilson
2016-10-27 11:41               ` Ville Syrjälä

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=20161024091431.GP20761@phenom.ffwll.local \
    --to=daniel@ffwll.ch \
    --cc=chris@chris-wilson.co.uk \
    --cc=intel-gfx@lists.freedesktop.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.