On Thursday, February 26, 2009 1:31:03 pm Jesse Barnes wrote: > Add support to Mesa and the intel driver for the new DRI2 swapbuffers > interface. Uses the new flush hook to make sure any outstanding rendering > is complete before sending the swapbuffers request.
Need to update the FBconfigs too; we now support the exchange method. -- Jesse Barnes, Intel Open Source Technology Center diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h index a726b93..b663028 100644 --- a/include/GL/internal/dri_interface.h +++ b/include/GL/internal/dri_interface.h @@ -681,6 +681,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..7af5484 100644 --- a/src/glx/x11/dri2.c +++ b/src/glx/x11/dri2.c @@ -30,7 +30,7 @@ * Kristian Høgsberg (k...@redhat.com) */ - +#include <stdio.h> #define NEED_REPLIES #include <X11/Xlibint.h> #include <X11/extensions/Xext.h> @@ -299,3 +299,51 @@ void DRI2CopyRegion(Display *dpy, XID drawable, XserverRegion region, UnlockDisplay(dpy); SyncHandle(); } + +DRI2Buffer *DRI2SwapBuffers(Display *dpy, XID drawable, int *recv_count) +{ + XExtDisplayInfo *info = DRI2FindDisplay(dpy); + xDRI2SwapBuffersReq *req; + xDRI2SwapBuffersReply rep; + xDRI2Buffer repBuffer; + DRI2Buffer *new_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; + } + + new_buffers = Xmalloc(rep.count * sizeof *new_buffers); + if (new_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); + new_buffers[i].attachment = repBuffer.attachment; + new_buffers[i].name = repBuffer.name; + new_buffers[i].pitch = repBuffer.pitch; + new_buffers[i].cpp = repBuffer.cpp; + new_buffers[i].flags = repBuffer.flags; + } + + *recv_count = rep.count; + + UnlockDisplay(dpy); + SyncHandle(); + + return new_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 0ef5d3a..f80f201 100644 --- a/src/glx/x11/dri2_glx.c +++ b/src/glx/x11/dri2_glx.c @@ -35,6 +35,7 @@ #include <X11/Xlib.h> #include <X11/extensions/Xfixes.h> #include <X11/extensions/Xdamage.h> +#include "glapi.h" #include "glxclient.h" #include "glcontextmodes.h" #include "xf86dri.h" @@ -61,6 +62,8 @@ struct __GLXDRIdisplayPrivateRec { int driMinor; int driPatch; + int swapAvailable; + unsigned long configureSeqno; Bool (*oldConfigProc)(Display *, XEvent *, xEvent *); }; @@ -223,8 +226,40 @@ static void dri2CopySubBuffer(__GLXDRIdrawable *pdraw, static void dri2SwapBuffers(__GLXDRIdrawable *pdraw) { __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw; + __GLXdisplayPrivate *dpyPriv = __glXInitialize(priv->base.psc->dpy); + __GLXDRIdisplayPrivate *pdp = + (__GLXDRIdisplayPrivate *)dpyPriv->dri2Display; + __GLXscreenConfigs *psc = pdraw->psc; + DRI2Buffer *buffers; + int i, count; + +#ifdef __DRI2_FLUSH + if (pdraw->psc->f) + (*pdraw->psc->f->flush)(pdraw->driDrawable); +#endif + + /* 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 || !count) + return dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height); + + /* Update our buffer list with what was returned */ + for (i = 0; i < count; i++) { + priv->buffers[i].attachment = buffers[i].attachment; + priv->buffers[i].name = buffers[i].name; + priv->buffers[i].pitch = buffers[i].pitch; + priv->buffers[i].cpp = buffers[i].cpp; + priv->buffers[i].flags = buffers[i].flags; + } - dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height); + priv->bufferCount = count; + + (*psc->dri2->setBuffers)(pdraw->driDrawable, priv->buffers, count); + + Xfree(buffers); } static void dri2WaitX(__GLXDRIdrawable *pdraw) @@ -517,6 +552,9 @@ _X_HIDDEN __GLXDRIdisplay *dri2CreateDisplay(Display *dpy) pdp->driPatch = 0; pdp->configureSeqno = 0; + pdp->swapAvailable = 0; + if (pdp->driMinor > 0) + 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..90a39df 100644 --- a/src/mesa/drivers/dri/common/dri_util.c +++ b/src/mesa/drivers/dri/common/dri_util.c @@ -488,6 +488,15 @@ dri2CreateNewDrawable(__DRIscreen *screen, return pdraw; } +static void +dri2SetBuffers(__DRIdrawable *draw, __DRIbuffer *buffers, int count) +{ + __DRIscreen *psp = draw->driScreenPriv; + + if (psp->DriverAPI.SetBuffers) + (*psp->DriverAPI.SetBuffers)(draw, buffers, count); +} + static void driDestroyDrawable(__DRIdrawable *pdp) @@ -832,6 +841,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 1aa173d..bef1907 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) { @@ -399,6 +423,16 @@ intel_glFlush(GLcontext *ctx) intel_flush(ctx, GL_TRUE); } +void intelFlushDrawable(__DRIdrawable *drawable) +{ + __DRIdrawablePrivate * dPriv = drawable->driverPrivate; + struct intel_context *intel = + (struct intel_context *) dPriv->driContextPriv->driverPrivate; + GLcontext *ctx = &intel->ctx; + + intel_flush(ctx, GL_TRUE); +} + void intelFinish(GLcontext * ctx) { diff --git a/src/mesa/drivers/dri/intel/intel_extensions.h b/src/mesa/drivers/dri/intel/intel_extensions.h index 97147ec..9283ee9 100644 --- a/src/mesa/drivers/dri/intel/intel_extensions.h +++ b/src/mesa/drivers/dri/intel/intel_extensions.h @@ -32,5 +32,8 @@ extern void intelInitExtensions(GLcontext *ctx, GLboolean enable_imaging); +extern void +intelFlushDrawable(__DRIdrawable *drawable); + #endif diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c index 09eba13..8a50a17 100644 --- a/src/mesa/drivers/dri/intel/intel_screen.c +++ b/src/mesa/drivers/dri/intel/intel_screen.c @@ -211,6 +211,11 @@ static const __DRItexBufferExtension intelTexBufferExtension = { intelSetTexBuffer, }; +static const __DRI2flushExtension intelFlushExtension = { + { __DRI2_FLUSH, __DRI2_FLUSH_VERSION }, + intelFlushDrawable, +}; + static const __DRIextension *intelScreenExtensions[] = { &driReadDrawableExtension, &driCopySubBufferExtension.base, @@ -475,11 +480,9 @@ intelFillInModes(__DRIscreenPrivate *psp, unsigned back_buffer_factor; int i; - /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't - * support pageflipping at all. - */ static const GLenum back_buffer_modes[] = { - GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML + GLX_NONE, GLX_SWAP_UNDEFINED_OML, + GLX_SWAP_EXCHANGE_OML, GLX_SWAP_COPY_OML }; uint8_t depth_bits_array[3]; @@ -697,11 +700,10 @@ __DRIconfig **intelInitScreen2(__DRIscreenPrivate *psp) intelScreenPrivate *intelScreen; GLenum fb_format[3]; GLenum fb_type[3]; - /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't - * support pageflipping at all. - */ + static const GLenum back_buffer_modes[] = { - GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML + GLX_NONE, GLX_SWAP_UNDEFINED_OML, + GLX_SWAP_EXCHANGE_OML, GLX_SWAP_COPY_OML }; uint8_t depth_bits[4], stencil_bits[4], msaa_samples_array[1]; int color; @@ -828,4 +830,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 ------------------------------------------------------------------------------ Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA -OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise -Strategies to boost innovation and cut costs with open source participation -Receive a $600 discount off the registration fee with the source code: SFAD http://p.sf.net/sfu/XcvMzF8H -- _______________________________________________ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel