diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h index e7fbf8e..1b637af 100644 --- a/include/GL/internal/dri_interface.h +++ b/include/GL/internal/dri_interface.h @@ -170,7 +170,7 @@ struct __DRIframeTrackingExtensionRec { * Used by drivers that implement the GLX_SGI_video_sync extension. */ #define __DRI_MEDIA_STREAM_COUNTER "DRI_MediaStreamCounter" -#define __DRI_MEDIA_STREAM_COUNTER_VERSION 1 +#define __DRI_MEDIA_STREAM_COUNTER_VERSION 2 struct __DRImediaStreamCounterExtensionRec { __DRIextension base; @@ -189,6 +189,18 @@ struct __DRImediaStreamCounterExtensionRec { int (*waitForMSC)(__DRIdrawable *drawable, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t * msc, int64_t * sbc); + + /** + * Like the screen version of getMSC, but also takes a drawable so that + * the appropriate pipe's counter can be retrieved. + * + * Get the number of vertical refreshes since some point in time before + * this function was first called (i.e., system start up). + * + * \since Internal API version 2 + */ + int (*getDrawableMSC)(__DRIscreen *screen, void *drawablePrivate, + int64_t *msc); }; diff --git a/src/glx/x11/glxcmds.c b/src/glx/x11/glxcmds.c index 707e398..7e8a0c1 100644 --- a/src/glx/x11/glxcmds.c +++ b/src/glx/x11/glxcmds.c @@ -1941,13 +1941,24 @@ static int __glXGetVideoSyncSGI(unsigned int *count) if ( (gc != NULL) && gc->isDirect ) { __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen ); - if (psc->msc != NULL && psc->driScreen.private != NULL) { - int ret; - int64_t temp; - - ret = psc->msc->getMSC(&psc->driScreen, &temp); - *count = (unsigned) temp; - return (ret == 0) ? 0 : GLX_BAD_CONTEXT; + if ( psc->msc && psc->driScreen.private ) { + __DRIdrawable * const pdraw = + GetDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL); + int64_t temp; + int ret; + + /* + * Try to use getDrawableMSC first so we get the right + * counter... + */ + if (psc->msc->base.version >= 2 && psc->msc->getDrawableMSC) + ret = (*psc->msc->getDrawableMSC)( &psc->driScreen, + pdraw->private, + & temp); + else + ret = (*psc->msc->getMSC)( &psc->driScreen, & temp); + *count = (unsigned) temp; + return (ret == 0) ? 0 : GLX_BAD_CONTEXT; } } #else @@ -1970,16 +1981,14 @@ static int __glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count if (psc->msc != NULL && psc->driScreen.private ) { __DRIdrawable * const pdraw = GetDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL); - if (pdraw != NULL) { - int ret; - int64_t msc; - int64_t sbc; - - ret = (*psc->msc->waitForMSC)(pdraw, 0, - divisor, remainder, &msc, &sbc); - *count = (unsigned) msc; - return (ret == 0) ? 0 : GLX_BAD_CONTEXT; - } + int ret; + int64_t msc; + int64_t sbc; + + ret = (*psc->msc->waitForMSC)(pdraw, 0, divisor, remainder, &msc, + &sbc); + *count = (unsigned) msc; + return (ret == 0) ? 0 : GLX_BAD_CONTEXT; } } #else diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c index d59ea0d..2e2e64c 100644 --- a/src/mesa/drivers/dri/common/dri_util.c +++ b/src/mesa/drivers/dri/common/dri_util.c @@ -356,10 +356,18 @@ static void driSwapBuffers(__DRIdrawable *drawable) &rect, 1, GL_TRUE); } +static int driDrawableGetMSC( __DRIscreen *screen, void *drawablePrivate, + int64_t *msc ) +{ + __DRIscreenPrivate *sPriv = screen->private; + + return sPriv->DriverAPI.GetDrawableMSC( sPriv, drawablePrivate, msc ); +} + /** * Called directly from a number of higher-level GLX functions. */ -static int driGetMSC( __DRIscreen *screen, int64_t *msc ) +static int driGetMSC( __DRIscreen *screen, void *drawablePrivate, int64_t *msc ) { __DRIscreenPrivate *sPriv = screen->private; @@ -396,6 +404,7 @@ const __DRImediaStreamCounterExtension driMediaStreamCounterExtension = { { __DRI_MEDIA_STREAM_COUNTER, __DRI_MEDIA_STREAM_COUNTER_VERSION }, driGetMSC, driWaitForMSC, + driDrawableGetMSC, }; static void driCopySubBuffer(__DRIdrawable *drawable, @@ -471,6 +480,8 @@ static void *driCreateNewDrawable(__DRIscreen *screen, pdp->numBackClipRects = 0; pdp->pClipRects = NULL; pdp->pBackClipRects = NULL; + pdp->vblSeq = 0; + pdp->vblFlags = 0; psp = (__DRIscreenPrivate *)screen->private; pdp->driScreenPriv = psp; @@ -485,6 +496,7 @@ static void *driCreateNewDrawable(__DRIscreen *screen, pdraw->private = pdp; pdraw->destroyDrawable = driDestroyDrawable; pdraw->swapBuffers = driSwapBuffers; /* called by glXSwapBuffers() */ + pdp->msc_base = 0; /* This special default value is replaced with the configured * default value when the drawable is first bound to a direct diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h index 91992a9..def0775 100644 --- a/src/mesa/drivers/dri/common/dri_util.h +++ b/src/mesa/drivers/dri/common/dri_util.h @@ -206,6 +206,14 @@ struct __DriverAPIRec { */ void (*setTexOffset)(__DRIcontext *pDRICtx, GLint texname, unsigned long long offset, GLint depth, GLuint pitch); + + /** + * New version of GetMSC so we can pass drawable data to the low level + * DRM driver (e.g. pipe info). + */ + int (*GetDrawableMSC) ( __DRIscreenPrivate * priv, + __DRIdrawablePrivate *drawablePrivate, + int64_t *count); }; @@ -318,6 +326,32 @@ struct __DRIdrawablePrivateRec { /*@}*/ /** + * \name Vertical blank tracking information + * Used for waiting on vertical blank events. + */ + /*@{*/ + unsigned int vblSeq; + unsigned int vblFlags; + /*@}*/ + + /** + * \name Monotonic MSC tracking + * + * Low level driver is responsible for updating msc_base and + * vblSeq values so that higher level code can calculate + * a new msc value or msc target for a WaitMSC call. The new value + * will be: + * msc = msc_base + get_vblank_count() - vblank_base; + * + * And for waiting on a value, core code will use: + * actual_target = target_msc - msc_base + vblank_base; + */ + /*@{*/ + int64_t vblank_base; + int64_t msc_base; + /*@}*/ + + /** * Pointer to context to which this drawable is currently bound. */ __DRIcontextPrivate *driContextPriv; diff --git a/src/mesa/drivers/dri/common/vblank.c b/src/mesa/drivers/dri/common/vblank.c index 3b5acfe..0596440 100644 --- a/src/mesa/drivers/dri/common/vblank.c +++ b/src/mesa/drivers/dri/common/vblank.c @@ -35,6 +35,16 @@ #include "vblank.h" #include "xmlpool.h" +static unsigned int msc_to_vblank(__DRIdrawablePrivate * dPriv, int64_t msc) +{ + return (unsigned int)(msc - dPriv->msc_base + dPriv->vblank_base); +} + +static int64_t vblank_to_msc(__DRIdrawablePrivate * dPriv, unsigned int vblank) +{ + return (int64_t)(vblank - dPriv->vblank_base + dPriv->msc_base); +} + /****************************************************************************/ /** @@ -42,7 +52,7 @@ * * Stores the 64-bit count of vertical refreshes since some (arbitrary) * point in time in \c count. Unless the value wraps around, which it - * may, it will never decrease. + * may, it will never decrease for a given drawable. * * \warning This function is called from \c glXGetVideoSyncSGI, which expects * a \c count of type \c unsigned (32-bit), and \c glXGetSyncValuesOML, which @@ -50,11 +60,14 @@ * currently always returns a \c sequence of type \c unsigned. * * \param priv Pointer to the DRI screen private struct. + * \param dPriv Pointer to the DRI drawable private struct * \param count Storage to hold MSC counter. * \return Zero is returned on success. A negative errno value * is returned on failure. */ -int driGetMSC32( __DRIscreenPrivate * priv, int64_t * count ) +int driDrawableGetMSC32( __DRIscreenPrivate * priv, + __DRIdrawablePrivate * dPriv, + int64_t * count) { drmVBlank vbl; int ret; @@ -63,13 +76,46 @@ int driGetMSC32( __DRIscreenPrivate * priv, int64_t * count ) vbl.request.type = DRM_VBLANK_RELATIVE; vbl.request.sequence = 0; + if ( dPriv && dPriv->vblFlags & VBLANK_FLAG_SECONDARY ) + vbl.request.type |= DRM_VBLANK_SECONDARY; ret = drmWaitVBlank( priv->fd, &vbl ); - *count = (int64_t)vbl.reply.sequence; + + if (dPriv) { + *count = vblank_to_msc(dPriv, vbl.reply.sequence); + } else { + /* Old driver (no knowledge of drawable MSC callback) */ + *count = vbl.reply.sequence; + } return ret; } +/** + * Get the current MSC refresh counter. + * + * Stores the 64-bit count of vertical refreshes since some (arbitrary) + * point in time in \c count. Unless the value wraps around, which it + * may, it will never decrease. + * + * \warning This function is called from \c glXGetVideoSyncSGI, which expects + * a \c count of type \c unsigned (32-bit), and \c glXGetSyncValuesOML, which + * expects a \c count of type \c int64_t (signed 64-bit). The kernel ioctl + * currently always returns a \c sequence of type \c unsigned. + * + * Since this function doesn't take a drawable, it may end up getting the MSC + * value from a pipe not associated with the caller's context, resuling in + * undesired behavior. + * + * \param priv Pointer to the DRI screen private struct. + * \param count Storage to hold MSC counter. + * \return Zero is returned on success. A negative errno value + * is returned on failure. + */ +int driGetMSC32( __DRIscreenPrivate * priv, int64_t * count ) +{ + return driDrawableGetMSC32(priv, NULL, count); +} /****************************************************************************/ /** @@ -123,7 +169,9 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv, */ vbl.request.type = dont_wait ? DRM_VBLANK_RELATIVE : DRM_VBLANK_ABSOLUTE; - vbl.request.sequence = next; + vbl.request.sequence = next ? msc_to_vblank(priv, next) : 0; + if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) + vbl.request.type |= DRM_VBLANK_SECONDARY; if ( drmWaitVBlank( priv->driScreenPriv->fd, &vbl ) != 0 ) { /* FIXME: This doesn't seem like the right thing to return here. @@ -131,8 +179,10 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv, return GLX_BAD_CONTEXT; } + *msc = vblank_to_msc(priv, vbl.reply.sequence); + dont_wait = 0; - if (target_msc != 0 && vbl.reply.sequence == target) + if (target_msc != 0 && *msc == target) break; /* Assuming the wait-done test fails, the next refresh to wait for @@ -142,9 +192,9 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv, * If this refresh has already happened, we add divisor to obtain * the next refresh after the current one that will satisfy it. */ - r = (vbl.reply.sequence % (unsigned int)divisor); - next = (vbl.reply.sequence - r + (unsigned int)remainder); - if (next <= vbl.reply.sequence) next += (unsigned int)divisor; + r = (*msc % (unsigned int)divisor); + next = (*msc - r + (unsigned int)remainder); + if (next <= *msc) next += (unsigned int)divisor; } while ( r != (unsigned int)remainder ); } @@ -154,7 +204,10 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv, */ vbl.request.type = DRM_VBLANK_ABSOLUTE; - vbl.request.sequence = target_msc; + vbl.request.sequence = target_msc ? msc_to_vblank(priv, target_msc) : 0; + + if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) + vbl.request.type |= DRM_VBLANK_SECONDARY; if ( drmWaitVBlank( priv->driScreenPriv->fd, &vbl ) != 0 ) { /* FIXME: This doesn't seem like the right thing to return here. @@ -163,8 +216,8 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv, } } - *msc = (target_msc & 0xffffffff00000000LL); - *msc |= vbl.reply.sequence; + *msc = vblank_to_msc(priv, vbl.reply.sequence); + if ( *msc < target_msc ) { *msc += 0x0000000100000000LL; } @@ -252,16 +305,21 @@ static int do_wait( drmVBlank * vbl, GLuint * vbl_seq, int fd ) * direct rendering context. */ -void driDrawableInitVBlank( __DRIdrawablePrivate *priv, GLuint flags, - GLuint *vbl_seq ) +void driDrawableInitVBlank( __DRIdrawablePrivate *priv ) { if ( priv->swap_interval == (unsigned)-1 ) { /* Get current vertical blank sequence */ - drmVBlank vbl = { .request={ .type = DRM_VBLANK_RELATIVE, .sequence = 0 } }; - do_wait( &vbl, vbl_seq, priv->driScreenPriv->fd ); - - priv->swap_interval = (flags & (VBLANK_FLAG_THROTTLE | - VBLANK_FLAG_SYNC)) != 0 ? 1 : 0; + drmVBlank vbl; + + vbl.request.type = DRM_VBLANK_RELATIVE; + if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) + vbl.request.type |= DRM_VBLANK_SECONDARY; + vbl.request.sequence = 0; + do_wait( &vbl, &priv->vblSeq, priv->driScreenPriv->fd ); + priv->vblank_base = priv->vblSeq; + + priv->swap_interval = + (priv->vblFlags & (VBLANK_FLAG_THROTTLE | VBLANK_FLAG_SYNC)) ? 1 : 0; } } diff --git a/src/mesa/drivers/dri/common/vblank.h b/src/mesa/drivers/dri/common/vblank.h index ec83adc..e8550b2 100644 --- a/src/mesa/drivers/dri/common/vblank.h +++ b/src/mesa/drivers/dri/common/vblank.h @@ -46,11 +46,13 @@ */ extern int driGetMSC32( __DRIscreenPrivate * priv, int64_t * count ); +extern int driDrawableGetMSC32( __DRIscreenPrivate * priv, + __DRIdrawablePrivate * drawablePrivate, + int64_t * count); extern int driWaitForMSC32( __DRIdrawablePrivate *priv, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t * msc ); extern GLuint driGetDefaultVBlankFlags( const driOptionCache *optionCache ); -extern void driDrawableInitVBlank ( __DRIdrawablePrivate *priv, GLuint flags, - GLuint *vbl_seq ); +extern void driDrawableInitVBlank ( __DRIdrawablePrivate *priv ); extern unsigned driGetVBlankInterval( const __DRIdrawablePrivate *priv, GLuint flags ); extern void driGetCurrentVBlank( const __DRIdrawablePrivate *priv, diff --git a/src/mesa/drivers/dri/ffb/ffb_xmesa.c b/src/mesa/drivers/dri/ffb/ffb_xmesa.c index 3a5551e..173c5fa 100644 --- a/src/mesa/drivers/dri/ffb/ffb_xmesa.c +++ b/src/mesa/drivers/dri/ffb/ffb_xmesa.c @@ -615,6 +615,7 @@ static const struct __DriverAPIRec ffbAPI = { .UnbindContext = ffbUnbindContext, .GetSwapInfo = NULL, .GetMSC = NULL, + .GetDrawableMSC = NULL, .WaitForMSC = NULL, .WaitForSBC = NULL, .SwapBuffersMSC = NULL diff --git a/src/mesa/drivers/dri/i810/i810screen.c b/src/mesa/drivers/dri/i810/i810screen.c index 3c7ec96..1a0d3c3 100644 --- a/src/mesa/drivers/dri/i810/i810screen.c +++ b/src/mesa/drivers/dri/i810/i810screen.c @@ -413,6 +413,7 @@ static const struct __DriverAPIRec i810API = { .UnbindContext = i810UnbindContext, .GetSwapInfo = NULL, .GetMSC = NULL, + .GetDrawableMSC = NULL, .WaitForMSC = NULL, .WaitForSBC = NULL, .SwapBuffersMSC = NULL diff --git a/src/mesa/drivers/dri/i915/intel_buffers.c b/src/mesa/drivers/dri/i915/intel_buffers.c index 46a67b1..faa13ad 100644 --- a/src/mesa/drivers/dri/i915/intel_buffers.c +++ b/src/mesa/drivers/dri/i915/intel_buffers.c @@ -243,7 +243,7 @@ intelWindowMoved(struct intel_context *intel) .y2 = sarea->planeB_y + sarea->planeB_h }; GLint areaA = driIntersectArea( drw_rect, planeA_rect ); GLint areaB = driIntersectArea( drw_rect, planeB_rect ); - GLuint flags = intel_fb->vblank_flags; + GLuint flags = dPriv->vblFlags; GLboolean pf_active; GLint pf_planes; @@ -311,19 +311,24 @@ intelWindowMoved(struct intel_context *intel) /* Update vblank info */ if (areaB > areaA || (areaA == areaB && areaB > 0)) { - flags = intel_fb->vblank_flags | VBLANK_FLAG_SECONDARY; + flags = dPriv->vblFlags | VBLANK_FLAG_SECONDARY; } else { - flags = intel_fb->vblank_flags & ~VBLANK_FLAG_SECONDARY; + flags = dPriv->vblFlags & ~VBLANK_FLAG_SECONDARY; } - if (flags != intel_fb->vblank_flags && intel_fb->vblank_flags && - !(intel_fb->vblank_flags & VBLANK_FLAG_NO_IRQ)) { + /* Check to see if we changed pipes */ + if (flags != dPriv->vblFlags && dPriv->vblFlags && + !(dPriv->vblFlags & VBLANK_FLAG_NO_IRQ)) { + int64_t count; drmVBlank vbl; int i; + /* + * Deal with page flipping + */ vbl.request.type = DRM_VBLANK_ABSOLUTE; - if ( intel_fb->vblank_flags & VBLANK_FLAG_SECONDARY ) { + if ( dPriv->vblFlags & VBLANK_FLAG_SECONDARY ) { vbl.request.type |= DRM_VBLANK_SECONDARY; } @@ -337,9 +342,19 @@ intelWindowMoved(struct intel_context *intel) drmWaitVBlank(intel->driFd, &vbl); } - intel_fb->vblank_flags = flags; - driGetCurrentVBlank(dPriv, intel_fb->vblank_flags, &intel_fb->vbl_seq); - intel_fb->vbl_waited = intel_fb->vbl_seq; + /* + * Update msc_base from old pipe + */ + driDrawableGetMSC32(dPriv->driScreenPriv, dPriv, &count); + dPriv->msc_base = count; + /* + * Then get new vblank_base and vblSeq values + */ + dPriv->vblFlags = flags; + driGetCurrentVBlank(dPriv, dPriv->vblFlags, &dPriv->vblSeq); + dPriv->vblank_base = dPriv->vblSeq; + + intel_fb->vbl_waited = dPriv->vblSeq; for (i = 0; i < intel_fb->pf_num_pages; i++) { if (intel_fb->color_rb[i]) @@ -347,7 +362,7 @@ intelWindowMoved(struct intel_context *intel) } } } else { - intel_fb->vblank_flags &= ~VBLANK_FLAG_SECONDARY; + dPriv->vblFlags &= ~VBLANK_FLAG_SECONDARY; } /* Update Mesa's notion of window size */ @@ -820,10 +835,10 @@ intelSwapBuffers(__DRIdrawablePrivate * dPriv) */ static GLboolean -intelScheduleSwap(const __DRIdrawablePrivate * dPriv, GLboolean *missed_target) +intelScheduleSwap(__DRIdrawablePrivate * dPriv, GLboolean *missed_target) { struct intel_framebuffer *intel_fb = dPriv->driverPrivate; - unsigned int interval = driGetVBlankInterval(dPriv, intel_fb->vblank_flags); + unsigned int interval = driGetVBlankInterval(dPriv, dPriv->vblFlags); struct intel_context *intel = intelScreenContext(dPriv->driScreenPriv->private); const intelScreenPrivate *intelScreen = intel->intelScreen; @@ -831,24 +846,24 @@ intelScheduleSwap(const __DRIdrawablePrivate * dPriv, GLboolean *missed_target) drm_i915_vblank_swap_t swap; GLboolean ret; - if (!intel_fb->vblank_flags || - (intel_fb->vblank_flags & VBLANK_FLAG_NO_IRQ) || + if (!dPriv->vblFlags || + (dPriv->vblFlags & VBLANK_FLAG_NO_IRQ) || intelScreen->current_rotation != 0 || intelScreen->drmMinor < (intel_fb->pf_active ? 9 : 6)) return GL_FALSE; swap.seqtype = DRM_VBLANK_ABSOLUTE; - if (intel_fb->vblank_flags & VBLANK_FLAG_SYNC) { + if (dPriv->vblFlags & VBLANK_FLAG_SYNC) { swap.seqtype |= DRM_VBLANK_NEXTONMISS; } else if (interval == 0) { return GL_FALSE; } swap.drawable = dPriv->hHWDrawable; - target = swap.sequence = intel_fb->vbl_seq + interval; + target = swap.sequence = dPriv->vblSeq + interval; - if ( intel_fb->vblank_flags & VBLANK_FLAG_SECONDARY ) { + if ( dPriv->vblFlags & VBLANK_FLAG_SECONDARY ) { swap.seqtype |= DRM_VBLANK_SECONDARY; } @@ -866,14 +881,14 @@ intelScheduleSwap(const __DRIdrawablePrivate * dPriv, GLboolean *missed_target) if (!drmCommandWriteRead(intel->driFd, DRM_I915_VBLANK_SWAP, &swap, sizeof(swap))) { - intel_fb->vbl_seq = swap.sequence; + dPriv->vblSeq = swap.sequence; swap.sequence -= target; *missed_target = swap.sequence > 0 && swap.sequence <= (1 << 23); intel_get_renderbuffer(&intel_fb->Base, BUFFER_BACK_LEFT)->vbl_pending = intel_get_renderbuffer(&intel_fb->Base, BUFFER_FRONT_LEFT)->vbl_pending = - intel_fb->vbl_seq; + dPriv->vblSeq; if (swap.seqtype & DRM_VBLANK_FLIP) { intel_flip_renderbuffers(intel_fb); @@ -918,7 +933,7 @@ intelSwapBuffers(__DRIdrawablePrivate * dPriv) if (screen->current_rotation != 0 || !intelScheduleSwap(dPriv, &missed_target)) { - driWaitForVBlank(dPriv, &intel_fb->vbl_seq, intel_fb->vblank_flags, + driWaitForVBlank(dPriv, &dPriv->vblSeq, dPriv->vblFlags, &missed_target); if (screen->current_rotation != 0 || !intelPageFlip(dPriv)) { diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c index d7af432..b85b0c2 100644 --- a/src/mesa/drivers/dri/i915/intel_context.c +++ b/src/mesa/drivers/dri/i915/intel_context.c @@ -616,18 +616,17 @@ intelMakeCurrent(__DRIcontextPrivate * driContextPriv, if (driDrawPriv->swap_interval == (unsigned)-1) { int i; - intel_fb->vblank_flags = (intel->intelScreen->irq_active != 0) + driDrawPriv->vblFlags = (intel->intelScreen->irq_active != 0) ? driGetDefaultVBlankFlags(&intel->optionCache) : VBLANK_FLAG_NO_IRQ; (*dri_interface->getUST) (&intel_fb->swap_ust); - driDrawableInitVBlank(driDrawPriv, intel_fb->vblank_flags, - &intel_fb->vbl_seq); - intel_fb->vbl_waited = intel_fb->vbl_seq; + driDrawableInitVBlank(driDrawPriv); + intel_fb->vbl_waited = driDrawPriv->vblSeq; for (i = 0; i < (intel->intelScreen->third.handle ? 3 : 2); i++) { if (intel_fb->color_rb[i]) - intel_fb->color_rb[i]->vbl_pending = intel_fb->vbl_seq; + intel_fb->color_rb[i]->vbl_pending = driDrawPriv->vblSeq; } } intel->driDrawable = driDrawPriv; @@ -731,6 +730,7 @@ intelContendedLock(struct intel_context *intel, GLuint flags) */ void LOCK_HARDWARE( struct intel_context *intel ) { + __DRIdrawablePrivate *dPriv = intel->driDrawable; char __ret=0; struct intel_framebuffer *intel_fb = NULL; struct intel_renderbuffer *intel_rb = NULL; @@ -748,14 +748,14 @@ void LOCK_HARDWARE( struct intel_context *intel ) BUFFER_BACK_LEFT); } - if (intel_rb && intel_fb->vblank_flags && - !(intel_fb->vblank_flags & VBLANK_FLAG_NO_IRQ) && + if (intel_rb && dPriv->vblFlags && + !(dPriv->vblFlags & VBLANK_FLAG_NO_IRQ) && (intel_fb->vbl_waited - intel_rb->vbl_pending) > (1<<23)) { drmVBlank vbl; vbl.request.type = DRM_VBLANK_ABSOLUTE; - if ( intel_fb->vblank_flags & VBLANK_FLAG_SECONDARY ) { + if ( dPriv->vblFlags & VBLANK_FLAG_SECONDARY ) { vbl.request.type |= DRM_VBLANK_SECONDARY; } diff --git a/src/mesa/drivers/dri/i915/intel_fbo.h b/src/mesa/drivers/dri/i915/intel_fbo.h index 411d634..f9a11d0 100644 --- a/src/mesa/drivers/dri/i915/intel_fbo.h +++ b/src/mesa/drivers/dri/i915/intel_fbo.h @@ -50,8 +50,6 @@ struct intel_framebuffer /* VBI */ - GLuint vbl_seq; - GLuint vblank_flags; GLuint vbl_waited; int64_t swap_ust; diff --git a/src/mesa/drivers/dri/i915/intel_screen.c b/src/mesa/drivers/dri/i915/intel_screen.c index 8be5d91..25f5efa 100644 --- a/src/mesa/drivers/dri/i915/intel_screen.c +++ b/src/mesa/drivers/dri/i915/intel_screen.c @@ -790,6 +790,7 @@ static const struct __DriverAPIRec intelAPI = { .UnbindContext = intelUnbindContext, .GetSwapInfo = intelGetSwapInfo, .GetMSC = driGetMSC32, + .GetDrawableMSC = driDrawableGetMSC32, .WaitForMSC = driWaitForMSC32, .WaitForSBC = NULL, .SwapBuffersMSC = NULL, diff --git a/src/mesa/drivers/dri/i965/intel_blit.c b/src/mesa/drivers/dri/i965/intel_blit.c index d1c1c8a..6343f61 100644 --- a/src/mesa/drivers/dri/i965/intel_blit.c +++ b/src/mesa/drivers/dri/i965/intel_blit.c @@ -76,7 +76,8 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv, if (!rect) { UNLOCK_HARDWARE( intel ); - driWaitForVBlank( dPriv, &intel->vbl_seq, intel->vblank_flags, & missed_target ); + driWaitForVBlank( dPriv, &dPriv->vblSeq, dPriv->vblFlags, + &missed_target ); LOCK_HARDWARE( intel ); } diff --git a/src/mesa/drivers/dri/i965/intel_buffers.c b/src/mesa/drivers/dri/i965/intel_buffers.c index 6c8b073..96ef9d8 100644 --- a/src/mesa/drivers/dri/i965/intel_buffers.c +++ b/src/mesa/drivers/dri/i965/intel_buffers.c @@ -33,6 +33,8 @@ #include "context.h" #include "framebuffer.h" #include "macros.h" +#include "utils.h" +#include "vblank.h" #include "swrast/swrast.h" GLboolean intel_intersect_cliprects( drm_clip_rect_t *dst, @@ -190,6 +192,50 @@ void intelWindowMoved( struct intel_context *intel ) } } + /* Get updated plane info so we sync against the right vblank counter */ + if (intel->intelScreen->driScrnPriv->ddx_version.minor >= 7) { + drmI830Sarea *sarea = intel->sarea; + drm_clip_rect_t drw_rect = { .x1 = dPriv->x, .x2 = dPriv->x + dPriv->w, + .y1 = dPriv->y, .y2 = dPriv->y + dPriv->h }; + drm_clip_rect_t planeA_rect = { .x1 = sarea->planeA_x, .y1 = sarea->planeA_y, + .x2 = sarea->planeA_x + sarea->planeA_w, + .y2 = sarea->planeA_y + sarea->planeA_h }; + drm_clip_rect_t planeB_rect = { .x1 = sarea->planeB_x, .y1 = sarea->planeB_y, + .x2 = sarea->planeB_x + sarea->planeB_w, + .y2 = sarea->planeB_y + sarea->planeB_h }; + GLint areaA = driIntersectArea( drw_rect, planeA_rect ); + GLint areaB = driIntersectArea( drw_rect, planeB_rect ); + GLuint flags = dPriv->vblFlags; + + /* Update vblank info + */ + if (areaB > areaA || (areaA == areaB && areaB > 0)) { + flags = dPriv->vblFlags | VBLANK_FLAG_SECONDARY; + } else { + flags = dPriv->vblFlags & ~VBLANK_FLAG_SECONDARY; + } + + /* Check to see if we changed pipes */ + if (flags != dPriv->vblFlags && dPriv->vblFlags && + !(dPriv->vblFlags & VBLANK_FLAG_NO_IRQ)) { + int64_t count; + + /* + * Update msc_base from old pipe + */ + driDrawableGetMSC32(dPriv->driScreenPriv, dPriv, &count); + dPriv->msc_base = count; + /* + * Then get new vblank_base and vblSeq values + */ + dPriv->vblFlags = flags; + driGetCurrentVBlank(dPriv, dPriv->vblFlags, &dPriv->vblSeq); + dPriv->vblank_base = dPriv->vblSeq; + } + } else { + dPriv->vblFlags &= ~VBLANK_FLAG_SECONDARY; + } + _mesa_resize_framebuffer(&intel->ctx, (GLframebuffer*)dPriv->driverPrivate, dPriv->w, dPriv->h); diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index 7ec316a..aa066ae 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -330,8 +330,8 @@ GLboolean intelInitContext( struct intel_context *intel, GLcontext *shareCtx = (GLcontext *) sharedContextPrivate; __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private; - volatile drmI830Sarea *saPriv = (volatile drmI830Sarea *) - (((GLubyte *)sPriv->pSAREA)+intelScreen->sarea_priv_offset); + volatile drmI830Sarea *saPriv = (drmI830Sarea *) + (((GLubyte *)sPriv->pSAREA)+intelScreen->sarea_priv_offset); if (!_mesa_initialize_context(&intel->ctx, mesaVis, shareCtx, @@ -349,9 +349,6 @@ GLboolean intelInitContext( struct intel_context *intel, driParseConfigFiles (&intel->optionCache, &intelScreen->optionCache, intel->driScreen->myNum, "i965"); - intel->vblank_flags = (intel->intelScreen->irq_active != 0) - ? driGetDefaultVBlankFlags(&intel->optionCache) : VBLANK_FLAG_NO_IRQ; - ctx->Const.MaxTextureMaxAnisotropy = 2.0; if (getenv("INTEL_STRICT_CONFORMANCE")) { @@ -578,17 +575,19 @@ GLboolean intelMakeCurrent(__DRIcontextPrivate *driContextPriv, if (driContextPriv) { struct intel_context *intel = (struct intel_context *) driContextPriv->driverPrivate; + driDrawPriv->vblFlags = (intel->intelScreen->irq_active != 0) + ? driGetDefaultVBlankFlags(&intel->optionCache) : VBLANK_FLAG_NO_IRQ; + + if (intel->driReadDrawable != driReadPriv) { intel->driReadDrawable = driReadPriv; } if ( intel->driDrawable != driDrawPriv ) { - /* Shouldn't the readbuffer be stored also? */ - driDrawableInitVBlank( driDrawPriv, intel->vblank_flags, - &intel->vbl_seq ); - intel->driDrawable = driDrawPriv; intelWindowMoved( intel ); + /* Shouldn't the readbuffer be stored also? */ + driDrawableInitVBlank( driDrawPriv ); } _mesa_make_current(&intel->ctx, diff --git a/src/mesa/drivers/dri/i965/intel_context.h b/src/mesa/drivers/dri/i965/intel_context.h index 65898ca..5848d0c 100644 --- a/src/mesa/drivers/dri/i965/intel_context.h +++ b/src/mesa/drivers/dri/i965/intel_context.h @@ -231,11 +231,6 @@ struct intel_context */ driOptionCache optionCache; - /* VBI - */ - GLuint vbl_seq; - GLuint vblank_flags; - int64_t swap_ust; int64_t swap_missed_ust; diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c index e35f7da..77fd9e3 100644 --- a/src/mesa/drivers/dri/i965/intel_screen.c +++ b/src/mesa/drivers/dri/i965/intel_screen.c @@ -549,6 +549,7 @@ static const struct __DriverAPIRec intelAPI = { .UnbindContext = intelUnbindContext, .GetSwapInfo = intelGetSwapInfo, .GetMSC = driGetMSC32, + .GetDrawableMSC = driDrawableGetMSC32, .WaitForMSC = driWaitForMSC32, .WaitForSBC = NULL, .SwapBuffersMSC = NULL, diff --git a/src/mesa/drivers/dri/mach64/mach64_context.c b/src/mesa/drivers/dri/mach64/mach64_context.c index ad661e1..138e84d 100644 --- a/src/mesa/drivers/dri/mach64/mach64_context.c +++ b/src/mesa/drivers/dri/mach64/mach64_context.c @@ -100,6 +100,7 @@ GLboolean mach64CreateContext( const __GLcontextModes *glVisual, { GLcontext *ctx, *shareCtx; __DRIscreenPrivate *driScreen = driContextPriv->driScreenPriv; + __DRIdrawablePrivate *dPriv = driContextPriv->driDrawablePriv; struct dd_function_table functions; mach64ContextPtr mmesa; mach64ScreenPtr mach64Screen; @@ -253,7 +254,7 @@ GLboolean mach64CreateContext( const __GLcontextModes *glVisual, mmesa->do_irqs = (mmesa->mach64Screen->irq && !getenv("MACH64_NO_IRQS")); - mmesa->vblank_flags = (mmesa->do_irqs) + dPriv->vblFlags = (mmesa->do_irqs) ? driGetDefaultVBlankFlags(&mmesa->optionCache) : VBLANK_FLAG_NO_IRQ; driContextPriv->driverPrivate = (void *)mmesa; @@ -330,8 +331,7 @@ mach64MakeCurrent( __DRIcontextPrivate *driContextPriv, } - driDrawableInitVBlank( driDrawPriv, newMach64Ctx->vblank_flags, - &newMach64Ctx->vbl_seq ); + driDrawableInitVBlank( driDrawPriv ); if ( newMach64Ctx->driDrawable != driDrawPriv ) { newMach64Ctx->driDrawable = driDrawPriv; diff --git a/src/mesa/drivers/dri/mach64/mach64_context.h b/src/mesa/drivers/dri/mach64/mach64_context.h index 8d89452..c602333 100644 --- a/src/mesa/drivers/dri/mach64/mach64_context.h +++ b/src/mesa/drivers/dri/mach64/mach64_context.h @@ -263,8 +263,6 @@ struct mach64_context { /* VBI */ - GLuint vbl_seq; - GLuint vblank_flags; GLuint do_irqs; /* Configuration cache diff --git a/src/mesa/drivers/dri/mach64/mach64_ioctl.c b/src/mesa/drivers/dri/mach64/mach64_ioctl.c index 36e7d3c..7405a27 100644 --- a/src/mesa/drivers/dri/mach64/mach64_ioctl.c +++ b/src/mesa/drivers/dri/mach64/mach64_ioctl.c @@ -279,7 +279,7 @@ static int mach64WaitForFrameCompletion( mach64ContextPtr mmesa ) /* Copy the back color buffer to the front color buffer. */ -void mach64CopyBuffer( const __DRIdrawablePrivate *dPriv ) +void mach64CopyBuffer( __DRIdrawablePrivate *dPriv ) { mach64ContextPtr mmesa; GLint nbox, i, ret; @@ -320,7 +320,7 @@ void mach64CopyBuffer( const __DRIdrawablePrivate *dPriv ) #endif UNLOCK_HARDWARE( mmesa ); - driWaitForVBlank( dPriv, &mmesa->vbl_seq, mmesa->vblank_flags, &missed_target ); + driWaitForVBlank( dPriv, &dPriv->vblSeq, dPriv->vblFlags, &missed_target ); LOCK_HARDWARE( mmesa ); /* use front buffer cliprects */ diff --git a/src/mesa/drivers/dri/mach64/mach64_ioctl.h b/src/mesa/drivers/dri/mach64/mach64_ioctl.h index 52fe863..c28bf31 100644 --- a/src/mesa/drivers/dri/mach64/mach64_ioctl.h +++ b/src/mesa/drivers/dri/mach64/mach64_ioctl.h @@ -78,7 +78,7 @@ extern void mach64FireBlitLocked( mach64ContextPtr mmesa, void *buffer, GLint offset, GLint pitch, GLint format, GLint x, GLint y, GLint width, GLint height ); -extern void mach64CopyBuffer( const __DRIdrawablePrivate *dPriv ); +extern void mach64CopyBuffer( __DRIdrawablePrivate *dPriv ); #if ENABLE_PERF_BOXES extern void mach64PerformanceCounters( mach64ContextPtr mmesa ); extern void mach64PerformanceBoxesLocked( mach64ContextPtr mmesa ); diff --git a/src/mesa/drivers/dri/mach64/mach64_screen.c b/src/mesa/drivers/dri/mach64/mach64_screen.c index 04eb081..a04b775 100644 --- a/src/mesa/drivers/dri/mach64/mach64_screen.c +++ b/src/mesa/drivers/dri/mach64/mach64_screen.c @@ -484,6 +484,7 @@ static struct __DriverAPIRec mach64API = { .UnbindContext = mach64UnbindContext, .GetSwapInfo = NULL, .GetMSC = driGetMSC32, + .GetDrawableMSC = driDrawableGetMSC32, .WaitForMSC = driWaitForMSC32, .WaitForSBC = NULL, .SwapBuffersMSC = NULL diff --git a/src/mesa/drivers/dri/mga/mga_xmesa.c b/src/mesa/drivers/dri/mga/mga_xmesa.c index 2f3516f..31042f9 100644 --- a/src/mesa/drivers/dri/mga/mga_xmesa.c +++ b/src/mesa/drivers/dri/mga/mga_xmesa.c @@ -452,6 +452,7 @@ mgaCreateContext( const __GLcontextModes *mesaVis, GLcontext *ctx, *shareCtx; mgaContextPtr mmesa; __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + __DRIdrawablePrivate *dPriv = driContextPriv->driDrawablePriv; mgaScreenPrivate *mgaScreen = (mgaScreenPrivate *)sPriv->private; drm_mga_sarea_t *saPriv = (drm_mga_sarea_t *)(((char*)sPriv->pSAREA)+ mgaScreen->sarea_priv_offset); @@ -650,7 +651,7 @@ mgaCreateContext( const __GLcontextModes *mesaVis, debug_control ); #endif - mmesa->vblank_flags = (mmesa->mgaScreen->irq == 0) + dPriv->vblFlags = (mmesa->mgaScreen->irq == 0) ? VBLANK_FLAG_NO_IRQ : driGetDefaultVBlankFlags(&mmesa->optionCache); (*dri_interface->getUST)( & mmesa->swap_ust ); @@ -882,8 +883,8 @@ mgaMakeCurrent(__DRIcontextPrivate *driContextPriv, mgaContextPtr mmesa = (mgaContextPtr) driContextPriv->driverPrivate; if (mmesa->driDrawable != driDrawPriv) { - driDrawableInitVBlank( driDrawPriv, mmesa->vblank_flags, - &mmesa->vbl_seq ); + driDrawableInitVBlank( driDrawPriv ); + mmesa->driDrawable = driDrawPriv; mmesa->dirty = ~0; mmesa->dirty_cliprects = (MGA_FRONT|MGA_BACK); @@ -948,6 +949,7 @@ static const struct __DriverAPIRec mgaAPI = { .UnbindContext = mgaUnbindContext, .GetSwapInfo = getSwapInfo, .GetMSC = driGetMSC32, + .GetDrawableMSC = driDrawableGetMSC32, .WaitForMSC = driWaitForMSC32, .WaitForSBC = NULL, .SwapBuffersMSC = NULL diff --git a/src/mesa/drivers/dri/mga/mgacontext.h b/src/mesa/drivers/dri/mga/mgacontext.h index 2124006..2681976 100644 --- a/src/mesa/drivers/dri/mga/mgacontext.h +++ b/src/mesa/drivers/dri/mga/mgacontext.h @@ -258,11 +258,6 @@ struct mga_context_t { drmBufPtr vertex_dma_buffer; drmBufPtr iload_buffer; - /* VBI - */ - GLuint vbl_seq; - GLuint vblank_flags; - int64_t swap_ust; int64_t swap_missed_ust; diff --git a/src/mesa/drivers/dri/mga/mgaioctl.c b/src/mesa/drivers/dri/mga/mgaioctl.c index 679d688..94126a3 100644 --- a/src/mesa/drivers/dri/mga/mgaioctl.c +++ b/src/mesa/drivers/dri/mga/mgaioctl.c @@ -428,8 +428,7 @@ void mgaCopyBuffer( const __DRIdrawablePrivate *dPriv ) FLUSH_BATCH( mmesa ); mgaWaitForFrameCompletion( mmesa ); - driWaitForVBlank( dPriv, & mmesa->vbl_seq, mmesa->vblank_flags, - & missed_target ); + driWaitForVBlank( dPriv, & dPriv->vblSeq, dPriv->vblFlags, & missed_target ); if ( missed_target ) { mmesa->swap_missed_count++; (void) (*dri_interface->getUST)( & mmesa->swap_missed_ust ); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index a8569a9..5ef24d8 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -283,7 +283,7 @@ GLboolean nouveauMakeCurrent( __DRIcontextPrivate *driContextPriv, struct gl_framebuffer *read_fb = (struct gl_framebuffer*)driReadPriv->driverPrivate; - driDrawableInitVBlank(driDrawPriv, nmesa->vblank_flags, &nmesa->vblank_seq ); + driDrawableInitVBlank(driDrawPriv); nmesa->driDrawable = driDrawPriv; _mesa_resize_framebuffer(nmesa->glCtx, draw_fb, diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index 9aff0ee..a617dd6 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -182,10 +182,6 @@ typedef struct nouveau_context { /* Configuration cache */ driOptionCache optionCache; - /* vblank stuff */ - uint32_t vblank_flags; - uint32_t vblank_seq; - GLuint new_state; GLuint new_render_state; GLuint render_index; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c index 3e7bab6..533b4b1 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_screen.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c @@ -205,6 +205,7 @@ static const struct __DriverAPIRec nouveauAPI = { .UnbindContext = nouveauUnbindContext, .GetSwapInfo = nouveauGetSwapInfo, .GetMSC = driGetMSC32, + .GetDrawableMSC = driDrawableGetMSC32, .WaitForMSC = driWaitForMSC32, .WaitForSBC = NULL, .SwapBuffersMSC = NULL, diff --git a/src/mesa/drivers/dri/r128/r128_context.c b/src/mesa/drivers/dri/r128/r128_context.c index c9fe11f..25efe5e 100644 --- a/src/mesa/drivers/dri/r128/r128_context.c +++ b/src/mesa/drivers/dri/r128/r128_context.c @@ -113,6 +113,7 @@ GLboolean r128CreateContext( const __GLcontextModes *glVisual, { GLcontext *ctx, *shareCtx; __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + __DRIdrawablePrivate *dPriv = driContextPriv->driDrawablePriv; struct dd_function_table functions; r128ContextPtr rmesa; r128ScreenPtr r128scrn; @@ -262,7 +263,7 @@ GLboolean r128CreateContext( const __GLcontextModes *glVisual, r128DDInitSpanFuncs( ctx ); r128DDInitState( rmesa ); - rmesa->vblank_flags = (rmesa->r128Screen->irq != 0) + dPriv->vblFlags = (rmesa->r128Screen->irq != 0) ? driGetDefaultVBlankFlags(&rmesa->optionCache) : VBLANK_FLAG_NO_IRQ; driContextPriv->driverPrivate = (void *)rmesa; @@ -347,8 +348,7 @@ r128MakeCurrent( __DRIcontextPrivate *driContextPriv, newR128Ctx->dirty = R128_UPLOAD_ALL; } - driDrawableInitVBlank( driDrawPriv, newR128Ctx->vblank_flags, - &newR128Ctx->vbl_seq ); + driDrawableInitVBlank( driDrawPriv ); newR128Ctx->driDrawable = driDrawPriv; _mesa_make_current( newR128Ctx->glCtx, diff --git a/src/mesa/drivers/dri/r128/r128_context.h b/src/mesa/drivers/dri/r128/r128_context.h index c51dd7f..3f7416e 100644 --- a/src/mesa/drivers/dri/r128/r128_context.h +++ b/src/mesa/drivers/dri/r128/r128_context.h @@ -210,11 +210,6 @@ struct r128_context { GLuint c_textureBytes; GLuint c_vertexBuffers; - /* VBI - */ - GLuint vbl_seq; - GLuint vblank_flags; - /* Configuration cache */ driOptionCache optionCache; diff --git a/src/mesa/drivers/dri/r128/r128_ioctl.c b/src/mesa/drivers/dri/r128/r128_ioctl.c index b0dba7d..e04c087 100644 --- a/src/mesa/drivers/dri/r128/r128_ioctl.c +++ b/src/mesa/drivers/dri/r128/r128_ioctl.c @@ -249,7 +249,7 @@ static int r128WaitForFrameCompletion( r128ContextPtr rmesa ) /* Copy the back color buffer to the front color buffer. */ -void r128CopyBuffer( const __DRIdrawablePrivate *dPriv ) +void r128CopyBuffer( __DRIdrawablePrivate *dPriv ) { r128ContextPtr rmesa; GLint nbox, i, ret; @@ -282,7 +282,7 @@ void r128CopyBuffer( const __DRIdrawablePrivate *dPriv ) } UNLOCK_HARDWARE( rmesa ); - driWaitForVBlank( dPriv, &rmesa->vbl_seq, rmesa->vblank_flags, &missed_target ); + driWaitForVBlank( dPriv, &dPriv->vblSeq, dPriv->vblFlags, &missed_target ); LOCK_HARDWARE( rmesa ); nbox = dPriv->numClipRects; /* must be in locked region */ @@ -328,7 +328,7 @@ void r128CopyBuffer( const __DRIdrawablePrivate *dPriv ) #endif } -void r128PageFlip( const __DRIdrawablePrivate *dPriv ) +void r128PageFlip( __DRIdrawablePrivate *dPriv ) { r128ContextPtr rmesa; GLint ret; @@ -359,7 +359,7 @@ void r128PageFlip( const __DRIdrawablePrivate *dPriv ) } UNLOCK_HARDWARE( rmesa ); - driWaitForVBlank( dPriv, &rmesa->vbl_seq, rmesa->vblank_flags, &missed_target ); + driWaitForVBlank( dPriv, &dPriv->vblSeq, dPriv->vblFlags, &missed_target ); LOCK_HARDWARE( rmesa ); /* The kernel will have been initialized to perform page flipping diff --git a/src/mesa/drivers/dri/r128/r128_ioctl.h b/src/mesa/drivers/dri/r128/r128_ioctl.h index 95779f0..0f9d11f 100644 --- a/src/mesa/drivers/dri/r128/r128_ioctl.h +++ b/src/mesa/drivers/dri/r128/r128_ioctl.h @@ -86,8 +86,8 @@ extern void r128ReadDepthSpanLocked( r128ContextPtr rmesa, extern void r128ReadDepthPixelsLocked( r128ContextPtr rmesa, GLuint n, const GLint x[], const GLint y[] ); -extern void r128CopyBuffer( const __DRIdrawablePrivate *dPriv ); -extern void r128PageFlip( const __DRIdrawablePrivate *dPriv ); +extern void r128CopyBuffer( __DRIdrawablePrivate *dPriv ); +extern void r128PageFlip( __DRIdrawablePrivate *dPriv ); void r128WaitForVBlank( r128ContextPtr rmesa ); extern void r128WaitForIdleLocked( r128ContextPtr rmesa ); diff --git a/src/mesa/drivers/dri/r128/r128_screen.c b/src/mesa/drivers/dri/r128/r128_screen.c index 9d65ebd..719f936 100644 --- a/src/mesa/drivers/dri/r128/r128_screen.c +++ b/src/mesa/drivers/dri/r128/r128_screen.c @@ -411,6 +411,7 @@ static struct __DriverAPIRec r128API = { .UnbindContext = r128UnbindContext, .GetSwapInfo = NULL, .GetMSC = driGetMSC32, + .GetDrawableMSC = driDrawableGetMSC32, .WaitForMSC = driWaitForMSC32, .WaitForSBC = NULL, .SwapBuffersMSC = NULL diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c index 8f43a2f..2b18889 100644 --- a/src/mesa/drivers/dri/r200/r200_context.c +++ b/src/mesa/drivers/dri/r200/r200_context.c @@ -248,6 +248,7 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, void *sharedContextPrivate) { __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + __DRIdrawablePrivate *dPriv = driContextPriv->driDrawablePriv; radeonScreenPtr screen = (radeonScreenPtr)(sPriv->private); struct dd_function_table functions; r200ContextPtr rmesa; @@ -499,7 +500,7 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, fthrottle_mode, rmesa->r200Screen->irq); - rmesa->vblank_flags = (rmesa->r200Screen->irq != 0) + dPriv->vblFlags = (rmesa->r200Screen->irq != 0) ? driGetDefaultVBlankFlags(&rmesa->optionCache) : VBLANK_FLAG_NO_IRQ; rmesa->prefer_gart_client_texturing = @@ -667,8 +668,7 @@ r200MakeCurrent( __DRIcontextPrivate *driContextPriv, fprintf(stderr, "%s ctx %p\n", __FUNCTION__, (void *)newCtx->glCtx); if ( newCtx->dri.drawable != driDrawPriv ) { - driDrawableInitVBlank( driDrawPriv, newCtx->vblank_flags, - &newCtx->vbl_seq ); + driDrawableInitVBlank( driDrawPriv ); } newCtx->dri.readable = driReadPriv; diff --git a/src/mesa/drivers/dri/r200/r200_context.h b/src/mesa/drivers/dri/r200/r200_context.h index c80180b..be73507 100644 --- a/src/mesa/drivers/dri/r200/r200_context.h +++ b/src/mesa/drivers/dri/r200/r200_context.h @@ -893,11 +893,8 @@ struct r200_context { GLuint TexGenCompSel; GLmatrix tmpmat; - /* VBI / buffer swap + /* buffer swap */ - GLuint vbl_seq; - GLuint vblank_flags; - int64_t swap_ust; int64_t swap_missed_ust; diff --git a/src/mesa/drivers/dri/r200/r200_ioctl.c b/src/mesa/drivers/dri/r200/r200_ioctl.c index c9c5a86..2ab9ff8 100644 --- a/src/mesa/drivers/dri/r200/r200_ioctl.c +++ b/src/mesa/drivers/dri/r200/r200_ioctl.c @@ -419,7 +419,7 @@ static void r200WaitForFrameCompletion( r200ContextPtr rmesa ) /* Copy the back color buffer to the front color buffer. */ -void r200CopyBuffer( const __DRIdrawablePrivate *dPriv, +void r200CopyBuffer( __DRIdrawablePrivate *dPriv, const drm_clip_rect_t *rect) { r200ContextPtr rmesa; @@ -449,7 +449,7 @@ void r200CopyBuffer( const __DRIdrawablePrivate *dPriv, if (!rect) { UNLOCK_HARDWARE( rmesa ); - driWaitForVBlank( dPriv, & rmesa->vbl_seq, rmesa->vblank_flags, & missed_target ); + driWaitForVBlank( dPriv, & dPriv->vblSeq, dPriv->vblFlags, & missed_target ); LOCK_HARDWARE( rmesa ); } @@ -513,7 +513,7 @@ void r200CopyBuffer( const __DRIdrawablePrivate *dPriv, } } -void r200PageFlip( const __DRIdrawablePrivate *dPriv ) +void r200PageFlip( __DRIdrawablePrivate *dPriv ) { r200ContextPtr rmesa; GLint ret; @@ -553,7 +553,7 @@ void r200PageFlip( const __DRIdrawablePrivate *dPriv ) */ r200WaitForFrameCompletion( rmesa ); UNLOCK_HARDWARE( rmesa ); - driWaitForVBlank( dPriv, & rmesa->vbl_seq, rmesa->vblank_flags, & missed_target ); + driWaitForVBlank( dPriv, & dPriv->vblSeq, dPriv->vblFlags, & missed_target ); if ( missed_target ) { rmesa->swap_missed_count++; (void) (*dri_interface->getUST)( & rmesa->swap_missed_ust ); diff --git a/src/mesa/drivers/dri/r200/r200_ioctl.h b/src/mesa/drivers/dri/r200/r200_ioctl.h index bf12679..4521fba 100644 --- a/src/mesa/drivers/dri/r200/r200_ioctl.h +++ b/src/mesa/drivers/dri/r200/r200_ioctl.h @@ -89,9 +89,9 @@ extern void r200ReleaseDmaRegion( r200ContextPtr rmesa, struct r200_dma_region *region, const char *caller ); -extern void r200CopyBuffer( const __DRIdrawablePrivate *drawable, +extern void r200CopyBuffer( __DRIdrawablePrivate *drawable, const drm_clip_rect_t *rect); -extern void r200PageFlip( const __DRIdrawablePrivate *drawable ); +extern void r200PageFlip( __DRIdrawablePrivate *drawable ); extern void r200Flush( GLcontext *ctx ); extern void r200Finish( GLcontext *ctx ); extern void r200WaitForIdleLocked( r200ContextPtr rmesa ); diff --git a/src/mesa/drivers/dri/r300/radeon_context.c b/src/mesa/drivers/dri/r300/radeon_context.c index 6dfaf3c..8316b74 100644 --- a/src/mesa/drivers/dri/r300/radeon_context.c +++ b/src/mesa/drivers/dri/r300/radeon_context.c @@ -127,6 +127,7 @@ GLboolean radeonInitContext(radeonContextPtr radeon, void *sharedContextPrivate) { __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + __DRIdrawablePrivate *dPriv = driContextPriv->driDrawablePriv; radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private); GLcontext* ctx; GLcontext* shareCtx; @@ -177,7 +178,7 @@ GLboolean radeonInitContext(radeonContextPtr radeon, radeon->do_usleeps ? "usleeps" : "busy waits", fthrottle_mode, radeon->radeonScreen->irq); - radeon->vblank_flags = (radeon->radeonScreen->irq != 0) + dPriv->vblFlags = (radeon->radeonScreen->irq != 0) ? driGetDefaultVBlankFlags(&radeon->optionCache) : VBLANK_FLAG_NO_IRQ; (*dri_interface->getUST) (&radeon->swap_ust); @@ -277,9 +278,7 @@ GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv, radeon->glCtx); if (radeon->dri.drawable != driDrawPriv) { - driDrawableInitVBlank(driDrawPriv, - radeon->vblank_flags, - &radeon->vbl_seq); + driDrawableInitVBlank(driDrawPriv); } radeon->dri.readable = driReadPriv; diff --git a/src/mesa/drivers/dri/r300/radeon_context.h b/src/mesa/drivers/dri/r300/radeon_context.h index 2f23941..38d8930 100644 --- a/src/mesa/drivers/dri/r300/radeon_context.h +++ b/src/mesa/drivers/dri/r300/radeon_context.h @@ -182,10 +182,7 @@ struct radeon_context { GLuint irqsEmitted; drm_radeon_irq_wait_t iw; - /* VBI / buffer swap */ - GLuint vbl_seq; - GLuint vblank_flags; - + /* buffer swap */ int64_t swap_ust; int64_t swap_missed_ust; diff --git a/src/mesa/drivers/dri/r300/radeon_ioctl.c b/src/mesa/drivers/dri/r300/radeon_ioctl.c index 0b8656b..eeef71a 100644 --- a/src/mesa/drivers/dri/r300/radeon_ioctl.c +++ b/src/mesa/drivers/dri/r300/radeon_ioctl.c @@ -157,7 +157,7 @@ static void radeonWaitForFrameCompletion(radeonContextPtr radeon) /* Copy the back color buffer to the front color buffer. */ -void radeonCopyBuffer(const __DRIdrawablePrivate * dPriv, +void radeonCopyBuffer(__DRIdrawablePrivate * dPriv, const drm_clip_rect_t * rect) { radeonContextPtr radeon; @@ -187,7 +187,7 @@ void radeonCopyBuffer(const __DRIdrawablePrivate * dPriv, if (!rect) { UNLOCK_HARDWARE(radeon); - driWaitForVBlank(dPriv, &radeon->vbl_seq, radeon->vblank_flags, + driWaitForVBlank(dPriv, &dPriv->vblSeq, dPriv->vblFlags, &missed_target); LOCK_HARDWARE(radeon); } @@ -253,7 +253,7 @@ void radeonCopyBuffer(const __DRIdrawablePrivate * dPriv, } } -void radeonPageFlip(const __DRIdrawablePrivate * dPriv) +void radeonPageFlip(__DRIdrawablePrivate * dPriv) { radeonContextPtr radeon; GLint ret; @@ -293,7 +293,7 @@ void radeonPageFlip(const __DRIdrawablePrivate * dPriv) */ radeonWaitForFrameCompletion(radeon); UNLOCK_HARDWARE(radeon); - driWaitForVBlank(dPriv, &radeon->vbl_seq, radeon->vblank_flags, + driWaitForVBlank(dPriv, &dPriv->vblSeq, dPriv->vblFlags, &missed_target); if (missed_target) { radeon->swap_missed_count++; diff --git a/src/mesa/drivers/dri/r300/radeon_ioctl.h b/src/mesa/drivers/dri/r300/radeon_ioctl.h index 3a80d36..210001e 100644 --- a/src/mesa/drivers/dri/r300/radeon_ioctl.h +++ b/src/mesa/drivers/dri/r300/radeon_ioctl.h @@ -46,9 +46,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #endif #include "radeon_drm.h" -extern void radeonCopyBuffer(const __DRIdrawablePrivate * drawable, +extern void radeonCopyBuffer(__DRIdrawablePrivate * drawable, const drm_clip_rect_t * rect); -extern void radeonPageFlip(const __DRIdrawablePrivate * drawable); +extern void radeonPageFlip(__DRIdrawablePrivate * drawable); extern void radeonFlush(GLcontext * ctx); extern void radeonFinish(GLcontext * ctx); extern void radeonWaitForIdleLocked(radeonContextPtr radeon); diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c index defc82f..fe6d3c2 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_context.c @@ -594,8 +594,7 @@ radeonMakeCurrent( __DRIcontextPrivate *driContextPriv, if ( newCtx->dri.drawable != driDrawPriv ) { /* XXX we may need to validate the drawable here!!! */ - driDrawableInitVBlank( driDrawPriv, newCtx->vblank_flags, - &newCtx->vbl_seq ); + driDrawableInitVBlank( driDrawPriv ); } newCtx->dri.readable = driReadPriv; diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index 10d3c2b..4cc87a9 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -961,6 +961,7 @@ static struct __DriverAPIRec radeonAPI = { .UnbindContext = radeonUnbindContext, .GetSwapInfo = getSwapInfo, .GetMSC = driGetMSC32, + .GetDrawableMSC = driDrawableGetMSC32, .WaitForMSC = driWaitForMSC32, .WaitForSBC = NULL, .SwapBuffersMSC = NULL, @@ -978,6 +979,7 @@ static const struct __DriverAPIRec r200API = { .UnbindContext = r200UnbindContext, .GetSwapInfo = getSwapInfo, .GetMSC = driGetMSC32, + .GetDrawableMSC = driDrawableGetMSC32, .WaitForMSC = driWaitForMSC32, .WaitForSBC = NULL, .SwapBuffersMSC = NULL, diff --git a/src/mesa/drivers/dri/sis/sis_screen.c b/src/mesa/drivers/dri/sis/sis_screen.c index 79682a7..6711935 100644 --- a/src/mesa/drivers/dri/sis/sis_screen.c +++ b/src/mesa/drivers/dri/sis/sis_screen.c @@ -314,6 +314,7 @@ static struct __DriverAPIRec sisAPI = { .UnbindContext = sisUnbindContext, .GetSwapInfo = NULL, .GetMSC = NULL, + .GetDrawableMSC = NULL, .WaitForMSC = NULL, .WaitForSBC = NULL, .SwapBuffersMSC = NULL diff --git a/src/mesa/drivers/dri/tdfx/tdfx_screen.c b/src/mesa/drivers/dri/tdfx/tdfx_screen.c index 5bdb446..6298de8 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_screen.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_screen.c @@ -355,6 +355,7 @@ static const struct __DriverAPIRec tdfxAPI = { .UnbindContext = tdfxUnbindContext, .GetSwapInfo = NULL, .GetMSC = NULL, + .GetDrawableMSC = NULL, .WaitForMSC = NULL, .WaitForSBC = NULL, .SwapBuffersMSC = NULL diff --git a/src/mesa/drivers/dri/unichrome/via_context.c b/src/mesa/drivers/dri/unichrome/via_context.c index 66e92cc..5d95d97 100644 --- a/src/mesa/drivers/dri/unichrome/via_context.c +++ b/src/mesa/drivers/dri/unichrome/via_context.c @@ -465,6 +465,7 @@ viaCreateContext(const __GLcontextModes *visual, GLcontext *ctx, *shareCtx; struct via_context *vmesa; __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + __DRIdrawablePrivate *dPriv = driContextPriv->driDrawablePriv; viaScreenPrivate *viaScreen = (viaScreenPrivate *)sPriv->private; drm_via_sarea_t *saPriv = (drm_via_sarea_t *) (((GLubyte *)sPriv->pSAREA) + viaScreen->sareaPrivOffset); @@ -658,7 +659,7 @@ viaCreateContext(const __GLcontextModes *visual, driQueryOptionb(&vmesa->optionCache, "no_rast")) FALLBACK(vmesa, VIA_FALLBACK_USER_DISABLE, 1); - vmesa->vblank_flags = + dPriv->vblFlags = vmesa->viaScreen->irqEnabled ? driGetDefaultVBlankFlags(&vmesa->optionCache) : VBLANK_FLAG_NO_IRQ; @@ -838,8 +839,7 @@ viaMakeCurrent(__DRIcontextPrivate *driContextPriv, readBuffer = (GLframebuffer *)driReadPriv->driverPrivate; if (vmesa->driDrawable != driDrawPriv) { - driDrawableInitVBlank(driDrawPriv, vmesa->vblank_flags, - &vmesa->vbl_seq); + driDrawableInitVBlank(driDrawPriv); } if ((vmesa->driDrawable != driDrawPriv) diff --git a/src/mesa/drivers/dri/unichrome/via_context.h b/src/mesa/drivers/dri/unichrome/via_context.h index 6321713..acd6f2e 100644 --- a/src/mesa/drivers/dri/unichrome/via_context.h +++ b/src/mesa/drivers/dri/unichrome/via_context.h @@ -321,9 +321,6 @@ struct via_context { */ driOptionCache optionCache; - GLuint vblank_flags; - GLuint vbl_seq; - int64_t swap_ust; int64_t swap_missed_ust; diff --git a/src/mesa/drivers/dri/unichrome/via_ioctl.c b/src/mesa/drivers/dri/unichrome/via_ioctl.c index 4a733fb..3c7dafd 100644 --- a/src/mesa/drivers/dri/unichrome/via_ioctl.c +++ b/src/mesa/drivers/dri/unichrome/via_ioctl.c @@ -507,7 +507,7 @@ void viaWaitIdleLocked( struct via_context *vmesa, GLboolean light ) * except that WAIT_IDLE() will spin the CPU polling, while this is * IRQ driven. */ -static void viaWaitIdleVBlank( const __DRIdrawablePrivate *dPriv, +static void viaWaitIdleVBlank( __DRIdrawablePrivate *dPriv, struct via_context *vmesa, GLuint value ) { @@ -523,8 +523,8 @@ static void viaWaitIdleVBlank( const __DRIdrawablePrivate *dPriv, vmesa->thrashing) viaSwapOutWork(vmesa); - driWaitForVBlank( dPriv, & vmesa->vbl_seq, - vmesa->vblank_flags, & missed_target ); + driWaitForVBlank( dPriv, & dPriv->vblSeq, dPriv->vblFlags, + & missed_target ); if ( missed_target ) { vmesa->swap_missed_count++; (*dri_interface->getUST)( &vmesa->swap_missed_ust ); @@ -591,7 +591,7 @@ void viaResetPageFlippingLocked(struct via_context *vmesa) /* * Copy the back buffer to the front buffer. */ -void viaCopyBuffer(const __DRIdrawablePrivate *dPriv) +void viaCopyBuffer(__DRIdrawablePrivate *dPriv) { struct via_context *vmesa = (struct via_context *)dPriv->driContextPriv->driverPrivate; @@ -607,7 +607,7 @@ void viaCopyBuffer(const __DRIdrawablePrivate *dPriv) VIA_FLUSH_DMA(vmesa); - if (vmesa->vblank_flags == VBLANK_FLAG_SYNC && + if (dPriv->vblFlags == VBLANK_FLAG_SYNC && vmesa->lastBreadcrumbWrite > 1) viaWaitIdleVBlank(dPriv, vmesa, vmesa->lastBreadcrumbWrite-1); else @@ -634,14 +634,14 @@ void viaCopyBuffer(const __DRIdrawablePrivate *dPriv) } -void viaPageFlip(const __DRIdrawablePrivate *dPriv) +void viaPageFlip(__DRIdrawablePrivate *dPriv) { struct via_context *vmesa = (struct via_context *)dPriv->driContextPriv->driverPrivate; struct via_renderbuffer buffer_tmp; VIA_FLUSH_DMA(vmesa); - if (vmesa->vblank_flags == VBLANK_FLAG_SYNC && + if (dPriv->vblFlags == VBLANK_FLAG_SYNC && vmesa->lastBreadcrumbWrite > 1) viaWaitIdleVBlank(dPriv, vmesa, vmesa->lastBreadcrumbWrite - 1); else diff --git a/src/mesa/drivers/dri/unichrome/via_ioctl.h b/src/mesa/drivers/dri/unichrome/via_ioctl.h index a81b427..44fc439 100644 --- a/src/mesa/drivers/dri/unichrome/via_ioctl.h +++ b/src/mesa/drivers/dri/unichrome/via_ioctl.h @@ -33,8 +33,8 @@ void viaFlushDma(struct via_context *vmesa); void viaFlushDmaLocked(struct via_context *vmesa, GLuint flags); void viaInitIoctlFuncs(GLcontext *ctx); -void viaCopyBuffer(const __DRIdrawablePrivate *dpriv); -void viaPageFlip(const __DRIdrawablePrivate *dpriv); +void viaCopyBuffer(__DRIdrawablePrivate *dpriv); +void viaPageFlip(__DRIdrawablePrivate *dpriv); void viaCheckDma(struct via_context *vmesa, GLuint bytes); void viaResetPageFlippingLocked(struct via_context *vmesa); void viaWaitIdle(struct via_context *vmesa, GLboolean light); diff --git a/src/mesa/drivers/dri/unichrome/via_screen.c b/src/mesa/drivers/dri/unichrome/via_screen.c index f3912ac..0ad18b4 100644 --- a/src/mesa/drivers/dri/unichrome/via_screen.c +++ b/src/mesa/drivers/dri/unichrome/via_screen.c @@ -334,6 +334,7 @@ static struct __DriverAPIRec viaAPI = { .UnbindContext = viaUnbindContext, .GetSwapInfo = getSwapInfo, .GetMSC = driGetMSC32, + .GetDrawableMSC = driDrawableGetMSC32, .WaitForMSC = driWaitForMSC32, .WaitForSBC = NULL, .SwapBuffersMSC = NULL