DRI2: Implement interface for drivers to access DRI2GetBuffersWithFormat
authorIan Romanick <idr@freedesktop.org>
Tue, 21 Apr 2009 03:55:56 +0000 (20:55 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Fri, 24 Apr 2009 19:48:20 +0000 (12:48 -0700)
Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Kristian Høgsberg <krh@redhat.com>
include/GL/internal/dri_interface.h
src/glx/x11/dri2_glx.c

index 335bf62a801258040f7788b2fac3e7807aabe8a6..bfa8a33b3c7c9988098862062ebf0f5e7040f84a 100644 (file)
@@ -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);
 };
 
 /**
index b6eeb913b66632951623e5eb9075c47d5c080479..fb31898db2d855c320be2aab78c6bb27be528e94 100644 (file)
@@ -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;