diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h index 539d28d..a1b2a1d 100644 --- a/src/mesa/drivers/dri/common/dri_util.h +++ b/src/mesa/drivers/dri/common/dri_util.h @@ -468,6 +468,15 @@ struct __DRIscreenPrivateRec { /*@}*/ /** + * \name Vertical blank tracking information + * Used for waiting on vertical blank events. + */ + /*@{*/ + unsigned int vblSeq; + unsigned int vblFlags; + /*@}*/ + + /** * \name Device-dependent private information (stored in the SAREA). * * This data is accessed by the client driver only. diff --git a/src/mesa/drivers/dri/common/vblank.c b/src/mesa/drivers/dri/common/vblank.c index e7ed545..307c957 100644 --- a/src/mesa/drivers/dri/common/vblank.c +++ b/src/mesa/drivers/dri/common/vblank.c @@ -63,6 +63,8 @@ int driGetMSC32( __DRIscreenPrivate * priv, int64_t * count ) vbl.request.type = DRM_VBLANK_RELATIVE; vbl.request.sequence = 0; + if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) + vbl.request.type |= DRM_VBLANK_SECONDARY; ret = drmWaitVBlank( priv->fd, &vbl ); *count = (int64_t)vbl.reply.sequence; @@ -124,6 +126,8 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv, vbl.request.type = dont_wait ? DRM_VBLANK_RELATIVE : DRM_VBLANK_ABSOLUTE; vbl.request.sequence = next; + if ( priv->driScreenPriv->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. @@ -257,7 +261,13 @@ void driDrawableInitVBlank( __DRIdrawablePrivate *priv, GLuint flags, { if ( priv->pdraw->swap_interval == (unsigned)-1 ) { /* Get current vertical blank sequence */ - drmVBlank vbl = { .request={ .type = DRM_VBLANK_RELATIVE, .sequence = 0 } }; + drmVBlank vbl; + + vbl.request.type = DRM_VBLANK_RELATIVE; + if ( flags & VBLANK_FLAG_SECONDARY ) { + vbl.request.type |= DRM_VBLANK_SECONDARY; + } + vbl.request.sequence = 0; do_wait( &vbl, vbl_seq, priv->driScreenPriv->fd ); priv->pdraw->swap_interval = (flags & (VBLANK_FLAG_THROTTLE | diff --git a/src/mesa/drivers/dri/i965/intel_blit.c b/src/mesa/drivers/dri/i965/intel_blit.c index f88cbb2..96689c2 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->driScreenPriv->vblSeq, + dPriv->driScreenPriv->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 d155c03..a2e2128 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, @@ -172,6 +174,7 @@ static void intelSetBackClipRects( struct intel_context *intel ) void intelWindowMoved( struct intel_context *intel ) { __DRIdrawablePrivate *dPriv = intel->driDrawable; + __DRIscreenPrivate *sPriv = intel->driScreen; if (!intel->ctx.DrawBuffer) { intelSetFrontClipRects( intel ); @@ -190,6 +193,46 @@ void intelWindowMoved( struct intel_context *intel ) } } + /* Get updated plane info so we sync against the right vblank counter */ + if (intel->intelScreen->driScrnPriv->ddxMinor >= 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 = sPriv->vblFlags; + + /* Update vblank info + */ + if (areaB > areaA || (areaA == areaB && areaB > 0)) { + flags = sPriv->vblFlags | VBLANK_FLAG_SECONDARY; + } else { + flags = sPriv->vblFlags & ~VBLANK_FLAG_SECONDARY; + } + + if (flags != sPriv->vblFlags && sPriv->vblFlags && + !(sPriv->vblFlags & VBLANK_FLAG_NO_IRQ)) { + drmVBlank vbl; + + vbl.request.type = DRM_VBLANK_ABSOLUTE; + + if ( sPriv->vblFlags & VBLANK_FLAG_SECONDARY ) { + vbl.request.type |= DRM_VBLANK_SECONDARY; + } + + sPriv->vblFlags = flags; + driGetCurrentVBlank(dPriv, sPriv->vblFlags, &sPriv->vblSeq); + } + } else { + sPriv->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 1fbf571..7da3147 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -328,8 +328,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); + drmI830Sarea *saPriv = (drmI830Sarea *) + (((GLubyte *)sPriv->pSAREA)+intelScreen->sarea_priv_offset); if (!_mesa_initialize_context(&intel->ctx, mesaVis, shareCtx, @@ -347,8 +347,8 @@ 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; + sPriv->vblFlags = (intel->intelScreen->irq_active != 0) + ? driGetDefaultVBlankFlags(&intel->optionCache) : VBLANK_FLAG_NO_IRQ; ctx->Const.MaxTextureMaxAnisotropy = 2.0; @@ -582,8 +582,9 @@ GLboolean intelMakeCurrent(__DRIcontextPrivate *driContextPriv, if ( intel->driDrawable != driDrawPriv ) { /* Shouldn't the readbuffer be stored also? */ - driDrawableInitVBlank( driDrawPriv, intel->vblank_flags, - &intel->vbl_seq ); + driDrawableInitVBlank( driDrawPriv, + intel->driDrawable->driScreenPriv->vblFlags, + &intel->driDrawable->driScreenPriv->vblSeq); intel->driDrawable = driDrawPriv; intelWindowMoved( intel ); diff --git a/src/mesa/drivers/dri/i965/intel_context.h b/src/mesa/drivers/dri/i965/intel_context.h index 053d93a..26d6923 100644 --- a/src/mesa/drivers/dri/i965/intel_context.h +++ b/src/mesa/drivers/dri/i965/intel_context.h @@ -237,7 +237,7 @@ struct intel_context __DRIdrawablePrivate *driReadDrawable; __DRIscreenPrivate *driScreen; intelScreenPrivate *intelScreen; - volatile drmI830Sarea *sarea; + drmI830Sarea *sarea; FILE *aub_file; @@ -248,11 +248,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/server/i830_common.h b/src/mesa/drivers/dri/i965/server/i830_common.h index f320378..452c400 100644 --- a/src/mesa/drivers/dri/i965/server/i830_common.h +++ b/src/mesa/drivers/dri/i965/server/i830_common.h @@ -119,6 +119,15 @@ typedef struct { unsigned int depth_tiled; unsigned int rotated_tiled; unsigned int rotated2_tiled; + + int planeA_x; + int planeA_y; + int planeA_w; + int planeA_h; + int planeB_x; + int planeB_y; + int planeB_w; + int planeB_h; } drmI830Sarea; /* Flags for perf_boxes