i915tex: Schedule flips when possible.
authorMichel Dänzer <michel@tungstengraphics.com>
Thu, 22 Feb 2007 16:24:09 +0000 (17:24 +0100)
committerMichel Dänzer <michel@tungstengraphics.com>
Thu, 22 Feb 2007 16:24:09 +0000 (17:24 +0100)
Also move vsync related state from context to window, so it's possible to
schedule several flips ahead of time with triple buffering.

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.h
src/mesa/drivers/dri/i915tex/intel_screen.c

index 640c73e3551133f4f7ad5bc9449840de9e868e08..dbe4ba2ac5ef3e678d9401fbb9022b1db3a98cb7 100644 (file)
@@ -55,8 +55,6 @@ intelCopyBuffer(const __DRIdrawablePrivate * dPriv,
 
    struct intel_context *intel;
    const intelScreenPrivate *intelScreen;
-   GLboolean missed_target;
-   int64_t ust;
 
    DBG("%s\n", __FUNCTION__);
 
@@ -68,41 +66,6 @@ intelCopyBuffer(const __DRIdrawablePrivate * dPriv,
 
    intelScreen = intel->intelScreen;
 
-   if (!rect && !intel->swap_scheduled && intelScreen->drmMinor >= 6 &&
-       !(intel->vblank_flags & VBLANK_FLAG_NO_IRQ) &&
-       intelScreen->current_rotation == 0) {
-      unsigned int interval = driGetVBlankInterval(dPriv, intel->vblank_flags);
-      unsigned int target;
-      drm_i915_vblank_swap_t swap;
-      swap.drawable = dPriv->hHWDrawable;
-      swap.seqtype = DRM_VBLANK_ABSOLUTE;
-      target = swap.sequence = intel->vbl_seq + interval;
-
-      if (intel->vblank_flags & VBLANK_FLAG_SYNC) {
-        swap.seqtype |= DRM_VBLANK_NEXTONMISS;
-      } else if (interval == 0) {
-        goto noschedule;
-      }
-
-      if ( intel->vblank_flags & VBLANK_FLAG_SECONDARY ) {
-        swap.seqtype |= DRM_VBLANK_SECONDARY;
-      }
-
-      intel_batchbuffer_flush(intel->batch);
-
-      if (!drmCommandWriteRead(intel->driFd, DRM_I915_VBLANK_SWAP, &swap,
-                              sizeof(swap))) {
-        intel->swap_scheduled = 1;
-        intel->vbl_seq = swap.sequence;
-        swap.sequence -= target;
-        missed_target = swap.sequence > 0 && swap.sequence <= (1 << 23);
-      }
-   } else {
-      intel->swap_scheduled = 0;
-   }
-noschedule:
-  
    if (intel->last_swap_fence) {
       driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE);
       driFenceUnReference(intel->last_swap_fence);
@@ -111,108 +74,88 @@ noschedule:
    intel->last_swap_fence = intel->first_swap_fence;
    intel->first_swap_fence = NULL;
 
-   if (!intel->swap_scheduled) {
-      if (!rect) {
-        driWaitForVBlank(dPriv, &intel->vbl_seq, intel->vblank_flags,
-                         &missed_target);
+   /* The LOCK_HARDWARE is required for the cliprects.  Buffer offsets
+    * should work regardless.
+    */
+   LOCK_HARDWARE(intel);
+
+   if (dPriv && dPriv->numClipRects) {
+      struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
+      const struct intel_region *frontRegion
+        = intel_get_rb_region(&intel_fb->Base, BUFFER_FRONT_LEFT);
+      const struct intel_region *backRegion
+        = 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;
+      const int cpp = frontRegion->cpp;
+      int BR13, CMD;
+      int i;
+
+      ASSERT(intel_fb);
+      ASSERT(intel_fb->Base.Name == 0);    /* Not a user-created FBO */
+      ASSERT(frontRegion);
+      ASSERT(backRegion);
+      ASSERT(frontRegion->pitch == backRegion->pitch);
+      ASSERT(frontRegion->cpp == backRegion->cpp);
+
+      if (cpp == 2) {
+        BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24);
+        CMD = XY_SRC_COPY_BLT_CMD;
+      }
+      else {
+        BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25);
+        CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
+               XY_SRC_COPY_BLT_WRITE_RGB);
       }
 
+      for (i = 0; i < nbox; i++, pbox++) {
+        drm_clip_rect_t box;
 
-      /* The LOCK_HARDWARE is required for the cliprects.  Buffer offsets
-       * should work regardless.
-       */
-      LOCK_HARDWARE(intel);
-
-      if (dPriv && dPriv->numClipRects) {
-        const intelScreenPrivate *intelScreen = intel->intelScreen;
-        struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
-        const struct intel_region *frontRegion
-           = intel_get_rb_region(&intel_fb->Base, BUFFER_FRONT_LEFT);
-        const struct intel_region *backRegion
-           = 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;
-        const int cpp = frontRegion->cpp;
-        int BR13, CMD;
-        int i;
-
-        ASSERT(intel_fb);
-        ASSERT(intel_fb->Base.Name == 0);    /* Not a user-created FBO */
-        ASSERT(frontRegion);
-        ASSERT(backRegion);
-        ASSERT(frontRegion->pitch == backRegion->pitch);
-        ASSERT(frontRegion->cpp == backRegion->cpp);
-
-        if (cpp == 2) {
-           BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24);
-           CMD = XY_SRC_COPY_BLT_CMD;
-        }
-        else {
-           BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25);
-           CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
-                  XY_SRC_COPY_BLT_WRITE_RGB);
-        }
+        if (pbox->x1 > pbox->x2 ||
+            pbox->y1 > pbox->y2 ||
+            pbox->x2 > intelScreen->width || pbox->y2 > intelScreen->height)
+           continue;
 
-        for (i = 0; i < nbox; i++, pbox++) {
-           drm_clip_rect_t box;
+        box = *pbox;
 
-           if (pbox->x1 > pbox->x2 ||
-               pbox->y1 > pbox->y2 ||
-               pbox->x2 > intelScreen->width || pbox->y2 > intelScreen->height)
-              continue;
+        if (rect) {
+           if (rect->x1 > box.x1)
+              box.x1 = rect->x1;
+           if (rect->y1 > box.y1)
+              box.y1 = rect->y1;
+           if (rect->x2 < box.x2)
+              box.x2 = rect->x2;
+           if (rect->y2 < box.y2)
+              box.y2 = rect->y2;
 
-           box = *pbox;
-
-           if (rect) {
-              if (rect->x1 > box.x1)
-                 box.x1 = rect->x1;
-              if (rect->y1 > box.y1)
-                 box.y1 = rect->y1;
-              if (rect->x2 < box.x2)
-                 box.x2 = rect->x2;
-              if (rect->y2 < box.y2)
-                 box.y2 = rect->y2;
-
-              if (box.x1 > box.x2 || box.y1 > box.y2)
-                 continue;
-           }
-
-           BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS);
-           OUT_BATCH(CMD);
-           OUT_BATCH(BR13);
-           OUT_BATCH((pbox->y1 << 16) | pbox->x1);
-           OUT_BATCH((pbox->y2 << 16) | pbox->x2);
-
-           OUT_RELOC(frontRegion->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
-                     DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0);
-           OUT_BATCH((pbox->y1 << 16) | pbox->x1);
-           OUT_BATCH(BR13 & 0xffff);
-           OUT_RELOC(backRegion->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ,
-                     DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0);
-
-           ADVANCE_BATCH();
+           if (box.x1 > box.x2 || box.y1 > box.y2)
+              continue;
         }
 
-        if (intel->first_swap_fence)
-           driFenceUnReference(intel->first_swap_fence);
-        intel->first_swap_fence = intel_batchbuffer_flush(intel->batch);
-        driFenceReference(intel->first_swap_fence);
-      }
+        BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS);
+        OUT_BATCH(CMD);
+        OUT_BATCH(BR13);
+        OUT_BATCH((pbox->y1 << 16) | pbox->x1);
+        OUT_BATCH((pbox->y2 << 16) | pbox->x2);
 
-      UNLOCK_HARDWARE(intel);
-   }
+        OUT_RELOC(frontRegion->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
+                  DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0);
+        OUT_BATCH((pbox->y1 << 16) | pbox->x1);
+        OUT_BATCH(BR13 & 0xffff);
+        OUT_RELOC(backRegion->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ,
+                  DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0);
 
-   if (!rect) {
-      intel->swap_count++;
-      (*dri_interface->getUST) (&ust);
-      if (missed_target) {
-         intel->swap_missed_count++;
-         intel->swap_missed_ust = ust - intel->swap_ust;
+        ADVANCE_BATCH();
       }
 
-      intel->swap_ust = ust;
+      if (intel->first_swap_fence)
+        driFenceUnReference(intel->first_swap_fence);
+      intel->first_swap_fence = intel_batchbuffer_flush(intel->batch);
+      driFenceReference(intel->first_swap_fence);
    }
+
+   UNLOCK_HARDWARE(intel);
 }
 
 
index 7db5ccfc26586459925fa3c10301acbadb5a2e14..8054d98646bd3e31313c40a23b32d38f26f5904f 100644 (file)
@@ -226,7 +226,7 @@ intelWindowMoved(struct intel_context *intel)
                                     .y2 = sarea->pipeB_y + sarea->pipeB_h };
       GLint areaA = driIntersectArea( drw_rect, pipeA_rect );
       GLint areaB = driIntersectArea( drw_rect, pipeB_rect );
-      GLuint flags = intel->vblank_flags;
+      GLuint flags = intel_fb->vblank_flags;
       GLboolean pf_active;
       GLint pf_pipes;
 
@@ -278,17 +278,17 @@ intelWindowMoved(struct intel_context *intel)
       /* Update vblank info
        */
       if (areaB > areaA || (areaA == areaB && areaB > 0)) {
-        flags = intel->vblank_flags | VBLANK_FLAG_SECONDARY;
+        flags = intel_fb->vblank_flags | VBLANK_FLAG_SECONDARY;
       } else {
-        flags = intel->vblank_flags & ~VBLANK_FLAG_SECONDARY;
+        flags = intel_fb->vblank_flags & ~VBLANK_FLAG_SECONDARY;
       }
 
-      if (flags != intel->vblank_flags) {
-        intel->vblank_flags = flags;
-        driGetCurrentVBlank(dPriv, intel->vblank_flags, &intel->vbl_seq);
+      if (flags != intel_fb->vblank_flags) {
+        intel_fb->vblank_flags = flags;
+        driGetCurrentVBlank(dPriv, intel_fb->vblank_flags, &intel_fb->vbl_seq);
       }
    } else {
-      intel->vblank_flags &= ~VBLANK_FLAG_SECONDARY;
+      intel_fb->vblank_flags &= ~VBLANK_FLAG_SECONDARY;
    }
 
    /* Update Mesa's notion of window size */
@@ -683,7 +683,6 @@ static GLboolean
 intelPageFlip(const __DRIdrawablePrivate * dPriv)
 {
    struct intel_context *intel;
-   GLboolean missed_target;
    int ret;
    struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
 
@@ -701,13 +700,6 @@ intelPageFlip(const __DRIdrawablePrivate * dPriv)
 
    intelFlush(&intel->ctx);
 
-   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 = 0;
 
    LOCK_HARDWARE(intel);
@@ -772,6 +764,83 @@ intelSwapBuffers(__DRIdrawablePrivate * dPriv)
 #else
 /* Trunk version:
  */
+
+static GLboolean
+intelScheduleSwap(const __DRIdrawablePrivate * dPriv, GLboolean *missed_target)
+{
+   struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
+   unsigned int interval = driGetVBlankInterval(dPriv, intel_fb->vblank_flags);
+   struct intel_context *intel =
+      intelScreenContext(dPriv->driScreenPriv->private);
+   const intelScreenPrivate *intelScreen = intel->intelScreen;
+   unsigned int target;
+   drm_i915_vblank_swap_t swap;
+   GLboolean ret;
+
+   if ((intel_fb->vblank_flags & VBLANK_FLAG_NO_IRQ) ||
+       intelScreen->current_rotation != 0 ||
+       intelScreen->drmMinor < (intel_fb->pf_active ? 9 : 6))
+      return GL_FALSE;
+
+   swap.seqtype = DRM_VBLANK_ABSOLUTE;
+
+   if (intel_fb->vblank_flags & VBLANK_FLAG_SYNC) {
+      swap.seqtype |= DRM_VBLANK_NEXTONMISS;
+   } else if (interval == 0) {
+      return GL_FALSE;
+   }
+
+   swap.drawable = dPriv->hHWDrawable;
+   target = swap.sequence = intel_fb->vbl_seq + interval;
+
+   if ( intel_fb->vblank_flags & VBLANK_FLAG_SECONDARY ) {
+      swap.seqtype |= DRM_VBLANK_SECONDARY;
+   }
+
+   LOCK_HARDWARE(intel);
+
+   intel_batchbuffer_flush(intel->batch);
+
+   if ( intel_fb->pf_active ) {
+      swap.seqtype |= DRM_VBLANK_FLIP;
+
+      intel_fb->pf_current_page = (((intel->sarea->pf_current_page >>
+                                    (intel_fb->pf_pipes & 0x2)) & 0x3) + 1) %
+                                 intel_fb->pf_num_pages;
+   }
+
+   if (!drmCommandWriteRead(intel->driFd, DRM_I915_VBLANK_SWAP, &swap,
+                           sizeof(swap))) {
+      intel_fb->vbl_seq = swap.sequence;
+      swap.sequence -= target;
+      *missed_target = swap.sequence > 0 && swap.sequence <= (1 << 23);
+
+      if (swap.seqtype & DRM_VBLANK_FLIP) {
+        intel_get_renderbuffer(&intel_fb->Base,
+                               BUFFER_FRONT_LEFT)->vbl_pending =
+           intel_get_renderbuffer(&intel_fb->Base,
+                                  BUFFER_BACK_LEFT)->vbl_pending = intel_fb->vbl_seq;
+
+        intel_flip_renderbuffers(intel_fb);
+        intel_draw_buffer(&intel->ctx, intel->ctx.DrawBuffer);
+      }
+
+      ret = GL_TRUE;
+   } else {
+      if (swap.seqtype & DRM_VBLANK_FLIP) {
+        intel_fb->pf_current_page = ((intel->sarea->pf_current_page >>
+                                       (intel_fb->pf_pipes & 0x2)) & 0x3) %
+                                    intel_fb->pf_num_pages;
+      }
+
+      ret = GL_FALSE;
+   }
+
+   UNLOCK_HARDWARE(intel);
+
+   return ret;
+}
+  
 void
 intelSwapBuffers(__DRIdrawablePrivate * dPriv)
 {
@@ -786,13 +855,34 @@ intelSwapBuffers(__DRIdrawablePrivate * dPriv)
 
       if (ctx->Visual.doubleBufferMode) {
          intelScreenPrivate *screen = intel->intelScreen;
-         _mesa_notifySwapBuffers(ctx);  /* flush pending rendering comands */
-         if (screen->current_rotation != 0 || !intelPageFlip(dPriv)) {
-            intelCopyBuffer(dPriv, NULL);
-         }
-         if (screen->current_rotation != 0) {
-            intelRotateWindow(intel, dPriv, BUFFER_BIT_FRONT_LEFT);
-         }
+        GLboolean missed_target;
+        struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
+        int64_t ust;
+         
+        _mesa_notifySwapBuffers(ctx);  /* flush pending rendering comands */
+
+         if (screen->current_rotation != 0 ||
+            !intelScheduleSwap(dPriv, &missed_target)) {
+           driWaitForVBlank(dPriv, &intel_fb->vbl_seq, intel_fb->vblank_flags,
+                            &missed_target);
+
+           if (screen->current_rotation != 0 || !intelPageFlip(dPriv)) {
+              intelCopyBuffer(dPriv, NULL);
+           }
+
+           if (screen->current_rotation != 0) {
+              intelRotateWindow(intel, dPriv, BUFFER_BIT_FRONT_LEFT);
+           }
+        }
+
+        intel_fb->swap_count++;
+        (*dri_interface->getUST) (&ust);
+        if (missed_target) {
+           intel_fb->swap_missed_count++;
+           intel_fb->swap_missed_ust = ust - intel_fb->swap_ust;
+        }
+
+        intel_fb->swap_ust = ust;
       }
    }
    else {
index 649fe549bf4ece2a03aa9c6f405d9190cbb669f7..b1352a766ef93007a1512be2cc211753f00596d5 100644 (file)
@@ -443,10 +443,6 @@ intelInitContext(struct intel_context *intel,
 
    intel->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS);
 
-   intel->vblank_flags = (intel->intelScreen->irq_active != 0)
-      ? driGetDefaultVBlankFlags(&intel->optionCache) : VBLANK_FLAG_NO_IRQ;
-
-   (*dri_interface->getUST) (&intel->swap_ust);
    _math_matrix_ctr(&intel->ViewportMatrix);
 
    /* Disable imaging extension until convolution is working in
@@ -591,7 +587,12 @@ intelMakeCurrent(__DRIcontextPrivate * driContextPriv,
       if (intel->ctx.DrawBuffer == &intel_fb->Base) {
 
         if (intel->driDrawable != driDrawPriv) {
-           driDrawableInitVBlank(driDrawPriv, intel->vblank_flags, &intel->vbl_seq);       
+           intel_fb->vblank_flags = (intel->intelScreen->irq_active != 0)
+              ? driGetDefaultVBlankFlags(&intel->optionCache)
+              : VBLANK_FLAG_NO_IRQ;
+           (*dri_interface->getUST) (&intel_fb->swap_ust);
+           driDrawableInitVBlank(driDrawPriv, intel_fb->vblank_flags,
+                                 &intel_fb->vbl_seq);
            intel->driDrawable = driDrawPriv;
            intelWindowMoved(intel);
         }
@@ -702,19 +703,34 @@ intelContendedLock(struct intel_context *intel, GLuint flags)
 void LOCK_HARDWARE( struct intel_context *intel )
 {
     char __ret=0;
-
+    struct intel_framebuffer *intel_fb = NULL;
+    struct intel_renderbuffer *intel_rb = NULL;
     _glthread_LOCK_MUTEX(lockMutex);
     assert(!intel->locked);
 
-    if (intel->swap_scheduled) {
+    if (intel->driDrawable) {
+       intel_fb = intel->driDrawable->driverPrivate;
+
+       if (intel_fb)
+         intel_rb =
+            intel_get_renderbuffer(&intel_fb->Base,
+                                   intel_fb->Base._ColorDrawBufferMask[0] ==
+                                   BUFFER_BIT_FRONT_LEFT ? BUFFER_FRONT_LEFT :
+                                   BUFFER_BACK_LEFT);
+    }
+
+    if (intel_rb && (intel_fb->vbl_waited - intel_rb->vbl_pending) > (1<<23)) {
        drmVBlank vbl;
+
        vbl.request.type = DRM_VBLANK_ABSOLUTE;
-       if ( intel->vblank_flags & VBLANK_FLAG_SECONDARY ) {
+
+       if ( intel_fb->vblank_flags & VBLANK_FLAG_SECONDARY ) {
            vbl.request.type |= DRM_VBLANK_SECONDARY;
        }
-       vbl.request.sequence = intel->vbl_seq;
+
+       vbl.request.sequence = intel_rb->vbl_pending;
        drmWaitVBlank(intel->driFd, &vbl);
-       intel->swap_scheduled = 0;
+       intel_fb->vbl_waited = intel_rb->vbl_pending;
     }
 
     DRM_CAS(intel->driHwLock, intel->hHWContext,
index 8f78597ba08f721192935525e5cb8fc98f421b44..44c20af7f803d642fab1d3a53d6d609a6c34d98f 100644 (file)
@@ -274,19 +274,6 @@ struct intel_context
     */
    driOptionCache optionCache;
 
-   /* VBI
-    */
-   GLuint vbl_seq;
-   GLuint vblank_flags;
-
-   int64_t swap_ust;
-   int64_t swap_missed_ust;
-
-   GLuint swap_count;
-   GLuint swap_missed_count;
-
-   GLuint swap_scheduled;
-
   /* Rotation. Need to match that of the
    * current screen.
    */
index 0446d681c61f7400b42cebfc1355781bde4e3bb1..963f5e706f4b39948fb5831e32e451fba9148a5f 100644 (file)
@@ -47,6 +47,18 @@ struct intel_framebuffer
    GLint pf_pipes;
    GLint pf_current_page;
    GLint pf_num_pages;
+
+   /* VBI
+    */
+   GLuint vbl_seq;
+   GLuint vblank_flags;
+   GLuint vbl_waited;
+
+   int64_t swap_ust;
+   int64_t swap_missed_ust;
+
+   GLuint swap_count;
+   GLuint swap_missed_count;
 };
 
 
@@ -68,6 +80,8 @@ struct intel_renderbuffer
    GLuint PairedStencil; /**< only used if this is a stencil renderbuffer */
 
    GLuint pf_pending;  /**< sequence number of pending flip */
+
+   GLuint vbl_pending;   /**< vblank sequence number of pending flip */
 };
 
 
index 4763d14f4f587e9835ed5e1b01a7eb3167570be4..86a3d79266220e9db5649177c731462ecbf6fe39 100644 (file)
@@ -679,21 +679,20 @@ intelDestroyBuffer(__DRIdrawablePrivate * driDrawPriv)
 static int
 intelGetSwapInfo(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo)
 {
-   struct intel_context *intel;
+   struct intel_framebuffer *intel_fb;
 
-   if ((dPriv == NULL) || (dPriv->driContextPriv == NULL)
-       || (dPriv->driContextPriv->driverPrivate == NULL)
+   if ((dPriv == NULL) || (dPriv->driverPrivate == NULL)
        || (sInfo == NULL)) {
       return -1;
    }
 
-   intel = dPriv->driContextPriv->driverPrivate;
-   sInfo->swap_count = intel->swap_count;
-   sInfo->swap_ust = intel->swap_ust;
-   sInfo->swap_missed_count = intel->swap_missed_count;
+   intel_fb = dPriv->driverPrivate;
+   sInfo->swap_count = intel_fb->swap_count;
+   sInfo->swap_ust = intel_fb->swap_ust;
+   sInfo->swap_missed_count = intel_fb->swap_missed_count;
 
    sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0)
-      ? driCalculateSwapUsage(dPriv, 0, intel->swap_missed_ust)
+      ? driCalculateSwapUsage(dPriv, 0, intel_fb->swap_missed_ust)
       : 0.0;
 
    return 0;