From patchwork Sun Oct 7 06:38:08 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mario Kleiner X-Patchwork-Id: 1560581 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 ECF993FC1A for ; Sun, 7 Oct 2012 06:39:37 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id A5BD79E7EB for ; Sat, 6 Oct 2012 23:39:37 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mx1.mpg.de (mx1.mpg.de [134.76.10.32]) by gabe.freedesktop.org (Postfix) with ESMTP id A96519ED69 for ; Sat, 6 Oct 2012 23:39:13 -0700 (PDT) X-IronPort-Reputation-Score: None X-IronPort-AV: E=McAfee;i="5400,1158,6857"; a="68975508" X-IronPort-AV: E=Sophos;i="4.80,547,1344204000"; d="scan'208";a="68975508" Received: from smtp-out.tuebingen.mpg.de (HELO tuebingen.mpg.de) ([192.124.26.249]) by mailer1.mpg.de with ESMTP; 07 Oct 2012 08:39:12 +0200 Received: from [10.38.134.15] (account mario.kleiner@tuebingen.mpg.de HELO fir.kyb.local) by tuebingen.mpg.de (CommuniGate Pro SMTP 5.4.2) with ESMTPA id 20975508; Sun, 07 Oct 2012 08:39:12 +0200 From: Mario Kleiner To: intel-gfx@lists.freedesktop.org Date: Sun, 7 Oct 2012 08:38:08 +0200 Message-Id: <1349591890-13732-2-git-send-email-mario.kleiner@tuebingen.mpg.de> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1349591890-13732-1-git-send-email-mario.kleiner@tuebingen.mpg.de> References: <1349591890-13732-1-git-send-email-mario.kleiner@tuebingen.mpg.de> Cc: daniel.vetter@ffwll.ch, Mario Kleiner Subject: [Intel-gfx] [PATCH 1/3] ddx/dri2: Make triple-buffering compatible with timestamping on Xorg 1.12+ 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 This patch adds support for OML_sync_control compliant pageflip completion timestamping while triple-buffering is enabled and the ddx is running on Xorg server 1.12 or later. It makes use of the DRI2SwapLimit api to allow up to two pending flips without throttling of the client, then defers invocation of DRI2SwapComplete() until the corresponding pageflips actually complete, just as in the double-buffering case, allowing for proper timestamping and glXWaitForSbcOML() behaviour. This should not impact triple-buffering performance. On server versions <= 1.11 without swaplimit api, triple-buffering is achieved by sacrificing OML_sync_control compliance, as in the old implementation. Tested against server without swaplimit api and 1.13 with swaplimit api, both with and without triplebuffering enabled. Signed-off-by: Mario Kleiner --- src/intel_dri.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 59 insertions(+), 8 deletions(-) diff --git a/src/intel_dri.c b/src/intel_dri.c index 64cb567..126acb2 100644 --- a/src/intel_dri.c +++ b/src/intel_dri.c @@ -310,6 +310,15 @@ I830DRI2CreateBuffer(DrawablePtr drawable, unsigned int attachment, drawable = &(get_drawable_pixmap(drawable)->drawable); is_glamor_pixmap = TRUE; } + +#if DRI2INFOREC_VERSION >= 6 + /* If swaplimit api supported, use it to tell server we are + * triple-buffering capable. This allows triple-buffering + * without need for hacks which compromise time-stamping. + */ + if (drawable->type == DRAWABLE_WINDOW) + DRI2SwapLimit(drawable, intel->use_triple_buffer ? 2 : 1); +#endif } if (pixmap == NULL) { @@ -815,6 +824,20 @@ static drm_intel_bo *get_pixmap_bo(I830DRI2BufferPrivatePtr priv) return bo; } +#if DRI2INFOREC_VERSION >= 6 +static Bool +I830DRI2SwapLimitValidate(DrawablePtr draw, int swap_limit) +{ + ScrnInfoPtr pScrn = xf86ScreenToScrn(draw->pScreen); + struct intel_screen_private *intel = intel_get_screen_private(pScrn); + + if ((swap_limit < 1 ) || (swap_limit > (intel->use_triple_buffer ? 2 : 1))) + return FALSE; + + return TRUE; +} +#endif + /* * Our internal swap routine takes care of actually exchanging, blitting, or * flipping buffers as necessary. @@ -914,10 +937,17 @@ I830DRI2ScheduleFlip(struct intel_screen_private *intel, /* Then flip DRI2 pointers and update the screen pixmap */ I830DRI2ExchangeBuffers(intel, info->front, info->back); + +#if DRI2INFOREC_VERSION < 6 + /* Only needed on Xorg <= 1.11 server, which doesn't have swaplimit + * api to do this cleanly. Breaks OML_sync_control timestamping. + */ DRI2SwapComplete(info->client, draw, 0, 0, 0, DRI2_EXCHANGE_COMPLETE, info->event_complete, info->event_data); +#endif + return TRUE; } @@ -1041,14 +1071,22 @@ void I830DRI2FlipEventHandler(unsigned int frame, unsigned int tv_sec, dixLookupDrawable(&drawable, flip_info->drawable_id, serverClient, M_ANY, DixWriteAccess); - - /* We assume our flips arrive in order, so we don't check the frame */ - switch (flip_info->type) { - case DRI2_SWAP: - if (!drawable) - break; - - /* Check for too small vblank count of pageflip completion, taking wraparound + /* Perform consistency check, final timestamping and swap completion here iff: + * - This is a pageflip completion for a classic double-buffered swap. + * - This is a pageflip completion for a triple-buffered swap and the XOrg 1.12+ + * server supports the swap limit api, so we were able to defer swap completion + * until this point without negative impact on performance. + * + * -> This allows OML_sync_control spec compliant timestamping. + * + * On older servers we already mark the swap as completed ahead of its completion in + * I830DRI2ScheduleFlip to allow triple-buffering at the cost of broken timestamping. + */ + if (drawable && ((flip_info->type == DRI2_SWAP) || + ((DRI2INFOREC_VERSION >= 6) && (flip_info->type == DRI2_SWAP_CHAIN)))) { + /* We assume our flips arrive in order, so we don't check the frame. + * + * Check for too small vblank count of pageflip completion, taking wraparound * into account. This usually means some defective kms pageflip completion, * causing wrong (msc, ust) return values and possible visual corruption. */ @@ -1072,6 +1110,11 @@ void I830DRI2FlipEventHandler(unsigned int frame, unsigned int tv_sec, DRI2SwapComplete(flip_info->client, drawable, frame, tv_sec, tv_usec, DRI2_FLIP_COMPLETE, flip_info->client ? flip_info->event_complete : NULL, flip_info->event_data); + } + + switch (flip_info->type) { + case DRI2_SWAP: + /* All completion work for double-buffered swaps already done above. */ break; case DRI2_SWAP_CHAIN: @@ -1596,6 +1639,14 @@ Bool I830DRI2ScreenInit(ScreenPtr screen) driverNames[0] = info.driverName; #endif +#if DRI2INFOREC_VERSION >= 6 + info.version = 6; + info.SwapLimitValidate = I830DRI2SwapLimitValidate; + /* Server has fallbacks for these undefined ones for v5 and v6: */ + info.AuthMagic = NULL; + info.ReuseBufferNotify = NULL; +#endif + return DRI2ScreenInit(screen, &info); }