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