xf86-video-ati: Branch 'master' - 3 commits

Michel Dänzer daenzer at kemper.freedesktop.org
Thu Jan 3 02:04:54 PST 2013


 src/evergreen_textured_videofuncs.c |    2 
 src/r600_textured_videofuncs.c      |    2 
 src/radeon.h                        |    1 
 src/radeon_dri2.c                   |   84 +++++++++++++++++++++++++-----------
 src/radeon_exa_funcs.c              |    4 -
 src/radeon_exa_render.c             |    2 
 src/radeon_exa_shared.c             |    3 -
 src/radeon_textured_videofuncs.c    |    8 +--
 src/radeon_video.c                  |   22 ++++++++-
 src/radeon_video.h                  |    2 
 10 files changed, 93 insertions(+), 37 deletions(-)

New commits:
commit 6981a5c087165b126c15ba0025cffdba218ab652
Author: Ilija Hadzic <ihadzic at research.bell-labs.com>
Date:   Wed Dec 19 10:35:43 2012 -0500

    DRI2: limit the swap rate when CRTC is in DPMS-off state
    
    If drawable is displayed on a CRTC and relevant CRTC is in
    DPMS off state, defer the swap by a fixed (hard-coded) time.
    
    This patch fixes a bug that caused an application to render
    at uncontrolled rate when CRTC goes into DPMS "off" state,
    thus thrashing the GPU and CPU and likely offsetting the
    power savings achieved by shutting off the display.
    
    Signed-off-by: Ilija Hadzic <ihadzic at research.bell-labs.com>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
index 8ebc687..27b04e3 100644
--- a/src/radeon_dri2.c
+++ b/src/radeon_dri2.c
@@ -31,6 +31,7 @@
 
 #include "radeon.h"
 #include "radeon_dri2.h"
+#include "radeon_video.h"
 
 #ifdef DRI2
 
@@ -67,6 +68,8 @@
 #define USE_DRI2_PRIME
 #endif
 
+#define FALLBACK_SWAP_DELAY 16
+
 #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,6,99,0, 0)
 typedef DRI2BufferPtr BufferPtr;
 #else
@@ -1263,6 +1266,14 @@ void radeon_dri2_flip_event_handler(unsigned int frame, unsigned int tv_sec,
     free(flip);
 }
 
+static
+CARD32 radeon_dri2_deferred_swap(OsTimerPtr timer, CARD32 now, pointer data)
+{
+    TimerFree(timer);
+    radeon_dri2_frame_event_handler(0, 0, 0, data);
+    return 0;
+}
+
 /*
  * ScheduleSwap is responsible for requesting a DRM vblank event for the
  * appropriate frame.
@@ -1292,7 +1303,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
     ScreenPtr screen = draw->pScreen;
     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
     RADEONInfoPtr info = RADEONPTR(scrn);
-    xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw, FALSE);
+    xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw, TRUE);
     drmVBlank vbl;
     int ret, flip = 0;
     DRI2FrameEventPtr swap_info = NULL;
@@ -1314,7 +1325,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
     radeon_dri2_ref_buffer(front);
     radeon_dri2_ref_buffer(back);
 
-    /* Drawable not displayed... just complete the swap */
+    /* either off-screen or CRTC not usable... just complete the swap */
     if (crtc == NULL)
         goto blit_fallback;
 
@@ -1337,6 +1348,18 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
         goto blit_fallback;
     }
 
+    /*
+     * CRTC is in DPMS off state, fallback to blit, but pace the
+     * application at the rate that roughly approximates the
+     * nominal frame rate of the relevant CRTC
+     */
+    if (!radeon_crtc_is_enabled(crtc)) {
+	TimerSet(NULL, 0, FALLBACK_SWAP_DELAY, radeon_dri2_deferred_swap,
+		 swap_info);
+	*target_msc = 0;
+	return TRUE;
+    }
+
     /* Get current count */
     vbl.request.type = DRM_VBLANK_RELATIVE;
     vbl.request.type |= populate_vbl_request_type(info, crtc);
@@ -1346,7 +1369,10 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
         xf86DrvMsg(scrn->scrnIndex, X_WARNING,
                 "first get vblank counter failed: %s\n",
                 strerror(errno));
-        goto blit_fallback;
+	TimerSet(NULL, 0, FALLBACK_SWAP_DELAY, radeon_dri2_deferred_swap,
+		 swap_info);
+	*target_msc = 0;
+	return TRUE;
     }
 
     current_msc = vbl.reply.sequence;
@@ -1395,7 +1421,10 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
             xf86DrvMsg(scrn->scrnIndex, X_WARNING,
                     "divisor 0 get vblank counter failed: %s\n",
                     strerror(errno));
-            goto blit_fallback;
+	    TimerSet(NULL, 0, FALLBACK_SWAP_DELAY, radeon_dri2_deferred_swap,
+		     swap_info);
+	    *target_msc = 0;
+            return TRUE;
         }
 
         *target_msc = vbl.reply.sequence + flip;
@@ -1440,7 +1469,10 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
         xf86DrvMsg(scrn->scrnIndex, X_WARNING,
                 "final get vblank counter failed: %s\n",
                 strerror(errno));
-        goto blit_fallback;
+	TimerSet(NULL, 0, FALLBACK_SWAP_DELAY, radeon_dri2_deferred_swap,
+		 swap_info);
+	*target_msc = 0;
+	return TRUE;
     }
 
     /* Adjust returned value for 1 fame pageflip offset of flip > 0 */
diff --git a/src/radeon_video.c b/src/radeon_video.c
index 9381e4a..a0de4f6 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -67,8 +67,7 @@ radeon_box_area(BoxPtr box)
     return (int) (box->x2 - box->x1) * (int) (box->y2 - box->y1);
 }
 
-static Bool
-radeon_crtc_is_enabled(xf86CrtcPtr crtc)
+Bool radeon_crtc_is_enabled(xf86CrtcPtr crtc)
 {
     drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
     return drmmode_crtc->dpms_mode == DPMSModeOn;
diff --git a/src/radeon_video.h b/src/radeon_video.h
index f097f2f..e6068e8 100644
--- a/src/radeon_video.h
+++ b/src/radeon_video.h
@@ -100,4 +100,6 @@ RADEONCopyMungedData(ScrnInfoPtr pScrn,
 		     unsigned int srcPitch, unsigned int srcPitch2,
 		     unsigned int dstPitch, unsigned int h, unsigned int w);
 
+Bool radeon_crtc_is_enabled(xf86CrtcPtr crtc);
+
 #endif
commit 3657672207322be651cdb94a811337b7c5668c84
Author: Ilija Hadzic <ihadzic at research.bell-labs.com>
Date:   Wed Dec 19 10:35:42 2012 -0500

    DRI2: change signature of radeon_dri2_drawable_crtc
    
    Return pointer to the CRTC instead of CRTC ID and expose
    consider_disabled option in arguments of this function.
    
    Signed-off-by: Ilija Hadzic <ihadzic at research.bell-labs.com>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
index 83bc2d2..8ebc687 100644
--- a/src/radeon_dri2.c
+++ b/src/radeon_dri2.c
@@ -774,24 +774,24 @@ radeon_dri2_client_state_changed(CallbackListPtr *ClientStateCallback, pointer d
     }
 }
 
-static int radeon_dri2_drawable_crtc(DrawablePtr pDraw)
+static
+xf86CrtcPtr radeon_dri2_drawable_crtc(DrawablePtr pDraw, Bool consider_disabled)
 {
     ScreenPtr pScreen = pDraw->pScreen;
     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
     xf86CrtcPtr crtc;
-    int crtc_id = -1;
 
-    crtc = radeon_pick_best_crtc(pScrn, FALSE,
+    crtc = radeon_pick_best_crtc(pScrn, consider_disabled,
 				 pDraw->x,
 				 pDraw->x + pDraw->width,
 				 pDraw->y,
 				 pDraw->y + pDraw->height);
 
     /* Make sure the CRTC is valid and this is the real front buffer */
-    if (crtc != NULL && !crtc->rotatedData) {
-        crtc_id = drmmode_get_crtc_id(crtc);
-    }
-    return crtc_id;
+    if (crtc != NULL && !crtc->rotatedData)
+	return crtc;
+    else
+	return NULL;
 }
 
 static Bool
@@ -803,9 +803,9 @@ radeon_dri2_schedule_flip(ScrnInfoPtr scrn, ClientPtr client,
     struct dri2_buffer_priv *back_priv;
     struct radeon_bo *bo;
     DRI2FrameEventPtr flip_info;
-
     /* Main crtc for this drawable shall finally deliver pageflip event. */
-    int ref_crtc_hw_id = radeon_dri2_drawable_crtc(draw);
+    xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw, FALSE);
+    int ref_crtc_hw_id = crtc ? drmmode_get_crtc_id(crtc) : -1;
 
     flip_info = calloc(1, sizeof(DRI2FrameEventRec));
     if (!flip_info)
@@ -1023,20 +1023,22 @@ cleanup:
     free(event);
 }
 
-static drmVBlankSeqType populate_vbl_request_type(RADEONInfoPtr info, int crtc)
+static
+drmVBlankSeqType populate_vbl_request_type(RADEONInfoPtr info, xf86CrtcPtr crtc)
 {
     drmVBlankSeqType type = 0;
+    int crtc_id = drmmode_get_crtc_id(crtc);
 
-    if (crtc == 1)
+    if (crtc_id == 1)
         type |= DRM_VBLANK_SECONDARY;
-    else if (crtc > 1)
+    else if (crtc_id > 1)
 #ifdef DRM_VBLANK_HIGH_CRTC_SHIFT
-	type |= (crtc << DRM_VBLANK_HIGH_CRTC_SHIFT) &
+	type |= (crtc_id << DRM_VBLANK_HIGH_CRTC_SHIFT) &
 		DRM_VBLANK_HIGH_CRTC_MASK;
 #else
 	ErrorF("radeon driver bug: %s called for CRTC %d > 1, but "
 	       "DRM_VBLANK_HIGH_CRTC_MASK not defined at build time\n",
-	       __func__, crtc);
+	       __func__, crtc_id);
 #endif
 
     return type; 
@@ -1053,10 +1055,10 @@ static int radeon_dri2_get_msc(DrawablePtr draw, CARD64 *ust, CARD64 *msc)
     RADEONInfoPtr info = RADEONPTR(scrn);
     drmVBlank vbl;
     int ret;
-    int crtc = radeon_dri2_drawable_crtc(draw);
+    xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw, FALSE);
 
     /* Drawable not displayed, make up a value */
-    if (crtc == -1) {
+    if (crtc == NULL) {
         *ust = 0;
         *msc = 0;
         return TRUE;
@@ -1092,8 +1094,9 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
     RADEONInfoPtr info = RADEONPTR(scrn);
     DRI2FrameEventPtr wait_info = NULL;
+    xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw, FALSE);
     drmVBlank vbl;
-    int ret, crtc = radeon_dri2_drawable_crtc(draw);
+    int ret;
     CARD64 current_msc;
 
     /* Truncate to match kernel interfaces; means occasional overflow
@@ -1103,7 +1106,7 @@ static int radeon_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
     remainder &= 0xffffffff;
 
     /* Drawable not visible, return immediately */
-    if (crtc == -1)
+    if (crtc == NULL)
         goto out_complete;
 
     wait_info = calloc(1, sizeof(DRI2FrameEventRec));
@@ -1289,8 +1292,9 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
     ScreenPtr screen = draw->pScreen;
     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
     RADEONInfoPtr info = RADEONPTR(scrn);
+    xf86CrtcPtr crtc = radeon_dri2_drawable_crtc(draw, FALSE);
     drmVBlank vbl;
-    int ret, crtc= radeon_dri2_drawable_crtc(draw), flip = 0;
+    int ret, flip = 0;
     DRI2FrameEventPtr swap_info = NULL;
     enum DRI2FrameEventType swap_type = DRI2_SWAP;
     CARD64 current_msc;
@@ -1311,7 +1315,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
     radeon_dri2_ref_buffer(back);
 
     /* Drawable not displayed... just complete the swap */
-    if (crtc == -1)
+    if (crtc == NULL)
         goto blit_fallback;
 
     swap_info = calloc(1, sizeof(DRI2FrameEventRec));
commit 61d0aec40e2521488c2fe43e7a6823e5c87d94d7
Author: Ilija Hadzic <ihadzic at research.bell-labs.com>
Date:   Wed Dec 19 10:35:41 2012 -0500

    video: add option to include disabled CRTCs in best CRTC search
    
    This patch adds an option called consider_disabled to
    radeon_pick_best_crtc function. If this option is set
    and searching for best-fit CRTC yields nothing, the search
    will be widened to include CRTCs in DPMS "off" state.
    The new option is not used yet; it will be in the patches
    to follow.
    
    v2: Do not look at the CRTC mode, we only care about its box.
    
    Signed-off-by: Ilija Hadzic <ihadzic at research.bell-labs.com>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>

diff --git a/src/evergreen_textured_videofuncs.c b/src/evergreen_textured_videofuncs.c
index a1956e7..be00ecf 100644
--- a/src/evergreen_textured_videofuncs.c
+++ b/src/evergreen_textured_videofuncs.c
@@ -452,7 +452,7 @@ EVERGREENDisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
 	if (pPriv->desired_crtc)
 	    crtc = pPriv->desired_crtc;
 	else
-	    crtc = radeon_pick_best_crtc(pScrn,
+	    crtc = radeon_pick_best_crtc(pScrn, FALSE,
 					 pPriv->drw_x,
 					 pPriv->drw_x + pPriv->dst_w,
 					 pPriv->drw_y,
diff --git a/src/r600_textured_videofuncs.c b/src/r600_textured_videofuncs.c
index 19cf82d..d20df7e 100644
--- a/src/r600_textured_videofuncs.c
+++ b/src/r600_textured_videofuncs.c
@@ -435,7 +435,7 @@ R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
 	if (pPriv->desired_crtc)
 	    crtc = pPriv->desired_crtc;
 	else
-	    crtc = radeon_pick_best_crtc(pScrn,
+	    crtc = radeon_pick_best_crtc(pScrn, FALSE,
 					 pPriv->drw_x,
 					 pPriv->drw_x + pPriv->dst_w,
 					 pPriv->drw_y,
diff --git a/src/radeon.h b/src/radeon.h
index 0ad1411..0ae3d1e 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -516,6 +516,7 @@ extern void RADEONInitVideo(ScreenPtr pScreen);
 extern void RADEONResetVideo(ScrnInfoPtr pScrn);
 extern Bool radeon_load_bicubic_texture(ScrnInfoPtr pScrn);
 extern xf86CrtcPtr radeon_pick_best_crtc(ScrnInfoPtr pScrn,
+					 Bool consider_disabled,
 					 int x1, int x2, int y1, int y2);
 
 extern void radeon_cs_flush_indirect(ScrnInfoPtr pScrn);
diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
index 919f1f6..83bc2d2 100644
--- a/src/radeon_dri2.c
+++ b/src/radeon_dri2.c
@@ -781,7 +781,7 @@ static int radeon_dri2_drawable_crtc(DrawablePtr pDraw)
     xf86CrtcPtr crtc;
     int crtc_id = -1;
 
-    crtc = radeon_pick_best_crtc(pScrn,
+    crtc = radeon_pick_best_crtc(pScrn, FALSE,
 				 pDraw->x,
 				 pDraw->x + pDraw->width,
 				 pDraw->y,
diff --git a/src/radeon_exa_funcs.c b/src/radeon_exa_funcs.c
index 2533d78..ce6186d 100644
--- a/src/radeon_exa_funcs.c
+++ b/src/radeon_exa_funcs.c
@@ -190,7 +190,7 @@ RADEONSolid(PixmapPtr pPix, int x1, int y1, int x2, int y2)
 
     if (info->accel_state->vsync)
 	RADEONWaitForVLine(pScrn, pPix,
-			   radeon_pick_best_crtc(pScrn, x1, x2, y1, y2),
+			   radeon_pick_best_crtc(pScrn, FALSE, x1, x2, y1, y2),
 			   y1, y2);
 
     BEGIN_RING(2*2);
@@ -304,7 +304,7 @@ RADEONCopy(PixmapPtr pDst,
 
     if (info->accel_state->vsync)
 	RADEONWaitForVLine(pScrn, pDst,
-			   radeon_pick_best_crtc(pScrn, dstX, dstX + w, dstY, dstY + h),
+			   radeon_pick_best_crtc(pScrn, FALSE, dstX, dstX + w, dstY, dstY + h),
 			   dstY, dstY + h);
 
     BEGIN_RING(2*3);
diff --git a/src/radeon_exa_render.c b/src/radeon_exa_render.c
index c673f2c..1a35742 100644
--- a/src/radeon_exa_render.c
+++ b/src/radeon_exa_render.c
@@ -2261,7 +2261,7 @@ static void RadeonCompositeTile(ScrnInfoPtr pScrn,
 
     if (info->accel_state->vsync)
         RADEONWaitForVLine(pScrn, pDst,
-			   radeon_pick_best_crtc(pScrn, dstX, dstX + w, dstY, dstY + h),
+			   radeon_pick_best_crtc(pScrn, FALSE, dstX, dstX + w, dstY, dstY + h),
 			   dstY, dstY + h);
 
     if (info->ChipFamily < CHIP_FAMILY_R200) {
diff --git a/src/radeon_exa_shared.c b/src/radeon_exa_shared.c
index 1218efb..cca1c67 100644
--- a/src/radeon_exa_shared.c
+++ b/src/radeon_exa_shared.c
@@ -63,7 +63,8 @@ void RADEONVlineHelperSet(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2)
     RADEONInfoPtr info = RADEONPTR(pScrn);
     struct radeon_accel_state *accel_state = info->accel_state;
 
-    accel_state->vline_crtc = radeon_pick_best_crtc(pScrn, x1, x2, y1, y2);
+    accel_state->vline_crtc =
+	radeon_pick_best_crtc(pScrn, FALSE, x1, x2, y1, y2);
     if (accel_state->vline_y1 == -1)
 	accel_state->vline_y1 = y1;
     if (y1 < accel_state->vline_y1)
diff --git a/src/radeon_textured_videofuncs.c b/src/radeon_textured_videofuncs.c
index 02eb0b7..cfac902 100644
--- a/src/radeon_textured_videofuncs.c
+++ b/src/radeon_textured_videofuncs.c
@@ -269,7 +269,7 @@ RADEONPrepareTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
 	if (pPriv->desired_crtc)
 	    crtc = pPriv->desired_crtc;
 	else
-	    crtc = radeon_pick_best_crtc(pScrn,
+	    crtc = radeon_pick_best_crtc(pScrn, FALSE,
 					 pPriv->drw_x,
 					 pPriv->drw_x + pPriv->dst_w,
 					 pPriv->drw_y,
@@ -813,7 +813,7 @@ R200PrepareTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
 	if (pPriv->desired_crtc)
 	    crtc = pPriv->desired_crtc;
 	else
-	    crtc = radeon_pick_best_crtc(pScrn,
+	    crtc = radeon_pick_best_crtc(pScrn, FALSE,
 					 pPriv->drw_x,
 					 pPriv->drw_x + pPriv->dst_w,
 					 pPriv->drw_y,
@@ -2165,7 +2165,7 @@ R300PrepareTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
 	if (pPriv->desired_crtc)
 	    crtc = pPriv->desired_crtc;
 	else
-	    crtc = radeon_pick_best_crtc(pScrn,
+	    crtc = radeon_pick_best_crtc(pScrn, FALSE,
 					 pPriv->drw_x,
 					 pPriv->drw_x + pPriv->dst_w,
 					 pPriv->drw_y,
@@ -3718,7 +3718,7 @@ R500PrepareTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
 	if (pPriv->desired_crtc)
 	    crtc = pPriv->desired_crtc;
 	else
-	    crtc = radeon_pick_best_crtc(pScrn,
+	    crtc = radeon_pick_best_crtc(pScrn, FALSE,
 					 pPriv->drw_x,
 					 pPriv->drw_x + pPriv->dst_w,
 					 pPriv->drw_y,
diff --git a/src/radeon_video.c b/src/radeon_video.c
index 8073081..9381e4a 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -75,7 +75,7 @@ radeon_crtc_is_enabled(xf86CrtcPtr crtc)
 }
 
 xf86CrtcPtr
-radeon_pick_best_crtc(ScrnInfoPtr pScrn,
+radeon_pick_best_crtc(ScrnInfoPtr pScrn, Bool consider_disabled,
 		      int x1, int x2, int y1, int y2)
 {
     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
@@ -103,6 +103,7 @@ radeon_pick_best_crtc(ScrnInfoPtr pScrn,
     if (primary_output && primary_output->crtc)
 	primary_crtc = primary_output->crtc->devPrivate;
 
+    /* first consider only enabled CRTCs */
     for (c = 0; c < xf86_config->num_crtc; c++) {
 	xf86CrtcPtr crtc = xf86_config->crtc[c];
 
@@ -118,6 +119,22 @@ radeon_pick_best_crtc(ScrnInfoPtr pScrn,
 	    best_coverage = coverage;
 	}
     }
+    if (best_crtc || !consider_disabled)
+	return best_crtc;
+
+    /* if we found nothing, repeat the search including disabled CRTCs */
+    for (c = 0; c < xf86_config->num_crtc; c++) {
+	xf86CrtcPtr crtc = xf86_config->crtc[c];
+
+	radeon_crtc_box(crtc, &crtc_box);
+	radeon_box_intersect(&cover_box, &crtc_box, &box);
+	coverage = radeon_box_area(&cover_box);
+	if (coverage > best_coverage ||
+	    (coverage == best_coverage && crtc == primary_crtc)) {
+	    best_crtc = crtc;
+	    best_coverage = coverage;
+	}
+    }
     return best_crtc;
 }
 


More information about the xorg-commit mailing list