i915tex: Support page flipping on both CRTCs independently.
authorMichel Dänzer <michel@tungstengraphics.com>
Thu, 15 Feb 2007 15:30:40 +0000 (16:30 +0100)
committerMichel Dänzer <michel@tungstengraphics.com>
Tue, 20 Feb 2007 18:15:44 +0000 (19:15 +0100)
No longer track page flipping state per context but per window, via struct
intel_framebuffer which wraps struct gl_framebuffer for windows.

src/mesa/drivers/dri/i915tex/intel_blit.c
src/mesa/drivers/dri/i915tex/intel_buffers.c
src/mesa/drivers/dri/i915tex/intel_buffers.h
src/mesa/drivers/dri/i915tex/intel_context.c
src/mesa/drivers/dri/i915tex/intel_context.h
src/mesa/drivers/dri/i915tex/intel_fbo.c
src/mesa/drivers/dri/i915tex/intel_fbo.h
src/mesa/drivers/dri/i915tex/intel_reg.h
src/mesa/drivers/dri/i915tex/intel_screen.c
src/mesa/drivers/dri/i915tex/intel_tris.c

index c08c45a9366a6f84fa6b6ca811568a7ba79e18a6..e33d28307649af166af028c943f4257de5beb187 100644 (file)
@@ -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);
index a8fb0b14a1cf109a4036ce24620ae77c714492f5..fdb6ea94441513aff93127502a84852dddbb2d86 100644 (file)
@@ -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) {
index 0faf0553474f280ec5e224ab2a95d2a0971ce55d..3b686cb5c184388f320858d2d26fc6d61796c0e8 100644 (file)
@@ -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);
index 7eb209cf5f435447a436a442fb7832aeec64dcbf..8d90489b4e871085076e327c952b671ac952028c 100644 (file)
@@ -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 )
index 321a945c0508053540d0a4f12916632104eaebfc..8f78597ba08f721192935525e5cb8fc98f421b44 100644 (file)
@@ -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:
index b739e22cca7dc94acd6699e21aaecba60b9e8c25..104cf1d9bbf9d1e1c5426f5f0933e971ebeb8e0c 100644 (file)
@@ -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);
 }
 
index 221f09b39ab4218e958ac564678fccad8dec59c1..d55f02967f7ca7fdf18f03385bd87b262ea677b2 100644 (file)
 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.
index 126d2ea7ffa86c55cd97fff2abb15dcbef440224..7828ba6ad392d64381b124d0389b04764694be51 100644 (file)
@@ -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
index efa1b014a61dd659efce4b642892a84b38f589dd..f26b3f33ad25c1f24603e6dd27b63dfc48d65b5b 100644 (file)
@@ -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;
    }
 }
 
index 4e0ca70c1ec7c93120cfbdc44bac163851dbaaea..9ac8c32f6003ebd6a666bfc9eaee63eaf1d7c0fa 100644 (file)
@@ -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.