From patchwork Tue Oct 16 14:34:53 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Imre Deak X-Patchwork-Id: 1601101 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork1.kernel.org (Postfix) with ESMTP id 163F140ABA for ; Tue, 16 Oct 2012 14:50:28 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 3CEBFA0894 for ; Tue, 16 Oct 2012 07:50:28 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga14.intel.com (mga14.intel.com [143.182.124.37]) by gabe.freedesktop.org (Postfix) with ESMTP id D48B79F5F3 for ; Tue, 16 Oct 2012 07:35:40 -0700 (PDT) Received: from azsmga001.ch.intel.com ([10.2.17.19]) by azsmga102.ch.intel.com with ESMTP; 16 Oct 2012 07:35:40 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.80,593,1344236400"; d="scan'208";a="205092410" Received: from ideak-desk.fi.intel.com (HELO localhost) ([10.237.72.98]) by azsmga001.ch.intel.com with ESMTP; 16 Oct 2012 07:35:39 -0700 From: Imre Deak To: intel-gfx@lists.freedesktop.org Date: Tue, 16 Oct 2012 17:34:53 +0300 Message-Id: <1350398096-3649-20-git-send-email-imre.deak@intel.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1350398096-3649-1-git-send-email-imre.deak@intel.com> References: <1350398096-3649-1-git-send-email-imre.deak@intel.com> Subject: [Intel-gfx] [PATCH 19/22] flip_test: add logic to track pending events X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org Errors-To: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org When we add the vblank tests later, it can happen that one type of event is pending while we are servicing another. Prepare for that by maintaining a pending/completed event mask. No functional change. Signed-off-by: Imre Deak --- tests/flip_test.c | 68 +++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 56 insertions(+), 12 deletions(-) diff --git a/tests/flip_test.c b/tests/flip_test.c index 45bd9e5..9772599 100644 --- a/tests/flip_test.c +++ b/tests/flip_test.c @@ -50,6 +50,8 @@ #define TEST_EINVAL (1 << 6) #define TEST_FLIP (1 << 7) +#define EVENT_FLIP (1 << 0) + drmModeRes *resources; int drm_fd; static drm_intel_bufmgr *bufmgr; @@ -101,6 +103,7 @@ struct test_output { struct kmstest_fb fb_info[2]; struct event_state flip_state; + unsigned int pending_events; }; static void emit_dummy_load(struct test_output *o) @@ -179,10 +182,28 @@ static int set_dpms(struct test_output *o, int mode) return drmModeConnectorSetProperty(drm_fd, o->id, dpms, mode); } +static void set_flag(unsigned int *v, unsigned int flag) +{ + assert(!(*v & flag)); + *v |= flag; +} + +static void clear_flag(unsigned int *v, unsigned int flag) +{ + assert(*v & flag); + *v &= ~flag; +} + static int do_page_flip(struct test_output *o, int fb_id) { - return drmModePageFlip(drm_fd, o->crtc, fb_id, DRM_MODE_PAGE_FLIP_EVENT, + int ret; + + ret = drmModePageFlip(drm_fd, o->crtc, fb_id, DRM_MODE_PAGE_FLIP_EVENT, o); + if (ret == 0) + set_flag(&o->pending_events, EVENT_FLIP); + + return ret; } static bool @@ -209,6 +230,7 @@ static void page_flip_handler(int fd, unsigned int frame, unsigned int sec, { struct test_output *o = data; + clear_flag(&o->pending_events, EVENT_FLIP); event_handler(&o->flip_state, frame, sec, usec); } @@ -250,20 +272,23 @@ static void check_state(struct test_output *o, struct event_state *es) } } -static void check_all_state(struct test_output *o) +static void check_all_state(struct test_output *o, + unsigned int completed_events) { - if (o->flags & TEST_FLIP) + if (completed_events & EVENT_FLIP) check_state(o, &o->flip_state); } -static void run_test_step(struct test_output *o) +/* Return mask of completed events. */ +static unsigned int run_test_step(struct test_output *o) { unsigned int new_fb_id; /* for funny reasons page_flip returns -EBUSY on disabled crtcs ... */ int expected_einval = o->flags & TEST_MODESET ? -EBUSY : -EINVAL; + unsigned int completed_events = 0; bool do_flip; - do_flip = o->flags & TEST_FLIP; + do_flip = (o->flags & TEST_FLIP) && !(o->pending_events & EVENT_FLIP); /* pan before the flip completes */ if (o->flags & TEST_PAN) { @@ -328,6 +353,8 @@ static void run_test_step(struct test_output *o) if (do_flip && (o->flags & TEST_EINVAL)) assert(do_page_flip(o, new_fb_id) == expected_einval); + + return completed_events; } static void update_state(struct event_state *es) @@ -337,9 +364,11 @@ static void update_state(struct event_state *es) es->count++; } -static void update_all_state(struct test_output *o) +static void update_all_state(struct test_output *o, + unsigned int completed_events) { - update_state(&o->flip_state); + if (completed_events & EVENT_FLIP) + update_state(&o->flip_state); } static void connector_find_preferred_mode(struct test_output *o, int crtc_id) @@ -479,13 +508,21 @@ static void check_final_state(struct test_output *o, struct event_state *es, } } -static void wait_for_events(struct test_output *o) +/* + * Wait until at least one pending event completes. Return mask of completed + * events. + */ +static unsigned int wait_for_events(struct test_output *o) { drmEventContext evctx; struct timeval timeout = { .tv_sec = 3, .tv_usec = 0 }; fd_set fds; + unsigned int event_mask; int ret; + event_mask = o->pending_events; + assert(event_mask); + memset(&evctx, 0, sizeof evctx); evctx.version = DRM_EVENT_CONTEXT_VERSION; evctx.vblank_handler = NULL; @@ -510,6 +547,11 @@ static void wait_for_events(struct test_output *o) } drmHandleEvent(drm_fd, &evctx); + + event_mask ^= o->pending_events; + assert(event_mask); + + return event_mask; } /* Returned the ellapsed time in us */ @@ -524,11 +566,13 @@ static unsigned event_loop(struct test_output *o, unsigned duration_sec) while (1) { struct timeval now; + unsigned int completed_events; - run_test_step(o); - wait_for_events(o); - check_all_state(o); - update_all_state(o); + completed_events = run_test_step(o); + if (o->pending_events) + completed_events |= wait_for_events(o); + check_all_state(o, completed_events); + update_all_state(o, completed_events); gettimeofday(&now, NULL); if (!timercmp(&now, &end, <))