diff --git a/src/drmmode_display.c b/src/drmmode_display.c index ab11583a6..11a6805b4 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -495,7 +495,7 @@ void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode) return; } -static void +void drmmode_crtc_scanout_destroy(drmmode_ptr drmmode, struct drmmode_scanout *scanout) { diff --git a/src/drmmode_display.h b/src/drmmode_display.h index bd3f5f987..6a9803fad 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -156,6 +156,8 @@ extern Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode, extern void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode); extern Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn); +extern void drmmode_crtc_scanout_destroy(drmmode_ptr drmmode, + struct drmmode_scanout *scanout); extern void drmmode_scanout_free(ScrnInfoPtr scrn); extern void drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode); diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index c108ceab2..787fbf264 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -728,7 +728,8 @@ can_exchange(ScrnInfoPtr pScrn, DrawablePtr draw, drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; if (crtc->enabled && - (crtc->rotatedData || drmmode_crtc->scanout[0].bo)) + (crtc->rotatedData || + drmmode_crtc->scanout[drmmode_crtc->scanout_id].bo)) return FALSE; } @@ -777,7 +778,7 @@ can_flip(ScrnInfoPtr pScrn, DrawablePtr draw, continue; if (!drmmode_crtc || drmmode_crtc->rotate.bo || - drmmode_crtc->scanout[0].bo) + drmmode_crtc->scanout[drmmode_crtc->scanout_id].bo) return FALSE; if (drmmode_crtc->pending_dpms_mode == DPMSModeOn) diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 424f9f724..3d13a092a 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -732,7 +732,7 @@ radeon_prime_scanout_update(PixmapDirtyUpdatePtr dirty) drmmode_crtc = xf86_crtc->driver_private; if (drmmode_crtc->scanout_update_pending || - !drmmode_crtc->scanout[0].pixmap || + !drmmode_crtc->scanout[drmmode_crtc->scanout_id].pixmap || drmmode_crtc->pending_dpms_mode != DPMSModeOn) return; @@ -986,7 +986,9 @@ static void radeon_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, void *event_data) { - radeon_scanout_do_update(crtc, 0); + drmmode_crtc_private_ptr drmmode_crtc = event_data; + + radeon_scanout_do_update(crtc, drmmode_crtc->scanout_id); radeon_scanout_update_abort(crtc, event_data); } @@ -1004,7 +1006,6 @@ radeon_scanout_update(xf86CrtcPtr xf86_crtc) if (!xf86_crtc->enabled || drmmode_crtc->scanout_update_pending || - !drmmode_crtc->scanout[0].pixmap || drmmode_crtc->pending_dpms_mode != DPMSModeOn) return; @@ -1091,9 +1092,17 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info, if (drmmode_page_flip_target_relative(pRADEONEnt, drmmode_crtc, drmmode_crtc->scanout[scanout_id].fb_id, 0, drm_queue_seq, 0) != 0) { - xf86DrvMsg(scrn->scrnIndex, X_WARNING, "flip queue failed in %s: %s\n", + xf86DrvMsg(scrn->scrnIndex, X_WARNING, "flip queue failed in %s: %s, " + "TearFree inactive until next modeset\n", __func__, strerror(errno)); radeon_drm_abort_entry(drm_queue_seq); + RegionCopy(DamageRegion(drmmode_crtc->scanout_damage), + &drmmode_crtc->scanout_last_region); + RegionEmpty(&drmmode_crtc->scanout_last_region); + radeon_scanout_update(xf86_crtc); + drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode, + &drmmode_crtc->scanout[scanout_id]); + drmmode_crtc->tear_free = FALSE; return; } @@ -1122,11 +1131,7 @@ static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL) if (drmmode_crtc->tear_free) radeon_scanout_flip(pScreen, info, crtc); - else if (info->shadow_primary -#if XF86_CRTC_VERSION >= 4 - || crtc->driverIsPerformingTransform -#endif - ) + else if (drmmode_crtc->scanout[drmmode_crtc->scanout_id].pixmap) radeon_scanout_update(crtc); } } diff --git a/src/radeon_present.c b/src/radeon_present.c index af55e462f..5c915dfd8 100644 --- a/src/radeon_present.c +++ b/src/radeon_present.c @@ -248,7 +248,7 @@ radeon_present_check_unflip(ScrnInfoPtr scrn) continue; if (!drmmode_crtc || drmmode_crtc->rotate.bo || - drmmode_crtc->scanout[0].bo) + drmmode_crtc->scanout[drmmode_crtc->scanout_id].bo) return FALSE; if (drmmode_crtc->pending_dpms_mode == DPMSModeOn)