[PATCH xf86-video-amdgpu 2/2] If a TearFree flip fails, fall back to non-TearFree operation

Michel Dänzer michel at daenzer.net
Thu Jul 13 08:46:26 UTC 2017


From: Michel Dänzer <michel.daenzer at amd.com>

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)

Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
---
 src/amdgpu_kms.c      | 21 +++++++++++++--------
 src/drmmode_display.c | 12 +++++++-----
 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 cc64eb5b7..2355a8979 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 ce46f7ba6..567d14641 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 f351bb09c..309ec6704 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);
-- 
2.13.2



More information about the amd-gfx mailing list