[Intel-gfx] [PATCH] mesa/intel: support for DRI2 swapbuffers
Jesse Barnes
jbarnes at virtuousgeek.org
Wed Feb 25 21:33:26 CET 2009
The DRI2 protocol and support bits for Mesa are pretty straightfoward. But I
still need to port this forward to the new flush hook code, since at
swapbuffers we need to make sure everything is flushed.
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index 27cc1be..5a60426 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -670,6 +670,9 @@ struct __DRIdri2ExtensionRec {
__DRIcontext *shared,
void *loaderPrivate);
+ void (*setBuffers)(__DRIdrawable *drawable,
+ __DRIbuffer *buffers,
+ int count);
};
#endif
diff --git a/src/glx/x11/dri2.c b/src/glx/x11/dri2.c
index f967432..564bd4b 100644
--- a/src/glx/x11/dri2.c
+++ b/src/glx/x11/dri2.c
@@ -299,3 +299,52 @@ void DRI2CopyRegion(Display *dpy, XID drawable, XserverRegion region,
UnlockDisplay(dpy);
SyncHandle();
}
+
+DRI2Buffer *DRI2SwapBuffers(Display *dpy, XID drawable, int *count)
+{
+ XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+ xDRI2SwapBuffersReq *req;
+ xDRI2SwapBuffersReply rep;
+ xDRI2Buffer repBuffer;
+ DRI2Buffer *buffers;
+ int i;
+
+ XextCheckExtension (dpy, info, dri2ExtensionName, False);
+
+ LockDisplay(dpy);
+ GetReq(DRI2SwapBuffers, req);
+ req->reqType = info->codes->major_opcode;
+ req->dri2ReqType = X_DRI2SwapBuffers;
+ req->drawable = drawable;
+
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return NULL;
+ }
+
+ /* We expect a new front & back in return */
+ buffers = Xmalloc(rep.count * sizeof(DRI2Buffer));
+ 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;
+ }
+
+ *count = rep.count;
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return buffers;
+}
diff --git a/src/glx/x11/dri2.h b/src/glx/x11/dri2.h
index 356c6bc..83dfaf6 100644
--- a/src/glx/x11/dri2.h
+++ b/src/glx/x11/dri2.h
@@ -67,4 +67,7 @@ extern void
DRI2CopyRegion(Display *dpy, XID drawable, XserverRegion region,
CARD32 dest, CARD32 src);
+extern DRI2Buffer *
+DRI2SwapBuffers(Display *dpy, XID drawable, int *count);
+
#endif
diff --git a/src/glx/x11/dri2_glx.c b/src/glx/x11/dri2_glx.c
index b878f05..d652f13 100644
--- a/src/glx/x11/dri2_glx.c
+++ b/src/glx/x11/dri2_glx.c
@@ -61,6 +61,8 @@ struct __GLXDRIdisplayPrivateRec {
int driMinor;
int driPatch;
+ int swapAvailable;
+
unsigned long configureSeqno;
Bool (*oldConfigProc)(Display *, XEvent *, xEvent *);
};
@@ -210,8 +212,34 @@ static void dri2CopySubBuffer(__GLXDRIdrawable *pdraw,
static void dri2SwapBuffers(__GLXDRIdrawable *pdraw)
{
__GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
+ __GLXDRIdisplayPrivate *pdp = (__GLXDRIdisplayPrivate *)priv->base.psc->dpy;
+ __GLXscreenConfigs *psc = pdraw->psc;
+ DRI2Buffer *buffers;
+ int i, j, count;
+
+ /* Old servers can't handle swapbuffers */
+ if (!pdp->swapAvailable)
+ return dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height);
+
+ buffers = DRI2SwapBuffers(pdraw->psc->dpy, pdraw->drawable, &count);
+ if (buffers == NULL)
+ return dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height);
+
+ /* Update our buffer list with what was returned */
+ for (j = 0; j < count; j++) {
+ for (i = 0; i < priv->bufferCount; i++) {
+ if (priv->buffers[i].attachment == buffers[j].attachment) {
+ priv->buffers[i].name = buffers[j].name;
+ priv->buffers[i].pitch = buffers[j].pitch;
+ priv->buffers[i].cpp = buffers[j].cpp;
+ priv->buffers[i].flags = buffers[j].flags;
+ }
+ }
+ }
- dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height);
+ (*psc->dri2->setBuffers)(pdraw->driDrawable, priv->buffers, count);
+
+ Xfree(buffers);
}
static void dri2DestroyScreen(__GLXscreenConfigs *psc)
@@ -442,6 +470,9 @@ _X_HIDDEN __GLXDRIdisplay *dri2CreateDisplay(Display *dpy)
pdp->driPatch = 0;
pdp->configureSeqno = 0;
+ pdp->swapAvailable = 0;
+ if (pdp->driMinor >= 1)
+ pdp->swapAvailable = 1;
pdp->base.destroyDisplay = dri2DestroyDisplay;
pdp->base.createScreen = dri2CreateScreen;
diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c
index ae79055..75afc45 100644
--- a/src/mesa/drivers/dri/common/dri_util.c
+++ b/src/mesa/drivers/dri/common/dri_util.c
@@ -488,6 +488,14 @@ dri2CreateNewDrawable(__DRIscreen *screen,
return pdraw;
}
+static void
+dri2SetBuffers(__DRIdrawable *draw, __DRIbuffer *buffers, int count)
+{
+ __DRIscreen *psp = draw->driScreenPriv;
+
+ (*psp->DriverAPI.SetBuffers)(draw, buffers, count);
+}
+
static void
driDestroyDrawable(__DRIdrawable *pdp)
@@ -832,6 +840,7 @@ const __DRIdri2Extension driDRI2Extension = {
dri2CreateNewScreen,
dri2CreateNewDrawable,
dri2CreateNewContext,
+ dri2SetBuffers,
};
/* This is the table of extensions that the loader will dlsym() for. */
diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h
index c95a5c8..2a6e1cd 100644
--- a/src/mesa/drivers/dri/common/dri_util.h
+++ b/src/mesa/drivers/dri/common/dri_util.h
@@ -225,6 +225,13 @@ struct __DriverAPIRec {
/* DRI2 Entry point */
const __DRIconfig **(*InitScreen2) (__DRIscreen * priv);
+
+ /**
+ * Update the render buffers with a new set
+ */
+ void (*SetBuffers) ( __DRIdrawable *drawable,
+ __DRIbuffer *buffers,
+ int count);
};
extern const struct __DriverAPIRec driDriverAPI;
diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c
index d7ccfa0..3bf4141 100644
--- a/src/mesa/drivers/dri/intel/intel_context.c
+++ b/src/mesa/drivers/dri/intel/intel_context.c
@@ -169,6 +169,30 @@ intelGetString(GLcontext * ctx, GLenum name)
}
}
+/*
+ * DRI may give us with a new set of buffers after a flip or swap, so
+ * update the attachments here.
+ */
+void intelSetBuffers(__DRIdrawable *drawable,
+ __DRIbuffer *buffers,
+ int count)
+{
+ __DRIcontext *context = drawable->driContextPriv;
+ struct intel_framebuffer *intel_fb = drawable->driverPrivate;
+ struct intel_context *intel = context->driverPrivate;
+ struct intel_renderbuffer *rb;
+ struct intel_region *region;
+ const char *region_name;
+ int i;
+
+ /*
+ * Ignore the buffers & count args, we'll just pick them up from our
+ * drawable.
+ */
+ intel_update_renderbuffers(context, drawable);
+ intel_draw_buffer(&intel->ctx, &intel_fb->Base);
+}
+
void
intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
{
diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
index a522711..45e1e56 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.c
+++ b/src/mesa/drivers/dri/intel/intel_screen.c
@@ -799,4 +799,6 @@ const struct __DriverAPIRec driDriverAPI = {
.CopySubBuffer = intelCopySubBuffer,
.InitScreen2 = intelInitScreen2,
+
+ .SetBuffers = intelSetBuffers,
};
diff --git a/src/mesa/drivers/dri/intel/intel_screen.h b/src/mesa/drivers/dri/intel/intel_screen.h
index e1036de..b23dcee 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.h
+++ b/src/mesa/drivers/dri/intel/intel_screen.h
@@ -103,4 +103,7 @@ intelMakeCurrent(__DRIcontextPrivate * driContextPriv,
extern struct intel_context *intelScreenContext(intelScreenPrivate *intelScreen);
+extern void intelSetBuffers(__DRIdrawable *drawable, __DRIbuffer *buffers,
+ int count);
+
#endif
More information about the Intel-gfx
mailing list