From: Michel Dänzer Date: Thu, 15 Feb 2007 15:30:40 +0000 (+0100) Subject: i915tex: Support page flipping on both CRTCs independently. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6b99cafd69a791d03ce749d0fd2b9f59ca265677;p=mesa.git i915tex: Support page flipping on both CRTCs independently. No longer track page flipping state per context but per window, via struct intel_framebuffer which wraps struct gl_framebuffer for windows. --- diff --git a/src/mesa/drivers/dri/i915tex/intel_blit.c b/src/mesa/drivers/dri/i915tex/intel_blit.c index c08c45a9366..e33d2830764 100644 --- a/src/mesa/drivers/dri/i915tex/intel_blit.c +++ b/src/mesa/drivers/dri/i915tex/intel_blit.c @@ -123,14 +123,13 @@ noschedule: */ LOCK_HARDWARE(intel); - if (intel->driDrawable && intel->driDrawable->numClipRects) { + if (dPriv && dPriv->numClipRects) { const intelScreenPrivate *intelScreen = intel->intelScreen; - struct gl_framebuffer *fb - = (struct gl_framebuffer *) dPriv->driverPrivate; + struct intel_framebuffer *intel_fb = dPriv->driverPrivate; const struct intel_region *frontRegion - = intel_get_rb_region(fb, BUFFER_FRONT_LEFT); + = intel_get_rb_region(&intel_fb->Base, BUFFER_FRONT_LEFT); const struct intel_region *backRegion - = intel_get_rb_region(fb, BUFFER_BACK_LEFT); + = intel_get_rb_region(&intel_fb->Base, BUFFER_BACK_LEFT); const int nbox = dPriv->numClipRects; const drm_clip_rect_t *pbox = dPriv->pClipRects; const int pitch = frontRegion->pitch; @@ -138,8 +137,8 @@ noschedule: int BR13, CMD; int i; - ASSERT(fb); - ASSERT(fb->Name == 0); /* Not a user-created FBO */ + ASSERT(intel_fb); + ASSERT(intel_fb->Base.Name == 0); /* Not a user-created FBO */ ASSERT(frontRegion); ASSERT(backRegion); ASSERT(frontRegion->pitch == backRegion->pitch); @@ -185,7 +184,7 @@ noschedule: OUT_BATCH((pbox->y1 << 16) | pbox->x1); OUT_BATCH((pbox->y2 << 16) | pbox->x2); - if (intel->sarea->pf_current_page == 0) + if (intel_fb->pf_current_page == 0) OUT_RELOC(frontRegion->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0); @@ -196,7 +195,7 @@ noschedule: OUT_BATCH((pbox->y1 << 16) | pbox->x1); OUT_BATCH(BR13 & 0xffff); - if (intel->sarea->pf_current_page == 0) + if (intel_fb->pf_current_page == 0) OUT_RELOC(backRegion->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0); @@ -406,6 +405,7 @@ void intelClearWithBlit(GLcontext * ctx, GLbitfield mask) { struct intel_context *intel = intel_context(ctx); + struct gl_framebuffer *fb = ctx->DrawBuffer; GLuint clear_depth; GLbitfield skipBuffers = 0; BATCH_LOCALS; @@ -417,7 +417,7 @@ intelClearWithBlit(GLcontext * ctx, GLbitfield mask) */ clear_depth = 0; if (mask & BUFFER_BIT_DEPTH) { - clear_depth = (GLuint) (ctx->DrawBuffer->_DepthMax * ctx->Depth.Clear); + clear_depth = (GLuint) (fb->_DepthMax * ctx->Depth.Clear); } if (mask & BUFFER_BIT_STENCIL) { clear_depth |= (ctx->Stencil.Clear & 0xff) << 24; @@ -440,12 +440,12 @@ intelClearWithBlit(GLcontext * ctx, GLbitfield mask) int i; /* Get clear bounds after locking */ - cx = ctx->DrawBuffer->_Xmin; - cy = ctx->DrawBuffer->_Ymin; - cw = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; - ch = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; + cx = fb->_Xmin; + cy = fb->_Ymin; + cw = fb->_Xmax - cx; + ch = fb->_Ymax - cy; - if (intel->ctx.DrawBuffer->Name == 0) { + if (fb->Name == 0) { /* clearing a window */ /* flip top to bottom */ @@ -470,8 +470,7 @@ intelClearWithBlit(GLcontext * ctx, GLbitfield mask) drm_clip_rect_t b; GLuint buf; GLuint clearMask = mask; /* use copy, since we modify it below */ - GLboolean all = (cw == ctx->DrawBuffer->Width && - ch == ctx->DrawBuffer->Height); + GLboolean all = (cw == fb->Width && ch == fb->Height); if (!all) { intel_intersect_cliprects(&b, &clear, box); @@ -490,7 +489,7 @@ intelClearWithBlit(GLcontext * ctx, GLbitfield mask) if ((clearMask & bufBit) && !(bufBit & skipBuffers)) { /* OK, clear this renderbuffer */ struct intel_region *irb_region = - intel_get_rb_region(ctx->DrawBuffer, buf); + intel_get_rb_region(fb, buf); struct _DriBufferObject *write_buffer = intel_region_buffer(intel->intelScreen, irb_region, all ? INTEL_WRITE_FULL : @@ -546,15 +545,7 @@ 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; - } + intel_wait_flips(intel, INTEL_BATCH_NO_CLIPRECTS); BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS); OUT_BATCH(CMD); diff --git a/src/mesa/drivers/dri/i915tex/intel_buffers.c b/src/mesa/drivers/dri/i915tex/intel_buffers.c index a8fb0b14a1c..fdb6ea94441 100644 --- a/src/mesa/drivers/dri/i915tex/intel_buffers.c +++ b/src/mesa/drivers/dri/i915tex/intel_buffers.c @@ -34,6 +34,7 @@ #include "intel_tris.h" #include "intel_regions.h" #include "intel_batchbuffer.h" +#include "intel_reg.h" #include "context.h" #include "utils.h" #include "drirenderbuffer.h" @@ -155,11 +156,14 @@ static void intelSetBackClipRects(struct intel_context *intel) { __DRIdrawablePrivate *dPriv = intel->driDrawable; + struct intel_framebuffer *intel_fb; if (!dPriv) return; - if (intel->sarea->pf_active || dPriv->numBackClipRects == 0) { + intel_fb = dPriv->driverPrivate; + + if (intel_fb->pf_active || dPriv->numBackClipRects == 0) { /* use the front clip rects */ intel->numClipRects = dPriv->numClipRects; intel->pClipRects = dPriv->pClipRects; @@ -185,7 +189,7 @@ intelWindowMoved(struct intel_context *intel) { GLcontext *ctx = &intel->ctx; __DRIdrawablePrivate *dPriv = intel->driDrawable; - GLframebuffer *drawFb = (GLframebuffer *) dPriv->driverPrivate; + struct intel_framebuffer *intel_fb = dPriv->driverPrivate; if (!intel->ctx.DrawBuffer) { /* when would this happen? -BP */ @@ -197,7 +201,7 @@ intelWindowMoved(struct intel_context *intel) } else { /* drawing to a window */ - switch (drawFb->_ColorDrawBufferMask[0]) { + switch (intel_fb->Base._ColorDrawBufferMask[0]) { case BUFFER_BIT_FRONT_LEFT: intelSetFrontClipRects(intel); break; @@ -212,7 +216,7 @@ intelWindowMoved(struct intel_context *intel) /* Update Mesa's notion of window size */ driUpdateFramebufferSize(ctx, dPriv); - drawFb->Initialized = GL_TRUE; /* XXX remove someday */ + intel_fb->Base.Initialized = GL_TRUE; /* XXX remove someday */ if (intel->intelScreen->driScrnPriv->ddxMinor >= 7) { drmI830Sarea *sarea = intel->sarea; @@ -227,7 +231,50 @@ intelWindowMoved(struct intel_context *intel) GLint areaA = driIntersectArea( drw_rect, pipeA_rect ); GLint areaB = driIntersectArea( drw_rect, pipeB_rect ); GLuint flags = intel->vblank_flags; + GLboolean pf_active; + GLint pf_pipes; + + /* Update page flipping info + */ + pf_pipes = 0; + + if (areaA > 0) + pf_pipes |= 1; + + if (areaB > 0) + pf_pipes |= 2; + + intel_fb->pf_current_page = (intel->sarea->pf_current_page >> + (intel_fb->pf_pipes & 0x2)) & 0x3; + + pf_active = (pf_pipes & intel->sarea->pf_active) == pf_pipes; + + if (1 /*INTEL_DEBUG & DEBUG_LOCK*/) + if (pf_active != intel_fb->pf_active) + _mesa_printf("%s - Page flipping %sactive\n", __progname, + pf_active ? "" : "in"); + + if (pf_active) { + if (pf_pipes != intel_fb->pf_pipes && intel_fb->pf_pipes == 0x3 && + (intel->sarea->pf_current_page & 0x3) != + ((intel->sarea->pf_current_page) >> 2 & 0x3)) { + drm_i915_flip_t flip; + + flip.pipes = (intel_fb->pf_current_page == + (intel->sarea->pf_current_page & 0x3)) ? 0x2 : 0x1; + + drmCommandWrite(intel->driFd, DRM_I915_FLIP, &flip, sizeof(flip)); + } + + intel_fb->pf_pipes = pf_pipes; + } + + intel_fb->pf_active = pf_active; + driFlipRenderbuffers(intel->ctx.WinSysDrawBuffer, intel_fb->pf_current_page); + intel_draw_buffer(&intel->ctx, intel->ctx.DrawBuffer); + /* Update vblank info + */ if (areaB > areaA || (areaA == areaB && areaB > 0)) { flags = intel->vblank_flags | VBLANK_FLAG_SECONDARY; } else { @@ -259,6 +306,7 @@ static void intelClearWithTris(struct intel_context *intel, GLbitfield mask) { GLcontext *ctx = &intel->ctx; + struct gl_framebuffer *fb = ctx->DrawBuffer; drm_clip_rect_t clear; if (INTEL_DEBUG & DEBUG_BLIT) @@ -274,10 +322,10 @@ intelClearWithTris(struct intel_context *intel, GLbitfield mask) intel->vtbl.install_meta_state(intel); /* Get clear bounds after locking */ - cx = ctx->DrawBuffer->_Xmin; - cy = ctx->DrawBuffer->_Ymin; - ch = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; - cw = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; + cx = fb->_Xmin; + cy = fb->_Ymin; + ch = fb->_Ymax - cx; + cw = fb->_Xmax - cy; /* note: regardless of 'all', cx, cy, cw, ch are now correct */ clear.x1 = cx; @@ -291,9 +339,9 @@ intelClearWithTris(struct intel_context *intel, GLbitfield mask) if (mask & (BUFFER_BIT_BACK_LEFT | BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH)) { struct intel_region *backRegion = - intel_get_rb_region(ctx->DrawBuffer, BUFFER_BACK_LEFT); + intel_get_rb_region(fb, BUFFER_BACK_LEFT); struct intel_region *depthRegion = - intel_get_rb_region(ctx->DrawBuffer, BUFFER_DEPTH); + intel_get_rb_region(fb, BUFFER_DEPTH); const GLuint clearColor = (backRegion && backRegion->cpp == 4) ? intel->ClearColor8888 : intel->ClearColor565; @@ -330,8 +378,7 @@ intelClearWithTris(struct intel_context *intel, GLbitfield mask) const GLuint bufBit = 1 << buf; if (mask & bufBit) { struct intel_renderbuffer *irbColor = - intel_renderbuffer(ctx->DrawBuffer-> - Attachment[buf].Renderbuffer); + intel_renderbuffer(fb->Attachment[buf].Renderbuffer); GLuint color = (irbColor->region->cpp == 4) ? intel->ClearColor8888 : intel->ClearColor565; @@ -372,6 +419,7 @@ intelRotateWindow(struct intel_context *intel, { intelScreenPrivate *screen = intel->intelScreen; drm_clip_rect_t fullRect; + struct intel_framebuffer *intel_fb; struct intel_region *src; const drm_clip_rect_t *clipRects; int numClipRects; @@ -421,8 +469,10 @@ intelRotateWindow(struct intel_context *intel, intel->vtbl.meta_draw_region(intel, screen->rotated_region, NULL); /* ? */ - if ((srcBuf == BUFFER_BIT_BACK_LEFT && intel->sarea->pf_current_page) || - (srcBuf == BUFFER_BIT_FRONT_LEFT && !intel->sarea->pf_current_page)) { + intel_fb = dPriv->driverPrivate; + + if ((srcBuf == BUFFER_BIT_BACK_LEFT && intel_fb->pf_current_page) || + (srcBuf == BUFFER_BIT_FRONT_LEFT && !intel_fb->pf_current_page)) { src = intel->intelScreen->front_region; clipRects = dPriv->pClipRects; numClipRects = dPriv->numClipRects; @@ -517,6 +567,7 @@ intelClear(GLcontext *ctx, GLbitfield mask) GLbitfield tri_mask = 0; GLbitfield blit_mask = 0; GLbitfield swrast_mask = 0; + struct gl_framebuffer *fb = ctx->DrawBuffer; GLuint i; if (0) @@ -536,7 +587,7 @@ intelClear(GLcontext *ctx, GLbitfield mask) /* HW stencil */ if (mask & BUFFER_BIT_STENCIL) { const struct intel_region *stencilRegion - = intel_get_rb_region(ctx->DrawBuffer, BUFFER_STENCIL); + = intel_get_rb_region(fb, BUFFER_STENCIL); if (stencilRegion) { /* have hw stencil */ if ((ctx->Stencil.WriteMask[0] & 0xff) != 0xff) { @@ -565,7 +616,7 @@ intelClear(GLcontext *ctx, GLbitfield mask) for (i = 0; i < BUFFER_COUNT; i++) { GLuint bufBit = 1 << i; if ((blit_mask | tri_mask) & bufBit) { - if (!ctx->DrawBuffer->Attachment[i].Renderbuffer->ClassID) { + if (!fb->Attachment[i].Renderbuffer->ClassID) { blit_mask &= ~bufBit; tri_mask &= ~bufBit; swrast_mask |= bufBit; @@ -587,15 +638,44 @@ intelClear(GLcontext *ctx, GLbitfield mask) } +/* Emit wait for pending flips */ +void +intel_wait_flips(struct intel_context *intel, GLuint batch_flags) +{ + struct intel_framebuffer *intel_fb = + (struct intel_framebuffer *) intel->ctx.DrawBuffer; + + if (intel_fb->Base.Name == 0 && intel_fb->flip_pending) { + GLuint mi_wait = MI_WAIT_FOR_EVENT; + GLint pf_pipes = intel_fb->pf_pipes; + BATCH_LOCALS; + + if (pf_pipes & 0x1) + mi_wait |= MI_WAIT_FOR_PLANE_A_FLIP; + + if (pf_pipes & 0x2) + mi_wait |= MI_WAIT_FOR_PLANE_B_FLIP; + + /* Wait for pending flips to take effect */ + BEGIN_BATCH(2, batch_flags); + OUT_BATCH(mi_wait); + OUT_BATCH(0); + ADVANCE_BATCH(); + + intel_fb->flip_pending = GL_FALSE; + } +} + /* Flip the front & back buffers */ -static void +static GLboolean intelPageFlip(const __DRIdrawablePrivate * dPriv) { struct intel_context *intel; GLboolean missed_target; int ret; + struct intel_framebuffer *intel_fb = dPriv->driverPrivate; if (INTEL_DEBUG & DEBUG_IOCTL) fprintf(stderr, "%s\n", __FUNCTION__); @@ -606,6 +686,9 @@ intelPageFlip(const __DRIdrawablePrivate * dPriv) intel = (struct intel_context *) dPriv->driContextPriv->driverPrivate; + if (intel->intelScreen->drmMinor < 9) + return GL_FALSE; + intelFlush(&intel->ctx); driWaitForVBlank(dPriv, &intel->vbl_seq, intel->vblank_flags, &missed_target); @@ -615,28 +698,36 @@ intelPageFlip(const __DRIdrawablePrivate * dPriv) (void)(*dri_interface->getUST) (&intel->swap_missed_ust); } + ret = 0; + LOCK_HARDWARE(intel); - if (!dPriv->numClipRects) { - UNLOCK_HARDWARE(intel); - usleep(10000); /* throttle invisible client 10ms */ - return; + if (dPriv->numClipRects && intel_fb->pf_active) { + drm_i915_flip_t flip; + + flip.pipes = intel_fb->pf_pipes; + + ret = drmCommandWrite(intel->driFd, DRM_I915_FLIP, &flip, sizeof(flip)); } - 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; + if (ret || !intel_fb->pf_active) + return GL_FALSE; + + if (!dPriv->numClipRects) { + usleep(10000); /* throttle invisible client 10ms */ } - driFlipRenderbuffers(intel->ctx.WinSysDrawBuffer, - intel->sarea->pf_current_page); - intel_draw_buffer(&intel->ctx, intel->ctx.DrawBuffer); + intel_fb->pf_current_page = (intel->sarea->pf_current_page >> + (intel_fb->pf_pipes & 0x2)) & 0x3; + + driFlipRenderbuffers(intel->ctx.WinSysDrawBuffer, intel_fb->pf_current_page); + intel_draw_buffer(&intel->ctx, &intel_fb->Base); - intel->flip_pending = GL_TRUE; + intel_fb->flip_pending = dPriv->numClipRects != 0; + + return GL_TRUE; } #if 0 @@ -682,10 +773,7 @@ intelSwapBuffers(__DRIdrawablePrivate * dPriv) if (ctx->Visual.doubleBufferMode) { intelScreenPrivate *screen = intel->intelScreen; _mesa_notifySwapBuffers(ctx); /* flush pending rendering comands */ - if (screen->current_rotation == 0 && intel->doPageFlip) { - intelPageFlip(dPriv); - } - else { + if (screen->current_rotation != 0 || !intelPageFlip(dPriv)) { intelCopyBuffer(dPriv, NULL); } if (screen->current_rotation != 0) { diff --git a/src/mesa/drivers/dri/i915tex/intel_buffers.h b/src/mesa/drivers/dri/i915tex/intel_buffers.h index 0faf0553474..3b686cb5c18 100644 --- a/src/mesa/drivers/dri/i915tex/intel_buffers.h +++ b/src/mesa/drivers/dri/i915tex/intel_buffers.h @@ -30,6 +30,7 @@ struct intel_context; +struct intel_framebuffer; extern GLboolean @@ -41,6 +42,8 @@ extern struct intel_region *intel_readbuf_region(struct intel_context *intel); extern struct intel_region *intel_drawbuf_region(struct intel_context *intel); +extern void intel_wait_flips(struct intel_context *intel, GLuint batch_flags); + extern void intelSwapBuffers(__DRIdrawablePrivate * dPriv); extern void intelWindowMoved(struct intel_context *intel); diff --git a/src/mesa/drivers/dri/i915tex/intel_context.c b/src/mesa/drivers/dri/i915tex/intel_context.c index 7eb209cf5f4..8d90489b4e8 100644 --- a/src/mesa/drivers/dri/i915tex/intel_context.c +++ b/src/mesa/drivers/dri/i915tex/intel_context.c @@ -690,21 +690,10 @@ intelContendedLock(struct intel_context *intel, GLuint flags) 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); } + /* Lock the hardware and validate our state. */ void LOCK_HARDWARE( struct intel_context *intel ) diff --git a/src/mesa/drivers/dri/i915tex/intel_context.h b/src/mesa/drivers/dri/i915tex/intel_context.h index 321a945c050..8f78597ba08 100644 --- a/src/mesa/drivers/dri/i915tex/intel_context.h +++ b/src/mesa/drivers/dri/i915tex/intel_context.h @@ -294,11 +294,6 @@ struct intel_context int width; 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 b739e22cca7..104cf1d9bbf 100644 --- a/src/mesa/drivers/dri/i915tex/intel_fbo.c +++ b/src/mesa/drivers/dri/i915tex/intel_fbo.c @@ -71,6 +71,21 @@ intel_renderbuffer(struct gl_renderbuffer *rb) struct intel_renderbuffer * intel_get_renderbuffer(struct gl_framebuffer *fb, GLuint attIndex) { + if (fb->Name == 0) { + struct intel_framebuffer *intel_fb = (struct intel_framebuffer*)fb; + + if (intel_fb->pf_current_page) { + switch (attIndex) { + case BUFFER_BACK_LEFT: + attIndex = BUFFER_FRONT_LEFT; + break; + case BUFFER_FRONT_LEFT: + attIndex = BUFFER_BACK_LEFT; + break; + } + } + } + return intel_renderbuffer(fb->Attachment[attIndex].Renderbuffer); } @@ -78,22 +93,7 @@ intel_get_renderbuffer(struct gl_framebuffer *fb, GLuint attIndex) struct intel_region * intel_get_rb_region(struct gl_framebuffer *fb, GLuint attIndex) { - 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); + struct intel_renderbuffer *irb = intel_get_renderbuffer(fb, attIndex); if (irb) return irb->region; @@ -109,7 +109,9 @@ intel_get_rb_region(struct gl_framebuffer *fb, GLuint attIndex) static struct gl_framebuffer * intel_new_framebuffer(GLcontext * ctx, GLuint name) { - /* there's no intel_framebuffer at this time, just use Mesa's class */ + /* Only drawable state in intel_framebuffer at this time, just use Mesa's + * class + */ return _mesa_new_framebuffer(ctx, name); } diff --git a/src/mesa/drivers/dri/i915tex/intel_fbo.h b/src/mesa/drivers/dri/i915tex/intel_fbo.h index 221f09b39ab..d55f02967f7 100644 --- a/src/mesa/drivers/dri/i915tex/intel_fbo.h +++ b/src/mesa/drivers/dri/i915tex/intel_fbo.h @@ -32,6 +32,20 @@ struct intel_context; struct intel_region; +/** + * Intel framebuffer, derived from gl_framebuffer. + */ +struct intel_framebuffer +{ + struct gl_framebuffer Base; + + /* Drawable page flipping state */ + GLboolean pf_active; + GLboolean flip_pending; + GLint pf_pipes; + GLint pf_current_page; +}; + /** * Intel renderbuffer, derived from gl_renderbuffer. diff --git a/src/mesa/drivers/dri/i915tex/intel_reg.h b/src/mesa/drivers/dri/i915tex/intel_reg.h index 126d2ea7ffa..7828ba6ad39 100644 --- a/src/mesa/drivers/dri/i915tex/intel_reg.h +++ b/src/mesa/drivers/dri/i915tex/intel_reg.h @@ -82,6 +82,7 @@ #define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) #define MI_WAIT_FOR_EVENT ((0x3<<23)) +#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6) #define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) #endif diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.c b/src/mesa/drivers/dri/i915tex/intel_screen.c index efa1b014a61..f26b3f33ad2 100644 --- a/src/mesa/drivers/dri/i915tex/intel_screen.c +++ b/src/mesa/drivers/dri/i915tex/intel_screen.c @@ -541,7 +541,12 @@ intelCreateBuffer(__DRIscreenPrivate * driScrnPriv, mesaVis->depthBits != 24); GLenum rgbFormat = (mesaVis->redBits == 5 ? GL_RGB5 : GL_RGBA8); - struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis); + struct intel_framebuffer *intel_fb = CALLOC_STRUCT(intel_framebuffer); + + if (!intel_fb) + return GL_FALSE; + + _mesa_initialize_framebuffer(&intel_fb->Base, mesaVis); /* setup the hardware-based renderbuffers */ { @@ -553,7 +558,8 @@ intelCreateBuffer(__DRIscreenPrivate * driScrnPriv, screen->cpp, screen->front.map); intel_set_span_functions(&frontRb->Base); - _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontRb->Base); + _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_FRONT_LEFT, + &frontRb->Base); } if (mesaVis->doubleBufferMode) { @@ -565,7 +571,8 @@ intelCreateBuffer(__DRIscreenPrivate * driScrnPriv, screen->cpp, screen->back.map); intel_set_span_functions(&backRb->Base); - _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backRb->Base); + _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_BACK_LEFT, + &backRb->Base); } if (mesaVis->depthBits == 24 && mesaVis->stencilBits == 8) { @@ -579,8 +586,10 @@ intelCreateBuffer(__DRIscreenPrivate * driScrnPriv, screen->depth.map); intel_set_span_functions(&depthStencilRb->Base); /* note: bind RB to two attachment points */ - _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthStencilRb->Base); - _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &depthStencilRb->Base); + _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_DEPTH, + &depthStencilRb->Base); + _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_STENCIL, + &depthStencilRb->Base); } else if (mesaVis->depthBits == 16) { /* just 16-bit depth buffer, no hw stencil */ @@ -592,17 +601,19 @@ intelCreateBuffer(__DRIscreenPrivate * driScrnPriv, screen->cpp, /* 2! */ screen->depth.map); intel_set_span_functions(&depthRb->Base); - _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base); + _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_DEPTH, &depthRb->Base); } /* now add any/all software-based renderbuffers we may need */ - _mesa_add_soft_renderbuffers(fb, GL_FALSE, /* never sw color */ - GL_FALSE, /* never sw depth */ - swStencil, mesaVis->accumRedBits > 0, GL_FALSE, /* never sw alpha */ - GL_FALSE /* never sw aux */ ); - driDrawPriv->driverPrivate = (void *) fb; - - return (driDrawPriv->driverPrivate != NULL); + _mesa_add_soft_renderbuffers(&intel_fb->Base, + GL_FALSE, /* never sw color */ + GL_FALSE, /* never sw depth */ + swStencil, mesaVis->accumRedBits > 0, + GL_FALSE, /* never sw alpha */ + GL_FALSE /* never sw aux */ ); + driDrawPriv->driverPrivate = (void *) intel_fb; + + return GL_TRUE; } } diff --git a/src/mesa/drivers/dri/i915tex/intel_tris.c b/src/mesa/drivers/dri/i915tex/intel_tris.c index 4e0ca70c1ec..9ac8c32f600 100644 --- a/src/mesa/drivers/dri/i915tex/intel_tris.c +++ b/src/mesa/drivers/dri/i915tex/intel_tris.c @@ -102,15 +102,7 @@ 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; - } + intel_wait_flips(intel, batch_flags); /* Emit a slot which will be filled with the inline primitive * command later.