summaryrefslogtreecommitdiff
path: root/src/glx/x11
diff options
context:
space:
mode:
Diffstat (limited to 'src/glx/x11')
-rw-r--r--src/glx/x11/dri2.c70
-rw-r--r--src/glx/x11/dri2.h10
-rw-r--r--src/glx/x11/dri2_glx.c104
-rw-r--r--src/glx/x11/dri_glx.c2
-rw-r--r--src/glx/x11/drisw_glx.c2
5 files changed, 167 insertions, 21 deletions
diff --git a/src/glx/x11/dri2.c b/src/glx/x11/dri2.c
index f967432b99..ebb2985924 100644
--- a/src/glx/x11/dri2.c
+++ b/src/glx/x11/dri2.c
@@ -39,6 +39,16 @@
#include "xf86drm.h"
#include "dri2.h"
+/* Allow the build to work with an older versions of dri2proto.h and
+ * dri2tokens.h.
+ */
+#if DRI2_MINOR < 1
+#undef DRI2_MINOR
+#define DRI2_MINOR 1
+#define X_DRI2GetBuffersWithFormat 7
+#endif
+
+
static char dri2ExtensionName[] = DRI2_NAME;
static XExtensionInfo *dri2Info;
static XEXT_GENERATE_CLOSE_DISPLAY (DRI2CloseDisplay, dri2Info)
@@ -276,6 +286,66 @@ DRI2Buffer *DRI2GetBuffers(Display *dpy, XID drawable,
return buffers;
}
+
+DRI2Buffer *DRI2GetBuffersWithFormat(Display *dpy, XID drawable,
+ int *width, int *height,
+ unsigned int *attachments, int count,
+ int *outCount)
+{
+ XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+ xDRI2GetBuffersReply rep;
+ xDRI2GetBuffersReq *req;
+ DRI2Buffer *buffers;
+ xDRI2Buffer repBuffer;
+ CARD32 *p;
+ int i;
+
+ XextCheckExtension (dpy, info, dri2ExtensionName, False);
+
+ LockDisplay(dpy);
+ GetReqExtra(DRI2GetBuffers, count * (4 * 2), req);
+ req->reqType = info->codes->major_opcode;
+ req->dri2ReqType = X_DRI2GetBuffersWithFormat;
+ req->drawable = drawable;
+ req->count = count;
+ p = (CARD32 *) &req[1];
+ for (i = 0; i < (count * 2); i++)
+ p[i] = attachments[i];
+
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return NULL;
+ }
+
+ *width = rep.width;
+ *height = rep.height;
+ *outCount = rep.count;
+
+ buffers = Xmalloc(rep.count * sizeof buffers[0]);
+ if (buffers == NULL) {
+ _XEatData(dpy, rep.count * sizeof repBuffer);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return NULL;
+ }
+
+ for (i = 0; i < rep.count; i++) {
+ _XReadPad(dpy, (char *) &repBuffer, sizeof repBuffer);
+ buffers[i].attachment = repBuffer.attachment;
+ buffers[i].name = repBuffer.name;
+ buffers[i].pitch = repBuffer.pitch;
+ buffers[i].cpp = repBuffer.cpp;
+ buffers[i].flags = repBuffer.flags;
+ }
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return buffers;
+}
+
+
void DRI2CopyRegion(Display *dpy, XID drawable, XserverRegion region,
CARD32 dest, CARD32 src)
{
diff --git a/src/glx/x11/dri2.h b/src/glx/x11/dri2.h
index 356c6bcb55..b0e61f80d7 100644
--- a/src/glx/x11/dri2.h
+++ b/src/glx/x11/dri2.h
@@ -63,6 +63,16 @@ DRI2GetBuffers(Display *dpy, XID drawable,
unsigned int *attachments, int count,
int *outCount);
+/**
+ * \note
+ * This function is only supported with DRI2 version 1.1 or later.
+ */
+extern DRI2Buffer *
+DRI2GetBuffersWithFormat(Display *dpy, XID drawable,
+ int *width, int *height,
+ unsigned int *attachments, int count,
+ int *outCount);
+
extern void
DRI2CopyRegion(Display *dpy, XID drawable, XserverRegion region,
CARD32 dest, CARD32 src);
diff --git a/src/glx/x11/dri2_glx.c b/src/glx/x11/dri2_glx.c
index b6eeb913b6..fb31898db2 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;
diff --git a/src/glx/x11/dri_glx.c b/src/glx/x11/dri_glx.c
index 87d62ad846..3ce410d9be 100644
--- a/src/glx/x11/dri_glx.c
+++ b/src/glx/x11/dri_glx.c
@@ -614,7 +614,7 @@ static __GLXDRIscreen *driCreateScreen(__GLXscreenConfigs *psc, int screen,
char *driverName;
int i;
- psp = Xmalloc(sizeof *psp);
+ psp = Xcalloc(1, sizeof *psp);
if (psp == NULL)
return NULL;
diff --git a/src/glx/x11/drisw_glx.c b/src/glx/x11/drisw_glx.c
index 35bbd9151c..5e3d763cff 100644
--- a/src/glx/x11/drisw_glx.c
+++ b/src/glx/x11/drisw_glx.c
@@ -359,7 +359,7 @@ driCreateScreen(__GLXscreenConfigs * psc, int screen,
const char *driverName = "swrast";
int i;
- psp = Xmalloc(sizeof *psp);
+ psp = Xcalloc(1, sizeof *psp);
if (psp == NULL)
return NULL;