[PATCH 5/6] DRI2: Implement interface for drivers to access DRI2GetBuffersWithFormat

Ian Romanick idr at freedesktop.org
Mon Apr 20 20:55:56 PDT 2009


Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
---
 include/GL/internal/dri_interface.h |   28 +++++++++-
 src/glx/x11/dri2_glx.c              |  104 ++++++++++++++++++++++++++++------
 2 files changed, 112 insertions(+), 20 deletions(-)

diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index 335bf62..bfa8a33 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -649,6 +649,7 @@ struct __DRIswrastExtensionRec {
 #define __DRI_BUFFER_ACCUM		6
 #define __DRI_BUFFER_FAKE_FRONT_LEFT	7
 #define __DRI_BUFFER_FAKE_FRONT_RIGHT	8
+#define __DRI_BUFFER_DEPTH_STENCIL	9  /**< Only available with DRI2 1.1 */
 
 struct __DRIbufferRec {
     unsigned int attachment;
@@ -659,7 +660,7 @@ struct __DRIbufferRec {
 };
 
 #define __DRI_DRI2_LOADER "DRI_DRI2Loader"
-#define __DRI_DRI2_LOADER_VERSION 2
+#define __DRI_DRI2_LOADER_VERSION 3
 struct __DRIdri2LoaderExtensionRec {
     __DRIextension base;
 
@@ -680,6 +681,31 @@ struct __DRIdri2LoaderExtensionRec {
      *                       into __DRIdri2ExtensionRec::createNewDrawable
      */
     void (*flushFrontBuffer)(__DRIdrawable *driDrawable, void *loaderPrivate);
+
+
+    /**
+     * Get list of buffers from the server
+     *
+     * Gets a list of buffer for the specified set of attachments.  Unlike
+     * \c ::getBuffers, this function takes a list of attachments paired with
+     * opaque \c unsigned \c int value describing the format of the buffer.
+     * It is the responsibility of the caller to know what the service that
+     * allocates the buffers will expect to receive for the format.
+     *
+     * \param driDrawable    Drawable whose buffers are being queried.
+     * \param width          Output where the width of the buffers is stored.
+     * \param height         Output where the height of the buffers is stored.
+     * \param attachments    List of pairs of attachment ID and opaque format
+     *                       requested for the drawable.
+     * \param count          Number of attachment / format pairs stored in
+     *                       \c attachments.
+     * \param loaderPrivate  Loader's private data that was previously passed
+     *                       into __DRIdri2ExtensionRec::createNewDrawable.
+     */
+    __DRIbuffer *(*getBuffersWithFormat)(__DRIdrawable *driDrawable,
+					 int *width, int *height,
+					 unsigned int *attachments, int count,
+					 int *out_count, void *loaderPrivate);
 };
 
 /**
diff --git a/src/glx/x11/dri2_glx.c b/src/glx/x11/dri2_glx.c
index b6eeb91..ed25783 100644
--- a/src/glx/x11/dri2_glx.c
+++ b/src/glx/x11/dri2_glx.c
@@ -47,6 +47,9 @@
 #include "dri2.h"
 #include "dri_common.h"
 
+#undef DRI2_MINOR
+#define DRI2_MINOR 1
+
 typedef struct __GLXDRIdisplayPrivateRec __GLXDRIdisplayPrivate;
 typedef struct __GLXDRIcontextPrivateRec __GLXDRIcontextPrivate;
 typedef struct __GLXDRIdrawablePrivateRec __GLXDRIdrawablePrivate;
@@ -289,30 +292,25 @@ static void dri2DestroyScreen(__GLXscreenConfigs *psc)
     psc->__driScreen = NULL;
 }
 
-static __DRIbuffer *
-dri2GetBuffers(__DRIdrawable *driDrawable,
-	       int *width, int *height,
-	       unsigned int *attachments, int count,
-	       int *out_count, void *loaderPrivate)
+/**
+ * Process list of buffer received from the server
+ *
+ * Processes the list of buffers received in a reply from the server to either
+ * \c DRI2GetBuffers or \c DRI2GetBuffersWithFormat.
+ */
+static void
+process_buffers(__GLXDRIdrawablePrivate *pdraw, DRI2Buffer *buffers,
+		unsigned count)
 {
-    __GLXDRIdrawablePrivate *pdraw = loaderPrivate;
-    DRI2Buffer *buffers;
     int i;
 
-    buffers = DRI2GetBuffers(pdraw->base.psc->dpy, pdraw->base.xDrawable,
-			     width, height, attachments, count, out_count);
-    if (buffers == NULL)
-       return NULL;
-
-    pdraw->width = *width;
-    pdraw->height = *height;
-    pdraw->bufferCount = *out_count;
+    pdraw->bufferCount = count;
     pdraw->have_fake_front = 0;
     pdraw->have_back = 0;
 
     /* This assumes the DRI2 buffer attachment tokens matches the
      * __DRIbuffer tokens. */
-    for (i = 0; i < *out_count; i++) {
+    for (i = 0; i < count; i++) {
 	pdraw->buffers[i].attachment = buffers[i].attachment;
 	pdraw->buffers[i].name = buffers[i].name;
 	pdraw->buffers[i].pitch = buffers[i].pitch;
@@ -324,6 +322,51 @@ dri2GetBuffers(__DRIdrawable *driDrawable,
 	    pdraw->have_back = 1;
     }
 
+}
+
+static __DRIbuffer *
+dri2GetBuffers(__DRIdrawable *driDrawable,
+	       int *width, int *height,
+	       unsigned int *attachments, int count,
+	       int *out_count, void *loaderPrivate)
+{
+    __GLXDRIdrawablePrivate *pdraw = loaderPrivate;
+    DRI2Buffer *buffers;
+
+    buffers = DRI2GetBuffers(pdraw->base.psc->dpy, pdraw->base.xDrawable,
+			     width, height, attachments, count, out_count);
+    if (buffers == NULL)
+       return NULL;
+
+    pdraw->width = *width;
+    pdraw->height = *height;
+    process_buffers(pdraw, buffers, *out_count);
+
+    Xfree(buffers);
+
+    return pdraw->buffers;
+}
+
+static __DRIbuffer *
+dri2GetBuffersWithFormat(__DRIdrawable *driDrawable,
+			 int *width, int *height,
+			 unsigned int *attachments, int count,
+			 int *out_count, void *loaderPrivate)
+{
+    __GLXDRIdrawablePrivate *pdraw = loaderPrivate;
+    DRI2Buffer *buffers;
+
+    buffers = DRI2GetBuffersWithFormat(pdraw->base.psc->dpy,
+				       pdraw->base.xDrawable,
+				       width, height, attachments,
+				       count, out_count);
+    if (buffers == NULL)
+       return NULL;
+
+    pdraw->width = *width;
+    pdraw->height = *height;
+    process_buffers(pdraw, buffers, *out_count);
+
     Xfree(buffers);
 
     return pdraw->buffers;
@@ -332,7 +375,15 @@ dri2GetBuffers(__DRIdrawable *driDrawable,
 static const __DRIdri2LoaderExtension dri2LoaderExtension = {
     { __DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION },
     dri2GetBuffers,
-    dri2FlushFrontBuffer
+    dri2FlushFrontBuffer,
+    dri2GetBuffersWithFormat,
+};
+
+static const __DRIdri2LoaderExtension dri2LoaderExtension_old = {
+    { __DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION },
+    dri2GetBuffers,
+    dri2FlushFrontBuffer,
+    NULL,
 };
 
 static const __DRIextension *loader_extensions[] = {
@@ -341,11 +392,19 @@ static const __DRIextension *loader_extensions[] = {
     NULL
 };
 
+static const __DRIextension *loader_extensions_old[] = {
+    &dri2LoaderExtension_old.base,
+    &systemTimeExtension.base,
+    NULL
+};
+
 static __GLXDRIscreen *dri2CreateScreen(__GLXscreenConfigs *psc, int screen,
 					__GLXdisplayPrivate *priv)
 {
     const __DRIconfig **driver_configs;
     const __DRIextension **extensions;
+    const __GLXDRIdisplayPrivate *const pdp = (__GLXDRIdisplayPrivate *)
+      priv->dri2Display;
     __GLXDRIscreen *psp;
     char *driverName, *deviceName;
     drm_magic_t magic;
@@ -402,9 +461,16 @@ static __GLXDRIscreen *dri2CreateScreen(__GLXscreenConfigs *psc, int screen,
 	return NULL;
     }
 
+    /* If the server does not support the protocol for
+     * DRI2GetBuffersWithFormat, don't supply that interface to the driver.
+     */
     psc->__driScreen = 
-	psc->dri2->createNewScreen(screen, psc->fd,
-				   loader_extensions, &driver_configs, psc);
+      psc->dri2->createNewScreen(screen, psc->fd,
+				 ((pdp->driMinor < 1) 
+				  ? loader_extensions_old
+				  : loader_extensions),
+				 &driver_configs, psc);
+
     if (psc->__driScreen == NULL) {
 	ErrorMessageF("failed to create dri screen\n");
 	return NULL;
-- 
1.6.0.6



More information about the xorg-devel mailing list