intel: fix buffer swaps and enable page flipping on 965
authorJesse Barnes <jbarnes@jbarnes-t61.(none)>
Tue, 22 Jul 2008 16:39:23 +0000 (09:39 -0700)
committerJesse Barnes <jbarnes@virtuousgeek.org>
Tue, 22 Jul 2008 16:39:23 +0000 (09:39 -0700)
Some buffer swap intel render buffer fields (pf_num_pages & vbl_pending) are
also used for page flipping, so enable the code that sets & updates them on
965.  This allows buffer swaps and page flips to work on 965 and prevents hangs
in LOCK_HARDWARE in the buffer swap case due to an uninitialized vbl_pending
field.

Fixes FDO #16118.

src/mesa/drivers/dri/intel/intel_buffers.c

index 2a25f079e9548dc1d5cc36d38346b2102344eb90..348c490af0d20f4b9baed770e36ed395cbfeb8c1 100644 (file)
@@ -197,7 +197,6 @@ intelSetBackClipRects(struct intel_context *intel)
    }
 }
 
-#ifdef I915
 static void
 intelUpdatePageFlipping(struct intel_context *intel,
                        GLint areaA, GLint areaB)
@@ -267,7 +266,6 @@ intelUpdatePageFlipping(struct intel_context *intel,
    intel_flip_renderbuffers(intel_fb);
    intel_draw_buffer(&intel->ctx, intel->ctx.DrawBuffer);
 }
-#endif /* I915 */
 
 /**
  * This will be called whenever the currently bound window is moved/resized.
@@ -318,9 +316,7 @@ intelWindowMoved(struct intel_context *intel)
       GLint areaB = driIntersectArea( drw_rect, planeB_rect );
       GLuint flags = dPriv->vblFlags;
 
-#ifdef I915
       intelUpdatePageFlipping(intel, areaA, areaB);
-#endif
 
       /* Update vblank info
        */
@@ -645,7 +641,6 @@ intel_wait_flips(struct intel_context *intel)
 static GLboolean
 intelPageFlip(const __DRIdrawablePrivate * dPriv)
 {
-#ifdef I915
    struct intel_context *intel;
    int ret;
    struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
@@ -698,40 +693,8 @@ intelPageFlip(const __DRIdrawablePrivate * dPriv)
    intel_draw_buffer(&intel->ctx, &intel_fb->Base);
 
    return GL_TRUE;
-#else
-   return GL_FALSE;
-#endif
 }
 
-#if 0
-void
-intelSwapBuffers(__DRIdrawablePrivate * dPriv)
-{
-   if (dPriv->driverPrivate) {
-      const struct gl_framebuffer *fb
-         = (struct gl_framebuffer *) dPriv->driverPrivate;
-      if (fb->Visual.doubleBufferMode) {
-         GET_CURRENT_CONTEXT(ctx);
-         if (ctx && ctx->DrawBuffer == fb) {
-            _mesa_notifySwapBuffers(ctx);       /* flush pending rendering */
-         }
-         if (intel->doPageFlip) {
-            intelPageFlip(dPriv);
-         }
-         else {
-            intelCopyBuffer(dPriv);
-         }
-      }
-   }
-   else {
-      _mesa_problem(NULL,
-                    "dPriv has no gl_framebuffer pointer in intelSwapBuffers");
-   }
-}
-#else
-/* Trunk version:
- */
-
 static GLboolean
 intelScheduleSwap(__DRIdrawablePrivate * dPriv, GLboolean *missed_target)
 {
@@ -746,8 +709,10 @@ intelScheduleSwap(__DRIdrawablePrivate * dPriv, GLboolean *missed_target)
 
    if (!dPriv->vblFlags ||
        (dPriv->vblFlags & VBLANK_FLAG_NO_IRQ) ||
-       intelScreen->drmMinor < (intel_fb->pf_active ? 9 : 6))
+       intelScreen->drmMinor < (intel_fb->pf_active ? 9 : 6)) {
+          printf("swap schedule failed: bad flags or drm minor\n");
       return GL_FALSE;
+   }
 
    interval = driGetVBlankInterval(dPriv);
 
@@ -756,6 +721,7 @@ intelScheduleSwap(__DRIdrawablePrivate * dPriv, GLboolean *missed_target)
    if (dPriv->vblFlags & VBLANK_FLAG_SYNC) {
       swap.seqtype |= DRM_VBLANK_NEXTONMISS;
    } else if (interval == 0) {
+          printf("swap schedule failed: bad interval\n");
       return GL_FALSE;
    }
 
@@ -803,6 +769,7 @@ intelScheduleSwap(__DRIdrawablePrivate * dPriv, GLboolean *missed_target)
       }
 
       ret = GL_FALSE;
+      printf("swap schedule failed: vblank swap failed\n");
    }
 
    UNLOCK_HARDWARE(intel);
@@ -832,8 +799,18 @@ intelSwapBuffers(__DRIdrawablePrivate * dPriv)
         _mesa_notifySwapBuffers(ctx);  /* flush pending rendering comands */
 
          if (!intelScheduleSwap(dPriv, &missed_target)) {
+                printf("schedule swap failed, trying to wait manually\n");
            driWaitForVBlank(dPriv, &missed_target);
 
+           /*
+            * Update each buffer's vbl_pending so we don't get too out of
+            * sync
+            */
+           intel_get_renderbuffer(&intel_fb->Base,
+                                  BUFFER_BACK_LEFT)->vbl_pending = 
+                   intel_get_renderbuffer(&intel_fb->Base,
+                                          BUFFER_FRONT_LEFT)->vbl_pending =
+                   dPriv->vblSeq;
            if (!intelPageFlip(dPriv)) {
               intelCopyBuffer(dPriv, NULL);
            }
@@ -854,7 +831,6 @@ intelSwapBuffers(__DRIdrawablePrivate * dPriv)
       fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__);
    }
 }
-#endif
 
 void
 intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h)