diff options
author | Michel Dänzer <michel.daenzer@amd.com> | 2017-07-13 17:40:58 +0900 |
---|---|---|
committer | Michel Dänzer <michel@daenzer.net> | 2017-07-26 16:49:31 +0900 |
commit | 4d36306bcebb8548455a21eae6a7216a9439d9e4 (patch) | |
tree | ab81b864f761d940d34c7fa34a4cb22db273dbad | |
parent | 88147c1a532a9275eb57e14d8c11be41bf4c1fe1 (diff) |
If a TearFree flip fails, fall back to non-TearFree operation
In order to avoid possible freeze / log file spam in that case.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=99769
(Ported from radeon commit 94dc2b80f3ef0b2c17c20501d824fb0447d52e7a)
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | src/amdgpu_kms.c | 21 | ||||
-rw-r--r-- | src/drmmode_display.c | 12 | ||||
-rw-r--r-- | src/drmmode_display.h | 2 |
3 files changed, 22 insertions, 13 deletions
diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c index cc64eb5..2355a89 100644 --- a/src/amdgpu_kms.c +++ b/src/amdgpu_kms.c @@ -902,7 +902,9 @@ static void amdgpu_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, void *event_data) { - amdgpu_scanout_do_update(crtc, 0); + drmmode_crtc_private_ptr drmmode_crtc = event_data; + + amdgpu_scanout_do_update(crtc, drmmode_crtc->scanout_id); amdgpu_scanout_update_abort(crtc, event_data); } @@ -921,7 +923,6 @@ amdgpu_scanout_update(xf86CrtcPtr xf86_crtc) if (!xf86_crtc->enabled || drmmode_crtc->scanout_update_pending || - !drmmode_crtc->scanout[drmmode_crtc->scanout_id].pixmap || drmmode_crtc->pending_dpms_mode != DPMSModeOn) return; @@ -1023,9 +1024,17 @@ amdgpu_scanout_flip(ScreenPtr pScreen, AMDGPUInfoPtr info, if (drmmode_page_flip_target_relative(pAMDGPUEnt, drmmode_crtc, drmmode_crtc->flip_pending->handle, 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)); amdgpu_drm_abort_entry(drm_queue_seq); + RegionCopy(DamageRegion(drmmode_crtc->scanout_damage), + &drmmode_crtc->scanout_last_region); + RegionEmpty(&drmmode_crtc->scanout_last_region); + amdgpu_scanout_update(xf86_crtc); + drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode, + &drmmode_crtc->scanout[scanout_id]); + drmmode_crtc->tear_free = FALSE; return; } @@ -1071,11 +1080,7 @@ static void AMDGPUBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL) if (drmmode_crtc->tear_free) amdgpu_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) amdgpu_scanout_update(crtc); } } diff --git a/src/drmmode_display.c b/src/drmmode_display.c index ce46f7b..567d146 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -438,7 +438,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) { @@ -707,15 +707,17 @@ drmmode_crtc_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode, ScreenPtr screen = scrn->pScreen; drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[0], + drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[scanout_id], mode->HDisplay, mode->VDisplay); if (drmmode_crtc->tear_free) { - drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[1], + drmmode_crtc_scanout_create(crtc, + &drmmode_crtc->scanout[scanout_id ^ 1], mode->HDisplay, mode->VDisplay); } - if (drmmode_crtc->scanout[0].pixmap && - (!drmmode_crtc->tear_free || drmmode_crtc->scanout[1].pixmap)) { + if (drmmode_crtc->scanout[scanout_id].pixmap && + (!drmmode_crtc->tear_free || + drmmode_crtc->scanout[scanout_id ^ 1].pixmap)) { RegionPtr region; BoxPtr box; diff --git a/src/drmmode_display.h b/src/drmmode_display.h index f351bb0..309ec67 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -185,6 +185,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); |