From af64dd2ae0aa31261002335f10d46492000f552b Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Fri, 2 Feb 2007 17:10:25 +0100 Subject: i915tex: Make page flipping work again. --- src/mesa/drivers/dri/i915tex/intel_blit.c | 40 +++++++++++----------- src/mesa/drivers/dri/i915tex/intel_buffers.c | 50 ++++++++++++++++------------ src/mesa/drivers/dri/i915tex/intel_context.c | 14 +++++++- src/mesa/drivers/dri/i915tex/intel_context.h | 4 +++ src/mesa/drivers/dri/i915tex/intel_fbo.c | 19 +++++++++-- src/mesa/drivers/dri/i915tex/intel_reg.h | 3 ++ src/mesa/drivers/dri/i915tex/intel_tris.c | 10 ++++++ 7 files changed, 94 insertions(+), 46 deletions(-) diff --git a/src/mesa/drivers/dri/i915tex/intel_blit.c b/src/mesa/drivers/dri/i915tex/intel_blit.c index 550669ab0c8..c08c45a9366 100644 --- a/src/mesa/drivers/dri/i915tex/intel_blit.c +++ b/src/mesa/drivers/dri/i915tex/intel_blit.c @@ -453,16 +453,6 @@ intelClearWithBlit(GLcontext * ctx, GLbitfield mask) clear.y1 = intel->driDrawable->y + intel->driDrawable->h - cy - ch; clear.x2 = clear.x1 + cw; clear.y2 = clear.y1 + ch; - - /* adjust for page flipping */ - if (intel->sarea->pf_current_page == 1) { - const GLuint tmp = mask; - mask &= ~(BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT); - if (tmp & BUFFER_BIT_FRONT_LEFT) - mask |= BUFFER_BIT_BACK_LEFT; - if (tmp & BUFFER_BIT_BACK_LEFT) - mask |= BUFFER_BIT_FRONT_LEFT; - } } else { /* clearing FBO */ @@ -499,11 +489,10 @@ intelClearWithBlit(GLcontext * ctx, GLbitfield mask) const GLbitfield bufBit = 1 << buf; if ((clearMask & bufBit) && !(bufBit & skipBuffers)) { /* OK, clear this renderbuffer */ - const struct intel_renderbuffer *irb - = intel_renderbuffer(ctx->DrawBuffer-> - Attachment[buf].Renderbuffer); + struct intel_region *irb_region = + intel_get_rb_region(ctx->DrawBuffer, buf); struct _DriBufferObject *write_buffer = - intel_region_buffer(intel->intelScreen, irb->region, + intel_region_buffer(intel->intelScreen, irb_region, all ? INTEL_WRITE_FULL : INTEL_WRITE_PART); @@ -511,16 +500,15 @@ intelClearWithBlit(GLcontext * ctx, GLbitfield mask) GLint pitch, cpp; GLuint BR13, CMD; - ASSERT(irb); - ASSERT(irb->region); + ASSERT(irb_region); - pitch = irb->region->pitch; - cpp = irb->region->cpp; + pitch = irb_region->pitch; + cpp = irb_region->cpp; DBG("%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n", __FUNCTION__, - irb->region->buffer, (pitch * cpp), - irb->region->draw_offset, + irb_region->buffer, (pitch * cpp), + irb_region->draw_offset, b.x1, b.y1, b.x2 - b.x1, b.y2 - b.y1); @@ -558,6 +546,16 @@ intelClearWithBlit(GLcontext * ctx, GLbitfield mask) _mesa_debug(ctx, "hardware blit clear buf %d rb id %d\n", buf, irb->Base.Name); */ + if (intel->flip_pending) { + /* Wait for a pending flip to take effect */ + BEGIN_BATCH(2, INTEL_BATCH_NO_CLIPRECTS); + OUT_BATCH(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP); + OUT_BATCH(0); + ADVANCE_BATCH(); + + intel->flip_pending = GL_FALSE; + } + BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS); OUT_BATCH(CMD); OUT_BATCH(BR13); @@ -565,7 +563,7 @@ intelClearWithBlit(GLcontext * ctx, GLbitfield mask) OUT_BATCH((b.y2 << 16) | b.x2); OUT_RELOC(write_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, - irb->region->draw_offset); + irb_region->draw_offset); OUT_BATCH(clearVal); ADVANCE_BATCH(); clearMask &= ~bufBit; /* turn off bit, for faster loop exit */ diff --git a/src/mesa/drivers/dri/i915tex/intel_buffers.c b/src/mesa/drivers/dri/i915tex/intel_buffers.c index 1ded0b5417f..a8fb0b14a1c 100644 --- a/src/mesa/drivers/dri/i915tex/intel_buffers.c +++ b/src/mesa/drivers/dri/i915tex/intel_buffers.c @@ -159,7 +159,7 @@ intelSetBackClipRects(struct intel_context *intel) if (!dPriv) return; - if (intel->sarea->pf_enabled == 0 && dPriv->numBackClipRects == 0) { + if (intel->sarea->pf_active || dPriv->numBackClipRects == 0) { /* use the front clip rects */ intel->numClipRects = dPriv->numClipRects; intel->pClipRects = dPriv->pClipRects; @@ -421,7 +421,8 @@ intelRotateWindow(struct intel_context *intel, intel->vtbl.meta_draw_region(intel, screen->rotated_region, NULL); /* ? */ - if (srcBuf == BUFFER_BIT_FRONT_LEFT) { + if ((srcBuf == BUFFER_BIT_BACK_LEFT && intel->sarea->pf_current_page) || + (srcBuf == BUFFER_BIT_FRONT_LEFT && !intel->sarea->pf_current_page)) { src = intel->intelScreen->front_region; clipRects = dPriv->pClipRects; numClipRects = dPriv->numClipRects; @@ -592,9 +593,9 @@ intelClear(GLcontext *ctx, GLbitfield mask) static void intelPageFlip(const __DRIdrawablePrivate * dPriv) { -#if 0 struct intel_context *intel; - int tmp, ret; + GLboolean missed_target; + int ret; if (INTEL_DEBUG & DEBUG_IOCTL) fprintf(stderr, "%s\n", __FUNCTION__); @@ -606,27 +607,36 @@ intelPageFlip(const __DRIdrawablePrivate * dPriv) intel = (struct intel_context *) dPriv->driContextPriv->driverPrivate; intelFlush(&intel->ctx); - LOCK_HARDWARE(intel); - if (dPriv->pClipRects) { - *(drm_clip_rect_t *) intel->sarea->boxes = dPriv->pClipRects[0]; - intel->sarea->nbox = 1; + driWaitForVBlank(dPriv, &intel->vbl_seq, intel->vblank_flags, &missed_target); + + if (missed_target) { + intel->swap_missed_count++; + (void)(*dri_interface->getUST) (&intel->swap_missed_ust); } - ret = drmCommandNone(intel->driFd, DRM_I830_FLIP); - if (ret) { - fprintf(stderr, "%s: %d\n", __FUNCTION__, ret); + LOCK_HARDWARE(intel); + + if (!dPriv->numClipRects) { UNLOCK_HARDWARE(intel); - exit(1); + usleep(10000); /* throttle invisible client 10ms */ + return; } - tmp = intel->sarea->last_enqueue; - intelRefillBatchLocked(intel); + ret = drmCommandNone(intel->driFd, DRM_I830_FLIP); UNLOCK_HARDWARE(intel); + if (ret) { + _mesa_error(&intel->ctx, GL_INVALID_OPERATION, "DRM_I830_FLIP: %d\n", + ret); + return; + } - intelSetDrawBuffer(&intel->ctx, intel->ctx.Color.DriverDrawBuffer); -#endif + driFlipRenderbuffers(intel->ctx.WinSysDrawBuffer, + intel->sarea->pf_current_page); + intel_draw_buffer(&intel->ctx, intel->ctx.DrawBuffer); + + intel->flip_pending = GL_TRUE; } #if 0 @@ -641,7 +651,7 @@ intelSwapBuffers(__DRIdrawablePrivate * dPriv) if (ctx && ctx->DrawBuffer == fb) { _mesa_notifySwapBuffers(ctx); /* flush pending rendering */ } - if (0 /*intel->doPageFlip */ ) { /* doPageFlip is never set !!! */ + if (intel->doPageFlip) { intelPageFlip(dPriv); } else { @@ -672,7 +682,7 @@ intelSwapBuffers(__DRIdrawablePrivate * dPriv) if (ctx->Visual.doubleBufferMode) { intelScreenPrivate *screen = intel->intelScreen; _mesa_notifySwapBuffers(ctx); /* flush pending rendering comands */ - if (0 /*intel->doPageFlip */ ) { /* doPageFlip is never set !!! */ + if (screen->current_rotation == 0 && intel->doPageFlip) { intelPageFlip(dPriv); } else { @@ -788,10 +798,6 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb) */ if (fb->Name == 0) { /* drawing to window system buffer */ - if (intel->sarea->pf_current_page == 1) { - /* page flipped back/front */ - front ^= 1; - } if (front) { intelSetFrontClipRects(intel); colorRegion = intel_get_rb_region(fb, BUFFER_FRONT_LEFT); diff --git a/src/mesa/drivers/dri/i915tex/intel_context.c b/src/mesa/drivers/dri/i915tex/intel_context.c index a5ce08b1701..7eb209cf5f4 100644 --- a/src/mesa/drivers/dri/i915tex/intel_context.c +++ b/src/mesa/drivers/dri/i915tex/intel_context.c @@ -59,6 +59,7 @@ #include "intel_buffer_objects.h" #include "intel_fbo.h" +#include "drirenderbuffer.h" #include "vblank.h" #include "utils.h" #include "xmlpool.h" /* for symbolic values of enum-type options */ @@ -683,13 +684,24 @@ intelContendedLock(struct intel_context *intel, GLuint flags) intel->current_rotation = sarea->rotation; } - /* Drawable changed? */ if (dPriv && intel->lastStamp != dPriv->lastStamp) { intelWindowMoved(intel); intel->lastStamp = dPriv->lastStamp; } + + /* Update page flipping info + */ + if (INTEL_DEBUG & DEBUG_LOCK) + if (intel->doPageFlip != intel->sarea->pf_active) + _mesa_printf("%s - age flipping %sactive\n", __progname, + intel->sarea->pf_active ? "" : "in"); + + intel->doPageFlip = intel->sarea->pf_active; + driFlipRenderbuffers(intel->ctx.WinSysDrawBuffer, + intel->sarea->pf_current_page); + intel_draw_buffer(&intel->ctx, intel->ctx.DrawBuffer); } diff --git a/src/mesa/drivers/dri/i915tex/intel_context.h b/src/mesa/drivers/dri/i915tex/intel_context.h index 96b911501f3..321a945c050 100644 --- a/src/mesa/drivers/dri/i915tex/intel_context.h +++ b/src/mesa/drivers/dri/i915tex/intel_context.h @@ -295,6 +295,10 @@ struct intel_context int height; int current_rotation; + /* Page flipping + */ + GLboolean doPageFlip; + GLboolean flip_pending; }; /* These are functions now: diff --git a/src/mesa/drivers/dri/i915tex/intel_fbo.c b/src/mesa/drivers/dri/i915tex/intel_fbo.c index ab0e569bd94..b739e22cca7 100644 --- a/src/mesa/drivers/dri/i915tex/intel_fbo.c +++ b/src/mesa/drivers/dri/i915tex/intel_fbo.c @@ -78,8 +78,23 @@ intel_get_renderbuffer(struct gl_framebuffer *fb, GLuint attIndex) struct intel_region * intel_get_rb_region(struct gl_framebuffer *fb, GLuint attIndex) { - struct intel_renderbuffer *irb - = intel_renderbuffer(fb->Attachment[attIndex].Renderbuffer); + GET_CURRENT_CONTEXT(ctx); + struct intel_context *intel = intel_context(ctx); + struct intel_renderbuffer *irb; + + if (intel->sarea->pf_current_page) { + switch (attIndex) { + case BUFFER_BACK_LEFT: + attIndex = BUFFER_FRONT_LEFT; + break; + case BUFFER_FRONT_LEFT: + attIndex = BUFFER_BACK_LEFT; + break; + } + } + + irb = intel_renderbuffer(fb->Attachment[attIndex].Renderbuffer); + if (irb) return irb->region; else diff --git a/src/mesa/drivers/dri/i915tex/intel_reg.h b/src/mesa/drivers/dri/i915tex/intel_reg.h index 1ec153266c7..126d2ea7ffa 100644 --- a/src/mesa/drivers/dri/i915tex/intel_reg.h +++ b/src/mesa/drivers/dri/i915tex/intel_reg.h @@ -81,4 +81,7 @@ #define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) #define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) +#define MI_WAIT_FOR_EVENT ((0x3<<23)) +#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) + #endif diff --git a/src/mesa/drivers/dri/i915tex/intel_tris.c b/src/mesa/drivers/dri/i915tex/intel_tris.c index 1ba49d8f6ec..4e0ca70c1ec 100644 --- a/src/mesa/drivers/dri/i915tex/intel_tris.c +++ b/src/mesa/drivers/dri/i915tex/intel_tris.c @@ -102,6 +102,16 @@ intelStartInlinePrimitive(struct intel_context *intel, /* _mesa_printf("%s *", __progname); */ + if (intel->flip_pending) { + /* Wait for a pending flip to take effect */ + BEGIN_BATCH(2, batch_flags); + OUT_BATCH(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP); + OUT_BATCH(0); + ADVANCE_BATCH(); + + intel->flip_pending = GL_FALSE; + } + /* Emit a slot which will be filled with the inline primitive * command later. */ -- cgit v1.2.3