On Thu, Feb 19, 2009 at 8:46 PM, Alan Hourihane <al...@fairlite.co.uk> wrote:
> Attached is a new DRI2 flush extension that allows the driver to perform
> a "real flush" before dispatching a swap or Xserver copy operation.
>
> Currently we do this before a DRI2CopyRegion() call.
>
> This allows drivers a real "end of scene" flush to ensure rendering is
> complete prior to a swap.
>
> I've committed this already to the gallium-mesa-7.4 branch, but any
> comments appreciated before I push to the master branch?

Hi Alan,

A couple of comments below.

commit b163d4f9ee2ab4d54daf7c17c097cae51c9c6db2
Author: Alan Hourihane <al...@vmware.com>
Date:   Thu Feb 19 18:39:08 2009 +0000

    glx: add support for a reallyFlush() function before swap occurs.

diff --git a/include/GL/internal/dri_interface.h
b/include/GL/internal/dri_interface.h
index 27cc1be..a726b93 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -78,6 +78,7 @@ typedef struct __DRIswrastExtensionRec                
__DRIswrastExtension;
 typedef struct __DRIbufferRec                  __DRIbuffer;
 typedef struct __DRIdri2ExtensionRec           __DRIdri2Extension;
 typedef struct __DRIdri2LoaderExtensionRec     __DRIdri2LoaderExtension;
+typedef struct __DRI2flushExtensionRec __DRI2flushExtension;

 /*...@}*/

@@ -245,6 +246,16 @@ struct __DRItexBufferExtensionRec {
                         __DRIdrawable *pDraw);
 };

+/**
+ * Used by drivers that implement DRI2
+ */
+#define __DRI2_FLUSH "DRI2_Flush"
+#define __DRI2_FLUSH_VERSION 1
+struct __DRI2flushExtensionRec {
+    __DRIextension base;
+    void (*flush)(__DRIdrawable *drawable);
+};
+

 /**
  * XML document describing the configuration options supported by the
diff --git a/src/glx/x11/dri2_glx.c b/src/glx/x11/dri2_glx.c
index 639aa19..fdda852 100644
--- a/src/glx/x11/dri2_glx.c
+++ b/src/glx/x11/dri2_glx.c
@@ -207,7 +207,13 @@ static void dri2CopySubBuffer(__GLXDRIdrawable *pdraw,
     xrect.width = width;
     xrect.height = height;

+#ifdef __DRI2_FLUSH
+    if (pdraw->psc->f)
+       (*pdraw->psc->f->flush)(pdraw->driDrawable);
+#endif
+
     region = XFixesCreateRegion(pdraw->psc->dpy, &xrect, 1);
+    /* should get a fence ID back from here at some point */
     DRI2CopyRegion(pdraw->psc->dpy, pdraw->drawable, region,
                   DRI2BufferFrontLeft, DRI2BufferBackLeft);
     XFixesDestroyRegion(pdraw->psc->dpy, region);
@@ -235,6 +241,11 @@ static void dri2WaitX(__GLXDRIdrawable *pdraw)
     xrect.width = priv->width;
     xrect.height = priv->height;

+#ifdef __DRI2_FLUSH
+    if (pdraw->psc->f)
+       (*pdraw->psc->f->flush)(pdraw->driDrawable);
+#endif
+

This flush call isn't necessary - glXWaitX() is called to wait for X
rendering to the drawable to finish so there can't be any unflushed
DRI driver activity.

     region = XFixesCreateRegion(pdraw->psc->dpy, &xrect, 1);
     DRI2CopyRegion(pdraw->psc->dpy, pdraw->drawable, region,
                   DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft);
@@ -255,6 +266,11 @@ static void dri2WaitGL(__GLXDRIdrawable *pdraw)
     xrect.width = priv->width;
     xrect.height = priv->height;

+#ifdef __DRI2_FLUSH
+    if (pdraw->psc->f)
+       (*pdraw->psc->f->flush)(pdraw->driDrawable);
+#endif
+
     region = XFixesCreateRegion(pdraw->psc->dpy, &xrect, 1);
     DRI2CopyRegion(pdraw->psc->dpy, pdraw->drawable, region,
                   DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
diff --git a/src/glx/x11/dri_common.c b/src/glx/x11/dri_common.c
index 4fda649..90c3d8c 100644
--- a/src/glx/x11/dri_common.c
+++ b/src/glx/x11/dri_common.c
@@ -392,6 +392,13 @@ driBindExtensions(__GLXscreenConfigs *psc, int dri2)
        }
 #endif

+#ifdef __DRI2_FLUSH
+       if ((strcmp(extensions[i]->name, __DRI2_FLUSH) == 0) && dri2) {
+           psc->f = (__DRI2flushExtension *) extensions[i];
+           /* internal driver extension, no GL extension exposed */
+       }
+#endif

The driver needs to know whether the loader is new enough that it
supports the flush extension so that it can enable the lazy glFlush()
optiomization.  An older loader will just ignore the flush extension
and thus never call that entry point, in which case the driver must
flush on every glFlush() call.  The only way to do this I can think of
right now is to add an 'enable()' entrypoint to the extension to tell
the driver that the loader will call ->flush() and it's ok to ignore
glFlush().

        /* Ignore unknown extensions */
     }
 }
diff --git a/src/glx/x11/glxclient.h b/src/glx/x11/glxclient.h
index 3e70759..caf58bb 100644
--- a/src/glx/x11/glxclient.h
+++ b/src/glx/x11/glxclient.h
@@ -519,6 +519,10 @@ struct __GLXscreenConfigsRec {
     const __DRItexBufferExtension *texBuffer;
 #endif

+#ifdef __DRI2_FLUSH
+    const __DRI2flushExtension *f;
+#endif
+
 #endif

     /**

------------------------------------------------------------------------------
Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA
-OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise
-Strategies to boost innovation and cut costs with open source participation
-Receive a $600 discount off the registration fee with the source code: SFAD
http://p.sf.net/sfu/XcvMzF8H
--
_______________________________________________
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel

Reply via email to