All of lore.kernel.org
 help / color / mirror / Atom feed
From: Imre Deak <imre.deak@intel.com>
To: intel-gfx@lists.freedesktop.org
Subject: [PATCH 22/22] flip_test: add wait-for-vblank tests
Date: Tue, 16 Oct 2012 17:34:56 +0300	[thread overview]
Message-ID: <1350398096-3649-23-git-send-email-imre.deak@intel.com> (raw)
In-Reply-To: <1350398096-3649-1-git-send-email-imre.deak@intel.com>

Signed-off-by: Imre Deak <imre.deak@intel.com>
---
 tests/flip_test.c |  130 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 126 insertions(+), 4 deletions(-)

diff --git a/tests/flip_test.c b/tests/flip_test.c
index 2b70f2a..7c3d0f2 100644
--- a/tests/flip_test.c
+++ b/tests/flip_test.c
@@ -49,8 +49,12 @@
 #define TEST_EBUSY		(1 << 5)
 #define TEST_EINVAL		(1 << 6)
 #define TEST_FLIP		(1 << 7)
+#define TEST_VBLANK		(1 << 8)
+#define TEST_VBLANK_BLOCK	(1 << 9)
+#define TEST_VBLANK_ABSOLUTE	(1 << 10)
 
 #define EVENT_FLIP		(1 << 0)
+#define EVENT_VBLANK		(1 << 1)
 
 drmModeRes *resources;
 int drm_fd;
@@ -108,6 +112,7 @@ struct test_output {
 	struct kmstest_fb fb_info[2];
 
 	struct event_state flip_state;
+	struct event_state vblank_state;
 	unsigned int pending_events;
 };
 
@@ -211,6 +216,51 @@ static int do_page_flip(struct test_output *o, int fb_id)
 	return ret;
 }
 
+struct vblank_reply {
+	unsigned int sequence;
+	struct timeval ts;
+};
+
+static int do_wait_for_vblank(struct test_output *o, int crtc_idx,
+			      int target_seq, struct vblank_reply *reply)
+{
+	drmVBlank wait_vbl;
+	int ret;
+	unsigned crtc_idx_mask;
+	bool event = !(o->flags & TEST_VBLANK_BLOCK);
+
+	memset(&wait_vbl, 0, sizeof(wait_vbl));
+
+	crtc_idx_mask = crtc_idx << DRM_VBLANK_HIGH_CRTC_SHIFT;
+	assert(!(crtc_idx_mask & ~DRM_VBLANK_HIGH_CRTC_MASK));
+
+	wait_vbl.request.type = crtc_idx_mask;
+	if (o->flags & TEST_VBLANK_ABSOLUTE)
+		wait_vbl.request.type |= DRM_VBLANK_ABSOLUTE;
+	else
+		wait_vbl.request.type |= DRM_VBLANK_RELATIVE;
+	if (event) {
+		wait_vbl.request.type |= DRM_VBLANK_EVENT;
+		wait_vbl.request.signal = (unsigned long)o;
+	}
+	wait_vbl.request.sequence = target_seq;
+
+	ret = drmWaitVBlank(drm_fd, &wait_vbl);
+
+	if (ret == 0) {
+		reply->ts.tv_sec = wait_vbl.reply.tval_sec;
+		reply->ts.tv_usec = wait_vbl.reply.tval_usec;
+		reply->sequence = wait_vbl.reply.sequence;
+
+		if (event) {
+			assert(!(o->pending_events & EVENT_VBLANK));
+			o->pending_events |= EVENT_VBLANK;
+		}
+	}
+
+	return ret;
+}
+
 static bool
 analog_tv_connector(struct test_output *o)
 {
@@ -240,6 +290,15 @@ static void page_flip_handler(int fd, unsigned int frame, unsigned int sec,
 	event_handler(&o->flip_state, frame, sec, usec);
 }
 
+static void vblank_handler(int fd, unsigned int frame, unsigned int sec,
+			      unsigned int usec, void *data)
+{
+	struct test_output *o = data;
+
+	clear_flag(&o->pending_events, EVENT_VBLANK);
+	event_handler(&o->vblank_state, frame, sec, usec);
+}
+
 static void check_state(struct test_output *o, struct event_state *es)
 {
 	struct timeval diff;
@@ -299,6 +358,8 @@ static void check_all_state(struct test_output *o,
 {
 	if (completed_events & EVENT_FLIP)
 		check_state(o, &o->flip_state);
+	if (completed_events & EVENT_VBLANK)
+		check_state(o, &o->vblank_state);
 }
 
 /* Return mask of completed events. */
@@ -309,12 +370,16 @@ static unsigned int run_test_step(struct test_output *o)
 	int expected_einval = o->flags & TEST_MODESET ? -EBUSY : -EINVAL;
 	unsigned int completed_events = 0;
 	bool do_flip;
+	bool do_vblank;
 
 	do_flip = (o->flags & TEST_FLIP) && !(o->pending_events & EVENT_FLIP);
+	do_vblank = (o->flags & TEST_VBLANK) &&
+		    !(o->pending_events & EVENT_VBLANK);
 
 	/* pan before the flip completes */
 	if (o->flags & TEST_PAN) {
-		int count = o->flip_state.count;
+		int count = do_flip ?
+			o->flip_state.count : o->vblank_state.count;
 		int x_ofs = count * 10 > o->mode.hdisplay ?
 			    o->mode.hdisplay : count * 10;
 
@@ -356,6 +421,24 @@ static unsigned int run_test_step(struct test_output *o)
 	if (do_flip)
 		do_or_die(do_page_flip(o, new_fb_id));
 
+	if (do_vblank) {
+		struct vblank_reply vbl_reply;
+		unsigned int target_seq;
+
+		target_seq = o->vblank_state.seq_step;
+		if (o->flags & TEST_VBLANK_ABSOLUTE)
+			target_seq += o->vblank_state.last_seq;
+
+		do_or_die(do_wait_for_vblank(o, o->crtc_idx, target_seq,
+					     &vbl_reply));
+		if (o->flags & TEST_VBLANK_BLOCK) {
+			event_handler(&o->vblank_state, vbl_reply.sequence,
+				      vbl_reply.ts.tv_sec,
+				      vbl_reply.ts.tv_usec);
+			completed_events = EVENT_VBLANK;
+		}
+	}
+
 	if (do_flip && (o->flags & TEST_EBUSY))
 		assert(do_page_flip(o, new_fb_id) == -EBUSY);
 
@@ -392,6 +475,9 @@ static void update_all_state(struct test_output *o,
 {
 	if (completed_events & EVENT_FLIP)
 		update_state(&o->flip_state);
+
+	if (completed_events & EVENT_VBLANK)
+		update_state(&o->vblank_state);
 }
 
 static void connector_find_preferred_mode(struct test_output *o, int crtc_id)
@@ -554,7 +640,7 @@ static unsigned int wait_for_events(struct test_output *o)
 
 	memset(&evctx, 0, sizeof evctx);
 	evctx.version = DRM_EVENT_CONTEXT_VERSION;
-	evctx.vblank_handler = NULL;
+	evctx.vblank_handler = vblank_handler;
 	evctx.page_flip_handler = page_flip_handler;
 
 	/* make timeout lax with the dummy load */
@@ -611,10 +697,14 @@ static unsigned event_loop(struct test_output *o, unsigned duration_sec)
 	gettimeofday(&end, NULL);
 	timersub(&end, &start, &tv_dur);
 
+	/* Flush any remaining events */
+	if (o->pending_events)
+		wait_for_events(o);
+
 	return tv_dur.tv_sec * 1000 * 1000 + tv_dur.tv_usec;
 }
 
-static void flip_mode(struct test_output *o, int duration)
+static void run_test_on_crtc(struct test_output *o, int duration)
 {
 	int bpp = 32, depth = 24;
 	unsigned ellapsed;
@@ -661,6 +751,7 @@ static void flip_mode(struct test_output *o, int duration)
 		sleep(1);
 
 	gettimeofday(&o->flip_state.last_ts, NULL);
+	gettimeofday(&o->vblank_state.last_ts, NULL);
 
 	if (do_page_flip(o, o->fb_ids[1])) {
 		fprintf(stderr, "failed to page flip: %s\n", strerror(errno));
@@ -670,11 +761,17 @@ static void flip_mode(struct test_output *o, int duration)
 
 	o->current_fb_id = 1;
 	o->flip_state.seq_step = 1;
+	if (o->flags & TEST_VBLANK_ABSOLUTE)
+		o->vblank_state.seq_step = 5;
+	else
+		o->vblank_state.seq_step = 1;
 
 	ellapsed = event_loop(o, duration);
 
 	if (o->flags & TEST_FLIP)
 		check_final_state(o, &o->flip_state, ellapsed);
+	if (o->flags & TEST_VBLANK)
+		check_final_state(o, &o->vblank_state, ellapsed);
 
 	fprintf(stdout, "\n%s on crtc %d, connector %d: PASSED\n\n",
 		o->test_name, crtc, o->id);
@@ -706,9 +803,10 @@ static int run_test(int duration, int flags, const char *test_name)
 			o.id = resources->connectors[c];
 			o.flags = flags;
 			o.flip_state.name = "flip";
+			o.vblank_state.name = "vblank";
 			o.crtc_idx = i;
 
-			flip_mode(&o, duration);
+			run_test_on_crtc(&o, duration);
 		}
 	}
 
@@ -723,6 +821,23 @@ int main(int argc, char **argv)
 		int flags;
 		const char *name;
 	} tests[] = {
+		{ 30, TEST_VBLANK | TEST_CHECK_TS, "wf-vblank" },
+		{ 30, TEST_VBLANK | TEST_VBLANK_BLOCK | TEST_CHECK_TS,
+					"blocking wf-vblank" },
+		{ 5,  TEST_VBLANK | TEST_VBLANK_ABSOLUTE,
+					"absolute wf-vblank" },
+		{ 5,  TEST_VBLANK | TEST_VBLANK_BLOCK | TEST_VBLANK_ABSOLUTE,
+					"blocking absolute wf-vblank" },
+		{ 5,  TEST_VBLANK | TEST_DPMS, "wf-vblank vs dpms" },
+		{ 5,  TEST_VBLANK | TEST_DPMS | TEST_WITH_DUMMY_LOAD,
+					"delayed wf-vblank vs dpms" },
+		{ 5,  TEST_VBLANK | TEST_PAN, "wf-vblank vs panning" },
+		{ 5,  TEST_VBLANK | TEST_PAN | TEST_WITH_DUMMY_LOAD,
+					"delayed wf-vblank vs panning" },
+		{ 5,  TEST_VBLANK | TEST_MODESET, "wf-vblank vs modeset" },
+		{ 5,  TEST_VBLANK | TEST_MODESET | TEST_WITH_DUMMY_LOAD,
+					"delayed wf-vblank vs modeset" },
+
 		{ 15, TEST_FLIP | TEST_CHECK_TS | TEST_EBUSY , "plain flip" },
 		{ 30, TEST_FLIP | TEST_DPMS | TEST_EINVAL, "flip vs dpms" },
 		{ 30, TEST_FLIP | TEST_DPMS | TEST_WITH_DUMMY_LOAD, "delayed flip vs dpms" },
@@ -730,6 +845,13 @@ int main(int argc, char **argv)
 		{ 30, TEST_FLIP | TEST_PAN | TEST_WITH_DUMMY_LOAD, "delayed flip vs panning" },
 		{ 30, TEST_FLIP | TEST_MODESET | TEST_EINVAL, "flip vs modeset" },
 		{ 30, TEST_FLIP | TEST_MODESET | TEST_WITH_DUMMY_LOAD, "delayed flip vs modeset" },
+
+		{ 30, TEST_FLIP | TEST_VBLANK | TEST_VBLANK_ABSOLUTE |
+		      TEST_CHECK_TS, "flip vs absolute wf-vblank" },
+		{ 30, TEST_FLIP | TEST_VBLANK | TEST_CHECK_TS,
+					"flip vs wf-vblank" },
+		{ 30, TEST_FLIP | TEST_VBLANK | TEST_VBLANK_BLOCK |
+			TEST_CHECK_TS, "flip vs blocking wf-vblank" },
 	};
 	int i;
 
-- 
1.7.9.5

      parent reply	other threads:[~2012-10-16 14:35 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-10-16 14:34 [PATCH 00/22] i-g-t: flip_test: add vblank test cases Imre Deak
2012-10-16 14:34 ` [PATCH 01/22] drmtest: add function to remove an DRM FB Imre Deak
2012-10-16 14:34 ` [PATCH 02/22] flip_test: free FBs after each test run Imre Deak
2012-10-16 14:34 ` [PATCH 03/22] flip_test: reset the state for " Imre Deak
2012-10-16 14:34 ` [PATCH 04/22] flip_test: check drmHandleEvents()' return value Imre Deak
2012-10-16 14:34 ` [PATCH 05/22] test_flip: fix checking for delayed event reception Imre Deak
2012-10-16 14:34 ` [PATCH 06/22] flip_test: store fb width, height in test context object Imre Deak
2012-10-16 14:34 ` [PATCH 07/22] flip_test: factor out drmModePageFlip Imre Deak
2012-10-16 14:34 ` [PATCH 08/22] flip_test: move output panning inside the flip_handler Imre Deak
2012-10-16 14:59   ` Daniel Vetter
2012-10-16 14:34 ` [PATCH 09/22] flip_test: factor out the event loop/wait for event logic Imre Deak
2012-10-16 14:34 ` [PATCH 10/22] flip_test: factor out the final state check Imre Deak
2012-10-16 14:34 ` [PATCH 11/22] flip_test: store current flip/received timestamps in the context obj Imre Deak
2012-10-16 14:34 ` [PATCH 12/22] flip_test: split the flip handler into logical parts Imre Deak
2012-10-16 14:34 ` [PATCH 13/22] flip_test: swap the order of check state/run test step Imre Deak
2012-10-16 14:34 ` [PATCH 14/22] flip_test: factor out the event state Imre Deak
2012-10-16 14:34 ` [PATCH 15/22] flip_test: don't skip checks for sequence #1 Imre Deak
2012-10-16 14:34 ` [PATCH 16/22] flip_test: store crtc_idx in the test context obj Imre Deak
2012-10-16 14:34 ` [PATCH 17/22] flip_test: unify the name of the current test in status messages Imre Deak
2012-10-16 14:34 ` [PATCH 18/22] flip_test: make page flip tests conditional Imre Deak
2012-10-16 14:34 ` [PATCH 19/22] flip_test: add logic to track pending events Imre Deak
2012-10-16 14:34 ` [PATCH 20/22] flip_test: add event sequence number tracking Imre Deak
2012-10-16 14:34 ` [PATCH 21/22] flip_test: add check to see if any event has occured Imre Deak
2012-10-16 14:34 ` Imre Deak [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=1350398096-3649-23-git-send-email-imre.deak@intel.com \
    --to=imre.deak@intel.com \
    --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.