[Mesa-dev] [PATCH 2/3] glx: add interface for flushing a drawable and throttling at the same time

Marek Olšák maraeo at gmail.com
Thu Nov 8 05:48:39 PST 2012


The motivation is to prevent a double flush in Gallium.

Gallium flushes in __DRI2flushExtensionRec::flush and dri2Throttle.
This will help consolidate the flushing.
---
 include/GL/internal/dri_interface.h           |   16 +++++++++++++-
 src/gallium/state_trackers/dri/drm/dri2.c     |    2 +-
 src/glx/dri2_glx.c                            |   28 ++++++++++++++++++++-----
 src/mesa/drivers/dri/intel/intel_screen.c     |    2 +-
 src/mesa/drivers/dri/nouveau/nouveau_screen.c |    2 +-
 src/mesa/drivers/dri/radeon/radeon_screen.c   |    2 +-
 6 files changed, 42 insertions(+), 10 deletions(-)

diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index 1e0f1d0..cefbb2a 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -263,11 +263,13 @@ struct __DRItexBufferExtensionRec {
 			__DRIdrawable *pDraw);
 };
 
+enum __DRI2throttleReason;
+
 /**
  * Used by drivers that implement DRI2
  */
 #define __DRI2_FLUSH "DRI2_Flush"
-#define __DRI2_FLUSH_VERSION 3
+#define __DRI2_FLUSH_VERSION 4
 struct __DRI2flushExtensionRec {
     __DRIextension base;
     void (*flush)(__DRIdrawable *drawable);
@@ -281,6 +283,18 @@ struct __DRI2flushExtensionRec {
      * \since 3
      */
     void (*invalidate)(__DRIdrawable *drawable);
+
+    /**
+     * Ask the driver to flush and throttle at the same time.
+     *
+     * \param drawable the drawable to invalidate
+     * \param reason   the reason why it has to throttle,
+     *                 0 disables the throttling
+     *
+     * \since 4
+     */
+    void (*flush_and_throttle)(__DRIdrawable *drawable,
+                               enum __DRI2throttleReason reason);
 };
 
 
diff --git a/src/gallium/state_trackers/dri/drm/dri2.c b/src/gallium/state_trackers/dri/drm/dri2.c
index 2f83dab..931867e 100644
--- a/src/gallium/state_trackers/dri/drm/dri2.c
+++ b/src/gallium/state_trackers/dri/drm/dri2.c
@@ -71,7 +71,7 @@ dri2_invalidate_drawable(__DRIdrawable *dPriv)
 }
 
 static const __DRI2flushExtension dri2FlushExtension = {
-    { __DRI2_FLUSH, __DRI2_FLUSH_VERSION },
+    { __DRI2_FLUSH, 3 },
     dri2_flush_drawable,
     dri2_invalidate_drawable,
 };
diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c
index 12b3026..7646cc7 100644
--- a/src/glx/dri2_glx.c
+++ b/src/glx/dri2_glx.c
@@ -540,6 +540,7 @@ __dri2CopySubBuffer(__GLXDRIdrawable *pdraw, int x, int y,
    struct dri2_screen *psc = (struct dri2_screen *) pdraw->psc;
    XRectangle xrect;
    XserverRegion region;
+   Bool throttled = False;
 
    /* Check we have the right attachments */
    if (!priv->have_back)
@@ -550,10 +551,18 @@ __dri2CopySubBuffer(__GLXDRIdrawable *pdraw, int x, int y,
    xrect.width = width;
    xrect.height = height;
 
-   if (psc->f)
-      (*psc->f->flush) (priv->driDrawable);
+   if (psc->f) {
+      if (psc->f->base.version >= 4) {
+         (*psc->f->flush_and_throttle) (priv->driDrawable, reason);
+         throttled = True;
+      }
+      else {
+         (*psc->f->flush) (priv->driDrawable);
+      }
+   }
 
-   dri2Throttle(psc, priv, reason);
+   if (!throttled)
+      dri2Throttle(psc, priv, reason);
 
    region = XFixesCreateRegion(psc->base.dpy, &xrect, 1);
    DRI2CopyRegion(psc->base.dpy, pdraw->xDrawable, region,
@@ -739,6 +748,7 @@ dri2SwapBuffers(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
     struct dri2_display *pdp =
 	(struct dri2_display *)dpyPriv->dri2Display;
     CARD64 ret = 0;
+    Bool throttled = False;
 
     /* Check we have the right attachments */
     if (!priv->have_back)
@@ -760,11 +770,19 @@ dri2SwapBuffers(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
           struct glx_context *gc = __glXGetCurrentContext();
 
           if (gc) {
-             (*psc->f->flush)(priv->driDrawable);
+             if (psc->f->base.version >= 4) {
+                (*psc->f->flush_and_throttle)(priv->driDrawable, __DRI2_THROTTLE_SWAPBUFFER);
+                throttled = True;
+             }
+             else {
+                (*psc->f->flush)(priv->driDrawable);
+             }
           }
        }
 
-       dri2Throttle(psc, priv, __DRI2_THROTTLE_SWAPBUFFER);
+       if (!throttled) {
+          dri2Throttle(psc, priv, __DRI2_THROTTLE_SWAPBUFFER);
+       }
 
        split_counter(target_msc, &target_msc_hi, &target_msc_lo);
        split_counter(divisor, &divisor_hi, &divisor_lo);
diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
index 0194804..98fc99f 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.c
+++ b/src/mesa/drivers/dri/intel/intel_screen.c
@@ -186,7 +186,7 @@ intelDRI2Flush(__DRIdrawable *drawable)
 }
 
 static const struct __DRI2flushExtensionRec intelFlushExtension = {
-    { __DRI2_FLUSH, __DRI2_FLUSH_VERSION },
+    { __DRI2_FLUSH, 3 },
     intelDRI2Flush,
     dri2InvalidateDrawable,
 };
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c
index dc6d758..ca39fff 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_screen.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c
@@ -216,7 +216,7 @@ nouveau_drawable_flush(__DRIdrawable *draw)
 }
 
 static const struct __DRI2flushExtensionRec nouveau_flush_extension = {
-    { __DRI2_FLUSH, __DRI2_FLUSH_VERSION },
+    { __DRI2_FLUSH, 3 },
     nouveau_drawable_flush,
     dri2InvalidateDrawable,
 };
diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c
index 6f4750a..a5fad70 100644
--- a/src/mesa/drivers/dri/radeon/radeon_screen.c
+++ b/src/mesa/drivers/dri/radeon/radeon_screen.c
@@ -193,7 +193,7 @@ radeonDRI2Flush(__DRIdrawable *drawable)
 }
 
 static const struct __DRI2flushExtensionRec radeonFlushExtension = {
-    { __DRI2_FLUSH, __DRI2_FLUSH_VERSION },
+    { __DRI2_FLUSH, 3 },
     radeonDRI2Flush,
     dri2InvalidateDrawable,
 };
-- 
1.7.9.5



More information about the mesa-dev mailing list