From 86773238f5b716fb59b721d8df61010f7e8cc0b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Fri, 31 Jul 2009 16:21:01 +0000 Subject: [PATCH] - Add DRI2 pageflipping patch. --- mesa-7.6-dri2-page-flip.patch | 329 ++++++++++++++++++++++++++++++++++ mesa.spec | 4 +- 2 files changed, 331 insertions(+), 2 deletions(-) create mode 100644 mesa-7.6-dri2-page-flip.patch diff --git a/mesa-7.6-dri2-page-flip.patch b/mesa-7.6-dri2-page-flip.patch new file mode 100644 index 0000000..f0115a7 --- /dev/null +++ b/mesa-7.6-dri2-page-flip.patch @@ -0,0 +1,329 @@ +diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h +index 910c916..ec6238f 100644 +--- a/include/GL/internal/dri_interface.h ++++ b/include/GL/internal/dri_interface.h +@@ -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 --git a/src/glx/x11/dri2.c b/src/glx/x11/dri2.c +index ebb2985..a7863ee 100644 +--- a/src/glx/x11/dri2.c ++++ b/src/glx/x11/dri2.c +@@ -369,3 +369,19 @@ void DRI2CopyRegion(Display *dpy, XID drawable, XserverRegion region, + 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 --git a/src/glx/x11/dri2.h b/src/glx/x11/dri2.h +index b0e61f8..fc80649 100644 +--- a/src/glx/x11/dri2.h ++++ b/src/glx/x11/dri2.h +@@ -77,4 +77,7 @@ extern void + DRI2CopyRegion(Display *dpy, XID drawable, XserverRegion region, + CARD32 dest, CARD32 src); + ++extern void ++DRI2SwapBuffers(Display *dpy, XID drawable); ++ + #endif +diff --git a/src/glx/x11/dri2_glx.c b/src/glx/x11/dri2_glx.c +index f4865ae..48c8c71 100644 +--- a/src/glx/x11/dri2_glx.c ++++ b/src/glx/x11/dri2_glx.c +@@ -35,6 +35,7 @@ + #include + #include + #include ++#include "glapi.h" + #include "glxclient.h" + #include "glcontextmodes.h" + #include "xf86dri.h" +@@ -63,6 +64,8 @@ struct __GLXDRIdisplayPrivateRec { + int driMajor; + int driMinor; + int driPatch; ++ ++ int swapAvailable; + }; + + struct __GLXDRIcontextPrivateRec { +@@ -224,13 +227,6 @@ static void dri2CopySubBuffer(__GLXDRIdrawable *pdraw, + dri2WaitX(pdraw); + } + +-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; +@@ -331,6 +327,31 @@ process_buffers(__GLXDRIdrawablePrivate *pdraw, DRI2Buffer *buffers, + + } + ++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, +@@ -544,6 +565,9 @@ _X_HIDDEN __GLXDRIdisplay *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 --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c +index 1d94060..3c5e580 100644 +--- a/src/mesa/drivers/dri/common/dri_util.c ++++ b/src/mesa/drivers/dri/common/dri_util.c +@@ -453,6 +453,7 @@ driCreateNewDrawable(__DRIscreen *psp, const __DRIconfig *config, + + pdp->driScreenPriv = psp; + pdp->driContextPriv = &psp->dummyContextPriv; ++ pdp->validBuffers = GL_FALSE; + + if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, &config->modes, + renderType == GLX_PIXMAP_BIT)) { +diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h +index c95a5c8..c3046d6 100644 +--- a/src/mesa/drivers/dri/common/dri_util.h ++++ b/src/mesa/drivers/dri/common/dri_util.h +@@ -380,6 +380,8 @@ struct __DRIdrawableRec { + * GLX_MESA_swap_control. + */ + unsigned int swap_interval; ++ ++ GLboolean validBuffers; + }; + + /** +diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c +index 4abb525..42e946f 100644 +--- a/src/mesa/drivers/dri/intel/intel_context.c ++++ b/src/mesa/drivers/dri/intel/intel_context.c +@@ -71,8 +71,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) + { +@@ -390,6 +388,7 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) + } + } + ++ drawable->validBuffers = GL_TRUE; + driUpdateFramebufferSize(&intel->ctx, drawable); + } + +@@ -477,7 +476,7 @@ intelInvalidateState(GLcontext * ctx, GLuint new_state) + 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); +@@ -908,11 +907,7 @@ intelMakeCurrent(__DRIcontextPrivate * driContextPriv, + (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. +@@ -1067,6 +1062,10 @@ void LOCK_HARDWARE( struct intel_context *intel ) + 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 --git a/src/mesa/drivers/dri/intel/intel_context.h b/src/mesa/drivers/dri/intel/intel_context.h +index 08bea88..57cb247 100644 +--- a/src/mesa/drivers/dri/intel/intel_context.h ++++ b/src/mesa/drivers/dri/intel/intel_context.h +@@ -462,6 +462,7 @@ extern void intelGetLock(struct intel_context *intel, GLuint flags); + + 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 --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 6bbc995..7767ff9 100644 +--- a/src/mesa/drivers/dri/intel/intel_screen.c ++++ b/src/mesa/drivers/dri/intel/intel_screen.c +@@ -225,6 +225,28 @@ static const __DRItexBufferExtension intelTexBufferExtension = { + 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, +@@ -233,6 +255,7 @@ static const __DRIextension *intelScreenExtensions[] = { + &driMediaStreamCounterExtension.base, + &intelTexOffsetExtension.base, + &intelTexBufferExtension.base, ++ &intelFlushExtension.base, + NULL + }; + +@@ -513,11 +536,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]; +@@ -738,11 +759,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; +diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c +index c5f5220..54c3d16 100644 +--- a/src/mesa/drivers/dri/intel/intel_tex_image.c ++++ b/src/mesa/drivers/dri/intel/intel_tex_image.c +@@ -751,7 +751,8 @@ intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target, + 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 diff --git a/mesa.spec b/mesa.spec index 1cbcc9b..57fdac5 100644 --- a/mesa.spec +++ b/mesa.spec @@ -21,7 +21,7 @@ Summary: Mesa graphics libraries Name: mesa Version: 7.6 -Release: 0.6%{?dist} +Release: 0.7%{?dist} License: MIT Group: System Environment/Libraries URL: http://www.mesa3d.org @@ -369,7 +369,7 @@ rm -rf $RPM_BUILD_ROOT %{demodir} %changelog -* Fri Jul 31 2009 Kristian Høgsberg 7.6-0.6 +* Fri Jul 31 2009 Kristian Høgsberg 7.6-0.7 - Add DRI2 pageflipping patch. * Sat Jul 25 2009 Fedora Release Engineering - 7.6-0.5