xf86-video-ati: Branch 'master' - 6 commits

Michel Dänzer daenzer at kemper.freedesktop.org
Wed Apr 22 18:31:37 PDT 2015


 src/drmmode_display.c        |  137 ++++++++++++++++++++++++-------------------
 src/drmmode_display.h        |    5 +
 src/radeon.h                 |    9 ++
 src/radeon_glamor_wrappers.c |    9 ++
 src/radeon_kms.c             |   62 ++++++++++++++++++-
 5 files changed, 158 insertions(+), 64 deletions(-)

New commits:
commit 80f3d727f93cb6efedd2b39338d2301035965fe2
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Wed Apr 22 13:33:15 2015 +0900

    On screen resize, clear the new buffer before displaying it
    
    Fixes garbage being intermittently visible during a screen resize.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=27757#c7
    
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 326d863..5af5900 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -1766,6 +1766,9 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
 	uint32_t tiling_flags = 0, base_align;
 	PixmapPtr ppix = screen->GetScreenPixmap(screen);
 	void *fb_shadow;
+	xRectangle rect;
+	Bool force;
+	GCPtr gc;
 
 	if (scrn->virtualX == width && scrn->virtualY == height)
 		return TRUE;
@@ -1909,6 +1912,23 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
 	scrn->pixmapPrivate.ptr = ppix->devPrivate.ptr;
 #endif
 
+	if (info->use_glamor)
+		radeon_glamor_create_screen_resources(scrn->pScreen);
+
+	/* Clear new buffer */
+	gc = GetScratchGC(ppix->drawable.depth, scrn->pScreen);
+	force = info->accel_state->force;
+	info->accel_state->force = TRUE;
+	ValidateGC(&ppix->drawable, gc);
+	rect.x = 0;
+	rect.y = 0;
+	rect.width = width;
+	rect.height = height;
+	(*gc->ops->PolyFillRect)(&ppix->drawable, gc, 1, &rect);
+	FreeScratchGC(gc);
+	info->accel_state->force = force;
+	radeon_cs_flush_indirect(scrn);
+
 	for (i = 0; i < xf86_config->num_crtc; i++) {
 		xf86CrtcPtr crtc = xf86_config->crtc[i];
 
@@ -1919,9 +1939,6 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
 				       crtc->rotation, crtc->x, crtc->y);
 	}
 
-	if (info->use_glamor)
-		radeon_glamor_create_screen_resources(scrn->pScreen);
-
 	if (old_fb_id)
 		drmModeRmFB(drmmode->fd, old_fb_id);
 	if (old_front)
diff --git a/src/radeon.h b/src/radeon.h
index cd03d53..7feed04 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -544,6 +544,7 @@ typedef struct {
 	CreateGCProcPtr SavedCreateGC;
 	RegionPtr (*SavedCopyArea)(DrawablePtr, DrawablePtr, GCPtr, int, int,
 				   int, int, int, int);
+	void (*SavedPolyFillRect)(DrawablePtr, GCPtr, int, xRectangle*);
 	CloseScreenProcPtr SavedCloseScreen;
 	GetImageProcPtr SavedGetImage;
 	GetSpansProcPtr SavedGetSpans;
diff --git a/src/radeon_glamor_wrappers.c b/src/radeon_glamor_wrappers.c
index db2e85f..7a57bc1 100644
--- a/src/radeon_glamor_wrappers.c
+++ b/src/radeon_glamor_wrappers.c
@@ -421,9 +421,17 @@ radeon_glamor_poly_fill_rect(DrawablePtr pDrawable, GCPtr pGC,
 			     int nrect, xRectangle *prect)
 {
 	ScrnInfoPtr scrn = xf86ScreenToScrn(pDrawable->pScreen);
+	RADEONInfoPtr info = RADEONPTR(scrn);
 	PixmapPtr pixmap = get_drawable_pixmap(pDrawable);
 	struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap);
 
+	if ((info->accel_state->force || (priv && !priv->bo)) &&
+	    radeon_glamor_prepare_access_gpu(priv)) {
+		info->glamor.SavedPolyFillRect(pDrawable, pGC, nrect, prect);
+		radeon_glamor_finish_access_gpu_rw(info, priv);
+		return;
+	}
+
 	if (radeon_glamor_prepare_access_cpu_rw(scrn, pixmap, priv)) {
 		if (radeon_glamor_prepare_access_gc(scrn, pGC)) {
 			fbPolyFillRect(pDrawable, pGC, nrect, prect);
@@ -622,6 +630,7 @@ radeon_glamor_validate_gc(GCPtr pGC, unsigned long changes, DrawablePtr pDrawabl
 
 	glamor_validate_gc(pGC, changes, pDrawable);
 	info->glamor.SavedCopyArea = pGC->ops->CopyArea;
+	info->glamor.SavedPolyFillRect = pGC->ops->PolyFillRect;
 
 	if (radeon_get_pixmap_private(get_drawable_pixmap(pDrawable)) ||
 	    (pGC->stipple && radeon_get_pixmap_private(pGC->stipple)) ||
commit 3999bf88cdb192fe2f30b03bd2ed6f6a3f9f9057
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Thu Apr 2 18:29:38 2015 +0900

    Make drmmode_copy_fb() work with glamor as well
    
    Needed for Xorg -background none.
    
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 8caad70..326d863 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -348,11 +348,15 @@ static PixmapPtr
 create_pixmap_for_fbcon(drmmode_ptr drmmode,
 			ScrnInfoPtr pScrn, int fbcon_id)
 {
-	PixmapPtr pixmap = NULL;
+	RADEONInfoPtr info = RADEONPTR(pScrn);
+	PixmapPtr pixmap = info->fbcon_pixmap;
 	struct radeon_bo *bo;
 	drmModeFBPtr fbcon;
 	struct drm_gem_flink flink;
 
+	if (pixmap)
+	    return pixmap;
+
 	fbcon = drmModeGetFB(drmmode->fd, fbcon_id);
 	if (fbcon == NULL)
 		return NULL;
@@ -379,12 +383,30 @@ create_pixmap_for_fbcon(drmmode_ptr drmmode,
 	pixmap = drmmode_create_bo_pixmap(pScrn, fbcon->width, fbcon->height,
 					  fbcon->depth, fbcon->bpp,
 					  fbcon->pitch, 0, bo, NULL);
+	info->fbcon_pixmap = pixmap;
 	radeon_bo_unref(bo);
 out_free_fb:
 	drmModeFreeFB(fbcon);
 	return pixmap;
 }
 
+static void
+destroy_pixmap_for_fbcon(ScrnInfoPtr pScrn)
+{
+	RADEONInfoPtr info = RADEONPTR(pScrn);
+
+	/* XXX: The current GPUVM support in the kernel doesn't allow removing
+	 * the virtual address range for this BO, so we need to keep around
+	 * the pixmap to avoid breaking glamor with GPUVM
+	 */
+	if (info->use_glamor && info->ChipFamily >= CHIP_FAMILY_CAYMAN)
+		return;
+
+	if (info->fbcon_pixmap)
+		pScrn->pScreen->DestroyPixmap(info->fbcon_pixmap);
+	info->fbcon_pixmap = NULL;
+}
+
 #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 10
 
 void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
@@ -394,8 +416,9 @@ void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
 	PixmapPtr src, dst;
 	ScreenPtr pScreen = pScrn->pScreen;
 	int fbcon_id = 0;
+	Bool force;
+	GCPtr gc;
 	int i;
-	Bool ret;
 
 	for (i = 0; i < xf86_config->num_crtc; i++) {
 		drmmode_crtc_private_ptr drmmode_crtc = xf86_config->crtc[i]->driver_private;
@@ -421,18 +444,22 @@ void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
 		return;
 
 	dst = pScreen->GetScreenPixmap(pScreen);
-	ret = info->accel_state->exa->PrepareCopy (src, dst,
-						   -1, -1, GXcopy, FB_ALLONES);
-	if (!ret)
-	  goto out_free_src;
-	info->accel_state->exa->Copy (dst, 0, 0, 0, 0,
-				      pScrn->virtualX, pScrn->virtualY);
-	info->accel_state->exa->DoneCopy (dst);
+
+	gc = GetScratchGC(pScrn->depth, pScreen);
+	ValidateGC(&dst->drawable, gc);
+
+	force = info->accel_state->force;
+	info->accel_state->force = TRUE;
+	(*gc->ops->CopyArea)(&src->drawable, &dst->drawable, gc, 0, 0,
+			     pScrn->virtualX, pScrn->virtualY, 0, 0);
+	info->accel_state->force = force;
+
+	FreeScratchGC(gc);
+
 	radeon_cs_flush_indirect(pScrn);
 
 	pScreen->canDoBGNoneRoot = TRUE;
- out_free_src:
-	drmmode_destroy_bo_pixmap(src);
+	destroy_pixmap_for_fbcon(pScrn);
 	return;
 }
 
diff --git a/src/radeon.h b/src/radeon.h
index 8220da7..cd03d53 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -475,6 +475,7 @@ typedef struct {
     uint_fast32_t     gpu_flushed;
     uint_fast32_t     gpu_synced;
     struct radeon_accel_state *accel_state;
+    PixmapPtr         fbcon_pixmap;
     Bool              accelOn;
     Bool              use_glamor;
     Bool              shadow_primary;
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index 554a88a..0690ef0 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -186,6 +186,9 @@ static void RADEONFreeRec(ScrnInfoPtr pScrn)
 
     info = RADEONPTR(pScrn);
 
+    if (info->fbcon_pixmap)
+	pScrn->pScreen->DestroyPixmap(info->fbcon_pixmap);
+
     if (info->dri2.drm_fd > 0) {
         DevUnion *pPriv;
         RADEONEntPtr pRADEONEnt;
@@ -1706,7 +1709,7 @@ Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL)
     pScrn->pScreen = pScreen;
 
 #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 10
-    if (bgNoneRoot && info->accelOn && !info->use_glamor) {
+    if (bgNoneRoot && info->accelOn) {
 	info->CreateWindow = pScreen->CreateWindow;
 	pScreen->CreateWindow = RADEONCreateWindow;
     }
@@ -1772,7 +1775,7 @@ Bool RADEONEnterVT_KMS(VT_FUNC_ARGS_DECL)
     pScrn->vtSema = TRUE;
 
 #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 10
-    if (bgNoneRoot && info->accelOn && !info->use_glamor)
+    if (bgNoneRoot && info->accelOn)
 	drmmode_copy_fb(pScrn, &info->drmmode);
 #endif
 
commit a4a8cdbcc10c1c5f07485a2af9e9e81e490c3e1d
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Thu Apr 2 17:46:34 2015 +0900

    Update scanout pixmap contents before setting a mode with it
    
    This ensures the scanout pixmaps used for Option "TearFree" and Option
    "ShadowPrimary" have been initialized when their initial mode is set.
    
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 064a64c..8caad70 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -718,6 +718,8 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 				drmmode_crtc->scanout_id = 0;
 				fb_id = drmmode_crtc->scanout[0].fb_id;
 				x = y = 0;
+
+				radeon_scanout_update_handler(pScrn, 0, 0, crtc);
 			}
 		}
 		ret = drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
diff --git a/src/radeon.h b/src/radeon.h
index 962a68d..8220da7 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -593,6 +593,10 @@ extern Bool RADEONGetPixmapOffsetPitch(PixmapPtr pPix,
 /* radeon_dri3.c */
 Bool radeon_dri3_screen_init(ScreenPtr screen);
 
+/* radeon_kms.c */
+void radeon_scanout_update_handler(ScrnInfoPtr scrn, uint32_t frame,
+				   uint64_t usec, void *event_data);
+
 /* radeon_present.c */
 Bool radeon_present_screen_init(ScreenPtr screen);
 
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index 5a2d2da..554a88a 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -385,7 +385,7 @@ radeon_scanout_update_abort(ScrnInfoPtr scrn, void *event_data)
     drmmode_crtc->scanout_update_pending = FALSE;
 }
 
-static void
+void
 radeon_scanout_update_handler(ScrnInfoPtr scrn, uint32_t frame, uint64_t usec,
 			      void *event_data)
 {
commit 673e1c7637687c74fc9bdeeeffb7ace0d04b734f
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Thu Apr 2 17:54:33 2015 +0900

    Defer initial modeset until the first BlockHandler invocation
    
    This ensures that the screen pixmap contents have been initialized when
    the initial modes are set.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=27757
    
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 76b2577..064a64c 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -395,8 +395,6 @@ void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
 	ScreenPtr pScreen = pScrn->pScreen;
 	int fbcon_id = 0;
 	int i;
-	int pitch;
-	uint32_t tiling_flags = 0;
 	Bool ret;
 
 	for (i = 0; i < xf86_config->num_crtc; i++) {
@@ -422,28 +420,7 @@ void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
 	if (!src)
 		return;
 
-	if (info->allowColorTiling) {
-		if (info->ChipFamily >= CHIP_FAMILY_R600) {
-			if (info->allowColorTiling2D) {
-				tiling_flags |= RADEON_TILING_MACRO;
-			} else {
-				tiling_flags |= RADEON_TILING_MICRO;
-			}
-		} else
-			tiling_flags |= RADEON_TILING_MACRO;
-	}
-
-	pitch = RADEON_ALIGN(pScrn->displayWidth,
-			     drmmode_get_pitch_align(pScrn, info->pixel_bytes, tiling_flags)) *
-		info->pixel_bytes;
-
-	dst = drmmode_create_bo_pixmap(pScrn, pScrn->virtualX,
-				       pScrn->virtualY, pScrn->depth,
-				       pScrn->bitsPerPixel, pitch,
-				       tiling_flags, info->front_bo, &info->front_surface);
-	if (!dst)
-		goto out_free_src;
-
+	dst = pScreen->GetScreenPixmap(pScreen);
 	ret = info->accel_state->exa->PrepareCopy (src, dst,
 						   -1, -1, GXcopy, FB_ALLONES);
 	if (!ret)
@@ -454,7 +431,6 @@ void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
 	radeon_cs_flush_indirect(pScrn);
 
 	pScreen->canDoBGNoneRoot = TRUE;
-	drmmode_destroy_bo_pixmap(dst);
  out_free_src:
 	drmmode_destroy_bo_pixmap(src);
 	return;
@@ -2109,7 +2085,8 @@ void drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y)
 	}
 }
 
-Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
+Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode,
+			       Bool set_hw)
 {
 	xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
 	int c;
@@ -2121,7 +2098,7 @@ Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
 		int		o;
 
 		/* Skip disabled CRTCs */
-		if (!crtc->enabled) {
+		if (set_hw && !crtc->enabled) {
 			drmmode_do_crtc_dpms(crtc, DPMSModeOff);
 			drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
 				       0, 0, 0, NULL, 0, NULL);
@@ -2157,9 +2134,16 @@ Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
 			crtc->desiredY = 0;
 		}
 
-		if (!crtc->funcs->set_mode_major(crtc, &crtc->desiredMode, crtc->desiredRotation,
-						 crtc->desiredX, crtc->desiredY))
-			return FALSE;
+		if (set_hw) {
+			if (!crtc->funcs->set_mode_major(crtc, &crtc->desiredMode, crtc->desiredRotation,
+							 crtc->desiredX, crtc->desiredY))
+				return FALSE;
+		} else {
+			crtc->mode = crtc->desiredMode;
+			crtc->rotation = crtc->desiredRotation;
+			crtc->x = crtc->desiredX;
+			crtc->y = crtc->desiredY;
+		}
 	}
 	return TRUE;
 }
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
index 49b02d6..2fdd3e0 100644
--- a/src/drmmode_display.h
+++ b/src/drmmode_display.h
@@ -126,7 +126,8 @@ extern void drmmode_fini(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
 extern Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode, struct radeon_bo_manager *bufmgr);
 extern void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, struct radeon_bo *bo);
 void drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y);
-extern Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
+extern Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode,
+				      Bool set_hw);
 #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 10
 extern void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
 #endif
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index 8ec156f..5a2d2da 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -245,7 +245,7 @@ static Bool RADEONCreateScreenResources_KMS(ScreenPtr pScreen)
 	return FALSE;
     pScreen->CreateScreenResources = RADEONCreateScreenResources_KMS;
 
-    if (!drmmode_set_desired_modes(pScrn, &info->drmmode))
+    if (!drmmode_set_desired_modes(pScrn, &info->drmmode, FALSE))
 	return FALSE;
 
     drmmode_uevent_init(pScrn, &info->drmmode);
@@ -535,6 +535,17 @@ static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL)
 #endif
 }
 
+static void RADEONBlockHandler_oneshot(BLOCKHANDLER_ARGS_DECL)
+{
+    SCREEN_PTR(arg);
+    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+
+    drmmode_set_desired_modes(pScrn, &info->drmmode, TRUE);
+
+    RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS);
+}
+
 static void
 radeon_flush_callback(CallbackListPtr *list,
 		      pointer user_data, pointer call_data)
@@ -1707,7 +1718,7 @@ Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL)
     pScreen->CloseScreen = RADEONCloseScreen_KMS;
     pScreen->SaveScreen  = RADEONSaveScreen_KMS;
     info->BlockHandler = pScreen->BlockHandler;
-    pScreen->BlockHandler = RADEONBlockHandler_KMS;
+    pScreen->BlockHandler = RADEONBlockHandler_oneshot;
 
     if (!AddCallback(&FlushCallback, radeon_flush_callback, pScrn))
         return FALSE;
@@ -1765,7 +1776,7 @@ Bool RADEONEnterVT_KMS(VT_FUNC_ARGS_DECL)
 	drmmode_copy_fb(pScrn, &info->drmmode);
 #endif
 
-    if (!drmmode_set_desired_modes(pScrn, &info->drmmode))
+    if (!drmmode_set_desired_modes(pScrn, &info->drmmode, TRUE))
 	return FALSE;
 
     return TRUE;
commit 37874a4eeace5df04b02c8fc28f67b824e3f0f5f
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Tue Apr 21 17:19:15 2015 +0900

    Defer initial drmmode_copy_fb call until root window creation
    
    That's late enough for acceleration to be fully initialized, but still
    early enough to set pScreen->canDoBGNoneRoot.
    
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index edeba47..76b2577 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -2113,12 +2113,6 @@ Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
 {
 	xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
 	int c;
-#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 10
-	RADEONInfoPtr info = RADEONPTR(pScrn);
-
-	if (bgNoneRoot && info->accelOn && !info->use_glamor)
-		drmmode_copy_fb(pScrn, drmmode);
-#endif
 
 	for (c = 0; c < config->num_crtc; c++) {
 		xf86CrtcPtr	crtc = config->crtc[c];
diff --git a/src/radeon.h b/src/radeon.h
index 1c794ce..962a68d 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -493,6 +493,9 @@ typedef struct {
     DisplayModePtr currentMode;
 
     CreateScreenResourcesProcPtr CreateScreenResources;
+#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 10
+    CreateWindowProcPtr CreateWindow;
+#endif
 
     Bool              IsSecondary;
     Bool              IsPrimary;
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index dd785f5..8ec156f 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -1012,6 +1012,34 @@ static void RADEONSetupCapabilities(ScrnInfoPtr pScrn)
 #endif
 }
 
+#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 10
+
+/* When the root window is created, initialize the screen contents from
+ * console if -background none was specified on the command line
+ */
+static Bool RADEONCreateWindow(WindowPtr pWin)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    ScrnInfoPtr pScrn;
+    RADEONInfoPtr info;
+    Bool ret;
+
+    if (pWin != pScreen->root)
+	ErrorF("%s called for non-root window %p\n", __func__, pWin);
+
+    pScrn = xf86ScreenToScrn(pScreen);
+    info = RADEONPTR(pScrn);
+    pScreen->CreateWindow = info->CreateWindow;
+    ret = pScreen->CreateWindow(pWin);
+
+    if (ret)
+	drmmode_copy_fb(pScrn, &info->drmmode);
+
+    return ret;
+}
+
+#endif
+
 Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
 {
     RADEONInfoPtr     info;
@@ -1666,6 +1694,13 @@ Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL)
     }
     pScrn->pScreen = pScreen;
 
+#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 10
+    if (bgNoneRoot && info->accelOn && !info->use_glamor) {
+	info->CreateWindow = pScreen->CreateWindow;
+	pScreen->CreateWindow = RADEONCreateWindow;
+    }
+#endif
+
     /* Provide SaveScreen & wrap BlockHandler and CloseScreen */
     /* Wrap CloseScreen */
     info->CloseScreen    = pScreen->CloseScreen;
@@ -1725,6 +1760,11 @@ Bool RADEONEnterVT_KMS(VT_FUNC_ARGS_DECL)
 
     pScrn->vtSema = TRUE;
 
+#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 10
+    if (bgNoneRoot && info->accelOn && !info->use_glamor)
+	drmmode_copy_fb(pScrn, &info->drmmode);
+#endif
+
     if (!drmmode_set_desired_modes(pScrn, &info->drmmode))
 	return FALSE;
 
commit 39c497f3efca5ca08343b884f44c93215dcdef31
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Thu Apr 2 18:10:42 2015 +0900

    Only copy fbcon BO contents if bgNoneRoot is TRUE
    
    Otherwise, the X server will initialize the screen pixmap contents
    anyway.
    
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 21a5937..edeba47 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -385,6 +385,8 @@ out_free_fb:
 	return pixmap;
 }
 
+#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 10
+
 void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
 {
 	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
@@ -397,9 +399,6 @@ void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
 	uint32_t tiling_flags = 0;
 	Bool ret;
 
-	if (info->accelOn == FALSE || info->use_glamor)
-		goto fallback;
-
 	for (i = 0; i < xf86_config->num_crtc; i++) {
 		drmmode_crtc_private_ptr drmmode_crtc = xf86_config->crtc[i]->driver_private;
 
@@ -408,7 +407,7 @@ void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
 	}
 
 	if (!fbcon_id)
-		goto fallback;
+		return;
 
 	if (fbcon_id == drmmode->fb_id) {
 		/* in some rare case there might be no fbcon and we might already
@@ -421,7 +420,7 @@ void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
 
 	src = create_pixmap_for_fbcon(drmmode, pScrn, fbcon_id);
 	if (!src)
-		goto fallback;
+		return;
 
 	if (info->allowColorTiling) {
 		if (info->ChipFamily >= CHIP_FAMILY_R600) {
@@ -454,23 +453,15 @@ void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
 	info->accel_state->exa->DoneCopy (dst);
 	radeon_cs_flush_indirect(pScrn);
 
-#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 10
 	pScreen->canDoBGNoneRoot = TRUE;
-#endif
 	drmmode_destroy_bo_pixmap(dst);
  out_free_src:
 	drmmode_destroy_bo_pixmap(src);
 	return;
-
-fallback:
-	/* map and memset the bo */
-	if (radeon_bo_map(info->front_bo, 1))
-		return;
-
-	memset(info->front_bo->ptr, 0x00, info->front_bo->size);
-	radeon_bo_unmap(info->front_bo);
 }
 
+#endif /* GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 10 */
+
 static void
 drmmode_crtc_scanout_destroy(drmmode_ptr drmmode,
 			     struct drmmode_scanout *scanout)
@@ -2122,8 +2113,12 @@ Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
 {
 	xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
 	int c;
+#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 10
+	RADEONInfoPtr info = RADEONPTR(pScrn);
 
-	drmmode_copy_fb(pScrn, drmmode);
+	if (bgNoneRoot && info->accelOn && !info->use_glamor)
+		drmmode_copy_fb(pScrn, drmmode);
+#endif
 
 	for (c = 0; c < config->num_crtc; c++) {
 		xf86CrtcPtr	crtc = config->crtc[c];
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
index 1908b46..49b02d6 100644
--- a/src/drmmode_display.h
+++ b/src/drmmode_display.h
@@ -127,7 +127,9 @@ extern Bool drmmode_set_bufmgr(ScrnInfoPtr pScrn, drmmode_ptr drmmode, struct ra
 extern void drmmode_set_cursor(ScrnInfoPtr scrn, drmmode_ptr drmmode, int id, struct radeon_bo *bo);
 void drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y);
 extern Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
+#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 10
 extern void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
+#endif
 extern Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn);
 
 extern void drmmode_scanout_free(ScrnInfoPtr scrn);


More information about the xorg-commit mailing list