[PATCH xf86-video-amdgpu 2/6] Don't try DRI2/Present flipping while the HW cursor can't be used

Michel Dänzer michel at daenzer.net
Thu Mar 24 10:14:26 UTC 2016


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

Flipping doesn't interact correctly with SW cursor: A flip makes the SW
cursor disappear. It will only appear again when the cursor is moved,
but it will be surrounded by corruption, because the SW cursor code
will restore stale screen contents at the old cursor location before
drawing the cursor at the new location.

(Ported from radeon commit 7f3d0780ca65a90117c2a61362dbc0899bd9c0b0)

Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
---
 src/amdgpu_dri2.c     |  1 +
 src/amdgpu_drv.h      |  5 +++++
 src/amdgpu_kms.c      |  8 ++++++--
 src/amdgpu_present.c  |  3 +++
 src/drmmode_display.c | 15 ++++++++++++++-
 5 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/src/amdgpu_dri2.c b/src/amdgpu_dri2.c
index 5778268..de628cd 100644
--- a/src/amdgpu_dri2.c
+++ b/src/amdgpu_dri2.c
@@ -697,6 +697,7 @@ can_flip(ScrnInfoPtr pScrn, DrawablePtr draw,
 
 	return draw->type == DRAWABLE_WINDOW &&
 	    info->allowPageFlip &&
+	    !info->hwcursor_disabled &&
 	    !info->drmmode.present_flipping &&
 	    pScrn->vtSema &&
 	    DRI2CanFlip(draw) && can_exchange(pScrn, draw, front, back);
diff --git a/src/amdgpu_drv.h b/src/amdgpu_drv.h
index 3b074fc..60aa0be 100644
--- a/src/amdgpu_drv.h
+++ b/src/amdgpu_drv.h
@@ -248,6 +248,11 @@ typedef struct {
 	int cursor_w;
 	int cursor_h;
 
+	/* If bit n of this field is set, xf86_config->crtc[n] currently can't
+	 * use the HW cursor
+	 */
+	unsigned hwcursor_disabled;
+
 	struct {
 		CreateGCProcPtr SavedCreateGC;
 		RegionPtr (*SavedCopyArea)(DrawablePtr, DrawablePtr, GCPtr,
diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c
index f840e10..f814dc0 100644
--- a/src/amdgpu_kms.c
+++ b/src/amdgpu_kms.c
@@ -793,6 +793,7 @@ Bool AMDGPUPreInit_KMS(ScrnInfoPtr pScrn, int flags)
 	int cpp;
 	uint64_t heap_size = 0;
 	uint64_t max_allocation = 0;
+	Bool sw_cursor;
 
 	if (flags & PROBE_DETECT)
 		return TRUE;
@@ -889,15 +890,18 @@ Bool AMDGPUPreInit_KMS(ScrnInfoPtr pScrn, int flags)
 			xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShadowPrimary enabled\n");
 	}
 
+	sw_cursor = xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE);
+
 	info->allowPageFlip = xf86ReturnOptValBool(info->Options,
 						   OPTION_PAGE_FLIP,
 						   TRUE);
-	if (info->tear_free || info->shadow_primary) {
+	if (sw_cursor || info->tear_free || info->shadow_primary) {
 		    xf86DrvMsg(pScrn->scrnIndex,
 			       info->allowPageFlip ? X_WARNING : X_DEFAULT,
 			       "KMS Pageflipping: disabled%s\n",
 			       info->allowPageFlip ?
-			       " because of ShadowPrimary/TearFree" : "");
+			       (sw_cursor ? " because of SWcursor" :
+				" because of ShadowPrimary/TearFree") : "");
 		    info->allowPageFlip = FALSE;
 	} else {
 		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
diff --git a/src/amdgpu_present.c b/src/amdgpu_present.c
index 67b59b7..4b33ce2 100644
--- a/src/amdgpu_present.c
+++ b/src/amdgpu_present.c
@@ -229,6 +229,9 @@ amdgpu_present_check_flip(RRCrtcPtr crtc, WindowPtr window, PixmapPtr pixmap,
 	if (!info->allowPageFlip)
 		return FALSE;
 
+	if (info->hwcursor_disabled)
+		return FALSE;
+
 	if (!sync_flip)
 		return FALSE;
 
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 1cbea6e..2406959 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -799,7 +799,20 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 		}
 	}
 
-	if (drmmode_can_use_hw_cursor(crtc))
+	/* Compute index of this CRTC into xf86_config->crtc */
+	for (i = 0; i < xf86_config->num_crtc; i++) {
+		if (xf86_config->crtc[i] != crtc)
+			continue;
+
+		if (!crtc->enabled || drmmode_can_use_hw_cursor(crtc))
+			info->hwcursor_disabled &= ~(1 << i);
+		else
+			info->hwcursor_disabled |= 1 << i;
+
+		break;
+	}
+
+	if (!info->hwcursor_disabled)
 		xf86_reload_cursors(pScreen);
 
 done:
-- 
2.8.0.rc3



More information about the xorg-driver-ati mailing list