Re: vblank problem (and proposed fix) on crtc > 1

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




oops, just realized that I didn't include one final change to the patch I have just sent, so here is the real one; disregard the previous one (sorry wasting bandwidth).


---------------------------- xf86-video-ati.patch ----------------------

diff --git a/src/radeon.h b/src/radeon.h
index 4c43717..ad80889 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -930,6 +930,9 @@ typedef struct {

     RADEONFBLayout    CurrentLayout;

+#ifdef RADEON_DRI2
+    Bool              high_crtc_works;
+#endif
 #ifdef XF86DRI
     Bool              directRenderingEnabled;
     Bool              directRenderingInited;
diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
index 66df03c..c45abe6 100644
--- a/src/radeon_dri2.c
+++ b/src/radeon_dri2.c
@@ -783,6 +783,7 @@ static int radeon_dri2_get_msc(DrawablePtr draw, CARD64 *ust, CARD64 *msc)
     drmVBlank vbl;
     int ret;
     int crtc = radeon_dri2_drawable_crtc(draw);
+    int high_crtc = 0;

     /* Drawable not displayed, make up a value */
     if (crtc == -1) {
@@ -791,8 +792,16 @@ static int radeon_dri2_get_msc(DrawablePtr draw, CARD64 *ust, CARD64 *msc)
         return TRUE;
     }
     vbl.request.type = DRM_VBLANK_RELATIVE;
-    if (crtc > 0)
+    if (crtc == 1)
         vbl.request.type |= DRM_VBLANK_SECONDARY;
+    else if (crtc > 1) {
+	if (info->high_crtc_works) {
+	    high_crtc = (crtc << DRM_VBLANK_HIGH_CRTC_SHIFT) &
+		DRM_VBLANK_HIGH_CRTC_MASK;
+	}
+	else vbl.request.type |= DRM_VBLANK_SECONDARY;
+    }
+    vbl.request.type |= high_crtc;
     vbl.request.sequence = 0;

     ret = drmWaitVBlank(info->dri2.drm_fd, &vbl);
@@ -825,6 +834,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
     drmVBlank vbl;
     int ret, crtc = radeon_dri2_drawable_crtc(draw);
     CARD64 current_msc;
+    int high_crtc = 0;

     /* Truncate to match kernel interfaces; means occasional overflow
      * misses, but that's generally not a big deal */
@@ -855,8 +865,16 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,

     /* Get current count */
     vbl.request.type = DRM_VBLANK_RELATIVE;
-    if (crtc > 0)
+    if (crtc == 1)
         vbl.request.type |= DRM_VBLANK_SECONDARY;
+    else if (crtc > 1) {
+	if (info->high_crtc_works) {
+ high_crtc = (crtc << DRM_VBLANK_HIGH_CRTC_SHIFT) & + DRM_VBLANK_HIGH_CRTC_MASK;
+	}
+	else vbl.request.type |= DRM_VBLANK_SECONDARY;
+    }
+    vbl.request.type |= high_crtc;
     vbl.request.sequence = 0;
     ret = drmWaitVBlank(info->dri2.drm_fd, &vbl);
     if (ret) {
@@ -882,8 +900,16 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
         if (current_msc >= target_msc)
             target_msc = current_msc;
         vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT;
-        if (crtc > 0)
+        if (crtc == 1)
             vbl.request.type |= DRM_VBLANK_SECONDARY;
+	else if (crtc > 1) {
+	    if (info->high_crtc_works) {
+ high_crtc = (crtc << DRM_VBLANK_HIGH_CRTC_SHIFT) & + DRM_VBLANK_HIGH_CRTC_MASK;
+	    }
+	    else vbl.request.type |= DRM_VBLANK_SECONDARY;
+	}
+	vbl.request.type |= high_crtc;
         vbl.request.sequence = target_msc;
         vbl.request.signal = (unsigned long)wait_info;
         ret = drmWaitVBlank(info->dri2.drm_fd, &vbl);
@@ -903,8 +929,15 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
      * so we queue an event that will satisfy the divisor/remainder equation.
      */
     vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT;
-    if (crtc > 0)
+    if (crtc == 1)
         vbl.request.type |= DRM_VBLANK_SECONDARY;
+    else if (crtc > 1) {
+	if (info->high_crtc_works) {
+ high_crtc = (crtc << DRM_VBLANK_HIGH_CRTC_SHIFT) & + DRM_VBLANK_HIGH_CRTC_MASK;
+	} else vbl.request.type |= DRM_VBLANK_SECONDARY;
+    }
+    vbl.request.type |= high_crtc;

     vbl.request.sequence = current_msc - (current_msc % divisor) +
         remainder;
@@ -1029,6 +1062,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
     CARD64 current_msc;
     BoxRec box;
     RegionRec region;
+    int high_crtc = 0;

     /* Truncate to match kernel interfaces; means occasional overflow
      * misses, but that's generally not a big deal */
@@ -1068,8 +1102,15 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,

     /* Get current count */
     vbl.request.type = DRM_VBLANK_RELATIVE;
-    if (crtc > 0)
+    if (crtc == 1)
         vbl.request.type |= DRM_VBLANK_SECONDARY;
+    else if (crtc > 1) {
+	if (info->high_crtc_works) {
+ high_crtc = (crtc << DRM_VBLANK_HIGH_CRTC_SHIFT) & + DRM_VBLANK_HIGH_CRTC_MASK;
+	} else vbl.request.type |= DRM_VBLANK_SECONDARY;
+    }
+    vbl.request.type |= high_crtc;
     vbl.request.sequence = 0;
     ret = drmWaitVBlank(info->dri2.drm_fd, &vbl);
     if (ret) {
@@ -1111,8 +1152,15 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
          */
         if (flip == 0)
             vbl.request.type |= DRM_VBLANK_NEXTONMISS;
-        if (crtc > 0)
+        if (crtc == 1)
             vbl.request.type |= DRM_VBLANK_SECONDARY;
+	else if (crtc > 1) {
+	    if (info->high_crtc_works) {
+ high_crtc = (crtc << DRM_VBLANK_HIGH_CRTC_SHIFT) & + DRM_VBLANK_HIGH_CRTC_MASK;
+	    } else vbl.request.type |= DRM_VBLANK_SECONDARY;
+	}
+	vbl.request.type |= high_crtc;

         /* If target_msc already reached or passed, set it to
          * current_msc to ensure we return a reasonable value back
@@ -1145,8 +1193,15 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
     vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT;
     if (flip == 0)
         vbl.request.type |= DRM_VBLANK_NEXTONMISS;
-    if (crtc > 0)
+    if (crtc == 1)
         vbl.request.type |= DRM_VBLANK_SECONDARY;
+    else if (crtc > 1) {
+	if (info->high_crtc_works) {
+ high_crtc = (crtc << DRM_VBLANK_HIGH_CRTC_SHIFT) & + DRM_VBLANK_HIGH_CRTC_MASK;
+	} else vbl.request.type |= DRM_VBLANK_SECONDARY;
+    }
+    vbl.request.type |= high_crtc;

     vbl.request.sequence = current_msc - (current_msc % divisor) +
         remainder;
@@ -1217,6 +1272,8 @@ radeon_dri2_screen_init(ScreenPtr pScreen)
     DRI2InfoRec dri2_info = { 0 };
 #ifdef USE_DRI2_SCHEDULING
     const char *driverNames[1];
+    drmVBlank vbl;
+    int c;
 #endif

     if (!info->useEXA) {
@@ -1248,6 +1305,7 @@ radeon_dri2_screen_init(ScreenPtr pScreen)
 #endif
     dri2_info.CopyRegion = radeon_dri2_copy_region;

+    info->high_crtc_works = FALSE;
 #ifdef USE_DRI2_SCHEDULING
     if (info->dri->pKernelDRMVersion->version_minor >= 4) {
         dri2_info.version = 4;
@@ -1261,6 +1319,22 @@ radeon_dri2_screen_init(ScreenPtr pScreen)
         xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "You need a newer kernel for sync extension\n");
     }

+    if (info->drmmode.mode_res->count_crtcs > 2) {
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "GPU with %d CRTCs found, probing VBLANKs on CRTC>1\n",
+ info->drmmode.mode_res->count_crtcs); + info->high_crtc_works = TRUE;
+	for (c=2; c<info->drmmode.mode_res->count_crtcs; c++) {
+	    vbl.request.type = DRM_VBLANK_RELATIVE;
+	    vbl.request.type |= (c << DRM_VBLANK_HIGH_CRTC_SHIFT) & DRM_VBLANK_HIGH_CRTC_MASK;
+	    vbl.request.sequence = 0;
+	    if (drmWaitVBlank(info->dri2.drm_fd, &vbl)) {
+		xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Kernel rejects VBLANK request on CRTC %d\n", c);
+		info->high_crtc_works = FALSE;
+	    }
+	}
+ if (info->high_crtc_works) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VBLANK request accepted on all CRTCs\n"); + } +
     if (pRADEONEnt->dri2_info_cnt == 0) {
 #if HAS_DIXREGISTERPRIVATEKEY
 	if (!dixRegisterPrivateKey(DRI2ClientEventsPrivateKey, PRIVATE_CLIENT, sizeof(DRI2ClientEventsRec))) {
_______________________________________________
dri-devel mailing list
dri-devel@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[Index of Archives]     [Linux DRI Users]     [Linux Intel Graphics]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux