[PATCH] dri2: Pass async swap requests to the drivers

Chris Wilson chris at chris-wilson.co.uk
Tue Sep 3 07:08:05 PDT 2013


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 <chris at chris-wilson.co.uk>
Cc: Eero Tamminen <eero.t.tamminen at intel.com>
Cc: Eric Anholt <eric at anholt.net>
Cc: Ben Skeggs <skeggsb at gmail.com>
---
 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



More information about the xorg-devel mailing list