Currently, the midlayer dri2 code intercepts swap_interval=0 SwapBuffers and converts it to a CopyRegion request. The backend cannot distinguish between a request for an asynchronous CopyRegion from DRI2ScheduleSwap and an ideally synchronized to vrefresh call from DRI2CopyRegion, so either CopySubBufferMESA tears or vblank_mode=0 is ineffective. The protocol is also equally ineffective at allowing the application to request the synchronisation and swap method. That will require DRI protocol changes, but in the meantime the backend can make meaningful decisions based on target/divider/remainder - except that feeding in swap_interval=0 to most backends again breaks as they are not prepared for asynchronous buffer swaps. So we have to regard this as an ABI break, and introduce a new field into DRI2InfoRec to allow backends to opt in to handling swap_interval=0 requests.
This principally^Wonly helps with fullscreen swap benchmarks (glxgears, Triangle) where the cost of the blit is of the same order as the rest of the rendering - i.e. such simple benchmarks can ideally expect a twofold speed improvement. Link: http://lists.x.org/archives/xorg-devel/2011-June/023102.html Link: http://lists.x.org/archives/xorg-devel/2012-November/034446.html Signed-off-by: Chris Wilson <[email protected]> Cc: Eero Tamminen <[email protected]> Cc: Eric Anholt <[email protected]> Cc: Ben Skeggs <[email protected]> --- hw/xfree86/dri2/dri2.c | 14 +++++++++++--- hw/xfree86/dri2/dri2.h | 5 ++++- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c index 0b047f0..90baae5 100644 --- a/hw/xfree86/dri2/dri2.c +++ b/hw/xfree86/dri2/dri2.c @@ -114,6 +114,7 @@ typedef struct _DRI2Screen { int fd; unsigned int lastSequence; int prime_id; + int scheduleSwap0; DRI2CreateBufferProcPtr CreateBuffer; DRI2DestroyBufferProcPtr DestroyBuffer; @@ -1104,8 +1105,9 @@ DRI2SwapBuffers(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc, return BadDrawable; } - /* Old DDX or no swap interval, just blit */ - if (!ds->ScheduleSwap || !pPriv->swap_interval || pPriv->prime_id) { + /* Old DDX or PRIME, just blit */ + if (!ds->ScheduleSwap || pPriv->prime_id || + (pPriv->swap_interval == 0 && !ds->scheduleSwap0)) { BoxRec box; RegionRec region; @@ -1127,7 +1129,9 @@ DRI2SwapBuffers(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc, * In the simple glXSwapBuffers case, all params will be 0, and we just * need to schedule a swap for the last swap target + the swap interval. */ - if (target_msc == 0 && divisor == 0 && remainder == 0) { + if (pPriv->swap_interval == 0) { + *swap_target = 0; + } else if (target_msc == 0 && divisor == 0 && remainder == 0) { /* If the current vblank count of the drawable's crtc is lower * than the count stored in last_swap_target from a previous swap * then reinitialize last_swap_target to the current crtc's msc, @@ -1487,6 +1491,10 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info) ds->CopyRegion2 = info->CopyRegion2; } + if (info->version >= 10) { + ds->scheduleSwap0 = info->scheduleSwap0; + } + /* * if the driver doesn't provide an AuthMagic function or the info struct * version is too low, call through LegacyAuthMagic diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h index 1e7afdd..1cf4288 100644 --- a/hw/xfree86/dri2/dri2.h +++ b/hw/xfree86/dri2/dri2.h @@ -205,7 +205,7 @@ typedef int (*DRI2GetParamProcPtr) (ClientPtr client, /** * Version of the DRI2InfoRec structure defined in this header */ -#define DRI2INFOREC_VERSION 9 +#define DRI2INFOREC_VERSION 10 typedef struct { unsigned int version; /**< Version of this struct */ @@ -252,6 +252,9 @@ typedef struct { DRI2CreateBuffer2ProcPtr CreateBuffer2; DRI2DestroyBuffer2ProcPtr DestroyBuffer2; DRI2CopyRegion2ProcPtr CopyRegion2; + + /* added in version 10 */ + int scheduleSwap0; } DRI2InfoRec, *DRI2InfoPtr; extern _X_EXPORT Bool DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info); -- 1.8.4.rc3 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
