On Friday, September 21, 2007 2:51 am Michel Dänzer wrote:
> >   - add code to Mesa so GetMSC/WaitForMSC set DRM_VBLANK_SECONDARY
> >     correctly
>
> One idea (with some handwaving :) would be the common code keeping
> around a pointer to the driver's vblank_flags variable or keeping
> track of the flags per drawable in some other sensible way.

I like the idea, here's something concrete.  I put the vblank stuff into 
the screen private, but I'm not sure if that's the best place 
(logically the vblank counters are screen specific), are there X 
compatibility issues with changing that structure?

Porting over other drivers should be trivial...

Thanks,
Jesse
diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h
index 539d28d..a1b2a1d 100644
--- a/src/mesa/drivers/dri/common/dri_util.h
+++ b/src/mesa/drivers/dri/common/dri_util.h
@@ -468,6 +468,15 @@ struct __DRIscreenPrivateRec {
     /[EMAIL PROTECTED]/
 
     /**
+     * \name Vertical blank tracking information
+     * Used for waiting on vertical blank events.
+     */
+    /[EMAIL PROTECTED]/
+    unsigned int vblSeq;
+    unsigned int vblFlags;
+    /[EMAIL PROTECTED]/
+
+    /**
      * \name Device-dependent private information (stored in the SAREA).
      *
      * This data is accessed by the client driver only.
diff --git a/src/mesa/drivers/dri/common/vblank.c b/src/mesa/drivers/dri/common/vblank.c
index e7ed545..307c957 100644
--- a/src/mesa/drivers/dri/common/vblank.c
+++ b/src/mesa/drivers/dri/common/vblank.c
@@ -63,6 +63,8 @@ int driGetMSC32( __DRIscreenPrivate * priv, int64_t * count )
 
    vbl.request.type = DRM_VBLANK_RELATIVE;
    vbl.request.sequence = 0;
+   if ( priv->vblFlags & VBLANK_FLAG_SECONDARY )
+      vbl.request.type |= DRM_VBLANK_SECONDARY;
 
    ret = drmWaitVBlank( priv->fd, &vbl );
    *count = (int64_t)vbl.reply.sequence;
@@ -124,6 +126,8 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv,
          vbl.request.type = dont_wait ? DRM_VBLANK_RELATIVE :
                                         DRM_VBLANK_ABSOLUTE;
          vbl.request.sequence = next;
+	 if ( priv->driScreenPriv->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.
@@ -257,7 +261,13 @@ void driDrawableInitVBlank( __DRIdrawablePrivate *priv, GLuint flags,
 {
    if ( priv->pdraw->swap_interval == (unsigned)-1 ) {
       /* Get current vertical blank sequence */
-      drmVBlank vbl = { .request={ .type = DRM_VBLANK_RELATIVE, .sequence = 0 } };
+      drmVBlank vbl;
+
+      vbl.request.type = DRM_VBLANK_RELATIVE;
+      if ( flags & VBLANK_FLAG_SECONDARY ) {
+	 vbl.request.type |= DRM_VBLANK_SECONDARY;
+      }
+      vbl.request.sequence = 0;
       do_wait( &vbl, vbl_seq, priv->driScreenPriv->fd );
 
       priv->pdraw->swap_interval = (flags & (VBLANK_FLAG_THROTTLE |
diff --git a/src/mesa/drivers/dri/i965/intel_blit.c b/src/mesa/drivers/dri/i965/intel_blit.c
index f88cbb2..96689c2 100644
--- a/src/mesa/drivers/dri/i965/intel_blit.c
+++ b/src/mesa/drivers/dri/i965/intel_blit.c
@@ -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->driScreenPriv->vblSeq,
+			 dPriv->driScreenPriv->vblFlags, &missed_target );
        LOCK_HARDWARE( intel );
    }
 
diff --git a/src/mesa/drivers/dri/i965/intel_buffers.c b/src/mesa/drivers/dri/i965/intel_buffers.c
index d155c03..a2e2128 100644
--- a/src/mesa/drivers/dri/i965/intel_buffers.c
+++ b/src/mesa/drivers/dri/i965/intel_buffers.c
@@ -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,
@@ -172,6 +174,7 @@ static void intelSetBackClipRects( struct intel_context *intel )
 void intelWindowMoved( struct intel_context *intel )
 {
    __DRIdrawablePrivate *dPriv = intel->driDrawable;
+   __DRIscreenPrivate *sPriv = intel->driScreen;
 
    if (!intel->ctx.DrawBuffer) {
       intelSetFrontClipRects( intel );
@@ -190,6 +193,46 @@ void intelWindowMoved( struct intel_context *intel )
       }
    }
 
+   /* Get updated plane info so we sync against the right vblank counter */
+   if (intel->intelScreen->driScrnPriv->ddxMinor >= 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 = sPriv->vblFlags;
+
+      /* Update vblank info
+       */
+      if (areaB > areaA || (areaA == areaB && areaB > 0)) {
+	 flags = sPriv->vblFlags | VBLANK_FLAG_SECONDARY;
+      } else {
+	 flags = sPriv->vblFlags & ~VBLANK_FLAG_SECONDARY;
+      }
+
+      if (flags != sPriv->vblFlags && sPriv->vblFlags &&
+	  !(sPriv->vblFlags & VBLANK_FLAG_NO_IRQ)) {
+	 drmVBlank vbl;
+
+	 vbl.request.type = DRM_VBLANK_ABSOLUTE;
+
+	 if ( sPriv->vblFlags & VBLANK_FLAG_SECONDARY ) {
+	    vbl.request.type |= DRM_VBLANK_SECONDARY;
+	 }
+
+	 sPriv->vblFlags = flags;
+	 driGetCurrentVBlank(dPriv, sPriv->vblFlags, &sPriv->vblSeq);
+      }
+   } else {
+      sPriv->vblFlags &= ~VBLANK_FLAG_SECONDARY;
+   }
+
    _mesa_resize_framebuffer(&intel->ctx,
 			    (GLframebuffer*)dPriv->driverPrivate,
 			    dPriv->w, dPriv->h);
diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c
index 1fbf571..6152b0f 100644
--- a/src/mesa/drivers/dri/i965/intel_context.c
+++ b/src/mesa/drivers/dri/i965/intel_context.c
@@ -328,8 +328,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);
+   drmI830Sarea *saPriv = (drmI830Sarea *)
+       (((GLubyte *)sPriv->pSAREA)+intelScreen->sarea_priv_offset);
 
    if (!_mesa_initialize_context(&intel->ctx,
 				 mesaVis, shareCtx, 
@@ -347,8 +347,8 @@ 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;
+   sPriv->vblFlags = (intel->intelScreen->irq_active != 0)
+       ? driGetDefaultVBlankFlags(&intel->optionCache) : VBLANK_FLAG_NO_IRQ;
 
    ctx->Const.MaxTextureMaxAnisotropy = 2.0;
 
@@ -582,8 +582,9 @@ GLboolean intelMakeCurrent(__DRIcontextPrivate *driContextPriv,
 
       if ( intel->driDrawable != driDrawPriv ) {
 	 /* Shouldn't the readbuffer be stored also? */
-	 driDrawableInitVBlank( driDrawPriv, intel->vblank_flags,
-		      &intel->vbl_seq );
+	  driDrawableInitVBlank( driDrawPriv,
+				 driDrawPriv->driScreenPriv->vblFlags,
+				 &driDrawPriv->driScreenPriv->vblSeq);
 
 	 intel->driDrawable = driDrawPriv;
 	 intelWindowMoved( intel );
diff --git a/src/mesa/drivers/dri/i965/intel_context.h b/src/mesa/drivers/dri/i965/intel_context.h
index 053d93a..26d6923 100644
--- a/src/mesa/drivers/dri/i965/intel_context.h
+++ b/src/mesa/drivers/dri/i965/intel_context.h
@@ -237,7 +237,7 @@ struct intel_context
    __DRIdrawablePrivate *driReadDrawable;
    __DRIscreenPrivate *driScreen;
    intelScreenPrivate *intelScreen; 
-   volatile drmI830Sarea *sarea; 
+   drmI830Sarea *sarea; 
    
    FILE *aub_file;
 
@@ -248,11 +248,6 @@ struct intel_context
     */
    driOptionCache optionCache;
 
-   /* VBI
-    */
-   GLuint vbl_seq;
-   GLuint vblank_flags;
-
    int64_t swap_ust;
    int64_t swap_missed_ust;
 
diff --git a/src/mesa/drivers/dri/i965/server/i830_common.h b/src/mesa/drivers/dri/i965/server/i830_common.h
index f320378..452c400 100644
--- a/src/mesa/drivers/dri/i965/server/i830_common.h
+++ b/src/mesa/drivers/dri/i965/server/i830_common.h
@@ -119,6 +119,15 @@ typedef struct {
         unsigned int depth_tiled;
         unsigned int rotated_tiled;
         unsigned int rotated2_tiled;
+
+	int planeA_x;
+	int planeA_y;
+	int planeA_w;
+	int planeA_h;
+	int planeB_x;
+	int planeB_y;
+	int planeB_w;
+	int planeB_h;
 } drmI830Sarea;
 
 /* Flags for perf_boxes
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
--
_______________________________________________
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel

Reply via email to