xf86-video-intel: src/i830_dri.c

Jesse Barnes jbarnes at kemper.freedesktop.org
Thu Feb 11 09:48:07 PST 2010


 src/i830_dri.c |   40 ++++++++++++++++++++++++++++++++--------
 1 file changed, 32 insertions(+), 8 deletions(-)

New commits:
commit 00e7312dc45e54cd4547a943897a524639cb0b38
Author: Jesse Barnes <jbarnes at virtuousgeek.org>
Date:   Thu Feb 11 09:46:12 2010 -0800

    DRI2: handle full height blits without tearing in CopyRegion
    
    On 965 and up, if we detect a full height blit, we should just wait for
    vblank, rather than try to do a scanline wait for the whole display.
    
    On pre-965, doing a scanline wait followed by a blit works, but in the
    full height case we need to give the blitter time to start up, so we
    wait until the bottom line of the blit minus 2 padding scanlines to
    accommodate.
    
    Fixes FDO bug #22475.
    
    Signed-off-by: Jesse Barnes <jbarnes at virtuousgeek.org>

diff --git a/src/i830_dri.c b/src/i830_dri.c
index d08beec..e64b25d 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -322,32 +322,56 @@ I830DRI2CopyRegion(DrawablePtr drawable, RegionPtr pRegion,
 		int y1, y2;
 		int pipe = -1, event, load_scan_lines_pipe;
 		xf86CrtcPtr crtc;
+		Bool full_height = FALSE;
 
 		box = REGION_EXTENTS(unused, gc->pCompositeClip);
 		crtc = i830_covering_crtc(scrn, box, NULL, &crtcbox);
 
-		/* Make sure the CRTC is valid and this is the real front buffer */
+		/*
+		 * Make sure the CRTC is valid and this is the real front
+		 * buffer
+		 */
 		if (crtc != NULL && !crtc->rotatedData) {
 			pipe = i830_crtc_to_pipe(crtc);
 
+			/*
+			 * Make sure we don't wait for a scanline that will
+			 * never occur
+			 */
+			y1 = (crtcbox.y1 <= box->y1) ? box->y1 - crtcbox.y1 : 0;
+			y2 = (box->y2 <= crtcbox.y2) ?
+			    box->y2 - crtcbox.y1 : crtcbox.y2 - crtcbox.y1;
+
+			if (y1 == 0 && y2 == (crtcbox.y2 - crtcbox.y1))
+			    full_height = TRUE;
+
+			/*
+			 * Pre-965 doesn't have SVBLANK, so we need a bit
+			 * of extra time for the blitter to start up and
+			 * do its job for a full height blit
+			 */
+			if (full_height && !IS_I965G(intel))
+			    y2 -= 2;
+
 			if (pipe == 0) {
 				event = MI_WAIT_FOR_PIPEA_SCAN_LINE_WINDOW;
 				load_scan_lines_pipe =
 				    MI_LOAD_SCAN_LINES_DISPLAY_PIPEA;
+				if (full_height && IS_I965G(intel))
+				    event = MI_WAIT_FOR_PIPEA_SVBLANK;
 			} else {
 				event = MI_WAIT_FOR_PIPEB_SCAN_LINE_WINDOW;
 				load_scan_lines_pipe =
 				    MI_LOAD_SCAN_LINES_DISPLAY_PIPEB;
+				if (full_height && IS_I965G(intel))
+				    event = MI_WAIT_FOR_PIPEB_SVBLANK;
 			}
 
-			/* Make sure we don't wait for a scanline that will never occur */
-			y1 = (crtcbox.y1 <= box->y1) ? box->y1 - crtcbox.y1 : 0;
-			y2 = (box->y2 <= crtcbox.y2) ?
-			    box->y2 - crtcbox.y1 : crtcbox.y2 - crtcbox.y1;
-
 			BEGIN_BATCH(5);
-			/* The documentation says that the LOAD_SCAN_LINES command
-			 * always comes in pairs. Don't ask me why. */
+			/*
+			 * The documentation says that the LOAD_SCAN_LINES
+			 * command always comes in pairs. Don't ask me why.
+			 */
 			OUT_BATCH(MI_LOAD_SCAN_LINES_INCL |
 				  load_scan_lines_pipe);
 			OUT_BATCH((y1 << 16) | y2);


More information about the xorg-commit mailing list