diff --git a/src/i830.h b/src/i830.h index 60dc1464..88542864 100644 --- a/src/i830.h +++ b/src/i830.h @@ -663,7 +663,9 @@ extern void I830EmitFlush(ScrnInfoPtr pScrn); extern void I830InitVideo(ScreenPtr pScreen); extern void i830_crtc_dpms_video(xf86CrtcPtr crtc, Bool on); - +extern xf86CrtcPtr i830_covering_crtc (ScrnInfoPtr pScrn, BoxPtr box, + xf86CrtcPtr desired, + BoxPtr crtc_box_ret); int i830_crtc_pipe (xf86CrtcPtr crtc); diff --git a/src/i830_dri.c b/src/i830_dri.c index fc059dfe..632280ea 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -303,6 +303,47 @@ I830DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion, REGION_COPY(pScreen, pCopyClip, pRegion); (*pGC->funcs->ChangeClip) (pGC, CT_REGION, pCopyClip, 0); ValidateGC(&pDstPixmap->drawable, pGC); + + /* Wait for the scanline to be outside the region to be copied */ + if (dstPrivate->attachment == DRI2BufferFrontLeft) { + BoxPtr box; + BoxRec crtcbox; + int y1, y2; + int pipe = -1, event, load_scan_lines_pipe; + xf86CrtcPtr crtc; + + box = REGION_EXTENTS(unused, pGC->pCompositeClip); + crtc = i830_covering_crtc(pScrn, box, NULL, &crtcbox); + + if (pI830->use_drm_mode) + pipe = drmmode_get_pipe_from_crtc_id(pI830->bufmgr, crtc); + else { + I830CrtcPrivatePtr intel_crtc = crtc->driver_private; + pipe = intel_crtc->pipe; + } + + if (pipe == 0) { + event = MI_WAIT_FOR_PIPEA_SCAN_LINE_WINDOW; + load_scan_lines_pipe = MI_LOAD_SCAN_LINES_DISPLAY_PIPEA; + } else { + event = MI_WAIT_FOR_PIPEB_SCAN_LINE_WINDOW; + load_scan_lines_pipe = MI_LOAD_SCAN_LINES_DISPLAY_PIPEB; + } + + y1 = box->y1 - crtc->y; + y2 = box->y2 - crtc->y; + + BEGIN_BATCH(5); + /* 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); + OUT_BATCH(MI_LOAD_SCAN_LINES_INCL | load_scan_lines_pipe); + OUT_BATCH((y1 << 16) | y2); + OUT_BATCH(MI_WAIT_FOR_EVENT | event); + ADVANCE_BATCH(); + } + (*pGC->ops->CopyArea)(&pSrcPixmap->drawable, &pDstPixmap->drawable, pGC, 0, 0, pDraw->width, pDraw->height, 0, 0); FreeScratchGC(pGC); diff --git a/src/i830_video.c b/src/i830_video.c index 5beee520..085e79a0 100644 --- a/src/i830_video.c +++ b/src/i830_video.c @@ -1713,7 +1713,7 @@ i830_box_area (BoxPtr box) * with greater coverage */ -static xf86CrtcPtr +xf86CrtcPtr i830_covering_crtc (ScrnInfoPtr pScrn, BoxPtr box, xf86CrtcPtr desired,