diff -up mesa-20090909/include/GL/internal/dri_interface.h.da mesa-20090909/include/GL/internal/dri_interface.h --- mesa-20090909/include/GL/internal/dri_interface.h.da 2009-09-09 09:43:36.000000000 +1000 +++ mesa-20090909/include/GL/internal/dri_interface.h 2009-09-09 08:56:48.000000000 +1000 @@ -262,10 +262,22 @@ struct __DRItexBufferExtensionRec { * Used by drivers that implement DRI2 */ #define __DRI2_FLUSH "DRI2_Flush" -#define __DRI2_FLUSH_VERSION 1 +#define __DRI2_FLUSH_VERSION 2 struct __DRI2flushExtensionRec { __DRIextension base; void (*flush)(__DRIdrawable *drawable); + + /** + * Flush all rendering queue in the driver to the drm and + * invalidate all buffers. The driver will call out to + * getBuffers/getBuffersWithFormat before it starts rendering + * again. + * + * \param drawable the drawable to flush and invalidate + * + * \since 2 + */ + void (*flushInvalidate)(__DRIdrawable *drawable); }; diff -up mesa-20090909/src/glx/x11/dri2.c.da mesa-20090909/src/glx/x11/dri2.c --- mesa-20090909/src/glx/x11/dri2.c.da 2009-09-09 09:43:36.000000000 +1000 +++ mesa-20090909/src/glx/x11/dri2.c 2009-09-09 08:56:48.000000000 +1000 @@ -377,3 +377,19 @@ DRI2CopyRegion(Display * dpy, XID drawab UnlockDisplay(dpy); SyncHandle(); } + +void DRI2SwapBuffers(Display *dpy, XID drawable) +{ + XExtDisplayInfo *info = DRI2FindDisplay(dpy); + xDRI2SwapBuffersReq *req; + + XextSimpleCheckExtension (dpy, info, dri2ExtensionName); + + LockDisplay(dpy); + GetReq(DRI2SwapBuffers, req); + req->reqType = info->codes->major_opcode; + req->dri2ReqType = X_DRI2SwapBuffers; + req->drawable = drawable; + UnlockDisplay(dpy); + SyncHandle(); +} diff -up mesa-20090909/src/glx/x11/dri2_glx.c.da mesa-20090909/src/glx/x11/dri2_glx.c --- mesa-20090909/src/glx/x11/dri2_glx.c.da 2009-09-09 09:43:36.000000000 +1000 +++ mesa-20090909/src/glx/x11/dri2_glx.c 2009-09-09 09:01:13.000000000 +1000 @@ -35,6 +35,7 @@ #include #include #include +#include "glapi.h" #include "glxclient.h" #include "glcontextmodes.h" #include "xf86dri.h" @@ -64,6 +65,8 @@ struct __GLXDRIdisplayPrivateRec int driMajor; int driMinor; int driPatch; + + int swapAvailable; }; struct __GLXDRIcontextPrivateRec @@ -232,14 +235,6 @@ dri2CopySubBuffer(__GLXDRIdrawable * pdr } static void -dri2SwapBuffers(__GLXDRIdrawable * pdraw) -{ - __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw; - - dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height); -} - -static void dri2WaitX(__GLXDRIdrawable * pdraw) { __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw; @@ -342,6 +337,31 @@ process_buffers(__GLXDRIdrawablePrivate } +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; + +#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); + + DRI2SwapBuffers(pdraw->psc->dpy, pdraw->drawable); + +#if __DRI2_FLUSH_VERSION >= 2 + if (pdraw->psc->f) + (*pdraw->psc->f->flushInvalidate)(pdraw->driDrawable); +#endif +} + static __DRIbuffer * dri2GetBuffers(__DRIdrawable * driDrawable, int *width, int *height, @@ -559,6 +579,9 @@ dri2CreateDisplay(Display * dpy) } pdp->driPatch = 0; + pdp->swapAvailable = 0; + if (pdp->driMinor >= 2) + pdp->swapAvailable = 1; pdp->base.destroyDisplay = dri2DestroyDisplay; pdp->base.createScreen = dri2CreateScreen; diff -up mesa-20090909/src/glx/x11/dri2.h.da mesa-20090909/src/glx/x11/dri2.h --- mesa-20090909/src/glx/x11/dri2.h.da 2009-09-09 09:43:36.000000000 +1000 +++ mesa-20090909/src/glx/x11/dri2.h 2009-09-09 08:56:48.000000000 +1000 @@ -85,4 +85,7 @@ DRI2CopyRegion(Display * dpy, XID drawab XserverRegion region, CARD32 dest, CARD32 src); +extern void +DRI2SwapBuffers(Display *dpy, XID drawable); + #endif diff -up mesa-20090909/src/mesa/drivers/dri/common/dri_util.c.da mesa-20090909/src/mesa/drivers/dri/common/dri_util.c --- mesa-20090909/src/mesa/drivers/dri/common/dri_util.c.da 2009-09-09 09:43:36.000000000 +1000 +++ mesa-20090909/src/mesa/drivers/dri/common/dri_util.c 2009-09-09 08:56:48.000000000 +1000 @@ -453,6 +453,7 @@ driCreateNewDrawable(__DRIscreen *psp, c pdp->driScreenPriv = psp; pdp->driContextPriv = &psp->dummyContextPriv; + pdp->validBuffers = GL_FALSE; if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, &config->modes, renderType == GLX_PIXMAP_BIT)) { diff -up mesa-20090909/src/mesa/drivers/dri/common/dri_util.h.da mesa-20090909/src/mesa/drivers/dri/common/dri_util.h --- mesa-20090909/src/mesa/drivers/dri/common/dri_util.h.da 2009-09-09 09:43:36.000000000 +1000 +++ mesa-20090909/src/mesa/drivers/dri/common/dri_util.h 2009-09-09 08:56:48.000000000 +1000 @@ -380,6 +380,8 @@ struct __DRIdrawableRec { * GLX_MESA_swap_control. */ unsigned int swap_interval; + + GLboolean validBuffers; }; /** diff -up mesa-20090909/src/mesa/drivers/dri/intel/intel_context.c.da mesa-20090909/src/mesa/drivers/dri/intel/intel_context.c --- mesa-20090909/src/mesa/drivers/dri/intel/intel_context.c.da 2009-09-09 09:43:36.000000000 +1000 +++ mesa-20090909/src/mesa/drivers/dri/intel/intel_context.c 2009-09-09 08:56:48.000000000 +1000 @@ -72,8 +72,6 @@ int INTEL_DEBUG = (0); #define DRIVER_DATE_GEM "GEM " DRIVER_DATE -static void intel_flush(GLcontext *ctx, GLboolean needs_mi_flush); - static const GLubyte * intelGetString(GLcontext * ctx, GLenum name) { @@ -391,6 +389,7 @@ intel_update_renderbuffers(__DRIcontext } } + drawable->validBuffers = GL_TRUE; driUpdateFramebufferSize(&intel->ctx, drawable); } @@ -478,7 +477,7 @@ intelInvalidateState(GLcontext * ctx, GL intel->vtbl.invalidate_state( intel, new_state ); } -static void +void intel_flush(GLcontext *ctx, GLboolean needs_mi_flush) { struct intel_context *intel = intel_context(ctx); @@ -936,11 +935,7 @@ intelMakeCurrent(__DRIcontextPrivate * d (struct intel_framebuffer *) driDrawPriv->driverPrivate; GLframebuffer *readFb = (GLframebuffer *) driReadPriv->driverPrivate; - if (driContextPriv->driScreenPriv->dri2.enabled) { - intel_update_renderbuffers(driContextPriv, driDrawPriv); - if (driDrawPriv != driReadPriv) - intel_update_renderbuffers(driContextPriv, driReadPriv); - } else { + if (!driContextPriv->driScreenPriv->dri2.enabled) { /* XXX FBO temporary fix-ups! These are released in * intelDextroyContext(), above. Changes here should be * reflected there. @@ -1095,6 +1090,10 @@ void LOCK_HARDWARE( struct intel_context if (intel->driDrawable) { intel_fb = intel->driDrawable->driverPrivate; + if (!intel->driDrawable->validBuffers) + intel_update_renderbuffers(intel->driContext, + intel->driDrawable); + if (intel_fb) intel_rb = intel_get_renderbuffer(&intel_fb->Base, diff -up mesa-20090909/src/mesa/drivers/dri/intel/intel_context.h.da mesa-20090909/src/mesa/drivers/dri/intel/intel_context.h --- mesa-20090909/src/mesa/drivers/dri/intel/intel_context.h.da 2009-09-09 09:43:36.000000000 +1000 +++ mesa-20090909/src/mesa/drivers/dri/intel/intel_context.h 2009-09-09 08:56:48.000000000 +1000 @@ -473,6 +473,7 @@ extern void intelGetLock(struct intel_co extern void intelFinish(GLcontext * ctx); extern void intelFlush(GLcontext * ctx); +extern void intel_flush(GLcontext * ctx, GLboolean needs_mi_flush); extern void intelInitDriverFunctions(struct dd_function_table *functions); diff -up mesa-20090909/src/mesa/drivers/dri/intel/intel_extensions.h.da mesa-20090909/src/mesa/drivers/dri/intel/intel_extensions.h --- mesa-20090909/src/mesa/drivers/dri/intel/intel_extensions.h.da 2009-09-09 09:43:36.000000000 +1000 +++ mesa-20090909/src/mesa/drivers/dri/intel/intel_extensions.h 2009-09-09 08:56:48.000000000 +1000 @@ -32,5 +32,8 @@ extern void intelInitExtensions(GLcontext *ctx, GLboolean enable_imaging); +extern void +intelFlushDrawable(__DRIdrawable *drawable); + #endif diff -up mesa-20090909/src/mesa/drivers/dri/intel/intel_screen.c.da mesa-20090909/src/mesa/drivers/dri/intel/intel_screen.c --- mesa-20090909/src/mesa/drivers/dri/intel/intel_screen.c.da 2009-09-09 08:56:16.000000000 +1000 +++ mesa-20090909/src/mesa/drivers/dri/intel/intel_screen.c 2009-09-09 08:56:48.000000000 +1000 @@ -229,6 +229,28 @@ static const __DRItexBufferExtension int intelSetTexBuffer2, }; +static void +intelDRI2Flush(__DRIdrawable *drawable) +{ + struct intel_context *intel = drawable->driContextPriv->driverPrivate; + GLcontext *ctx = &intel->ctx; + + intel_flush(ctx, GL_TRUE); +} + +static void +intelDRI2FlushInvalidate(__DRIdrawable *drawable) +{ + intelDRI2Flush(drawable); + drawable->validBuffers = GL_FALSE; +} + +static const struct __DRI2flushExtensionRec intelFlushExtension = { + { __DRI2_FLUSH, __DRI2_FLUSH_VERSION }, + intelDRI2Flush, + intelDRI2FlushInvalidate, +}; + static const __DRIextension *intelScreenExtensions[] = { &driReadDrawableExtension, &driCopySubBufferExtension.base, @@ -237,6 +259,7 @@ static const __DRIextension *intelScreen &driMediaStreamCounterExtension.base, &intelTexOffsetExtension.base, &intelTexBufferExtension.base, + &intelFlushExtension.base, NULL }; @@ -517,11 +540,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]; @@ -742,11 +763,10 @@ __DRIconfig **intelInitScreen2(__DRIscre 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; diff -up mesa-20090909/src/mesa/drivers/dri/intel/intel_tex_image.c.da mesa-20090909/src/mesa/drivers/dri/intel/intel_tex_image.c --- mesa-20090909/src/mesa/drivers/dri/intel/intel_tex_image.c.da 2009-09-09 09:43:36.000000000 +1000 +++ mesa-20090909/src/mesa/drivers/dri/intel/intel_tex_image.c 2009-09-09 08:56:48.000000000 +1000 @@ -747,7 +747,8 @@ intelSetTexBuffer2(__DRIcontext *pDRICtx if (!intelObj) return; - intel_update_renderbuffers(pDRICtx, dPriv); + if (!dPriv->validBuffers) + intel_update_renderbuffers(pDRICtx, dPriv); rb = intel_fb->color_rb[0]; /* If the region isn't set, then intel_update_renderbuffers was unable