xf86-video-amdgpu: Branch 'master' - 2 commits

Michel Dänzer daenzer at kemper.freedesktop.org
Fri Oct 20 08:34:23 UTC 2017


 src/amdgpu_kms.c |  162 +++++++++++++++++++++++++++++++++----------------------
 1 file changed, 98 insertions(+), 64 deletions(-)

New commits:
commit b67a2b62b20c17db7471f5bbea591ab55806cb29
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Thu Oct 19 16:46:35 2017 +0200

    Bail if there's a problem with ShadowFB
    
    If we hit a problem while setting up ShadowFB, just carrying on trying
    to set up HW acceleration instead is unlikely to work.
    
    (Ported from radeon commit 7d435354099119234d443b07e2df1c7b9f97cf3c)
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c
index e3d7d71..3598dd2 100644
--- a/src/amdgpu_kms.c
+++ b/src/amdgpu_kms.c
@@ -1174,11 +1174,11 @@ static Bool AMDGPUPreInitAccel_KMS(ScrnInfoPtr pScrn)
 			   "GPU acceleration disabled, using ShadowFB\n");
 	}
 
-	info->dri2.available = FALSE;
-	info->shadow_fb = TRUE;
 	if (!xf86LoadSubModule(pScrn, "shadow"))
-		info->shadow_fb = FALSE;
+		return FALSE;
 
+	info->dri2.available = FALSE;
+	info->shadow_fb = TRUE;
 	return TRUE;
 }
 
@@ -1727,7 +1727,7 @@ Bool AMDGPUScreenInit_KMS(ScreenPtr pScreen, int argc, char **argv)
 		if (info->fb_shadow == NULL) {
 			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 				   "Failed to allocate shadow framebuffer\n");
-			info->shadow_fb = FALSE;
+			return FALSE;
 		} else {
 			if (!fbScreenInit(pScreen, info->fb_shadow,
 					  pScrn->virtualX, pScrn->virtualY,
commit 55396cc45c9aae3b1985ced1044b6b93064667c3
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Thu Oct 19 16:20:03 2017 +0200

    Fix VT switching with ShadowFB
    
    We were trying to call acceleration specific functions from LeaveVT.
    Instead, memset the scanout buffer to all 0 in LeaveVT and allocate a
    new one in EnterVT.
    
    Bugzilla: https://bugs.freedesktop.org/102948
    Fixes: c16ff42f927d ("Make all active CRTCs scan out an all-black
                          framebuffer in LeaveVT")
    (Ported from radeon commit 34da04daec82077571558ac3fe1ec0c1203a01ad)
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c
index 6fe4326..e3d7d71 100644
--- a/src/amdgpu_kms.c
+++ b/src/amdgpu_kms.c
@@ -1941,6 +1941,33 @@ Bool AMDGPUEnterVT_KMS(ScrnInfoPtr pScrn)
 
 	amdgpu_set_drm_master(pScrn);
 
+	if (info->shadow_fb) {
+		int pitch;
+		struct amdgpu_buffer *front_buffer =
+			amdgpu_alloc_pixmap_bo(pScrn, pScrn->virtualX,
+					       pScrn->virtualY, pScrn->depth,
+					       AMDGPU_CREATE_PIXMAP_LINEAR,
+					       pScrn->bitsPerPixel,
+					       &pitch);
+
+		if (front_buffer) {
+			if (amdgpu_bo_map(pScrn, front_buffer) == 0) {
+				memset(front_buffer->cpu_ptr, 0, pitch * pScrn->virtualY);
+				amdgpu_bo_unref(&info->front_buffer);
+				info->front_buffer = front_buffer;
+			} else {
+				amdgpu_bo_unref(&front_buffer);
+				front_buffer = NULL;
+			}
+		}
+
+		if (!front_buffer) {
+			xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+				   "Failed to allocate new scanout BO after VT switch, "
+				   "other DRM masters may see screen contents\n");
+		}
+	}
+
 	pScrn->vtSema = TRUE;
 
 	if (!drmmode_set_desired_modes(pScrn, &info->drmmode, TRUE))
@@ -1963,84 +1990,91 @@ pixmap_unref_fb(void *value, XID id, void *cdata)
 void AMDGPULeaveVT_KMS(ScrnInfoPtr pScrn)
 {
 	AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
-	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn);
 	ScreenPtr pScreen = pScrn->pScreen;
-	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-	struct drmmode_scanout black_scanout = { .pixmap = NULL, .bo = NULL };
-	xf86CrtcPtr crtc;
-	drmmode_crtc_private_ptr drmmode_crtc;
-	unsigned w = 0, h = 0;
-	int i;
 
 	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG,
 		       "AMDGPULeaveVT_KMS\n");
 
-	/* Compute maximum scanout dimensions of active CRTCs */
-	for (i = 0; i < xf86_config->num_crtc; i++) {
-		crtc = xf86_config->crtc[i];
-		drmmode_crtc = crtc->driver_private;
-
-		if (!drmmode_crtc->fb)
-			continue;
-
-		w = max(w, crtc->mode.HDisplay);
-		h = max(h, crtc->mode.VDisplay);
-	}
+	if (!info->shadow_fb) {
+		AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn);
+		xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+		struct drmmode_scanout black_scanout = { .pixmap = NULL, .bo = NULL };
+		xf86CrtcPtr crtc;
+		drmmode_crtc_private_ptr drmmode_crtc;
+		unsigned w = 0, h = 0;
+		int i;
+
+		/* Compute maximum scanout dimensions of active CRTCs */
+		for (i = 0; i < xf86_config->num_crtc; i++) {
+			crtc = xf86_config->crtc[i];
+			drmmode_crtc = crtc->driver_private;
+
+			if (!drmmode_crtc->fb)
+				continue;
 
-	/* Make all active CRTCs scan out from an all-black framebuffer */
-	if (w > 0 && h > 0) {
-		if (drmmode_crtc_scanout_create(crtc, &black_scanout, w, h)) {
-			struct drmmode_fb *black_fb =
-				amdgpu_pixmap_get_fb(black_scanout.pixmap);
+			w = max(w, crtc->mode.HDisplay);
+			h = max(h, crtc->mode.VDisplay);
+		}
 
-			amdgpu_pixmap_clear(black_scanout.pixmap);
-			amdgpu_glamor_finish(pScrn);
+		/* Make all active CRTCs scan out from an all-black framebuffer */
+		if (w > 0 && h > 0) {
+			if (drmmode_crtc_scanout_create(crtc, &black_scanout, w, h)) {
+				struct drmmode_fb *black_fb =
+					amdgpu_pixmap_get_fb(black_scanout.pixmap);
 
-			for (i = 0; i < xf86_config->num_crtc; i++) {
-				crtc = xf86_config->crtc[i];
-				drmmode_crtc = crtc->driver_private;
+				amdgpu_pixmap_clear(black_scanout.pixmap);
+				amdgpu_glamor_finish(pScrn);
 
-				if (drmmode_crtc->fb) {
-					if (black_fb) {
-						drmmode_set_mode(crtc, black_fb, &crtc->mode, 0, 0);
-					} else {
-						drmModeSetCrtc(pAMDGPUEnt->fd,
-							       drmmode_crtc->mode_crtc->crtc_id, 0, 0,
-							       0, NULL, 0, NULL);
-						drmmode_fb_reference(pAMDGPUEnt->fd, &drmmode_crtc->fb,
-								     NULL);
-					}
+				for (i = 0; i < xf86_config->num_crtc; i++) {
+					crtc = xf86_config->crtc[i];
+					drmmode_crtc = crtc->driver_private;
 
-					if (pScrn->is_gpu) {
-						if (drmmode_crtc->scanout[0].pixmap)
-							pixmap_unref_fb(drmmode_crtc->scanout[0].pixmap,
-									None, pAMDGPUEnt);
-						if (drmmode_crtc->scanout[1].pixmap)
-							pixmap_unref_fb(drmmode_crtc->scanout[1].pixmap,
-									None, pAMDGPUEnt);
-					} else {
-						drmmode_crtc_scanout_free(drmmode_crtc);
+					if (drmmode_crtc->fb) {
+						if (black_fb) {
+							drmmode_set_mode(crtc, black_fb, &crtc->mode, 0, 0);
+						} else {
+							drmModeSetCrtc(pAMDGPUEnt->fd,
+								       drmmode_crtc->mode_crtc->crtc_id, 0,
+								       0, 0, NULL, 0, NULL);
+							drmmode_fb_reference(pAMDGPUEnt->fd,
+									     &drmmode_crtc->fb, NULL);
+						}
+
+						if (pScrn->is_gpu) {
+							if (drmmode_crtc->scanout[0].pixmap)
+								pixmap_unref_fb(drmmode_crtc->scanout[0].pixmap,
+										None, pAMDGPUEnt);
+							if (drmmode_crtc->scanout[1].pixmap)
+								pixmap_unref_fb(drmmode_crtc->scanout[1].pixmap,
+										None, pAMDGPUEnt);
+						} else {
+							drmmode_crtc_scanout_free(drmmode_crtc);
+						}
 					}
 				}
 			}
 		}
-	}
 
-	xf86RotateFreeShadow(pScrn);
-	drmmode_crtc_scanout_destroy(&info->drmmode, &black_scanout);
+		xf86RotateFreeShadow(pScrn);
+		drmmode_crtc_scanout_destroy(&info->drmmode, &black_scanout);
 
-	/* Unreference FBs of all pixmaps. After this, the only FB remaining
-	 * should be the all-black one being scanned out by active CRTCs
-	 */
-	for (i = 0; i < currentMaxClients; i++) {
-		if (i > 0 &&
-		    (!clients[i] || clients[i]->clientState != ClientStateRunning))
-			continue;
+		/* Unreference FBs of all pixmaps. After this, the only FB remaining
+		 * should be the all-black one being scanned out by active CRTCs
+		 */
+		for (i = 0; i < currentMaxClients; i++) {
+			if (i > 0 &&
+			    (!clients[i] || clients[i]->clientState != ClientStateRunning))
+				continue;
+
+			FindClientResourcesByType(clients[i], RT_PIXMAP, pixmap_unref_fb,
+						  pAMDGPUEnt);
+		}
 
-		FindClientResourcesByType(clients[i], RT_PIXMAP, pixmap_unref_fb,
-					  pAMDGPUEnt);
+		pixmap_unref_fb(pScreen->GetScreenPixmap(pScreen), None, pAMDGPUEnt);
+	} else {
+		memset(info->front_buffer->cpu_ptr, 0, pScrn->virtualX *
+		       info->pixel_bytes * pScrn->virtualY);
 	}
-	pixmap_unref_fb(pScreen->GetScreenPixmap(pScreen), None, pAMDGPUEnt);
 
 	TimerSet(NULL, 0, 1000, cleanup_black_fb, pScreen);
 


More information about the xorg-commit mailing list