i915tex: Make page flipping work again.
authorMichel Dänzer <michel@tungstengraphics.com>
Fri, 2 Feb 2007 16:10:25 +0000 (17:10 +0100)
committerMichel Dänzer <michel@tungstengraphics.com>
Tue, 20 Feb 2007 18:15:44 +0000 (19:15 +0100)
src/mesa/drivers/dri/i915tex/intel_blit.c
src/mesa/drivers/dri/i915tex/intel_buffers.c
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_reg.h
src/mesa/drivers/dri/i915tex/intel_tris.c

index 550669ab0c80ab521afcbede3988478e8826c377..c08c45a9366a6f84fa6b6ca811568a7ba79e18a6 100644 (file)
@@ -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 */
index 1ded0b5417fe05c18265deb70cf1f2a9c0e4696f..a8fb0b14a1cf109a4036ce24620ae77c714492f5 100644 (file)
@@ -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);
index a5ce08b17012ecba7b667341ec705a32e4eac2a0..7eb209cf5f435447a436a442fb7832aeec64dcbf 100644 (file)
@@ -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);
 }
 
 
index 96b911501f3fbc8f26fb26e268668f387148e54e..321a945c0508053540d0a4f12916632104eaebfc 100644 (file)
@@ -295,6 +295,10 @@ struct intel_context
   int height;
   int current_rotation;
 
+  /* Page flipping
+   */
+  GLboolean doPageFlip;
+  GLboolean flip_pending;
 };
 
 /* These are functions now:
index ab0e569bd9460bd387197f5e84e27d7a85d69753..b739e22cca7dc94acd6699e21aaecba60b9e8c25 100644 (file)
@@ -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
index 1ec153266c79999bab959ba1fba5a48fda70e500..126d2ea7ffa86c55cd97fff2abb15dcbef440224 100644 (file)
@@ -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
index 1ba49d8f6ec6bbee7d730455186990cef06b81d4..4e0ca70c1ec7c93120cfbdc44bac163851dbaaea 100644 (file)
@@ -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.
     */