Refactor and fix core vblank support
authorJesse Barnes <jesse.barnes@intel.com>
Mon, 29 Oct 2007 18:56:31 +0000 (11:56 -0700)
committerJesse Barnes <jesse.barnes@intel.com>
Mon, 29 Oct 2007 19:06:00 +0000 (12:06 -0700)
Consolidate support for synchronizing to and retrieving vblank counters.  Also
fix the core vblank code to return monotonic MSC counters, which are required
by some GLX extensions.  Adding support for multiple pipes to a low level
driver is fairly easy, the Intel 965 driver provides simple example code (see
intel_buffers.c:intelWindowMoved()).

The new code bumps the media stream counter extension version to 2 and adds a
new getDrawableMSC callback.  This callback takes a drawablePrivate pointer,
which is used to calculate the MSC value seen by clients based on the actual
vblank counter(s) returned from the kernel.  The new drawable private fields
are as follows:
  - vblSeq - used for tracking vblank counts for buffer swapping
  - vblFlags - flags (e.g. current pipe), updated by low level driver
  - msc_base - MSC counter from the last time the current pipe changed
  - vblank_base - kernel DRM vblank counter from the last time the pipe changed

Using the above variables, the core vblank code (in vblank.c) can calculate a
monotonic MSC value.  The low level DRI drivers are responsible for updating
the current pipe (by setting VBLANK_FLAG_SECONDARY for example in vblFlags)
along with msc_base and vblank_base whenever the pipe associated with a given
drawable changes (again, see intelWindowMoved for an example of this).

Drivers should fill in the GetDrawableMSC DriverAPIRec field to point to
driDrawableGetMSC32 and add code for pipe switching as outlined above to fully
support the new scheme.

50 files changed:
include/GL/internal/dri_interface.h
src/glx/x11/glxcmds.c
src/mesa/drivers/dri/common/dri_util.c
src/mesa/drivers/dri/common/dri_util.h
src/mesa/drivers/dri/common/vblank.c
src/mesa/drivers/dri/common/vblank.h
src/mesa/drivers/dri/ffb/ffb_xmesa.c
src/mesa/drivers/dri/i810/i810screen.c
src/mesa/drivers/dri/i915/intel_buffers.c
src/mesa/drivers/dri/i915/intel_context.c
src/mesa/drivers/dri/i915/intel_fbo.h
src/mesa/drivers/dri/i915/intel_screen.c
src/mesa/drivers/dri/i965/intel_blit.c
src/mesa/drivers/dri/i965/intel_buffers.c
src/mesa/drivers/dri/i965/intel_context.c
src/mesa/drivers/dri/i965/intel_context.h
src/mesa/drivers/dri/i965/intel_screen.c
src/mesa/drivers/dri/mach64/mach64_context.c
src/mesa/drivers/dri/mach64/mach64_context.h
src/mesa/drivers/dri/mach64/mach64_ioctl.c
src/mesa/drivers/dri/mach64/mach64_ioctl.h
src/mesa/drivers/dri/mach64/mach64_screen.c
src/mesa/drivers/dri/mga/mga_xmesa.c
src/mesa/drivers/dri/mga/mgacontext.h
src/mesa/drivers/dri/mga/mgaioctl.c
src/mesa/drivers/dri/nouveau/nouveau_context.c
src/mesa/drivers/dri/nouveau/nouveau_context.h
src/mesa/drivers/dri/nouveau/nouveau_screen.c
src/mesa/drivers/dri/r128/r128_context.c
src/mesa/drivers/dri/r128/r128_context.h
src/mesa/drivers/dri/r128/r128_ioctl.c
src/mesa/drivers/dri/r128/r128_ioctl.h
src/mesa/drivers/dri/r128/r128_screen.c
src/mesa/drivers/dri/r200/r200_context.c
src/mesa/drivers/dri/r200/r200_context.h
src/mesa/drivers/dri/r200/r200_ioctl.c
src/mesa/drivers/dri/r200/r200_ioctl.h
src/mesa/drivers/dri/r300/radeon_context.c
src/mesa/drivers/dri/r300/radeon_context.h
src/mesa/drivers/dri/r300/radeon_ioctl.c
src/mesa/drivers/dri/r300/radeon_ioctl.h
src/mesa/drivers/dri/radeon/radeon_context.c
src/mesa/drivers/dri/radeon/radeon_screen.c
src/mesa/drivers/dri/sis/sis_screen.c
src/mesa/drivers/dri/tdfx/tdfx_screen.c
src/mesa/drivers/dri/unichrome/via_context.c
src/mesa/drivers/dri/unichrome/via_context.h
src/mesa/drivers/dri/unichrome/via_ioctl.c
src/mesa/drivers/dri/unichrome/via_ioctl.h
src/mesa/drivers/dri/unichrome/via_screen.c

index e7fbf8e8b8b68a244e309652dbb753691ce5e35d..1b637afaf387ae0d6689e018feb1d765cddd4f25 100644 (file)
@@ -170,7 +170,7 @@ struct __DRIframeTrackingExtensionRec {
  * Used by drivers that implement the GLX_SGI_video_sync extension.
  */
 #define __DRI_MEDIA_STREAM_COUNTER "DRI_MediaStreamCounter"
-#define __DRI_MEDIA_STREAM_COUNTER_VERSION 1
+#define __DRI_MEDIA_STREAM_COUNTER_VERSION 2
 struct __DRImediaStreamCounterExtensionRec {
     __DRIextension base;
 
@@ -189,6 +189,18 @@ struct __DRImediaStreamCounterExtensionRec {
     int (*waitForMSC)(__DRIdrawable *drawable,
                      int64_t target_msc, int64_t divisor, int64_t remainder,
                      int64_t * msc, int64_t * sbc);
+
+    /**
+     * Like the screen version of getMSC, but also takes a drawable so that
+     * the appropriate pipe's counter can be retrieved.
+     *
+     * Get the number of vertical refreshes since some point in time before
+     * this function was first called (i.e., system start up).
+     *
+     * \since Internal API version 2
+     */
+    int (*getDrawableMSC)(__DRIscreen *screen, void *drawablePrivate,
+                         int64_t *msc);
 };
 
 
index 707e398d1d6028387a7b369704c1ea4ab06608e8..7e8a0c146d531febbd07b2b224d33c1189897136 100644 (file)
@@ -1941,13 +1941,24 @@ static int __glXGetVideoSyncSGI(unsigned int *count)
    if ( (gc != NULL) && gc->isDirect ) {
       __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy,
                                                            gc->screen );
-      if (psc->msc != NULL && psc->driScreen.private != NULL) {
-        int       ret;
-        int64_t   temp;
-
-        ret = psc->msc->getMSC(&psc->driScreen, &temp);
-        *count = (unsigned) temp;
-        return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
+      if ( psc->msc && psc->driScreen.private ) {
+          __DRIdrawable * const pdraw = 
+              GetDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
+         int64_t temp; 
+         int ret;
+         /*
+          * Try to use getDrawableMSC first so we get the right
+          * counter...
+          */
+         if (psc->msc->base.version >= 2 && psc->msc->getDrawableMSC)
+             ret = (*psc->msc->getDrawableMSC)( &psc->driScreen,
+                                                pdraw->private,
+                                                & temp);
+         else
+             ret = (*psc->msc->getMSC)( &psc->driScreen, & temp);
+         *count = (unsigned) temp;
+         return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
       }
    }
 #else
@@ -1970,16 +1981,14 @@ static int __glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count
       if (psc->msc != NULL && psc->driScreen.private ) {
         __DRIdrawable * const pdraw = 
             GetDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
-        if (pdraw != NULL) {
-           int       ret;
-           int64_t   msc;
-           int64_t   sbc;
-
-           ret = (*psc->msc->waitForMSC)(pdraw, 0,
-                                         divisor, remainder, &msc, &sbc);
-           *count = (unsigned) msc;
-           return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
-        }
+        int       ret;
+        int64_t   msc;
+        int64_t   sbc;
+
+        ret = (*psc->msc->waitForMSC)(pdraw, 0, divisor, remainder, &msc,
+                                      &sbc);
+        *count = (unsigned) msc;
+        return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
       }
    }
 #else
index d59ea0ddad04dde9d068c251dd6bd271292feb0a..2e2e64c4d180e7fa709197b7c05b08b6f4ce279a 100644 (file)
@@ -356,10 +356,18 @@ static void driSwapBuffers(__DRIdrawable *drawable)
                                   &rect, 1, GL_TRUE);
 }
 
+static int driDrawableGetMSC( __DRIscreen *screen, void *drawablePrivate,
+                             int64_t *msc )
+{
+    __DRIscreenPrivate *sPriv = screen->private;
+
+    return sPriv->DriverAPI.GetDrawableMSC( sPriv, drawablePrivate, msc );
+}
+
 /**
  * Called directly from a number of higher-level GLX functions.
  */
-static int driGetMSC( __DRIscreen *screen, int64_t *msc )
+static int driGetMSC( __DRIscreen *screen, void *drawablePrivate, int64_t *msc )
 {
     __DRIscreenPrivate *sPriv = screen->private;
 
@@ -396,6 +404,7 @@ const __DRImediaStreamCounterExtension driMediaStreamCounterExtension = {
     { __DRI_MEDIA_STREAM_COUNTER, __DRI_MEDIA_STREAM_COUNTER_VERSION },
     driGetMSC,
     driWaitForMSC,
+    driDrawableGetMSC,
 };
 
 static void driCopySubBuffer(__DRIdrawable *drawable,
@@ -471,6 +480,8 @@ static void *driCreateNewDrawable(__DRIscreen *screen,
     pdp->numBackClipRects = 0;
     pdp->pClipRects = NULL;
     pdp->pBackClipRects = NULL;
+    pdp->vblSeq = 0;
+    pdp->vblFlags = 0;
 
     psp = (__DRIscreenPrivate *)screen->private;
     pdp->driScreenPriv = psp;
@@ -485,6 +496,7 @@ static void *driCreateNewDrawable(__DRIscreen *screen,
     pdraw->private = pdp;
     pdraw->destroyDrawable = driDestroyDrawable;
     pdraw->swapBuffers = driSwapBuffers;  /* called by glXSwapBuffers() */
+    pdp->msc_base = 0;
 
     /* This special default value is replaced with the configured
      * default value when the drawable is first bound to a direct
index 91992a9a24225133def35d4438655b85f6ff466e..def07758398e83f2cd33d3f4e377f2b4a4620a7c 100644 (file)
@@ -206,6 +206,14 @@ struct __DriverAPIRec {
      */
     void (*setTexOffset)(__DRIcontext *pDRICtx, GLint texname,
                         unsigned long long offset, GLint depth, GLuint pitch);
+
+    /**
+     * New version of GetMSC so we can pass drawable data to the low level
+     * DRM driver (e.g. pipe info).
+     */
+    int (*GetDrawableMSC) ( __DRIscreenPrivate * priv,
+                           __DRIdrawablePrivate *drawablePrivate,
+                           int64_t *count);
 };
 
 
@@ -317,6 +325,32 @@ struct __DRIdrawablePrivateRec {
     drm_clip_rect_t *pBackClipRects;
     /*@}*/
 
+    /**
+     * \name Vertical blank tracking information
+     * Used for waiting on vertical blank events.
+     */
+    /*@{*/
+    unsigned int vblSeq;
+    unsigned int vblFlags;
+    /*@}*/
+
+    /**
+     * \name Monotonic MSC tracking
+     *
+     * Low level driver is responsible for updating msc_base and
+     * vblSeq values so that higher level code can calculate
+     * a new msc value or msc target for a WaitMSC call.  The new value
+     * will be:
+     *   msc = msc_base + get_vblank_count() - vblank_base;
+     *
+     * And for waiting on a value, core code will use:
+     *   actual_target = target_msc - msc_base + vblank_base;
+     */
+    /*@{*/
+    int64_t vblank_base;
+    int64_t msc_base;
+    /*@}*/
+
     /**
      * Pointer to context to which this drawable is currently bound.
      */
index 3b5acfecb128cff27f79f54adee1a27b370aa065..059644046329fcd936025e604e314a2425d719f3 100644 (file)
 #include "vblank.h"
 #include "xmlpool.h"
 
+static unsigned int msc_to_vblank(__DRIdrawablePrivate * dPriv, int64_t msc)
+{
+   return (unsigned int)(msc - dPriv->msc_base + dPriv->vblank_base);
+}
+
+static int64_t vblank_to_msc(__DRIdrawablePrivate * dPriv, unsigned int vblank)
+{
+   return (int64_t)(vblank - dPriv->vblank_base + dPriv->msc_base);
+}
+
 
 /****************************************************************************/
 /**
@@ -42,7 +52,7 @@
  *
  * Stores the 64-bit count of vertical refreshes since some (arbitrary)
  * point in time in \c count.  Unless the value wraps around, which it
- * may, it will never decrease.
+ * may, it will never decrease for a given drawable.
  *
  * \warning This function is called from \c glXGetVideoSyncSGI, which expects
  * a \c count of type \c unsigned (32-bit), and \c glXGetSyncValuesOML, which 
  * currently always returns a \c sequence of type \c unsigned.
  *
  * \param priv   Pointer to the DRI screen private struct.
+ * \param dPriv  Pointer to the DRI drawable private struct
  * \param count  Storage to hold MSC counter.
  * \return       Zero is returned on success.  A negative errno value
  *               is returned on failure.
  */
-int driGetMSC32( __DRIscreenPrivate * priv, int64_t * count )
+int driDrawableGetMSC32( __DRIscreenPrivate * priv,
+                        __DRIdrawablePrivate * dPriv,
+                        int64_t * count)
 {
    drmVBlank vbl;
    int ret;
@@ -63,13 +76,46 @@ int driGetMSC32( __DRIscreenPrivate * priv, int64_t * count )
 
    vbl.request.type = DRM_VBLANK_RELATIVE;
    vbl.request.sequence = 0;
+   if ( dPriv && dPriv->vblFlags & VBLANK_FLAG_SECONDARY )
+      vbl.request.type |= DRM_VBLANK_SECONDARY;
 
    ret = drmWaitVBlank( priv->fd, &vbl );
-   *count = (int64_t)vbl.reply.sequence;
+
+   if (dPriv) {
+      *count = vblank_to_msc(dPriv, vbl.reply.sequence);
+   } else {
+      /* Old driver (no knowledge of drawable MSC callback) */
+      *count = vbl.reply.sequence;
+   }
 
    return ret;
 }
 
+/**
+ * Get the current MSC refresh counter.
+ *
+ * Stores the 64-bit count of vertical refreshes since some (arbitrary)
+ * point in time in \c count.  Unless the value wraps around, which it
+ * may, it will never decrease.
+ *
+ * \warning This function is called from \c glXGetVideoSyncSGI, which expects
+ * a \c count of type \c unsigned (32-bit), and \c glXGetSyncValuesOML, which 
+ * expects a \c count of type \c int64_t (signed 64-bit).  The kernel ioctl 
+ * currently always returns a \c sequence of type \c unsigned.
+ *
+ * Since this function doesn't take a drawable, it may end up getting the MSC
+ * value from a pipe not associated with the caller's context, resuling in
+ * undesired behavior.
+ *
+ * \param priv   Pointer to the DRI screen private struct.
+ * \param count  Storage to hold MSC counter.
+ * \return       Zero is returned on success.  A negative errno value
+ *               is returned on failure.
+ */
+int driGetMSC32( __DRIscreenPrivate * priv, int64_t * count )
+{
+   return driDrawableGetMSC32(priv, NULL, count);
+}
 
 /****************************************************************************/
 /**
@@ -123,7 +169,9 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv,
           */
          vbl.request.type = dont_wait ? DRM_VBLANK_RELATIVE :
                                         DRM_VBLANK_ABSOLUTE;
-         vbl.request.sequence = next;
+         vbl.request.sequence = next ? msc_to_vblank(priv, next) : 0;
+        if ( priv->vblFlags & VBLANK_FLAG_SECONDARY )
+           vbl.request.type |= DRM_VBLANK_SECONDARY;
 
         if ( drmWaitVBlank( priv->driScreenPriv->fd, &vbl ) != 0 ) {
            /* FIXME: This doesn't seem like the right thing to return here.
@@ -131,8 +179,10 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv,
            return GLX_BAD_CONTEXT;
         }
 
+        *msc = vblank_to_msc(priv, vbl.reply.sequence);
+
          dont_wait = 0;
-         if (target_msc != 0 && vbl.reply.sequence == target)
+         if (target_msc != 0 && *msc == target)
             break;
 
          /* Assuming the wait-done test fails, the next refresh to wait for
@@ -142,9 +192,9 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv,
           * If this refresh has already happened, we add divisor to obtain 
           * the next refresh after the current one that will satisfy it.
           */
-         r = (vbl.reply.sequence % (unsigned int)divisor);
-         next = (vbl.reply.sequence - r + (unsigned int)remainder);
-         if (next <= vbl.reply.sequence) next += (unsigned int)divisor;
+         r = (*msc % (unsigned int)divisor);
+         next = (*msc - r + (unsigned int)remainder);
+         if (next <= *msc) next += (unsigned int)divisor;
 
       } while ( r != (unsigned int)remainder );
    }
@@ -154,7 +204,10 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv,
        */
 
       vbl.request.type = DRM_VBLANK_ABSOLUTE;
-      vbl.request.sequence = target_msc;
+      vbl.request.sequence = target_msc ? msc_to_vblank(priv, target_msc) : 0;
+
+      if ( priv->vblFlags & VBLANK_FLAG_SECONDARY )
+        vbl.request.type |= DRM_VBLANK_SECONDARY;
 
       if ( drmWaitVBlank( priv->driScreenPriv->fd, &vbl ) != 0 ) {
         /* FIXME: This doesn't seem like the right thing to return here.
@@ -163,8 +216,8 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv,
       }
    }
 
-   *msc  = (target_msc & 0xffffffff00000000LL);
-   *msc |= vbl.reply.sequence;
+   *msc = vblank_to_msc(priv, vbl.reply.sequence);
+
    if ( *msc < target_msc ) {
       *msc += 0x0000000100000000LL;
    }
@@ -252,16 +305,21 @@ static int do_wait( drmVBlank * vbl, GLuint * vbl_seq, int fd )
  * direct rendering context.
  */
 
-void driDrawableInitVBlank( __DRIdrawablePrivate *priv, GLuint flags,
-                           GLuint *vbl_seq )
+void driDrawableInitVBlank( __DRIdrawablePrivate *priv )
 {
    if ( priv->swap_interval == (unsigned)-1 ) {
       /* Get current vertical blank sequence */
-      drmVBlank vbl = { .request={ .type = DRM_VBLANK_RELATIVE, .sequence = 0 } };
-      do_wait( &vbl, vbl_seq, priv->driScreenPriv->fd );
-
-      priv->swap_interval = (flags & (VBLANK_FLAG_THROTTLE |
-                                     VBLANK_FLAG_SYNC)) != 0 ? 1 : 0;
+      drmVBlank vbl;
+      vbl.request.type = DRM_VBLANK_RELATIVE;
+      if ( priv->vblFlags & VBLANK_FLAG_SECONDARY )
+        vbl.request.type |= DRM_VBLANK_SECONDARY;
+      vbl.request.sequence = 0;
+      do_wait( &vbl, &priv->vblSeq, priv->driScreenPriv->fd );
+      priv->vblank_base = priv->vblSeq;
+
+      priv->swap_interval =
+        (priv->vblFlags & (VBLANK_FLAG_THROTTLE | VBLANK_FLAG_SYNC)) ? 1 : 0;
    }
 }
 
index ec83adc78dd1e98efeed9c24d6852215a0f1537d..e8550b281244ed2332783d350adf335858565834 100644 (file)
                                          */
 
 extern int driGetMSC32( __DRIscreenPrivate * priv, int64_t * count );
+extern int driDrawableGetMSC32( __DRIscreenPrivate * priv,
+                               __DRIdrawablePrivate * drawablePrivate,
+                               int64_t * count);
 extern int driWaitForMSC32( __DRIdrawablePrivate *priv,
     int64_t target_msc, int64_t divisor, int64_t remainder, int64_t * msc );
 extern GLuint driGetDefaultVBlankFlags( const driOptionCache *optionCache );
-extern void driDrawableInitVBlank ( __DRIdrawablePrivate *priv, GLuint flags,
-                                   GLuint *vbl_seq );
+extern void driDrawableInitVBlank ( __DRIdrawablePrivate *priv );
 extern unsigned driGetVBlankInterval( const  __DRIdrawablePrivate *priv,
                                      GLuint flags );
 extern void driGetCurrentVBlank( const  __DRIdrawablePrivate *priv,
index 3a5551eeb375f9aa89e598714413d6065d56fae6..173c5fa952a005657fd578385efd45e6fb4905f9 100644 (file)
@@ -615,6 +615,7 @@ static const struct __DriverAPIRec ffbAPI = {
    .UnbindContext   = ffbUnbindContext,
    .GetSwapInfo     = NULL,
    .GetMSC          = NULL,
+   .GetDrawableMSC  = NULL,
    .WaitForMSC      = NULL,
    .WaitForSBC      = NULL,
    .SwapBuffersMSC  = NULL
index 3c7ec96ff3d6b2fcd26d6dde86fedd7b95cb595b..1a0d3c33d7b149411910c82b0fc4d6f3d0143d55 100644 (file)
@@ -413,6 +413,7 @@ static const struct __DriverAPIRec i810API = {
    .UnbindContext   = i810UnbindContext,
    .GetSwapInfo     = NULL,
    .GetMSC          = NULL,
+   .GetDrawableMSC  = NULL,
    .WaitForMSC      = NULL,
    .WaitForSBC      = NULL,
    .SwapBuffersMSC  = NULL
index 46a67b141e7170fdfc29a0756413be5a76e002ae..faa13adbcb3f903dde150ff3484e0eda9ed2e848 100644 (file)
@@ -243,7 +243,7 @@ intelWindowMoved(struct intel_context *intel)
                                     .y2 = sarea->planeB_y + sarea->planeB_h };
       GLint areaA = driIntersectArea( drw_rect, planeA_rect );
       GLint areaB = driIntersectArea( drw_rect, planeB_rect );
-      GLuint flags = intel_fb->vblank_flags;
+      GLuint flags = dPriv->vblFlags;
       GLboolean pf_active;
       GLint pf_planes;
 
@@ -311,19 +311,24 @@ intelWindowMoved(struct intel_context *intel)
       /* Update vblank info
        */
       if (areaB > areaA || (areaA == areaB && areaB > 0)) {
-        flags = intel_fb->vblank_flags | VBLANK_FLAG_SECONDARY;
+        flags = dPriv->vblFlags | VBLANK_FLAG_SECONDARY;
       } else {
-        flags = intel_fb->vblank_flags & ~VBLANK_FLAG_SECONDARY;
+        flags = dPriv->vblFlags & ~VBLANK_FLAG_SECONDARY;
       }
 
-      if (flags != intel_fb->vblank_flags && intel_fb->vblank_flags &&
-         !(intel_fb->vblank_flags & VBLANK_FLAG_NO_IRQ)) {
+      /* Check to see if we changed pipes */
+      if (flags != dPriv->vblFlags && dPriv->vblFlags &&
+         !(dPriv->vblFlags & VBLANK_FLAG_NO_IRQ)) {
+        int64_t count;
         drmVBlank vbl;
         int i;
 
+        /*
+         * Deal with page flipping
+         */
         vbl.request.type = DRM_VBLANK_ABSOLUTE;
 
-        if ( intel_fb->vblank_flags & VBLANK_FLAG_SECONDARY ) {
+        if ( dPriv->vblFlags & VBLANK_FLAG_SECONDARY ) {
            vbl.request.type |= DRM_VBLANK_SECONDARY;
         }
 
@@ -337,9 +342,19 @@ intelWindowMoved(struct intel_context *intel)
            drmWaitVBlank(intel->driFd, &vbl);
         }
 
-        intel_fb->vblank_flags = flags;
-        driGetCurrentVBlank(dPriv, intel_fb->vblank_flags, &intel_fb->vbl_seq);
-        intel_fb->vbl_waited = intel_fb->vbl_seq;
+        /*
+         * Update msc_base from old pipe
+         */
+        driDrawableGetMSC32(dPriv->driScreenPriv, dPriv, &count);
+        dPriv->msc_base = count;
+        /*
+         * Then get new vblank_base and vblSeq values
+         */
+        dPriv->vblFlags = flags;
+        driGetCurrentVBlank(dPriv, dPriv->vblFlags, &dPriv->vblSeq);
+        dPriv->vblank_base = dPriv->vblSeq;
+
+        intel_fb->vbl_waited = dPriv->vblSeq;
 
         for (i = 0; i < intel_fb->pf_num_pages; i++) {
            if (intel_fb->color_rb[i])
@@ -347,7 +362,7 @@ intelWindowMoved(struct intel_context *intel)
         }
       }
    } else {
-      intel_fb->vblank_flags &= ~VBLANK_FLAG_SECONDARY;
+      dPriv->vblFlags &= ~VBLANK_FLAG_SECONDARY;
    }
 
    /* Update Mesa's notion of window size */
@@ -820,10 +835,10 @@ intelSwapBuffers(__DRIdrawablePrivate * dPriv)
  */
 
 static GLboolean
-intelScheduleSwap(const __DRIdrawablePrivate * dPriv, GLboolean *missed_target)
+intelScheduleSwap(__DRIdrawablePrivate * dPriv, GLboolean *missed_target)
 {
    struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
-   unsigned int interval = driGetVBlankInterval(dPriv, intel_fb->vblank_flags);
+   unsigned int interval = driGetVBlankInterval(dPriv, dPriv->vblFlags);
    struct intel_context *intel =
       intelScreenContext(dPriv->driScreenPriv->private);
    const intelScreenPrivate *intelScreen = intel->intelScreen;
@@ -831,24 +846,24 @@ intelScheduleSwap(const __DRIdrawablePrivate * dPriv, GLboolean *missed_target)
    drm_i915_vblank_swap_t swap;
    GLboolean ret;
 
-   if (!intel_fb->vblank_flags ||
-       (intel_fb->vblank_flags & VBLANK_FLAG_NO_IRQ) ||
+   if (!dPriv->vblFlags ||
+       (dPriv->vblFlags & 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) {
+   if (dPriv->vblFlags & 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;
+   target = swap.sequence = dPriv->vblSeq + interval;
 
-   if ( intel_fb->vblank_flags & VBLANK_FLAG_SECONDARY ) {
+   if ( dPriv->vblFlags & VBLANK_FLAG_SECONDARY ) {
       swap.seqtype |= DRM_VBLANK_SECONDARY;
    }
 
@@ -866,14 +881,14 @@ intelScheduleSwap(const __DRIdrawablePrivate * dPriv, GLboolean *missed_target)
 
    if (!drmCommandWriteRead(intel->driFd, DRM_I915_VBLANK_SWAP, &swap,
                            sizeof(swap))) {
-      intel_fb->vbl_seq = swap.sequence;
+      dPriv->vblSeq = swap.sequence;
       swap.sequence -= target;
       *missed_target = swap.sequence > 0 && swap.sequence <= (1 << 23);
 
       intel_get_renderbuffer(&intel_fb->Base, BUFFER_BACK_LEFT)->vbl_pending =
         intel_get_renderbuffer(&intel_fb->Base,
                                BUFFER_FRONT_LEFT)->vbl_pending =
-        intel_fb->vbl_seq;
+        dPriv->vblSeq;
 
       if (swap.seqtype & DRM_VBLANK_FLIP) {
         intel_flip_renderbuffers(intel_fb);
@@ -918,7 +933,7 @@ intelSwapBuffers(__DRIdrawablePrivate * dPriv)
 
          if (screen->current_rotation != 0 ||
             !intelScheduleSwap(dPriv, &missed_target)) {
-           driWaitForVBlank(dPriv, &intel_fb->vbl_seq, intel_fb->vblank_flags,
+           driWaitForVBlank(dPriv, &dPriv->vblSeq, dPriv->vblFlags,
                             &missed_target);
 
            if (screen->current_rotation != 0 || !intelPageFlip(dPriv)) {
index d7af432ad6b50493e63d64a8ed31f3b0b169dfa7..b85b0c2939c19d2b639b0ee5de3286aed8e09424 100644 (file)
@@ -616,18 +616,17 @@ intelMakeCurrent(__DRIcontextPrivate * driContextPriv,
            if (driDrawPriv->swap_interval == (unsigned)-1) {
               int i;
 
-              intel_fb->vblank_flags = (intel->intelScreen->irq_active != 0)
+              driDrawPriv->vblFlags = (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_fb->vbl_waited = intel_fb->vbl_seq;
+              driDrawableInitVBlank(driDrawPriv);
+              intel_fb->vbl_waited = driDrawPriv->vblSeq;
 
               for (i = 0; i < (intel->intelScreen->third.handle ? 3 : 2); i++) {
                  if (intel_fb->color_rb[i])
-                    intel_fb->color_rb[i]->vbl_pending = intel_fb->vbl_seq;
+                    intel_fb->color_rb[i]->vbl_pending = driDrawPriv->vblSeq;
               }
            }
            intel->driDrawable = driDrawPriv;
@@ -731,6 +730,7 @@ intelContendedLock(struct intel_context *intel, GLuint flags)
  */
 void LOCK_HARDWARE( struct intel_context *intel )
 {
+    __DRIdrawablePrivate *dPriv = intel->driDrawable;
     char __ret=0;
     struct intel_framebuffer *intel_fb = NULL;
     struct intel_renderbuffer *intel_rb = NULL;
@@ -748,14 +748,14 @@ void LOCK_HARDWARE( struct intel_context *intel )
                                    BUFFER_BACK_LEFT);
     }
 
-    if (intel_rb && intel_fb->vblank_flags &&
-       !(intel_fb->vblank_flags & VBLANK_FLAG_NO_IRQ) &&
+    if (intel_rb && dPriv->vblFlags &&
+       !(dPriv->vblFlags & VBLANK_FLAG_NO_IRQ) &&
        (intel_fb->vbl_waited - intel_rb->vbl_pending) > (1<<23)) {
        drmVBlank vbl;
 
        vbl.request.type = DRM_VBLANK_ABSOLUTE;
 
-       if ( intel_fb->vblank_flags & VBLANK_FLAG_SECONDARY ) {
+       if ( dPriv->vblFlags & VBLANK_FLAG_SECONDARY ) {
            vbl.request.type |= DRM_VBLANK_SECONDARY;
        }
 
index 411d634231739da545b8e45b2a409176cde374fc..f9a11d02e30f4d3e6eef107661440f67764a7409 100644 (file)
@@ -50,8 +50,6 @@ struct intel_framebuffer
 
    /* VBI
     */
-   GLuint vbl_seq;
-   GLuint vblank_flags;
    GLuint vbl_waited;
 
    int64_t swap_ust;
index 8be5d910a0b322fd7cdd793c5562e113c483cc35..25f5efa7bcfa9e8744b0b3f02ad868b7c1f70970 100644 (file)
@@ -790,6 +790,7 @@ static const struct __DriverAPIRec intelAPI = {
    .UnbindContext = intelUnbindContext,
    .GetSwapInfo = intelGetSwapInfo,
    .GetMSC = driGetMSC32,
+   .GetDrawableMSC = driDrawableGetMSC32,
    .WaitForMSC = driWaitForMSC32,
    .WaitForSBC = NULL,
    .SwapBuffersMSC = NULL,
index d1c1c8afb6a11ac1b957d839619e31e9cf195233..6343f613cc9df681188a01c8010c40521ffd5673 100644 (file)
@@ -76,7 +76,8 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv,
    if (!rect)
    {
        UNLOCK_HARDWARE( intel );
-       driWaitForVBlank( dPriv, &intel->vbl_seq, intel->vblank_flags, & missed_target );
+       driWaitForVBlank( dPriv, &dPriv->vblSeq, dPriv->vblFlags,
+                        &missed_target );
        LOCK_HARDWARE( intel );
    }
 
index 6c8b07350265fba00fb0c449d80b5596a636edab..96ef9d8c208a61bb78b3b01f93a9440aca4f52fb 100644 (file)
@@ -33,6 +33,8 @@
 #include "context.h"
 #include "framebuffer.h"
 #include "macros.h"
+#include "utils.h"
+#include "vblank.h"
 #include "swrast/swrast.h"
 
 GLboolean intel_intersect_cliprects( drm_clip_rect_t *dst,
@@ -190,6 +192,50 @@ void intelWindowMoved( struct intel_context *intel )
       }
    }
 
+   /* Get updated plane info so we sync against the right vblank counter */
+   if (intel->intelScreen->driScrnPriv->ddx_version.minor >= 7) {
+      drmI830Sarea *sarea = intel->sarea;
+      drm_clip_rect_t drw_rect = { .x1 = dPriv->x, .x2 = dPriv->x + dPriv->w,
+                                  .y1 = dPriv->y, .y2 = dPriv->y + dPriv->h };
+      drm_clip_rect_t planeA_rect = { .x1 = sarea->planeA_x, .y1 = sarea->planeA_y,
+                                    .x2 = sarea->planeA_x + sarea->planeA_w,
+                                    .y2 = sarea->planeA_y + sarea->planeA_h };
+      drm_clip_rect_t planeB_rect = { .x1 = sarea->planeB_x, .y1 = sarea->planeB_y,
+                                    .x2 = sarea->planeB_x + sarea->planeB_w,
+                                    .y2 = sarea->planeB_y + sarea->planeB_h };
+      GLint areaA = driIntersectArea( drw_rect, planeA_rect );
+      GLint areaB = driIntersectArea( drw_rect, planeB_rect );
+      GLuint flags = dPriv->vblFlags;
+
+      /* Update vblank info
+       */
+      if (areaB > areaA || (areaA == areaB && areaB > 0)) {
+        flags = dPriv->vblFlags | VBLANK_FLAG_SECONDARY;
+      } else {
+        flags = dPriv->vblFlags & ~VBLANK_FLAG_SECONDARY;
+      }
+
+      /* Check to see if we changed pipes */
+      if (flags != dPriv->vblFlags && dPriv->vblFlags &&
+         !(dPriv->vblFlags & VBLANK_FLAG_NO_IRQ)) {
+        int64_t count;
+
+        /*
+         * Update msc_base from old pipe
+         */
+        driDrawableGetMSC32(dPriv->driScreenPriv, dPriv, &count);
+        dPriv->msc_base = count;
+        /*
+         * Then get new vblank_base and vblSeq values
+         */
+        dPriv->vblFlags = flags;
+        driGetCurrentVBlank(dPriv, dPriv->vblFlags, &dPriv->vblSeq);
+        dPriv->vblank_base = dPriv->vblSeq;
+      }
+   } else {
+      dPriv->vblFlags &= ~VBLANK_FLAG_SECONDARY;
+   }
+
    _mesa_resize_framebuffer(&intel->ctx,
                            (GLframebuffer*)dPriv->driverPrivate,
                            dPriv->w, dPriv->h);
index 9850997aad1f7d8af7483bbade8fd7398de7535d..d654d2d30dea089e703330853c29e2f14415443f 100644 (file)
@@ -342,8 +342,8 @@ GLboolean intelInitContext( struct intel_context *intel,
    GLcontext *shareCtx = (GLcontext *) sharedContextPrivate;
    __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
    intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private;
-   volatile drmI830Sarea *saPriv = (volatile drmI830Sarea *)
-      (((GLubyte *)sPriv->pSAREA)+intelScreen->sarea_priv_offset);
+   volatile drmI830Sarea *saPriv = (drmI830Sarea *)
+     (((GLubyte *)sPriv->pSAREA)+intelScreen->sarea_priv_offset);
 
    if (!_mesa_initialize_context(&intel->ctx,
                                 mesaVis, shareCtx, 
@@ -361,9 +361,6 @@ GLboolean intelInitContext( struct intel_context *intel,
    driParseConfigFiles (&intel->optionCache, &intelScreen->optionCache,
                   intel->driScreen->myNum, "i965");
 
-   intel->vblank_flags = (intel->intelScreen->irq_active != 0)
-          ? driGetDefaultVBlankFlags(&intel->optionCache) : VBLANK_FLAG_NO_IRQ;
-
    ctx->Const.MaxTextureMaxAnisotropy = 2.0;
 
    if (getenv("INTEL_STRICT_CONFORMANCE")) {
@@ -592,17 +589,19 @@ GLboolean intelMakeCurrent(__DRIcontextPrivate *driContextPriv,
    if (driContextPriv) {
       struct intel_context *intel = (struct intel_context *) driContextPriv->driverPrivate;
 
+      driDrawPriv->vblFlags = (intel->intelScreen->irq_active != 0)
+         ? driGetDefaultVBlankFlags(&intel->optionCache) : VBLANK_FLAG_NO_IRQ;
+
+
       if (intel->driReadDrawable != driReadPriv) {
           intel->driReadDrawable = driReadPriv;
       }
 
       if ( intel->driDrawable != driDrawPriv ) {
-        /* Shouldn't the readbuffer be stored also? */
-        driDrawableInitVBlank( driDrawPriv, intel->vblank_flags,
-                     &intel->vbl_seq );
-
         intel->driDrawable = driDrawPriv;
         intelWindowMoved( intel );
+        /* Shouldn't the readbuffer be stored also? */
+        driDrawableInitVBlank( driDrawPriv );
       }
 
       _mesa_make_current(&intel->ctx,
index 65898caaa75ea67a6d6e275e18931ed2d41905a1..5848d0c1ba0262c5cd8b81a50fc5094c97ff1352 100644 (file)
@@ -231,11 +231,6 @@ struct intel_context
     */
    driOptionCache optionCache;
 
-   /* VBI
-    */
-   GLuint vbl_seq;
-   GLuint vblank_flags;
-
    int64_t swap_ust;
    int64_t swap_missed_ust;
 
index e35f7da938731a178a0a4e4d72425089e843ab82..77fd9e386a6340b639cd03733315547621d1eabc 100644 (file)
@@ -549,6 +549,7 @@ static const struct __DriverAPIRec intelAPI = {
    .UnbindContext   = intelUnbindContext,
    .GetSwapInfo     = intelGetSwapInfo,
    .GetMSC          = driGetMSC32,
+   .GetDrawableMSC  = driDrawableGetMSC32,
    .WaitForMSC      = driWaitForMSC32,
    .WaitForSBC      = NULL,
    .SwapBuffersMSC  = NULL,
index ad661e198cda9264687102b74c7cf8ba5293bcee..138e84decb9e2c1d5715d7a1e4f5d1df1a46b7eb 100644 (file)
@@ -100,6 +100,7 @@ GLboolean mach64CreateContext( const __GLcontextModes *glVisual,
 {
    GLcontext *ctx, *shareCtx;
    __DRIscreenPrivate *driScreen = driContextPriv->driScreenPriv;
+   __DRIdrawablePrivate *dPriv = driContextPriv->driDrawablePriv;
    struct dd_function_table functions;
    mach64ContextPtr mmesa;
    mach64ScreenPtr mach64Screen;
@@ -253,7 +254,7 @@ GLboolean mach64CreateContext( const __GLcontextModes *glVisual,
 
    mmesa->do_irqs = (mmesa->mach64Screen->irq && !getenv("MACH64_NO_IRQS"));
 
-   mmesa->vblank_flags = (mmesa->do_irqs)
+   dPriv->vblFlags = (mmesa->do_irqs)
       ? driGetDefaultVBlankFlags(&mmesa->optionCache) : VBLANK_FLAG_NO_IRQ;
 
    driContextPriv->driverPrivate = (void *)mmesa;
@@ -330,8 +331,7 @@ mach64MakeCurrent( __DRIcontextPrivate *driContextPriv,
       }
 
       
-      driDrawableInitVBlank( driDrawPriv, newMach64Ctx->vblank_flags,
-                            &newMach64Ctx->vbl_seq );
+      driDrawableInitVBlank( driDrawPriv );
 
       if ( newMach64Ctx->driDrawable != driDrawPriv ) {
         newMach64Ctx->driDrawable = driDrawPriv;
index 8d89452412bb3f76b6f44492f988db078d772ed3..c6023330245bffbabbc80f195a499f36f888e682 100644 (file)
@@ -263,8 +263,6 @@ struct mach64_context {
 
    /* VBI
     */
-   GLuint vbl_seq;
-   GLuint vblank_flags;
    GLuint do_irqs;
 
    /* Configuration cache
index 36e7d3c5d3defc56ccaea4d50c856d0b77aa6143..7405a27f8eb4b7c722491642bcf75d462e24a13f 100644 (file)
@@ -279,7 +279,7 @@ static int mach64WaitForFrameCompletion( mach64ContextPtr mmesa )
 
 /* Copy the back color buffer to the front color buffer.
  */
-void mach64CopyBuffer( const __DRIdrawablePrivate *dPriv )
+void mach64CopyBuffer( __DRIdrawablePrivate *dPriv )
 {
    mach64ContextPtr mmesa;
    GLint nbox, i, ret;
@@ -320,7 +320,7 @@ void mach64CopyBuffer( const __DRIdrawablePrivate *dPriv )
 #endif
 
    UNLOCK_HARDWARE( mmesa );
-   driWaitForVBlank( dPriv, &mmesa->vbl_seq, mmesa->vblank_flags, &missed_target );
+   driWaitForVBlank( dPriv, &dPriv->vblSeq, dPriv->vblFlags, &missed_target );
    LOCK_HARDWARE( mmesa );
 
    /* use front buffer cliprects */
index 52fe86348456f90e570644a9e651345159f48678..c28bf31c49f36ed081dbb183eab499c7283320a2 100644 (file)
@@ -78,7 +78,7 @@ extern void mach64FireBlitLocked( mach64ContextPtr mmesa, void *buffer,
                                  GLint offset, GLint pitch, GLint format,
                                  GLint x, GLint y, GLint width, GLint height );
 
-extern void mach64CopyBuffer( const __DRIdrawablePrivate *dPriv );
+extern void mach64CopyBuffer( __DRIdrawablePrivate *dPriv );
 #if ENABLE_PERF_BOXES
 extern void mach64PerformanceCounters( mach64ContextPtr mmesa );
 extern void mach64PerformanceBoxesLocked( mach64ContextPtr mmesa );
index 04eb0815149b6abf506db90a430d4c8f454f8bf2..a04b7754842e59f707a9e4f34adac9b3f6d4b525 100644 (file)
@@ -484,6 +484,7 @@ static struct __DriverAPIRec mach64API = {
    .UnbindContext   = mach64UnbindContext,
    .GetSwapInfo     = NULL,
    .GetMSC          = driGetMSC32,
+   .GetDrawableMSC  = driDrawableGetMSC32,
    .WaitForMSC      = driWaitForMSC32,
    .WaitForSBC      = NULL,
    .SwapBuffersMSC  = NULL
index 2f3516fd38c1909ad97015daacc124bb74aa32e0..31042f9739b88f054648b4c40fed755daad7b58f 100644 (file)
@@ -452,6 +452,7 @@ mgaCreateContext( const __GLcontextModes *mesaVis,
    GLcontext *ctx, *shareCtx;
    mgaContextPtr mmesa;
    __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+   __DRIdrawablePrivate *dPriv = driContextPriv->driDrawablePriv;
    mgaScreenPrivate *mgaScreen = (mgaScreenPrivate *)sPriv->private;
    drm_mga_sarea_t *saPriv = (drm_mga_sarea_t *)(((char*)sPriv->pSAREA)+
                                              mgaScreen->sarea_priv_offset);
@@ -650,7 +651,7 @@ mgaCreateContext( const __GLcontextModes *mesaVis,
                                    debug_control );
 #endif
 
-   mmesa->vblank_flags = (mmesa->mgaScreen->irq == 0)
+   dPriv->vblFlags = (mmesa->mgaScreen->irq == 0)
        ? VBLANK_FLAG_NO_IRQ : driGetDefaultVBlankFlags(&mmesa->optionCache);
 
    (*dri_interface->getUST)( & mmesa->swap_ust );
@@ -882,8 +883,8 @@ mgaMakeCurrent(__DRIcontextPrivate *driContextPriv,
       mgaContextPtr mmesa = (mgaContextPtr) driContextPriv->driverPrivate;
 
       if (mmesa->driDrawable != driDrawPriv) {
-        driDrawableInitVBlank( driDrawPriv, mmesa->vblank_flags,
-                               &mmesa->vbl_seq );
+        driDrawableInitVBlank( driDrawPriv );
+
         mmesa->driDrawable = driDrawPriv;
         mmesa->dirty = ~0; 
         mmesa->dirty_cliprects = (MGA_FRONT|MGA_BACK); 
@@ -948,6 +949,7 @@ static const struct __DriverAPIRec mgaAPI = {
    .UnbindContext   = mgaUnbindContext,
    .GetSwapInfo     = getSwapInfo,
    .GetMSC          = driGetMSC32,
+   .GetDrawableMSC  = driDrawableGetMSC32,
    .WaitForMSC      = driWaitForMSC32,
    .WaitForSBC      = NULL,
    .SwapBuffersMSC  = NULL
index 2124006ade600b7b6d470aaa6487d864c7270139..2681976fc2b946e336b45910e9ed4424fbf3b041 100644 (file)
@@ -258,11 +258,6 @@ struct mga_context_t {
    drmBufPtr  vertex_dma_buffer;
    drmBufPtr  iload_buffer;
 
-   /* VBI
-    */
-   GLuint vbl_seq;
-   GLuint vblank_flags;
-
    int64_t swap_ust;
    int64_t swap_missed_ust;
 
index 679d68892592dc71b65dfb9408aa6ac186f48eb6..94126a31f91e1fbaf225f7084f13c1407f5a6f44 100644 (file)
@@ -428,8 +428,7 @@ void mgaCopyBuffer( const __DRIdrawablePrivate *dPriv )
    FLUSH_BATCH( mmesa );
 
    mgaWaitForFrameCompletion( mmesa );
-   driWaitForVBlank( dPriv, & mmesa->vbl_seq, mmesa->vblank_flags,
-                    & missed_target );
+   driWaitForVBlank( dPriv, & dPriv->vblSeq, dPriv->vblFlags, & missed_target );
    if ( missed_target ) {
       mmesa->swap_missed_count++;
       (void) (*dri_interface->getUST)( & mmesa->swap_missed_ust );
index a8569a9f1537fed0f5154ddd29d84fcc959ec0bb..5ef24d827064a000f044c82dd75e329df48f3177 100644 (file)
@@ -283,7 +283,7 @@ GLboolean nouveauMakeCurrent( __DRIcontextPrivate *driContextPriv,
                struct gl_framebuffer *read_fb =
                        (struct gl_framebuffer*)driReadPriv->driverPrivate;
 
-               driDrawableInitVBlank(driDrawPriv, nmesa->vblank_flags, &nmesa->vblank_seq );
+               driDrawableInitVBlank(driDrawPriv);
                nmesa->driDrawable = driDrawPriv;
 
                _mesa_resize_framebuffer(nmesa->glCtx, draw_fb,
index 9aff0ee668b28fe1905fc70edf2079facea86f9b..a617dd62826bae05ca96102b6d620dbee65e5c5f 100644 (file)
@@ -182,10 +182,6 @@ typedef struct nouveau_context {
        /* Configuration cache */
        driOptionCache optionCache;
 
-       /* vblank stuff */
-       uint32_t vblank_flags;
-       uint32_t vblank_seq;
-
        GLuint new_state;
        GLuint new_render_state;
        GLuint render_index;
index 3e7bab63f34cde788aaecf6c60245133e4bc4560..533b4b1e6e15335dde34b986fa7631f3f4a0d4ae 100644 (file)
@@ -205,6 +205,7 @@ static const struct __DriverAPIRec nouveauAPI = {
        .UnbindContext   = nouveauUnbindContext,
        .GetSwapInfo     = nouveauGetSwapInfo,
        .GetMSC          = driGetMSC32,
+       .GetDrawableMSC  = driDrawableGetMSC32,
        .WaitForMSC      = driWaitForMSC32,
        .WaitForSBC      = NULL,
        .SwapBuffersMSC  = NULL,
index c9fe11f38bd7d58e032785f9828b4df5e8a35d7a..25efe5e4cd744087e713dd9ca2fa21117de5e88b 100644 (file)
@@ -113,6 +113,7 @@ GLboolean r128CreateContext( const __GLcontextModes *glVisual,
 {
    GLcontext *ctx, *shareCtx;
    __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+   __DRIdrawablePrivate *dPriv = driContextPriv->driDrawablePriv;
    struct dd_function_table functions;
    r128ContextPtr rmesa;
    r128ScreenPtr r128scrn;
@@ -262,7 +263,7 @@ GLboolean r128CreateContext( const __GLcontextModes *glVisual,
    r128DDInitSpanFuncs( ctx );
    r128DDInitState( rmesa );
 
-   rmesa->vblank_flags = (rmesa->r128Screen->irq != 0)
+   dPriv->vblFlags = (rmesa->r128Screen->irq != 0)
        ? driGetDefaultVBlankFlags(&rmesa->optionCache) : VBLANK_FLAG_NO_IRQ;
 
    driContextPriv->driverPrivate = (void *)rmesa;
@@ -347,8 +348,7 @@ r128MakeCurrent( __DRIcontextPrivate *driContextPriv,
         newR128Ctx->dirty = R128_UPLOAD_ALL;
       }
 
-      driDrawableInitVBlank( driDrawPriv, newR128Ctx->vblank_flags,
-                            &newR128Ctx->vbl_seq );
+      driDrawableInitVBlank( driDrawPriv );
       newR128Ctx->driDrawable = driDrawPriv;
 
       _mesa_make_current( newR128Ctx->glCtx,
index c51dd7fa58dc4ce5011850499380e3ae673baf1d..3f7416e9cc9d28dcdfc10076eea3fbaac0536eb4 100644 (file)
@@ -210,11 +210,6 @@ struct r128_context {
    GLuint c_textureBytes;
    GLuint c_vertexBuffers;
 
-   /* VBI
-    */
-   GLuint vbl_seq;
-   GLuint vblank_flags;
-
    /* Configuration cache
     */
    driOptionCache optionCache;
index b0dba7d04e12d81eca8f9fcaa82138730b972637..e04c0872f0d823434bc08448d2e446a1c431d704 100644 (file)
@@ -249,7 +249,7 @@ static int r128WaitForFrameCompletion( r128ContextPtr rmesa )
 
 /* Copy the back color buffer to the front color buffer.
  */
-void r128CopyBuffer( const __DRIdrawablePrivate *dPriv )
+void r128CopyBuffer( __DRIdrawablePrivate *dPriv )
 {
    r128ContextPtr rmesa;
    GLint nbox, i, ret;
@@ -282,7 +282,7 @@ void r128CopyBuffer( const __DRIdrawablePrivate *dPriv )
    }
 
    UNLOCK_HARDWARE( rmesa );
-   driWaitForVBlank( dPriv, &rmesa->vbl_seq, rmesa->vblank_flags, &missed_target );
+   driWaitForVBlank( dPriv, &dPriv->vblSeq, dPriv->vblFlags, &missed_target );
    LOCK_HARDWARE( rmesa );
 
    nbox = dPriv->numClipRects; /* must be in locked region */
@@ -328,7 +328,7 @@ void r128CopyBuffer( const __DRIdrawablePrivate *dPriv )
 #endif
 }
 
-void r128PageFlip( const __DRIdrawablePrivate *dPriv )
+void r128PageFlip( __DRIdrawablePrivate *dPriv )
 {
    r128ContextPtr rmesa;
    GLint ret;
@@ -359,7 +359,7 @@ void r128PageFlip( const __DRIdrawablePrivate *dPriv )
    }
 
    UNLOCK_HARDWARE( rmesa );
-   driWaitForVBlank( dPriv, &rmesa->vbl_seq, rmesa->vblank_flags, &missed_target );
+   driWaitForVBlank( dPriv, &dPriv->vblSeq, dPriv->vblFlags, &missed_target );
    LOCK_HARDWARE( rmesa );
 
    /* The kernel will have been initialized to perform page flipping
index 95779f09bef37ef1d6148139ee5b128d748e4f39..0f9d11fe699857b48c33cab6b4a2ae7b012b3151 100644 (file)
@@ -86,8 +86,8 @@ extern void r128ReadDepthSpanLocked( r128ContextPtr rmesa,
 extern void r128ReadDepthPixelsLocked( r128ContextPtr rmesa, GLuint n,
                                       const GLint x[], const GLint y[] );
 
-extern void r128CopyBuffer( const __DRIdrawablePrivate *dPriv );
-extern void r128PageFlip( const __DRIdrawablePrivate *dPriv );
+extern void r128CopyBuffer( __DRIdrawablePrivate *dPriv );
+extern void r128PageFlip( __DRIdrawablePrivate *dPriv );
 void r128WaitForVBlank( r128ContextPtr rmesa );
 
 extern void r128WaitForIdleLocked( r128ContextPtr rmesa );
index 9d65ebddf7d77023a1cbea2fbeb6dffa69a5ba2c..719f9367c01f8b2975fa673b54267038ff43f2ae 100644 (file)
@@ -411,6 +411,7 @@ static struct __DriverAPIRec r128API = {
    .UnbindContext   = r128UnbindContext,
    .GetSwapInfo     = NULL,
    .GetMSC          = driGetMSC32,
+   .GetDrawableMSC  = driDrawableGetMSC32,
    .WaitForMSC      = driWaitForMSC32,
    .WaitForSBC      = NULL,
    .SwapBuffersMSC  = NULL
index 8f43a2f312843b1d798054b4e84595cdae904487..2b188897f1ea654e320081db86eee1c077c5759e 100644 (file)
@@ -248,6 +248,7 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
                             void *sharedContextPrivate)
 {
    __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+   __DRIdrawablePrivate *dPriv = driContextPriv->driDrawablePriv;
    radeonScreenPtr screen = (radeonScreenPtr)(sPriv->private);
    struct dd_function_table functions;
    r200ContextPtr rmesa;
@@ -499,7 +500,7 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
              fthrottle_mode,
              rmesa->r200Screen->irq);
 
-   rmesa->vblank_flags = (rmesa->r200Screen->irq != 0)
+   dPriv->vblFlags = (rmesa->r200Screen->irq != 0)
        ? driGetDefaultVBlankFlags(&rmesa->optionCache) : VBLANK_FLAG_NO_IRQ;
 
    rmesa->prefer_gart_client_texturing = 
@@ -667,8 +668,7 @@ r200MakeCurrent( __DRIcontextPrivate *driContextPriv,
         fprintf(stderr, "%s ctx %p\n", __FUNCTION__, (void *)newCtx->glCtx);
 
       if ( newCtx->dri.drawable != driDrawPriv ) {
-        driDrawableInitVBlank( driDrawPriv, newCtx->vblank_flags,
-                               &newCtx->vbl_seq );
+         driDrawableInitVBlank( driDrawPriv );
       }
 
       newCtx->dri.readable = driReadPriv;
index c80180bdbcc184aaa9300689735f4fb271c14e91..be73507995b2eac51bce890da11ecdf6827c3dae 100644 (file)
@@ -893,11 +893,8 @@ struct r200_context {
    GLuint TexGenCompSel;
    GLmatrix tmpmat;
 
-   /* VBI / buffer swap
+   /* buffer swap
     */
-   GLuint vbl_seq;
-   GLuint vblank_flags;
-
    int64_t swap_ust;
    int64_t swap_missed_ust;
 
index c9c5a861722f3c35aad9cf17928e79f9767cc95f..2ab9ff8a467bf2377201fdfcf3a5c9e4a10296b0 100644 (file)
@@ -419,7 +419,7 @@ static void r200WaitForFrameCompletion( r200ContextPtr rmesa )
 
 /* Copy the back color buffer to the front color buffer.
  */
-void r200CopyBuffer( const __DRIdrawablePrivate *dPriv,
+void r200CopyBuffer( __DRIdrawablePrivate *dPriv,
                      const drm_clip_rect_t      *rect)
 {
    r200ContextPtr rmesa;
@@ -449,7 +449,7 @@ void r200CopyBuffer( const __DRIdrawablePrivate *dPriv,
    if (!rect)
    {
        UNLOCK_HARDWARE( rmesa );
-       driWaitForVBlank( dPriv, & rmesa->vbl_seq, rmesa->vblank_flags, & missed_target );
+       driWaitForVBlank( dPriv, & dPriv->vblSeq, dPriv->vblFlags, & missed_target );
        LOCK_HARDWARE( rmesa );
    }
 
@@ -513,7 +513,7 @@ void r200CopyBuffer( const __DRIdrawablePrivate *dPriv,
    }
 }
 
-void r200PageFlip( const __DRIdrawablePrivate *dPriv )
+void r200PageFlip( __DRIdrawablePrivate *dPriv )
 {
    r200ContextPtr rmesa;
    GLint ret;
@@ -553,7 +553,7 @@ void r200PageFlip( const __DRIdrawablePrivate *dPriv )
     */
    r200WaitForFrameCompletion( rmesa );
    UNLOCK_HARDWARE( rmesa );
-   driWaitForVBlank( dPriv, & rmesa->vbl_seq, rmesa->vblank_flags, & missed_target );
+   driWaitForVBlank( dPriv, & dPriv->vblSeq, dPriv->vblFlags, & missed_target );
    if ( missed_target ) {
       rmesa->swap_missed_count++;
       (void) (*dri_interface->getUST)( & rmesa->swap_missed_ust );
index bf1267994729c70f265904c954616ad67b9f3882..4521fbabf1df2012d8077b743e6c20963098d9e8 100644 (file)
@@ -89,9 +89,9 @@ extern void r200ReleaseDmaRegion( r200ContextPtr rmesa,
                                    struct r200_dma_region *region,
                                    const char *caller );
 
-extern void r200CopyBuffer( const __DRIdrawablePrivate *drawable,
+extern void r200CopyBuffer( __DRIdrawablePrivate *drawable,
                            const drm_clip_rect_t      *rect);
-extern void r200PageFlip( const __DRIdrawablePrivate *drawable );
+extern void r200PageFlip( __DRIdrawablePrivate *drawable );
 extern void r200Flush( GLcontext *ctx );
 extern void r200Finish( GLcontext *ctx );
 extern void r200WaitForIdleLocked( r200ContextPtr rmesa );
index 6dfaf3c6472c662e296a0f726f3d375df5cc9da8..8316b745cef4892fc6864a15619d2686d8b66922 100644 (file)
@@ -127,6 +127,7 @@ GLboolean radeonInitContext(radeonContextPtr radeon,
                            void *sharedContextPrivate)
 {
        __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+       __DRIdrawablePrivate *dPriv = driContextPriv->driDrawablePriv;
        radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private);
        GLcontext* ctx;
        GLcontext* shareCtx;
@@ -177,7 +178,7 @@ GLboolean radeonInitContext(radeonContextPtr radeon,
                        radeon->do_usleeps ? "usleeps" : "busy waits",
                        fthrottle_mode, radeon->radeonScreen->irq);
 
-       radeon->vblank_flags = (radeon->radeonScreen->irq != 0)
+       dPriv->vblFlags = (radeon->radeonScreen->irq != 0)
            ? driGetDefaultVBlankFlags(&radeon->optionCache) : VBLANK_FLAG_NO_IRQ;
 
        (*dri_interface->getUST) (&radeon->swap_ust);
@@ -277,9 +278,7 @@ GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv,
                                radeon->glCtx);
 
                if (radeon->dri.drawable != driDrawPriv) {
-                       driDrawableInitVBlank(driDrawPriv,
-                                             radeon->vblank_flags,
-                                             &radeon->vbl_seq);
+                   driDrawableInitVBlank(driDrawPriv);
                }
 
                radeon->dri.readable = driReadPriv;
index 2f239417a973a625fccc7529e6334872a13f8d88..38d893060169f6417a6b3197ef8c30ff9467d44f 100644 (file)
@@ -182,10 +182,7 @@ struct radeon_context {
        GLuint irqsEmitted;
        drm_radeon_irq_wait_t iw;
 
-       /* VBI / buffer swap */
-       GLuint vbl_seq;
-       GLuint vblank_flags;
-
+       /* buffer swap */
        int64_t swap_ust;
        int64_t swap_missed_ust;
 
index 0b8656b9c1d7e1001a49a574d7ab123b9e31e047..eeef71aaaffc42d560d84c4e9786a5e3b78ac8e1 100644 (file)
@@ -157,7 +157,7 @@ static void radeonWaitForFrameCompletion(radeonContextPtr radeon)
 
 /* Copy the back color buffer to the front color buffer.
  */
-void radeonCopyBuffer(const __DRIdrawablePrivate * dPriv,
+void radeonCopyBuffer(__DRIdrawablePrivate * dPriv,
                      const drm_clip_rect_t      * rect)
 {
        radeonContextPtr radeon;
@@ -187,7 +187,7 @@ void radeonCopyBuffer(const __DRIdrawablePrivate * dPriv,
        if (!rect)
        {
            UNLOCK_HARDWARE(radeon);
-           driWaitForVBlank(dPriv, &radeon->vbl_seq, radeon->vblank_flags,
+           driWaitForVBlank(dPriv, &dPriv->vblSeq, dPriv->vblFlags,
                             &missed_target);
            LOCK_HARDWARE(radeon);
        }
@@ -253,7 +253,7 @@ void radeonCopyBuffer(const __DRIdrawablePrivate * dPriv,
        }
 }
 
-void radeonPageFlip(const __DRIdrawablePrivate * dPriv)
+void radeonPageFlip(__DRIdrawablePrivate * dPriv)
 {
        radeonContextPtr radeon;
        GLint ret;
@@ -293,7 +293,7 @@ void radeonPageFlip(const __DRIdrawablePrivate * dPriv)
         */
        radeonWaitForFrameCompletion(radeon);
        UNLOCK_HARDWARE(radeon);
-       driWaitForVBlank(dPriv, &radeon->vbl_seq, radeon->vblank_flags,
+       driWaitForVBlank(dPriv, &dPriv->vblSeq, dPriv->vblFlags,
                         &missed_target);
        if (missed_target) {
                radeon->swap_missed_count++;
index 3a80d36c6223e87033faed58c94fd7640bd21b36..210001e8e07271f79d90e3994ca529dda62c7224 100644 (file)
@@ -46,9 +46,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #endif
 #include "radeon_drm.h"
 
-extern void radeonCopyBuffer(const __DRIdrawablePrivate * drawable,
+extern void radeonCopyBuffer(__DRIdrawablePrivate * drawable,
                             const drm_clip_rect_t      * rect);
-extern void radeonPageFlip(const __DRIdrawablePrivate * drawable);
+extern void radeonPageFlip(__DRIdrawablePrivate * drawable);
 extern void radeonFlush(GLcontext * ctx);
 extern void radeonFinish(GLcontext * ctx);
 extern void radeonWaitForIdleLocked(radeonContextPtr radeon);
index defc82fa26b9fb022af3a1d07a8b7fd5dec94103..fe6d3c21b8077cfdd47e69f4c5516effb922e7ed 100644 (file)
@@ -594,8 +594,7 @@ radeonMakeCurrent( __DRIcontextPrivate *driContextPriv,
 
       if ( newCtx->dri.drawable != driDrawPriv ) {
          /* XXX we may need to validate the drawable here!!! */
-        driDrawableInitVBlank( driDrawPriv, newCtx->vblank_flags,
-                               &newCtx->vbl_seq );
+         driDrawableInitVBlank( driDrawPriv );
       }
 
       newCtx->dri.readable = driReadPriv;
index 10d3c2b27ca2ce4fafe134be0994c40a8ee5f095..4cc87a95aefc38744c32660b349a5642bebe0fd0 100644 (file)
@@ -961,6 +961,7 @@ static struct __DriverAPIRec radeonAPI = {
    .UnbindContext   = radeonUnbindContext,
    .GetSwapInfo     = getSwapInfo,
    .GetMSC          = driGetMSC32,
+   .GetDrawableMSC  = driDrawableGetMSC32,
    .WaitForMSC      = driWaitForMSC32,
    .WaitForSBC      = NULL,
    .SwapBuffersMSC  = NULL,
@@ -978,6 +979,7 @@ static const struct __DriverAPIRec r200API = {
    .UnbindContext   = r200UnbindContext,
    .GetSwapInfo     = getSwapInfo,
    .GetMSC          = driGetMSC32,
+   .GetDrawableMSC  = driDrawableGetMSC32,
    .WaitForMSC      = driWaitForMSC32,
    .WaitForSBC      = NULL,
    .SwapBuffersMSC  = NULL,
index 79682a725300491d78cf4e23415acd601e3b3697..671193577d4784ce74810072c1273b2c41bffa64 100644 (file)
@@ -314,6 +314,7 @@ static struct __DriverAPIRec sisAPI = {
    .UnbindContext   = sisUnbindContext,
    .GetSwapInfo     = NULL,
    .GetMSC          = NULL,
+   .GetDrawableMSC  = NULL,
    .WaitForMSC      = NULL,
    .WaitForSBC      = NULL,
    .SwapBuffersMSC  = NULL
index 5bdb446d1551ed1d8ddf4e9bb297ccb6aa8096dc..6298de82f40f05887aeb08d36d98cc20b789d74b 100644 (file)
@@ -355,6 +355,7 @@ static const struct __DriverAPIRec tdfxAPI = {
    .UnbindContext   = tdfxUnbindContext,
    .GetSwapInfo     = NULL,
    .GetMSC          = NULL,
+   .GetDrawableMSC  = NULL,
    .WaitForMSC      = NULL,
    .WaitForSBC      = NULL,
    .SwapBuffersMSC  = NULL
index 66e92cc602e07f871ae72b9ff52f8f8a0e6ae664..5d95d97d5391fdc5398005cf4d12ffa12478af4f 100644 (file)
@@ -465,6 +465,7 @@ viaCreateContext(const __GLcontextModes *visual,
     GLcontext *ctx, *shareCtx;
     struct via_context *vmesa;
     __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+    __DRIdrawablePrivate *dPriv = driContextPriv->driDrawablePriv;
     viaScreenPrivate *viaScreen = (viaScreenPrivate *)sPriv->private;
     drm_via_sarea_t *saPriv = (drm_via_sarea_t *)
         (((GLubyte *)sPriv->pSAREA) + viaScreen->sareaPrivOffset);
@@ -658,7 +659,7 @@ viaCreateContext(const __GLcontextModes *visual,
         driQueryOptionb(&vmesa->optionCache, "no_rast"))
        FALLBACK(vmesa, VIA_FALLBACK_USER_DISABLE, 1);
 
-    vmesa->vblank_flags =
+    dPriv->vblFlags =
        vmesa->viaScreen->irqEnabled ?
         driGetDefaultVBlankFlags(&vmesa->optionCache) : VBLANK_FLAG_NO_IRQ;
 
@@ -838,8 +839,7 @@ viaMakeCurrent(__DRIcontextPrivate *driContextPriv,
         readBuffer = (GLframebuffer *)driReadPriv->driverPrivate;
 
        if (vmesa->driDrawable != driDrawPriv) {
-          driDrawableInitVBlank(driDrawPriv, vmesa->vblank_flags,
-                                &vmesa->vbl_seq);
+           driDrawableInitVBlank(driDrawPriv);
        }
 
        if ((vmesa->driDrawable != driDrawPriv)
index 632171368820bcf39b7554b4930e1dc0e3079a6e..acd6f2e2b1cfe3c0d5bace717e69f40a67e6b8c8 100644 (file)
@@ -321,9 +321,6 @@ struct via_context {
     */
    driOptionCache optionCache;
 
-   GLuint vblank_flags;
-   GLuint vbl_seq;
-
    int64_t swap_ust;
    int64_t swap_missed_ust;
 
index 4a733fb00c23a0f13218da633531600a66384f5e..3c7dafd0e6baaa2777e5c785921fea3ef3e44c96 100644 (file)
@@ -507,7 +507,7 @@ void viaWaitIdleLocked( struct via_context *vmesa, GLboolean light )
  * except that WAIT_IDLE() will spin the CPU polling, while this is
  * IRQ driven.
  */
-static void viaWaitIdleVBlank( const __DRIdrawablePrivate *dPriv, 
+static void viaWaitIdleVBlank(  __DRIdrawablePrivate *dPriv, 
                               struct via_context *vmesa,
                               GLuint value )
 {
@@ -523,8 +523,8 @@ static void viaWaitIdleVBlank( const __DRIdrawablePrivate *dPriv,
          vmesa->thrashing)
         viaSwapOutWork(vmesa);
 
-      driWaitForVBlank( dPriv, & vmesa->vbl_seq, 
-                       vmesa->vblank_flags, & missed_target );
+      driWaitForVBlank( dPriv, & dPriv->vblSeq, dPriv->vblFlags,
+                       & missed_target );
       if ( missed_target ) {
         vmesa->swap_missed_count++;
         (*dri_interface->getUST)( &vmesa->swap_missed_ust );
@@ -591,7 +591,7 @@ void viaResetPageFlippingLocked(struct via_context *vmesa)
 /*
  * Copy the back buffer to the front buffer. 
  */
-void viaCopyBuffer(const __DRIdrawablePrivate *dPriv)
+void viaCopyBuffer(__DRIdrawablePrivate *dPriv)
 {
    struct via_context *vmesa = 
       (struct via_context *)dPriv->driContextPriv->driverPrivate;
@@ -607,7 +607,7 @@ void viaCopyBuffer(const __DRIdrawablePrivate *dPriv)
 
    VIA_FLUSH_DMA(vmesa);
 
-   if (vmesa->vblank_flags == VBLANK_FLAG_SYNC &&
+   if (dPriv->vblFlags == VBLANK_FLAG_SYNC &&
        vmesa->lastBreadcrumbWrite > 1)
       viaWaitIdleVBlank(dPriv, vmesa, vmesa->lastBreadcrumbWrite-1);
    else
@@ -634,14 +634,14 @@ void viaCopyBuffer(const __DRIdrawablePrivate *dPriv)
 }
 
 
-void viaPageFlip(const __DRIdrawablePrivate *dPriv)
+void viaPageFlip(__DRIdrawablePrivate *dPriv)
 {
     struct via_context *vmesa = 
        (struct via_context *)dPriv->driContextPriv->driverPrivate;
     struct via_renderbuffer buffer_tmp;
 
     VIA_FLUSH_DMA(vmesa);
-   if (vmesa->vblank_flags == VBLANK_FLAG_SYNC &&
+   if (dPriv->vblFlags == VBLANK_FLAG_SYNC &&
        vmesa->lastBreadcrumbWrite > 1)
       viaWaitIdleVBlank(dPriv, vmesa, vmesa->lastBreadcrumbWrite - 1);
    else
index a81b427d807ea44445e4dacdf4a4a63a4c3d01c6..44fc439c9fdf564fc17a758143f3e11504a62359 100644 (file)
@@ -33,8 +33,8 @@ void viaFlushDma(struct via_context *vmesa);
 void viaFlushDmaLocked(struct via_context *vmesa, GLuint flags);
 
 void viaInitIoctlFuncs(GLcontext *ctx);
-void viaCopyBuffer(const __DRIdrawablePrivate *dpriv);
-void viaPageFlip(const __DRIdrawablePrivate *dpriv);
+void viaCopyBuffer(__DRIdrawablePrivate *dpriv);
+void viaPageFlip(__DRIdrawablePrivate *dpriv);
 void viaCheckDma(struct via_context *vmesa, GLuint bytes);
 void viaResetPageFlippingLocked(struct via_context *vmesa);
 void viaWaitIdle(struct via_context *vmesa, GLboolean light);
index f3912ac352146ffde3fce314620d594de376f27f..0ad18b4300972b764ff0334305f496e26f57e39b 100644 (file)
@@ -334,6 +334,7 @@ static struct __DriverAPIRec viaAPI = {
    .UnbindContext   = viaUnbindContext,
    .GetSwapInfo     = getSwapInfo,
    .GetMSC          = driGetMSC32,
+   .GetDrawableMSC  = driDrawableGetMSC32,
    .WaitForMSC      = driWaitForMSC32,
    .WaitForSBC      = NULL,
    .SwapBuffersMSC  = NULL