[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

xorg-server: Changes to 'upstream-unstable'



 configure.ac                     |    2 
 dix/events.c                     |    6 -
 glx/glxdri2.c                    |   82 +++++++++++++-
 hw/vfb/InitOutput.c              |   30 -----
 hw/xfree86/common/xf86pciBus.c   |   10 -
 hw/xfree86/ddc/edid.h            |    2 
 hw/xfree86/ddc/interpret_edid.c  |    7 -
 hw/xfree86/dri2/dri2.c           |  217 ++++++++++++++++++++++++++++++++++-----
 hw/xfree86/dri2/dri2.h           |   46 +++++++-
 hw/xfree86/dri2/dri2ext.c        |   96 +++++++++++++----
 hw/xfree86/modes/xf86EdidModes.c |   87 +++++++++++++++
 11 files changed, 487 insertions(+), 98 deletions(-)

New commits:
commit dbac41b624e4aa86a6a184b7ebb52bfdd367bbf0
Author: Adam Jackson <ajax@redhat.com>
Date:   Fri Jun 19 12:42:07 2009 -0400

    pci: Dump vendor/devices ids in the printed device list
    (cherry picked from commit eb35402d0a5290e8a73d7d1e92f173294c364cc2)

diff --git a/hw/xfree86/common/xf86pciBus.c b/hw/xfree86/common/xf86pciBus.c
index 467a0c3..5b29a15 100644
--- a/hw/xfree86/common/xf86pciBus.c
+++ b/hw/xfree86/common/xf86pciBus.c
@@ -417,18 +417,16 @@ xf86PciProbe(void)
 	if (xf86IsPrimaryPci(info))
 	    prim = "*";
 
-	xf86Msg( X_PROBED, "PCI:%s(%u@%u:%u:%u) ", prim, info->domain,
-		 info->bus, info->dev, info->func );
+	xf86Msg(X_PROBED, "PCI:%s(%u:%u:%u:%u) %04x:%04x:%04x:%04x ", prim,
+		info->domain, info->bus, info->dev, info->func,
+		info->vendor_id, info->device_id,
+		info->subvendor_id, info->subdevice_id);
 
 	if (vendorname)
 	    xf86ErrorF("%s ", vendorname);
-	else
-	    xf86ErrorF("unknown vendor (0x%04x) ", info->vendor_id);
 
 	if (chipname)
 	    xf86ErrorF("%s ", chipname);
-	else
-	    xf86ErrorF("unknown chipset (0x%04x) ", info->device_id);
 
 	xf86ErrorF("rev %d", info->revision);
 

commit 6be19e8f43086fb4b7fb30a47b89b5f3eed798ef
Author: Ian Romanick <ian.d.romanick@intel.com>
Date:   Wed Apr 8 14:54:30 2009 -0700

    Use a #define instead of a magic number
    
    The number of buffers is likely to change in the future, so having
    this as a define is the right way to go.
    
    Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
    (cherry picked from commit 03aebed519986c4dd03e02b3b3d4af1f64595ca7)

diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index c671670..f2682d4 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -82,6 +82,8 @@ struct __GLXDRIcontext {
     __DRIcontext	*driContext;
 };
 
+#define MAX_DRAWABLE_BUFFERS 5
+
 struct __GLXDRIdrawable {
     __GLXdrawable	 base;
     __DRIdrawable	*driDrawable;
@@ -90,7 +92,7 @@ struct __GLXDRIdrawable {
     /* Dimensions as last reported by DRI2GetBuffers. */
     int width;
     int height;
-    __DRIbuffer buffers[5];
+    __DRIbuffer buffers[MAX_DRAWABLE_BUFFERS];
     int count;
 };
 
@@ -365,7 +367,7 @@ dri2GetBuffers(__DRIdrawable *driDrawable,
 
     buffers = DRI2GetBuffers(private->base.pDraw,
 			     width, height, attachments, count, out_count);
-    if (*out_count > 5) {
+    if (*out_count > MAX_DRAWABLE_BUFFERS) {
 	*out_count = 0;
 	return NULL;
     }

commit 540d5b87a4e24d85ec46620dfedd7bd7979180ea
Author: Jerome Glisse <glisse@freedesktop.org>
Date:   Mon May 11 22:52:46 2009 +0200

    DRI2: update DRI2 private drawable width & height according to X drawable
    (cherry picked from commit f250eea2e90fc50bec5214c2f41132b95edc2c46)

diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 1d49d7c..385c5e8 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -257,6 +257,8 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
 
     pPriv->buffers = buffers;
     pPriv->bufferCount = *out_count;
+    pPriv->width = pDraw->width;
+    pPriv->height = pDraw->height;
     *width = pPriv->width;
     *height = pPriv->height;
 

commit ec9f1ae32474bc0507a3c66e63bdf2835d467a34
Author: Ian Romanick <ian.d.romanick@intel.com>
Date:   Mon Apr 27 15:11:10 2009 -0700

    DRI2: Force allocation of real-front buffer for non-windows as well
    
    For redirected rendering we end up with pixmaps (which the app thinks are
    windows) that are double buffered.
    
    Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
    Tested-by: Pierre Willenbrock <pierre@pirsoft.de>
    (cherry picked from commit 0d9d3f3e361f769822caedccf4c2a58cc9930ecc)

diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 9ded048..1d49d7c 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -206,18 +206,21 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
 	 * attachments.  The counting logic in the loop accounts for the case
 	 * where the client requests both the fake and real front-buffer.
 	 */
-	if (pDraw->type == DRAWABLE_WINDOW) {
-	    if (attachment == DRI2BufferBackLeft) {
-		need_real_front++;
-		front_format = format;
-	    }
+	if (attachment == DRI2BufferBackLeft) {
+	    need_real_front++;
+	    front_format = format;
+	}
 
-	    if (attachment == DRI2BufferFrontLeft) {
-		need_real_front--;
+	if (attachment == DRI2BufferFrontLeft) {
+	    need_real_front--;
+	    front_format = format;
+
+	    if (pDraw->type == DRAWABLE_WINDOW) {
 		need_fake_front++;
-		front_format = format;
 	    }
+	}
 
+	if (pDraw->type == DRAWABLE_WINDOW) {
 	    if (attachment == DRI2BufferFakeFrontLeft) {
 		need_fake_front--;
 		have_fake_front = 1;

commit 4fad615d689c61c6c3a000295a1fa755359737cb
Author: Ian Romanick <ian.d.romanick@intel.com>
Date:   Fri Apr 24 12:49:19 2009 -0700

    DRI2: Implement protocol for DRI2GetBuffersWithFormat
    
    This change implements the protocol for DRI2GetBuffersWithFormat, but
    the bulk of the differences are the changes to the extension / driver
    interface to make this function work.  The old CreateBuffers and
    DeleteBuffers routines are replaced with CreateBuffer and DeleteBuffer
    (both singular).
    
    This allows drivers to allocate buffers for a drawable one at a time.
    As a result, 3D drivers can now allocate the (fake) front-buffer for a
    window only when it is needed.  Since 3D drivers only ask for the
    front-buffer on demand, the real front-buffer is always created.  This
    allows CopyRegion impelemenations of SwapBuffers to continue working.
    As with previous version of this code, if the client asks for the
    front-buffer for a window, we instead give it the fake front-buffer.
    
    Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
    Reviewed-by: Kristian Høgsberg <krh@redhat.com>

diff --git a/configure.ac b/configure.ac
index af4ba4f..1f0fddd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -859,7 +859,7 @@ if test "x$DRI" = xyes; then
 	AC_SUBST(GL_CFLAGS)
 fi
 
-PKG_CHECK_MODULES([DRI2PROTO], [dri2proto >= 1.99.3],
+PKG_CHECK_MODULES([DRI2PROTO], [dri2proto >= 2.1],
                   [HAVE_DRI2PROTO=yes], [HAVE_DRI2PROTO=no])
 case "$DRI2,$HAVE_DRI2PROTO" in
 	yes,no)
diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index 84d2c03..c671670 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -359,7 +359,7 @@ dri2GetBuffers(__DRIdrawable *driDrawable,
 	       int *out_count, void *loaderPrivate)
 {
     __GLXDRIdrawable *private = loaderPrivate;
-    DRI2BufferPtr buffers;
+    DRI2BufferPtr *buffers;
     int i;
     int j;
 
@@ -380,15 +380,59 @@ dri2GetBuffers(__DRIdrawable *driDrawable,
 	/* Do not send the real front buffer of a window to the client.
 	 */
 	if ((private->base.pDraw->type == DRAWABLE_WINDOW)
-	    && (buffers[i].attachment == DRI2BufferFrontLeft)) {
+	    && (buffers[i]->attachment == DRI2BufferFrontLeft)) {
 	    continue;
 	}
 
-	private->buffers[j].attachment = buffers[i].attachment;
-	private->buffers[j].name = buffers[i].name;
-	private->buffers[j].pitch = buffers[i].pitch;
-	private->buffers[j].cpp = buffers[i].cpp;
-	private->buffers[j].flags = buffers[i].flags;
+	private->buffers[j].attachment = buffers[i]->attachment;
+	private->buffers[j].name = buffers[i]->name;
+	private->buffers[j].pitch = buffers[i]->pitch;
+	private->buffers[j].cpp = buffers[i]->cpp;
+	private->buffers[j].flags = buffers[i]->flags;
+	j++;
+    }
+
+    *out_count = j;
+    return private->buffers;
+}
+
+static __DRIbuffer *
+dri2GetBuffersWithFormat(__DRIdrawable *driDrawable,
+			 int *width, int *height,
+			 unsigned int *attachments, int count,
+			 int *out_count, void *loaderPrivate)
+{
+    __GLXDRIdrawable *private = loaderPrivate;
+    DRI2BufferPtr *buffers;
+    int i;
+    int j = 0;
+
+    buffers = DRI2GetBuffersWithFormat(private->base.pDraw,
+				       width, height, attachments, count,
+				       out_count);
+    if (*out_count > MAX_DRAWABLE_BUFFERS) {
+	*out_count = 0;
+	return NULL;
+    }
+
+    private->width = *width;
+    private->height = *height;
+
+    /* This assumes the DRI2 buffer attachment tokens matches the
+     * __DRIbuffer tokens. */
+    for (i = 0; i < *out_count; i++) {
+	/* Do not send the real front buffer of a window to the client.
+	 */
+	if ((private->base.pDraw->type == DRAWABLE_WINDOW)
+	    && (buffers[i]->attachment == DRI2BufferFrontLeft)) {
+	    continue;
+	}
+
+	private->buffers[j].attachment = buffers[i]->attachment;
+	private->buffers[j].name = buffers[i]->name;
+	private->buffers[j].pitch = buffers[i]->pitch;
+	private->buffers[j].cpp = buffers[i]->cpp;
+	private->buffers[j].flags = buffers[i]->flags;
 	j++;
     }
 
@@ -407,6 +451,7 @@ static const __DRIdri2LoaderExtension loaderExtension = {
     { __DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION },
     dri2GetBuffers,
     dri2FlushFrontBuffer,
+    dri2GetBuffersWithFormat,
 };
 
 static const __DRIextension *loader_extensions[] = {
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 80de18f..9ded048 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -53,7 +53,7 @@ typedef struct _DRI2Drawable {
     unsigned int	 refCount;
     int			 width;
     int			 height;
-    DRI2BufferPtr	 buffers;
+    DRI2BufferPtr	*buffers;
     int			 bufferCount;
     unsigned int	 pendingSequence;
 } DRI2DrawableRec, *DRI2DrawablePtr;
@@ -63,8 +63,8 @@ typedef struct _DRI2Screen {
     const char			*deviceName;
     int				 fd;
     unsigned int		 lastSequence;
-    DRI2CreateBuffersProcPtr	 CreateBuffers;
-    DRI2DestroyBuffersProcPtr	 DestroyBuffers;
+    DRI2CreateBufferProcPtr	 CreateBuffer;
+    DRI2DestroyBufferProcPtr	 DestroyBuffer;
     DRI2CopyRegionProcPtr	 CopyRegion;
 
     HandleExposuresProcPtr       HandleExposures;
@@ -132,71 +132,130 @@ DRI2CreateDrawable(DrawablePtr pDraw)
     return Success;
 }
 
-DRI2BufferPtr
-DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height,
-	       unsigned int *attachments, int count, int *out_count)
+static int
+find_attachment(DRI2BufferPtr *buffer_list, int count, unsigned attachment)
+{
+    int i;
+
+    if (buffer_list == NULL) {
+	return -1;
+    }
+
+    for (i = 0; i < count; i++) {
+	if ((buffer_list[i] != NULL)
+	    && (buffer_list[i]->attachment == attachment)) {
+	    return i;
+	}
+    }
+
+    return -1;
+}
+
+static DRI2BufferPtr
+allocate_or_reuse_buffer(DrawablePtr pDraw, DRI2ScreenPtr ds,
+			 DRI2DrawablePtr pPriv,
+			 unsigned int attachment, unsigned int format,
+			 int dimensions_match)
+{
+    DRI2BufferPtr buffer;
+    int old_buf;
+
+    old_buf = find_attachment(pPriv->buffers, pPriv->bufferCount, attachment);
+
+    if ((old_buf < 0)
+	|| !dimensions_match
+	|| (pPriv->buffers[old_buf]->format != format)) {
+	buffer = (*ds->CreateBuffer)(pDraw, attachment, format);
+    } else {
+	buffer = pPriv->buffers[old_buf];
+	pPriv->buffers[old_buf] = NULL;
+    }
+
+    return buffer;
+}
+
+static DRI2BufferPtr *
+do_get_buffers(DrawablePtr pDraw, int *width, int *height,
+	       unsigned int *attachments, int count, int *out_count,
+	       int has_format)
 {
     DRI2ScreenPtr   ds = DRI2GetScreen(pDraw->pScreen);
     DRI2DrawablePtr pPriv = DRI2GetDrawable(pDraw);
-    DRI2BufferPtr   buffers;
-    unsigned int temp_buf[32];
-    unsigned int *temp = temp_buf;
+    DRI2BufferPtr  *buffers;
+    int need_real_front = 0;
+    int need_fake_front = 0;
     int have_fake_front = 0;
+    int front_format = 0;
+    const int dimensions_match = (pDraw->width == pPriv->width)
+	&& (pDraw->height == pPriv->height);
+    int i;
 
 
-    /* If the drawable is a window and the front-buffer is requested, silently
-     * add the fake front-buffer to the list of requested attachments.  The
-     * counting logic in the loop accounts for the case where the client
-     * requests both the fake and real front-buffer.
-     */
-    if (pDraw->type == DRAWABLE_WINDOW) {
-	int need_fake_front = 0;
-	int i;
+    buffers = xalloc((count + 1) * sizeof(buffers[0]));
 
-	if ((count + 1) > 32) {
-	    temp = xalloc((count + 1) * sizeof(temp[0]));
-	}
+    for (i = 0; i < count; i++) {
+	const unsigned attachment = *(attachments++);
+	const unsigned format = (has_format) ? *(attachments++) : 0;
+
+	buffers[i] = allocate_or_reuse_buffer(pDraw, ds, pPriv, attachment,
+					      format, dimensions_match);
 
-	for (i = 0; i < count; i++) {
-	    if (attachments[i] == DRI2BufferFrontLeft) {
+
+	/* If the drawable is a window and the front-buffer is requested,
+	 * silently add the fake front-buffer to the list of requested
+	 * attachments.  The counting logic in the loop accounts for the case
+	 * where the client requests both the fake and real front-buffer.
+	 */
+	if (pDraw->type == DRAWABLE_WINDOW) {
+	    if (attachment == DRI2BufferBackLeft) {
+		need_real_front++;
+		front_format = format;
+	    }
+
+	    if (attachment == DRI2BufferFrontLeft) {
+		need_real_front--;
 		need_fake_front++;
+		front_format = format;
 	    }
 
-	    if (attachments[i] == DRI2BufferFakeFrontLeft) {
+	    if (attachment == DRI2BufferFakeFrontLeft) {
 		need_fake_front--;
 		have_fake_front = 1;
 	    }
-
-	    temp[i] = attachments[i];
-	}
-
-	if (need_fake_front > 0) {
-	    temp[i] = DRI2BufferFakeFrontLeft;
-	    count++;
-	    have_fake_front = 1;
-	    attachments = temp;
 	}
     }
 
+    if (need_real_front > 0) {
+	buffers[i++] = allocate_or_reuse_buffer(pDraw, ds, pPriv,
+						DRI2BufferFrontLeft,
+						front_format, dimensions_match);
+    }
 
-    if (pPriv->buffers == NULL ||
-	pDraw->width != pPriv->width || pDraw->height != pPriv->height)
-    {
-	buffers = (*ds->CreateBuffers)(pDraw, attachments, count);
-	(*ds->DestroyBuffers)(pDraw, pPriv->buffers, pPriv->bufferCount);
-	pPriv->buffers = buffers;
-	pPriv->bufferCount = count;
-	pPriv->width = pDraw->width;
-	pPriv->height = pDraw->height;
+    if (need_fake_front > 0) {
+	buffers[i++] = allocate_or_reuse_buffer(pDraw, ds, pPriv,
+						DRI2BufferFakeFrontLeft,
+						front_format, dimensions_match);
+	have_fake_front = 1;
     }
 
-    if (temp != temp_buf) {
-	xfree(temp);
+    *out_count = i;
+
+
+    if (pPriv->buffers != NULL) {
+	for (i = 0; i < pPriv->bufferCount; i++) {
+	    if (pPriv->buffers[i] != NULL) {
+		(*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]);
+	    }
+	}
+
+	xfree(pPriv->buffers);
     }
 
+
+    pPriv->buffers = buffers;
+    pPriv->bufferCount = *out_count;
     *width = pPriv->width;
     *height = pPriv->height;
-    *out_count = pPriv->bufferCount;
 
 
     /* If the client is getting a fake front-buffer, pre-fill it with the
@@ -220,6 +279,22 @@ DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height,
     return pPriv->buffers;
 }
 
+DRI2BufferPtr *
+DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height,
+	       unsigned int *attachments, int count, int *out_count)
+{
+    return do_get_buffers(pDraw, width, height, attachments, count,
+			  out_count, FALSE);
+}
+
+DRI2BufferPtr *
+DRI2GetBuffersWithFormat(DrawablePtr pDraw, int *width, int *height,
+			 unsigned int *attachments, int count, int *out_count)
+{
+    return do_get_buffers(pDraw, width, height, attachments, count,
+			  out_count, TRUE);
+}
+
 int
 DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
 	       unsigned int dest, unsigned int src)
@@ -237,10 +312,10 @@ DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
     pSrcBuffer = NULL;
     for (i = 0; i < pPriv->bufferCount; i++)
     {
-	if (pPriv->buffers[i].attachment == dest)
-	    pDestBuffer = &pPriv->buffers[i];
-	if (pPriv->buffers[i].attachment == src)
-	    pSrcBuffer = &pPriv->buffers[i];
+	if (pPriv->buffers[i]->attachment == dest)
+	    pDestBuffer = pPriv->buffers[i];
+	if (pPriv->buffers[i]->attachment == src)
+	    pSrcBuffer = pPriv->buffers[i];
     }
     if (pSrcBuffer == NULL || pDestBuffer == NULL)
 	return BadValue;
@@ -266,7 +341,16 @@ DRI2DestroyDrawable(DrawablePtr pDraw)
     if (pPriv->refCount > 0)
 	return;
 
-    (*ds->DestroyBuffers)(pDraw, pPriv->buffers, pPriv->bufferCount);
+    if (pPriv->buffers != NULL) {
+	int i;
+
+	for (i = 0; i < pPriv->bufferCount; i++) {
+	    (*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]);
+	}
+
+	xfree(pPriv->buffers);
+    }
+
     xfree(pPriv);
 
     if (pDraw->type == DRAWABLE_WINDOW)
@@ -320,11 +404,18 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
     if (!ds)
 	return FALSE;
 
+    if ((info->version < 2)
+	|| (info->CreateBuffer == NULL)
+	|| (info->DestroyBuffer == NULL)) {
+	return FALSE;
+    }
+
+
     ds->fd	       = info->fd;
     ds->driverName     = info->driverName;
     ds->deviceName     = info->deviceName;
-    ds->CreateBuffers  = info->CreateBuffers;
-    ds->DestroyBuffers = info->DestroyBuffers;
+    ds->CreateBuffer   = info->CreateBuffer;
+    ds->DestroyBuffer  = info->DestroyBuffer;
     ds->CopyRegion     = info->CopyRegion;
 
     dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, ds);
@@ -371,7 +462,7 @@ static XF86ModuleVersionInfo DRI2VersRec =
     MODINFOSTRING1,
     MODINFOSTRING2,
     XORG_VERSION_CURRENT,
-    1, 0, 0,
+    1, 1, 0,
     ABI_CLASS_EXTENSION,
     ABI_EXTENSION_VERSION,
     MOD_CLASS_NONE,
diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h
index e6c4b97..c9a0d3f 100644
--- a/hw/xfree86/dri2/dri2.h
+++ b/hw/xfree86/dri2/dri2.h
@@ -41,6 +41,7 @@ typedef struct {
     unsigned int pitch;
     unsigned int cpp;
     unsigned int flags;
+    unsigned int format;
     void *driverPrivate;
 } DRI2BufferRec, *DRI2BufferPtr;
 
@@ -58,8 +59,19 @@ typedef void		(*DRI2CopyRegionProcPtr)(DrawablePtr pDraw,
 typedef void		(*DRI2WaitProcPtr)(WindowPtr pWin,
 					   unsigned int sequence);
 
+typedef DRI2BufferPtr	(*DRI2CreateBufferProcPtr)(DrawablePtr pDraw,
+						   unsigned int attachment,
+						   unsigned int format);
+typedef void		(*DRI2DestroyBufferProcPtr)(DrawablePtr pDraw,
+						    DRI2BufferPtr buffer);
+
+/**
+ * Version of the DRI2InfoRec structure defined in this header
+ */
+#define DRI2INFOREC_VERSION 2
+
 typedef struct {
-    unsigned int version;	/* Version of this struct */
+    unsigned int version;	/**< Version of this struct */
     int fd;
     const char *driverName;
     const char *deviceName;
@@ -69,6 +81,14 @@ typedef struct {
     DRI2CopyRegionProcPtr	CopyRegion;
     DRI2WaitProcPtr		Wait;
 
+    /**
+     * \name Fields added in version 2 of the structure.
+     */
+    /*@{*/
+    DRI2CreateBufferProcPtr	CreateBuffer;
+    DRI2DestroyBufferProcPtr	DestroyBuffer;
+    /*@}*/
+
 }  DRI2InfoRec, *DRI2InfoPtr;
 
 Bool DRI2ScreenInit(ScreenPtr	pScreen,
@@ -88,7 +108,7 @@ int DRI2CreateDrawable(DrawablePtr pDraw);
 
 void DRI2DestroyDrawable(DrawablePtr pDraw);
 
-DRI2BufferPtr DRI2GetBuffers(DrawablePtr pDraw,
+DRI2BufferPtr *DRI2GetBuffers(DrawablePtr pDraw,
 			     int *width,
 			     int *height,
 			     unsigned int *attachments,
@@ -118,4 +138,8 @@ int DRI2CopyRegion(DrawablePtr pDraw,
  */
 extern _X_EXPORT void DRI2Version(int *major, int *minor);
 
+extern _X_EXPORT DRI2BufferPtr *DRI2GetBuffersWithFormat(DrawablePtr pDraw,
+	int *width, int *height, unsigned int *attachments, int count,
+	int *out_count);
+
 #endif
diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c
index ccc1bbb..97b96fa 100644
--- a/hw/xfree86/dri2/dri2ext.c
+++ b/hw/xfree86/dri2/dri2ext.c
@@ -81,7 +81,7 @@ ProcDRI2QueryVersion(ClientPtr client)
     rep.length = 0;
     rep.sequenceNumber = client->sequence;
     rep.majorVersion = 1;
-    rep.minorVersion = 0;
+    rep.minorVersion = 1;
 
     if (client->swapped) {
     	swaps(&rep.sequenceNumber, n);
@@ -193,32 +193,20 @@ ProcDRI2DestroyDrawable(ClientPtr client)
     return client->noClientException;
 }
 
-static int
-ProcDRI2GetBuffers(ClientPtr client)
+
+static void
+send_buffers_reply(ClientPtr client, DrawablePtr pDrawable,
+		   DRI2BufferPtr *buffers, int count, int width, int height)
 {
-    REQUEST(xDRI2GetBuffersReq);
     xDRI2GetBuffersReply rep;
-    DrawablePtr pDrawable;
-    DRI2BufferPtr buffers;
-    int i, status, width, height, count;
-    unsigned int *attachments;
-    xDRI2Buffer buffer;
-    int skip;
+    int skip = 0;
+    int i;
 
-    REQUEST_FIXED_SIZE(xDRI2GetBuffersReq, stuff->count * 4);
-    if (!validDrawable(client, stuff->drawable, &pDrawable, &status))
-	return status;
-
-    attachments = (unsigned int *) &stuff[1];
-    buffers = DRI2GetBuffers(pDrawable, &width, &height,
-			     attachments, stuff->count, &count);
-
-    skip = 0;
     if (pDrawable->type == DRAWABLE_WINDOW) {
 	for (i = 0; i < count; i++) {
 	    /* Do not send the real front buffer of a window to the client.
 	     */
-	    if (buffers[i].attachment == DRI2BufferFrontLeft) {
+	    if (buffers[i]->attachment == DRI2BufferFrontLeft) {
 		skip++;
 		continue;
 	    }
@@ -234,20 +222,66 @@ ProcDRI2GetBuffers(ClientPtr client)
     WriteToClient(client, sizeof(xDRI2GetBuffersReply), &rep);
 
     for (i = 0; i < count; i++) {
+	xDRI2Buffer buffer;
+
 	/* Do not send the real front buffer of a window to the client.
 	 */
 	if ((pDrawable->type == DRAWABLE_WINDOW)
-	    && (buffers[i].attachment == DRI2BufferFrontLeft)) {
+	    && (buffers[i]->attachment == DRI2BufferFrontLeft)) {
 	    continue;
 	}
 
-	buffer.attachment = buffers[i].attachment;
-	buffer.name = buffers[i].name;
-	buffer.pitch = buffers[i].pitch;
-	buffer.cpp = buffers[i].cpp;
-	buffer.flags = buffers[i].flags;
+	buffer.attachment = buffers[i]->attachment;
+	buffer.name = buffers[i]->name;
+	buffer.pitch = buffers[i]->pitch;
+	buffer.cpp = buffers[i]->cpp;
+	buffer.flags = buffers[i]->flags;
 	WriteToClient(client, sizeof(xDRI2Buffer), &buffer);
     }
+}
+
+
+static int
+ProcDRI2GetBuffers(ClientPtr client)
+{
+    REQUEST(xDRI2GetBuffersReq);
+    DrawablePtr pDrawable;
+    DRI2BufferPtr *buffers;
+    int status, width, height, count;
+    unsigned int *attachments;
+
+    REQUEST_FIXED_SIZE(xDRI2GetBuffersReq, stuff->count * 4);
+    if (!validDrawable(client, stuff->drawable, &pDrawable, &status))
+	return status;
+
+    attachments = (unsigned int *) &stuff[1];
+    buffers = DRI2GetBuffers(pDrawable, &width, &height,
+			     attachments, stuff->count, &count);
+
+
+    send_buffers_reply(client, pDrawable, buffers, count, width, height);
+
+    return client->noClientException;
+}
+
+static int
+ProcDRI2GetBuffersWithFormat(ClientPtr client)
+{
+    REQUEST(xDRI2GetBuffersReq);
+    DrawablePtr pDrawable;
+    DRI2BufferPtr *buffers;
+    int status, width, height, count;
+    unsigned int *attachments;
+
+    REQUEST_FIXED_SIZE(xDRI2GetBuffersReq, stuff->count * (2 * 4));
+    if (!validDrawable(client, stuff->drawable, &pDrawable, &status))
+	return status;
+
+    attachments = (unsigned int *) &stuff[1];
+    buffers = DRI2GetBuffersWithFormat(pDrawable, &width, &height,
+				       attachments, stuff->count, &count);
+
+    send_buffers_reply(client, pDrawable, buffers, count, width, height);
 
     return client->noClientException;
 }
@@ -314,6 +348,8 @@ ProcDRI2Dispatch (ClientPtr client)
 	return ProcDRI2GetBuffers(client);
     case X_DRI2CopyRegion:
 	return ProcDRI2CopyRegion(client);
+    case X_DRI2GetBuffersWithFormat:
+	return ProcDRI2GetBuffersWithFormat(client);
     default:
 	return BadRequest;
     }

commit 98c3c21735197fbd2c8166c9bdabf055e14c9009
Author: Ian Romanick <ian.d.romanick@intel.com>
Date:   Fri Apr 24 12:09:21 2009 -0700

    DRI2: Add interface for drivers to query DRI2 extension version
    
    Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
    (cherry picked from commit 28ddfc88d8d547941c7f4713db527a3c2f9ec35a)

diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 0b52a0f..80de18f 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -380,3 +380,12 @@ static XF86ModuleVersionInfo DRI2VersRec =
 
 _X_EXPORT XF86ModuleData dri2ModuleData = { &DRI2VersRec, DRI2Setup, NULL };
 
+void
+DRI2Version(int *major, int *minor)
+{
+    if (major != NULL)
+	*major = DRI2VersRec.majorversion;
+
+    if (minor != NULL)
+	*minor = DRI2VersRec.minorversion;
+}
diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h
index 5e7fd65..e6c4b97 100644
--- a/hw/xfree86/dri2/dri2.h
+++ b/hw/xfree86/dri2/dri2.h
@@ -100,4 +100,22 @@ int DRI2CopyRegion(DrawablePtr pDraw,
 		   unsigned int dest,
 		   unsigned int src);
 
+/**
+ * Determine the major and minor version of the DRI2 extension.
+ *
+ * Provides a mechanism to other modules (e.g., 2D drivers) to determine the
+ * version of the DRI2 extension.  While it is possible to peek directly at
+ * the \c XF86ModuleData from a layered module, such a module will fail to
+ * load (due to an unresolved symbol) if the DRI2 extension is not loaded.
+ *
+ * \param major  Location to store the major verion of the DRI2 extension
+ * \param minor  Location to store the minor verion of the DRI2 extension
+ *
+ * \note
+ * This interface was added some time after the initial release of the DRI2
+ * module.  Layered modules that wish to use this interface must first test
+ * its existance by calling \c xf86LoaderCheckSymbol.
+ */
+extern _X_EXPORT void DRI2Version(int *major, int *minor);
+
 #endif

commit 4cb4c210c365fd40ad314e0707eb38811f240a12
Author: Ian Romanick <ian.d.romanick@intel.com>
Date:   Thu Apr 16 12:10:34 2009 -0700

    DRI2: Add missing front-buffer flush callback.
    
    Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
    (cherry picked from commit d1e916d29be8b470cbc8cadcf6e83991fdbc5a9f)

diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index 0daf9aa..84d2c03 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -396,9 +396,17 @@ dri2GetBuffers(__DRIdrawable *driDrawable,
     return private->buffers;
 }
 
+static void 
+dri2FlushFrontBuffer(__DRIdrawable *driDrawable, void *loaderPrivate)
+{
+    (void) driDrawable;
+    __glXDRIdrawableWaitGL((__GLXdrawable *) loaderPrivate);
+}
+
 static const __DRIdri2LoaderExtension loaderExtension = {
     { __DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION },
     dri2GetBuffers,
+    dri2FlushFrontBuffer,
 };
 
 static const __DRIextension *loader_extensions[] = {

commit aa13faef2b1464f808e04de9826c6b8b8b91ae89
Author: Ian Romanick <ian.d.romanick@intel.com>
Date:   Wed Apr 15 11:13:48 2009 -0700

    DRI2: Don't leave empty entries in private->buffers
    
    This should fix bug #21130.
    
    Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
    (cherry picked from commit de1e43181bd670877b994db221ad8a04b5d63324)

diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index 4596cc5..0daf9aa 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -361,7 +361,7 @@ dri2GetBuffers(__DRIdrawable *driDrawable,
     __GLXDRIdrawable *private = loaderPrivate;
     DRI2BufferPtr buffers;
     int i;
-    int skip = 0;
+    int j;
 
     buffers = DRI2GetBuffers(private->base.pDraw,
 			     width, height, attachments, count, out_count);
@@ -375,23 +375,24 @@ dri2GetBuffers(__DRIdrawable *driDrawable,
 
     /* This assumes the DRI2 buffer attachment tokens matches the
      * __DRIbuffer tokens. */
+    j = 0;
     for (i = 0; i < *out_count; i++) {
 	/* Do not send the real front buffer of a window to the client.
 	 */
 	if ((private->base.pDraw->type == DRAWABLE_WINDOW)
 	    && (buffers[i].attachment == DRI2BufferFrontLeft)) {
-	    skip++;
 	    continue;
 	}
 
-	private->buffers[i].attachment = buffers[i].attachment;
-	private->buffers[i].name = buffers[i].name;
-	private->buffers[i].pitch = buffers[i].pitch;
-	private->buffers[i].cpp = buffers[i].cpp;
-	private->buffers[i].flags = buffers[i].flags;
+	private->buffers[j].attachment = buffers[i].attachment;
+	private->buffers[j].name = buffers[i].name;
+	private->buffers[j].pitch = buffers[i].pitch;
+	private->buffers[j].cpp = buffers[i].cpp;
+	private->buffers[j].flags = buffers[i].flags;
+	j++;
     }
 
-    *out_count -= skip;
+    *out_count = j;
     return private->buffers;
 }
 

commit d7277296ed7aea7bd41b3489d4ceef750d400206
Author: Ian Romanick <ian.d.romanick@intel.com>
Date:   Thu Apr 9 14:38:24 2009 -0700

    DRI2: Synchronize the contents of the real and fake front-buffers
    
    Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
    (cherry picked from commit 567cf67959b30432ae30f4851ec17b3a375ab838)

diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 351d02b..0b52a0f 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -141,6 +141,7 @@ DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height,
     DRI2BufferPtr   buffers;
     unsigned int temp_buf[32];
     unsigned int *temp = temp_buf;
+    int have_fake_front = 0;
 
 
     /* If the drawable is a window and the front-buffer is requested, silently
@@ -163,6 +164,7 @@ DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height,
 
 	    if (attachments[i] == DRI2BufferFakeFrontLeft) {
 		need_fake_front--;
+		have_fake_front = 1;
 	    }
 
 	    temp[i] = attachments[i];
@@ -171,6 +173,7 @@ DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height,
 	if (need_fake_front > 0) {
 	    temp[i] = DRI2BufferFakeFrontLeft;
 	    count++;
+	    have_fake_front = 1;
 	    attachments = temp;
 	}
     }
@@ -195,6 +198,25 @@ DRI2GetBuffers(DrawablePtr pDraw, int *width, int *height,
     *height = pPriv->height;
     *out_count = pPriv->bufferCount;
 
+
+    /* If the client is getting a fake front-buffer, pre-fill it with the
+     * contents of the real front-buffer.  This ensures correct operation of
+     * applications that call glXWaitX before calling glDrawBuffer.
+     */
+    if (have_fake_front) {
+	BoxRec box;
+	RegionRec region;
+
+	box.x1 = 0;
+	box.y1 = 0;
+	box.x2 = pPriv->width;
+	box.y2 = pPriv->height;
+	REGION_INIT(pDraw->pScreen, &region, &box, 0);
+
+	DRI2CopyRegion(pDraw, &region, DRI2BufferFakeFrontLeft,
+		       DRI2BufferFrontLeft);
+    }
+
     return pPriv->buffers;
 }
 

commit 73b786f7e7f46d40bf3b039538540c2e25f45947
Author: Ian Romanick <ian.d.romanick@intel.com>
Date:   Thu Apr 9 14:31:01 2009 -0700

    DRI2: Do not send the real front buffer of a window to the client
    
    Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
    (cherry picked from commit f1a995d1496d73741731e32f475097c44a8da972)

diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index 4544a2c..4596cc5 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -361,6 +361,7 @@ dri2GetBuffers(__DRIdrawable *driDrawable,
     __GLXDRIdrawable *private = loaderPrivate;
     DRI2BufferPtr buffers;
     int i;
+    int skip = 0;
 
     buffers = DRI2GetBuffers(private->base.pDraw,
 			     width, height, attachments, count, out_count);
@@ -375,6 +376,14 @@ dri2GetBuffers(__DRIdrawable *driDrawable,
     /* This assumes the DRI2 buffer attachment tokens matches the
      * __DRIbuffer tokens. */


Reply to: