[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

xserver-xorg-video-ati: Changes to 'upstream-unstable'



 .editorconfig         |    3 
 Makefile.am           |    2 
 autogen.sh            |   11 -
 conf/10-radeon.conf   |    5 
 conf/Makefile.am      |   24 ++
 configure.ac          |   20 +-
 man/radeon.man        |   17 +
 src/ati.c             |   40 +++-
 src/drmmode_display.c |  495 +++++++++++++++++++++++++++++++++++---------------
 src/drmmode_display.h |   15 +
 src/radeon.h          |   24 --
 src/radeon_dri2.c     |   42 +++-
 src/radeon_dri3.c     |   37 +++
 src/radeon_glamor.c   |   11 -
 src/radeon_kms.c      |  326 +++++++++++++++++++-------------
 src/radeon_present.c  |   19 +
 src/radeon_probe.h    |    2 
 17 files changed, 760 insertions(+), 333 deletions(-)

New commits:
commit 66227060872219c1a0dc84fa4cea6264f7548446
Author: Michel Dänzer <michel.daenzer@amd.com>
Date:   Thu Mar 16 16:38:15 2017 +0900

    Bump version for 7.9.0 release

diff --git a/configure.ac b/configure.ac
index 732f705..b83b18f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -23,7 +23,7 @@
 # Initialize Autoconf
 AC_PREREQ([2.60])
 AC_INIT([xf86-video-ati],
-        [7.8.99],
+        [7.9.0],
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
         [xf86-video-ati])
 

commit 9a71445094b728f3d78db8f6808b4782ee19a453
Author: Michel Dänzer <michel.daenzer@amd.com>
Date:   Wed Mar 8 17:42:56 2017 +0900

    Pass TRUE to drmmode_set_desired_modes the first time for GPU screens
    
    This is the only place we call drmmode_set_desired_modes for GPU screens
    during server startup. Without this change, the display outputs of
    secondary GPUs may stay on even while Xorg isn't using them.
    
    Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index 907ebfc..424f9f7 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -328,7 +328,8 @@ static Bool RADEONCreateScreenResources_KMS(ScreenPtr pScreen)
 	}
     }
 
-    if (!drmmode_set_desired_modes(pScrn, &info->drmmode, FALSE))
+    if (!drmmode_set_desired_modes(pScrn, &info->drmmode,
+				   radeon_is_gpu_screen(pScreen)))
 	return FALSE;
 
     drmmode_uevent_init(pScrn, &info->drmmode);

commit 67ae5e00a748ad52cf92738d401afff2947b1891
Author: Michel Dänzer <michel.daenzer@amd.com>
Date:   Wed Mar 8 11:20:30 2017 +0900

    Skip some initialization steps for GPU screens
    
    Xorg doesn't use the following functionality of GPU screens, so don't
    bother initializing it:
    
    * DRI page flipping
    * DRI3 / Present / SYNC fences
    * XVideo / XvMC
    * Root window with background None
    
    Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

diff --git a/src/radeon.h b/src/radeon.h
index 815c12a..7374411 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -183,8 +183,10 @@ typedef enum {
 #if XF86_CRTC_VERSION >= 5
 #define RADEON_PIXMAP_SHARING 1
 #define radeon_is_gpu_screen(screen) (screen)->isGPU
+#define radeon_is_gpu_scrn(scrn) (scrn)->is_gpu
 #else
 #define radeon_is_gpu_screen(screen) 0
+#define radeon_is_gpu_scrn(scrn) 0
 #endif
 
 #define RADEON_VSYNC_TIMEOUT	20000 /* Maximum wait for VSYNC (in usecs) */
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index 7a561fa..907ebfc 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -1811,32 +1811,36 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
 		   info->tear_free == 2 ? "auto" : (info->tear_free ? "on" : "off"));
     }
 
-    if (info->dri2.pKernelDRMVersion->version_minor >= 8) {
-	Bool sw_cursor = xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE);
-
-	info->allowPageFlip = xf86ReturnOptValBool(info->Options,
-						   OPTION_PAGE_FLIP, TRUE);
-
-	if (sw_cursor || info->shadow_primary) {
-	    xf86DrvMsg(pScrn->scrnIndex,
-		       info->allowPageFlip ? X_WARNING : X_DEFAULT,
-		       "KMS Pageflipping: disabled%s\n",
-		       info->allowPageFlip ?
-		       (sw_cursor ? " because of SWcursor" :
-			" because of ShadowPrimary") : "");
-	    info->allowPageFlip = FALSE;
-	} else {
-	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		       "KMS Pageflipping: %sabled\n", info->allowPageFlip ? "en" : "dis");
+    if (!radeon_is_gpu_scrn(pScrn)) {
+	if (info->dri2.pKernelDRMVersion->version_minor >= 8) {
+	    Bool sw_cursor = xf86ReturnOptValBool(info->Options,
+						  OPTION_SW_CURSOR, FALSE);
+
+	    info->allowPageFlip = xf86ReturnOptValBool(info->Options,
+						       OPTION_PAGE_FLIP, TRUE);
+
+	    if (sw_cursor || info->shadow_primary) {
+		xf86DrvMsg(pScrn->scrnIndex,
+			   info->allowPageFlip ? X_WARNING : X_DEFAULT,
+			   "KMS Pageflipping: disabled%s\n",
+			   info->allowPageFlip ?
+			   (sw_cursor ? " because of SWcursor" :
+			    " because of ShadowPrimary") : "");
+		info->allowPageFlip = FALSE;
+	    } else {
+		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+			   "KMS Pageflipping: %sabled\n",
+			   info->allowPageFlip ? "en" : "dis");
+	    }
 	}
-    }
 
-    if (!info->use_glamor) {
-	info->swapBuffersWait =
-	    xf86ReturnOptValBool(info->Options, OPTION_SWAPBUFFERS_WAIT, TRUE);
-	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		   "SwapBuffers wait for vsync: %sabled\n",
-		   info->swapBuffersWait ? "en" : "dis");
+	if (!info->use_glamor) {
+	    info->swapBuffersWait =
+		xf86ReturnOptValBool(info->Options, OPTION_SWAPBUFFERS_WAIT, TRUE);
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		       "SwapBuffers wait for vsync: %sabled\n",
+		       info->swapBuffersWait ? "en" : "dis");
+	}
     }
 
     if (xf86ReturnOptValBool(info->Options, OPTION_DELETE_DP12, FALSE)) {
@@ -2244,33 +2248,35 @@ Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL)
     }
 #endif
 
-    if (xorgGetVersion() >= XORG_VERSION_NUMERIC(1,18,3,0,0))
-	value = info->use_glamor;
-    else
-	value = FALSE;
-    from = X_DEFAULT;
+    if (!radeon_is_gpu_screen(pScreen)) {
+	if (xorgGetVersion() >= XORG_VERSION_NUMERIC(1,18,3,0,0))
+	    value = info->use_glamor;
+	else
+	    value = FALSE;
+	from = X_DEFAULT;
 
-    if (!info->r600_shadow_fb) {
-	if (xf86GetOptValBool(info->Options, OPTION_DRI3, &value))
-	    from = X_CONFIG;
+	if (!info->r600_shadow_fb) {
+	    if (xf86GetOptValBool(info->Options, OPTION_DRI3, &value))
+		from = X_CONFIG;
 
-	if (xf86GetOptValInteger(info->Options, OPTION_DRI, &driLevel) &&
-	    (driLevel == 2 || driLevel == 3)) {
-	    from = X_CONFIG;
-	    value = driLevel == 3;
+	    if (xf86GetOptValInteger(info->Options, OPTION_DRI, &driLevel) &&
+		(driLevel == 2 || driLevel == 3)) {
+		from = X_CONFIG;
+		value = driLevel == 3;
+	    }
 	}
-    }
 
-    if (value) {
-	value = radeon_sync_init(pScreen) &&
-	    radeon_present_screen_init(pScreen) &&
-	    radeon_dri3_screen_init(pScreen);
+	if (value) {
+	    value = radeon_sync_init(pScreen) &&
+		radeon_present_screen_init(pScreen) &&
+		radeon_dri3_screen_init(pScreen);
 
-	if (!value)
-	    from = X_WARNING;
-    }
+	    if (!value)
+		from = X_WARNING;
+	}
 
-    xf86DrvMsg(pScrn->scrnIndex, from, "DRI3 %sabled\n", value ? "en" : "dis");
+	xf86DrvMsg(pScrn->scrnIndex, from, "DRI3 %sabled\n", value ? "en" : "dis");
+    }
 
     pScrn->vtSema = TRUE;
     xf86SetBackingStore(pScreen);
@@ -2325,7 +2331,8 @@ Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL)
      */
     /* xf86DiDGAInit(pScreen, info->LinearAddr + pScrn->fbOffset); */
 #endif
-    if (info->r600_shadow_fb == FALSE) {
+    if (info->r600_shadow_fb == FALSE &&
+	!radeon_is_gpu_screen(pScreen)) {
         /* Init Xv */
         xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
                        "Initializing Xv\n");
@@ -2341,12 +2348,14 @@ Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL)
     }
     pScrn->pScreen = pScreen;
 
-    if (serverGeneration == 1 && bgNoneRoot && info->accelOn) {
-	info->CreateWindow = pScreen->CreateWindow;
-	pScreen->CreateWindow = RADEONCreateWindow_oneshot;
+    if (!radeon_is_gpu_screen(pScreen)) {
+	if (serverGeneration == 1 && bgNoneRoot && info->accelOn) {
+	    info->CreateWindow = pScreen->CreateWindow;
+	    pScreen->CreateWindow = RADEONCreateWindow_oneshot;
+	}
+	info->WindowExposures = pScreen->WindowExposures;
+	pScreen->WindowExposures = RADEONWindowExposures_oneshot;
     }
-    info->WindowExposures = pScreen->WindowExposures;
-    pScreen->WindowExposures = RADEONWindowExposures_oneshot;
 
     /* Provide SaveScreen & wrap BlockHandler and CloseScreen */
     /* Wrap CloseScreen */

commit f0e7948e1c0e984fc27f235f365639e9cf628291
Author: Jochen Rollwagen <joro-2013@t-online.de>
Date:   Sun Mar 5 11:32:38 2017 +0100

    Fix build for XServer 1.13
    
    Latest git build stops with the error message
    
    radeon_kms.c: In function 'RADEONWindowExposures_oneshot':
    radeon_kms.c:1644:45: error: expected expression before 'RegionPtr'
         pScreen->WindowExposures(pWin, pRegion, RegionPtr pBSRegion);
    
    This patch fixes the build.
    
    Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>

diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index 572dfcc..7a561fa 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -1641,7 +1641,7 @@ static void RADEONWindowExposures_oneshot(WindowPtr pWin, RegionPtr pRegion
 
     pScreen->WindowExposures = info->WindowExposures;
 #if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,16,99,901,0)
-    pScreen->WindowExposures(pWin, pRegion, RegionPtr pBSRegion);
+    pScreen->WindowExposures(pWin, pRegion, pBSRegion);
 #else
     pScreen->WindowExposures(pWin, pRegion);
 #endif

commit d63881623f0686a66a2e3e3c1f84e496aa52ec6b
Author: Michel Dänzer <michel.daenzer@amd.com>
Date:   Thu Mar 2 16:22:51 2017 +0900

    Don't call radeon_cs_flush_indirect & radeon_bo_wait in drmmode_copy_fb
    
    RADEONWindowExposures_oneshot takes care of it.
    
    Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index a7904a3..ab11583 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -490,9 +490,6 @@ void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
 
 	FreeScratchGC(gc);
 
-	radeon_cs_flush_indirect(pScrn);
-	radeon_bo_wait(info->front_bo);
-
 	pScreen->canDoBGNoneRoot = TRUE;
 	destroy_pixmap_for_fbcon(pScrn);
 	return;

commit cc9d6b7db9c2078be1e530a64af6d517c6a42024
Author: Michel Dänzer <michel.daenzer@amd.com>
Date:   Wed Mar 1 17:35:59 2017 +0900

    Move DPMS check from radeon_scanout_do_update to radeon_scanout_flip
    
    When radeon_scanout_do_update is called from
    drmmode_crtc_scanout_update, drmmode_crtc->pending_dpms_mode may still
    be != DPMSModeOn, e.g. during server startup.
    
    Fixes intermittently showing garbage with TearFree enabled.

diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index c2089eb..572dfcc 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -882,7 +882,6 @@ radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id)
     Bool force;
 
     if (!xf86_crtc->enabled ||
-	drmmode_crtc->pending_dpms_mode != DPMSModeOn ||
 	!drmmode_crtc->scanout[scanout_id].pixmap)
 	return FALSE;
 
@@ -1069,7 +1068,8 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info,
     uintptr_t drm_queue_seq;
     unsigned scanout_id;
 
-    if (drmmode_crtc->scanout_update_pending)
+    if (drmmode_crtc->scanout_update_pending ||
+	drmmode_crtc->pending_dpms_mode != DPMSModeOn)
 	return;
 
     scanout_id = drmmode_crtc->scanout_id ^ 1;

commit 0a12bf1085505017068dfdfd31d23133e51b45b9
Author: Michel Dänzer <michel.daenzer@amd.com>
Date:   Wed Mar 1 18:00:40 2017 +0900

    Call drmmode_set_desired_modes from a WindowExposures hook
    
    This is the earliest opportunity where the root window contents are
    guaranteed to be initialized, and prevents drmmode_set_mode_major from
    getting called before drmmode_set_desired_modes via RADEONUnblank ->
    drmmode_crtc_dpms. Also, in contrast to the BlockHandler hook, this is
    called when running Xorg with -pogo.
    
    Fixes intermittently showing garbage on server startup or after server
    reset.
    
    As a bonus, this avoids trouble due to higher layers (e.g. the tigervnc
    Xorg module) calling RADEONBlockHandler_oneshot repeatedly even after
    we set pScreen->BlockHandler = RADEONBlockHandler_KMS.
    
    v2:
    * Drop spaces between XORG_VERSION_NUMERIC arguments
    * Call radeon_bo_wait after radeon_cs_flush_indirect
    
    Bugzilla: https://bugs.freedesktop.org/99457
    Reviewed-by: Alex Deucher <alexander.deucher@amd.com> (v1)

diff --git a/src/radeon.h b/src/radeon.h
index bfff232..815c12a 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -523,6 +523,7 @@ typedef struct {
 
     CreateScreenResourcesProcPtr CreateScreenResources;
     CreateWindowProcPtr CreateWindow;
+    WindowExposuresProcPtr WindowExposures;
 
     Bool              IsSecondary;
 
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index 331f3f1..c2089eb 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -1137,17 +1137,6 @@ 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);
-
-    RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS);
-
-    drmmode_set_desired_modes(pScrn, &info->drmmode, TRUE);
-}
-
 static Bool RADEONIsFastFBWorking(ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr info = RADEONPTR(pScrn);
@@ -1636,6 +1625,32 @@ static Bool RADEONCreateWindow_oneshot(WindowPtr pWin)
     return ret;
 }
 
+/* When the root window is mapped, set the initial modes */
+static void RADEONWindowExposures_oneshot(WindowPtr pWin, RegionPtr pRegion
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,16,99,901,0)
+					  , RegionPtr pBSRegion
+#endif
+    )
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+
+    if (pWin != pScreen->root)
+	ErrorF("%s called for non-root window %p\n", __func__, pWin);
+
+    pScreen->WindowExposures = info->WindowExposures;
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,16,99,901,0)
+    pScreen->WindowExposures(pWin, pRegion, RegionPtr pBSRegion);
+#else
+    pScreen->WindowExposures(pWin, pRegion);
+#endif
+
+    radeon_cs_flush_indirect(pScrn);
+    radeon_bo_wait(info->front_bo);
+    drmmode_set_desired_modes(pScrn, &info->drmmode, TRUE);
+}
+
 Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
 {
     RADEONInfoPtr     info;
@@ -2330,6 +2345,8 @@ Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL)
 	info->CreateWindow = pScreen->CreateWindow;
 	pScreen->CreateWindow = RADEONCreateWindow_oneshot;
     }
+    info->WindowExposures = pScreen->WindowExposures;
+    pScreen->WindowExposures = RADEONWindowExposures_oneshot;
 
     /* Provide SaveScreen & wrap BlockHandler and CloseScreen */
     /* Wrap CloseScreen */
@@ -2337,7 +2354,7 @@ Bool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL)
     pScreen->CloseScreen = RADEONCloseScreen_KMS;
     pScreen->SaveScreen  = RADEONSaveScreen_KMS;
     info->BlockHandler = pScreen->BlockHandler;
-    pScreen->BlockHandler = RADEONBlockHandler_oneshot;
+    pScreen->BlockHandler = RADEONBlockHandler_KMS;
 
     info->CreateScreenResources = pScreen->CreateScreenResources;
     pScreen->CreateScreenResources = RADEONCreateScreenResources_KMS;

commit df2d749a4db33298c8ce9f2cfb77c20c5538c9cc
Author: Michel Dänzer <michel.daenzer@amd.com>
Date:   Thu Mar 2 16:05:42 2017 +0900

    Fix bogus indentation
    
    Trivial.
    
    Fixes: 58cd1600057e ("Allow toggling TearFree at runtime via output property")

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 9c69b55..a7904a3 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -769,7 +769,7 @@ drmmode_crtc_prime_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode,
 	
 #endif /* RADEON_PIXMAP_SHARING */
 
-			static void
+static void
 drmmode_crtc_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode,
 			    unsigned scanout_id, int *fb_id, int *x, int *y)
 {

commit 9035b6abea557828e672ee455f0c84e43da0906f
Author: Michel Dänzer <michel.daenzer@amd.com>
Date:   Tue Feb 28 18:13:42 2017 +0900

    present: Flush before flipping
    
    This isn't necessary for DRI clients, but the Present extension can also
    be used for presenting normal pixmaps rendered to via the X11 protocol.
    
    Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

diff --git a/src/radeon_present.c b/src/radeon_present.c
index 01409ff..af55e46 100644
--- a/src/radeon_present.c
+++ b/src/radeon_present.c
@@ -347,6 +347,8 @@ radeon_present_flip(RRCrtcPtr crtc, uint64_t event_id, uint64_t target_msc,
 
     event->event_id = event_id;
 
+    radeon_cs_flush_indirect(scrn);
+
     ret = radeon_do_pageflip(scrn, RADEON_DRM_QUEUE_CLIENT_DEFAULT, handle,
 			     event_id, event, crtc_id,
 			     radeon_present_flip_event,

commit 0a4eb0e12f0c9c653cf4cea6fd62e1a507eb261c
Author: Michel Dänzer <michel.daenzer@amd.com>
Date:   Fri Feb 10 12:52:02 2017 +0900

    present: Use async flip for unflip if possible
    
    In that case, unflip operations should finish faster in general.
    
    Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

diff --git a/src/radeon_present.c b/src/radeon_present.c
index 6409fe3..01409ff 100644
--- a/src/radeon_present.c
+++ b/src/radeon_present.c
@@ -48,6 +48,8 @@
 
 #include "present.h"
 
+static present_screen_info_rec radeon_present_screen_info;
+
 struct radeon_present_vblank_event {
     uint64_t event_id;
     Bool unflip;
@@ -370,6 +372,9 @@ radeon_present_unflip(ScreenPtr screen, uint64_t event_id)
     xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
     struct radeon_present_vblank_event *event;
     PixmapPtr pixmap = screen->GetScreenPixmap(screen);
+    enum drmmode_flip_sync flip_sync =
+	(radeon_present_screen_info.capabilities & PresentCapabilityAsync) ?
+	FLIP_ASYNC : FLIP_VSYNC;
     uint32_t handle;
     int old_fb_id;
     int i;
@@ -396,7 +401,7 @@ radeon_present_unflip(ScreenPtr screen, uint64_t event_id)
 
     if (radeon_do_pageflip(scrn, RADEON_DRM_QUEUE_CLIENT_DEFAULT, handle,
 			   event_id, event, -1, radeon_present_flip_event,
-			   radeon_present_flip_abort, FLIP_VSYNC, 0))
+			   radeon_present_flip_abort, flip_sync, 0))
 	return;
 
 modeset:

commit 9a951a3e551db58ba50e7a594521ceac54d90615
Author: Michel Dänzer <michel.daenzer@amd.com>
Date:   Tue Feb 28 18:06:55 2017 +0900

    present: Also flush before using a flip to unflip
    
    Not doing so might result in intermittently scanning out stale contents
    of the screen pixmap.
    
    Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

diff --git a/src/radeon_present.c b/src/radeon_present.c
index 1b0ddcb..6409fe3 100644
--- a/src/radeon_present.c
+++ b/src/radeon_present.c
@@ -374,6 +374,8 @@ radeon_present_unflip(ScreenPtr screen, uint64_t event_id)
     int old_fb_id;
     int i;
 
+    radeon_cs_flush_indirect(scrn);
+
     if (!radeon_present_check_unflip(scrn))
 	goto modeset;
 
@@ -404,7 +406,6 @@ modeset:
     old_fb_id = info->drmmode.fb_id;
     info->drmmode.fb_id = 0;
 
-    radeon_cs_flush_indirect(scrn);
     radeon_bo_wait(info->front_bo);
     for (i = 0; i < config->num_crtc; i++) {
 	xf86CrtcPtr crtc = config->crtc[i];

commit f2bc882f1c1082bed9f496cfab6c8f07a76bc122
Author: Michel Dänzer <michel.daenzer@amd.com>
Date:   Tue Feb 28 17:31:14 2017 +0900

    Handle rotation in the driver also with Xorg 1.12-1.18
    
    We cannot use the HW cursor in that case, but in turn we get more
    efficient and less teary updates of rotated outputs.
    
    Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 38b36b2..9c69b55 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -673,23 +673,20 @@ drmmode_crtc_update_tear_free(xf86CrtcPtr crtc)
 
 #if XF86_CRTC_VERSION >= 4
 
+#if XF86_CRTC_VERSION < 7
+#define XF86DriverTransformOutput TRUE
+#define XF86DriverTransformNone FALSE
+#endif
+
 static Bool
 drmmode_handle_transform(xf86CrtcPtr crtc)
 {
 	Bool ret;
 
-#if XF86_CRTC_VERSION >= 7
 	if (crtc->transformPresent || crtc->rotation != RR_Rotate_0)
 	    crtc->driverIsPerformingTransform = XF86DriverTransformOutput;
 	else
 	    crtc->driverIsPerformingTransform = XF86DriverTransformNone;
-#else
-	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
-	RADEONInfoPtr info = RADEONPTR(crtc->scrn);
-
-	crtc->driverIsPerformingTransform = crtc->transformPresent ||
-		(drmmode_crtc->tear_free && crtc->rotation != RR_Rotate_0);
-#endif
 
 	ret = xf86CrtcRotate(crtc);
 

commit ae921a3150f69c38b5b3c88a9e37d54fdf0d5093
Author: Michel Dänzer <michel.daenzer@amd.com>
Date:   Tue Feb 28 17:47:09 2017 +0900

    Fold drmmode_crtc_scanout_allocate into drmmode_crtc_scanout_create
    
    Not used anywhere else anymore.
    
    Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 560bfae..38b36b2 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -550,10 +550,9 @@ drmmode_scanout_free(ScrnInfoPtr scrn)
 		drmmode_crtc_scanout_free(xf86_config->crtc[c]->driver_private);
 }
 
-static void *
-drmmode_crtc_scanout_allocate(xf86CrtcPtr crtc,
-			      struct drmmode_scanout *scanout,
-			      int width, int height, int *pitch)
+static PixmapPtr
+drmmode_crtc_scanout_create(xf86CrtcPtr crtc, struct drmmode_scanout *scanout,
+			    int width, int height)
 {
 	ScrnInfoPtr pScrn = crtc->scrn;
 	RADEONInfoPtr info = RADEONPTR(pScrn);
@@ -561,11 +560,11 @@ drmmode_crtc_scanout_allocate(xf86CrtcPtr crtc,
 	drmmode_ptr drmmode = drmmode_crtc->drmmode;
 	struct radeon_surface surface;
 	uint32_t tiling = RADEON_CREATE_PIXMAP_TILING_MACRO;
-	int ret;
+	int pitch;
 
-	if (scanout->bo) {
+	if (scanout->pixmap) {
 		if (scanout->width == width && scanout->height == height)
-			return scanout->bo->ptr;
+			return scanout->pixmap;
 
 		drmmode_crtc_scanout_destroy(drmmode, scanout);
 	}
@@ -574,48 +573,16 @@ drmmode_crtc_scanout_allocate(xf86CrtcPtr crtc,
 		tiling |= RADEON_CREATE_PIXMAP_TILING_MICRO;
 	scanout->bo = radeon_alloc_pixmap_bo(pScrn, width, height, pScrn->depth,
 					     tiling, pScrn->bitsPerPixel,
-					     pitch, &surface, &tiling);
+					     &pitch, &surface, &tiling);
 	if (scanout->bo == NULL)
-		return NULL;
-
-	radeon_bo_map(scanout->bo, 1);
+		goto error;
 
-	ret = drmModeAddFB(drmmode->fd, width, height, pScrn->depth,
-			   pScrn->bitsPerPixel, *pitch,
+	if (drmModeAddFB(drmmode->fd, width, height, pScrn->depth,
+			   pScrn->bitsPerPixel, pitch,
 			   scanout->bo->handle,
-			   &scanout->fb_id);
-	if (ret) {
+			   &scanout->fb_id) != 0) {
 		ErrorF("failed to add scanout fb\n");
-		radeon_bo_unref(scanout->bo);
-		scanout->bo = NULL;
-		return NULL;
-	}
-
-	scanout->width = width;
-	scanout->height = height;
-	return scanout->bo->ptr;
-}
-
-static PixmapPtr
-drmmode_crtc_scanout_create(xf86CrtcPtr crtc, struct drmmode_scanout *scanout,
-			    int width, int height)
-{
-	ScrnInfoPtr pScrn = crtc->scrn;
-	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
-	drmmode_ptr drmmode = drmmode_crtc->drmmode;
-	int pitch;
-
-	if (scanout->pixmap) {
-		if (scanout->width == width && scanout->height == height)
-			return scanout->pixmap;
-
-		drmmode_crtc_scanout_destroy(drmmode, scanout);
-	}
-
-	if (!scanout->bo) {
-		if (!drmmode_crtc_scanout_allocate(crtc, scanout, width, height,
-						   &pitch))
-			return NULL;
+		goto error;
 	}
 
 	scanout->pixmap = drmmode_create_bo_pixmap(pScrn,
@@ -623,9 +590,15 @@ drmmode_crtc_scanout_create(xf86CrtcPtr crtc, struct drmmode_scanout *scanout,
 						 pScrn->depth,
 						 pScrn->bitsPerPixel,
 						 pitch, scanout->bo, NULL);
-	if (scanout->pixmap == NULL)
+	if (scanout->pixmap) {
+		scanout->width = width;
+		scanout->height = height;
+	} else {
 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 			   "Couldn't allocate scanout pixmap for CRTC\n");
+error:
+		drmmode_crtc_scanout_destroy(drmmode, scanout);
+	}
 
 	return scanout->pixmap;
 }

commit 987a34adb319923ad36e2b47a26837248f187c3e
Author: Michel Dänzer <michel.daenzer@amd.com>
Date:   Tue Feb 28 17:17:20 2017 +0900

    Call drmmode_crtc_scanout_create in drmmode_crtc_shadow_allocate as well
    
    Calling drmmode_crtc_scanout_allocate in drmmode_crtc_shadow_allocate
    resulted in drmmode_crtc_scanout_create called from
    drmmode_crtc_shadow_create passing an uninitialized pitch value to
    drmmode_create_bo_pixmap.
    
    Fixes issues such as failure to allocate the scanout pixmap or visual
    corruption and GPUVM faults when attempting to use rotation with Xorg
    <1.19.
    
    Bugzilla: https://bugs.freedesktop.org/99916
    Fixes: ea30d856ba5e ("Pass pitch from drmmode_crtc_scanout_allocate to drmmode_create_bo_pixmap")
    Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index fd22a19..560bfae 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -1194,14 +1194,20 @@ drmmode_show_cursor (xf86CrtcPtr crtc)
 			 info->cursor_w, info->cursor_h);
 }
 
+/* Xorg expects a non-NULL return value from drmmode_crtc_shadow_allocate, and
+ * passes that back to drmmode_crtc_scanout_create; it doesn't use it for
+ * anything else.
+ */
 static void *
 drmmode_crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
 {
 	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
-	int pitch;
 
-	return drmmode_crtc_scanout_allocate(crtc, &drmmode_crtc->rotate,
-					     width, height, &pitch);
+	if (!drmmode_crtc_scanout_create(crtc, &drmmode_crtc->rotate, width,
+					 height))
+		return NULL;
+
+	return (void*)~0UL;
 }
 
 static PixmapPtr
@@ -1209,11 +1215,12 @@ drmmode_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
 {
 	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
 
-	/* Xorg passes in the return value of drmmode_crtc_shadow_allocate
-	 * for data, but that's redundant for drmmode_crtc_scanout_create.
-	 */
-	return drmmode_crtc_scanout_create(crtc, &drmmode_crtc->rotate, width,
-					   height);
+	if (!data) {
+		drmmode_crtc_scanout_create(crtc, &drmmode_crtc->rotate, width,
+					    height);
+	}
+
+	return drmmode_crtc->rotate.pixmap;
 }
 
 static void

commit 244d4bc7f8c8f6bc90f49556c0b9344c8aa40295
Author: Michel Dänzer <michel.daenzer@amd.com>
Date:   Thu Feb 9 18:55:04 2017 +0900

    present: Wait for screen pixmap BO idle before setting modes for unflip
    
    To make sure the screen pixmap contents are up to date when it starts
    being scanned out.
    
    Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

diff --git a/src/radeon_present.c b/src/radeon_present.c
index b36e29b..1b0ddcb 100644
--- a/src/radeon_present.c
+++ b/src/radeon_present.c
@@ -404,6 +404,8 @@ modeset:
     old_fb_id = info->drmmode.fb_id;
     info->drmmode.fb_id = 0;
 
+    radeon_cs_flush_indirect(scrn);
+    radeon_bo_wait(info->front_bo);
     for (i = 0; i < config->num_crtc; i++) {
 	xf86CrtcPtr crtc = config->crtc[i];
 	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;

commit 3ff29e5a14451916bc66b4e0028e9a317f0723f8
Author: Michel Dänzer <michel.daenzer@amd.com>
Date:   Thu Feb 9 18:50:40 2017 +0900

    present: Only call drmModeRmFB after setting modes for unflip
    
    Fixes display intermittently blanking when a modeset is used for unflip.
    
    Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

diff --git a/src/radeon_present.c b/src/radeon_present.c
index 29800fe..b36e29b 100644
--- a/src/radeon_present.c
+++ b/src/radeon_present.c
@@ -371,6 +371,7 @@ radeon_present_unflip(ScreenPtr screen, uint64_t event_id)
     struct radeon_present_vblank_event *event;
     PixmapPtr pixmap = screen->GetScreenPixmap(screen);
     uint32_t handle;
+    int old_fb_id;
     int i;
 
     if (!radeon_present_check_unflip(scrn))
@@ -400,7 +401,7 @@ modeset:
     /* info->drmmode.fb_id still points to the FB for the last flipped BO.
      * Clear it, drmmode_set_mode_major will re-create it
      */
-    drmModeRmFB(info->drmmode.fd, info->drmmode.fb_id);
+    old_fb_id = info->drmmode.fb_id;
     info->drmmode.fb_id = 0;
 
     for (i = 0; i < config->num_crtc; i++) {
@@ -417,6 +418,7 @@ modeset:
 	    drmmode_crtc->need_modeset = TRUE;
     }
 
+    drmModeRmFB(info->drmmode.fd, old_fb_id);
     present_event_notify(event_id, 0, 0);
 
     info->drmmode.present_flipping = FALSE;

commit 0c29deb5a97d9a57e994cc0053c49ddf7aca6ecb
Author: Michel Dänzer <michel.daenzer@amd.com>
Date:   Tue Feb 21 16:56:27 2017 +0900

    Use drmmode_crtc_scanout_free in drmmode_fini
    
    We were leaking drmmode_crtc->scanout_damage, which caused trouble on
    server reset. Fixes server reset with active separate scanout pixmaps.
    
    Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 5b0236d..fd22a19 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -2618,13 +2618,8 @@ void drmmode_fini(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
 #endif
 	}
 
-	for (c = 0; c < config->num_crtc; c++) {
-		xf86CrtcPtr crtc = config->crtc[c];
-		drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
-
-		drmmode_crtc_scanout_destroy(&info->drmmode, &drmmode_crtc->scanout[0]);
-		drmmode_crtc_scanout_destroy(&info->drmmode, &drmmode_crtc->scanout[1]);
-	}
+	for (c = 0; c < config->num_crtc; c++)
+		drmmode_crtc_scanout_free(config->crtc[c]->driver_private);
 }
 
 

commit 58cd1600057e41aade0106d4acf78e23eac6e44f
Author: Michel Dänzer <michel.daenzer@amd.com>
Date:   Thu Dec 1 18:37:57 2016 +0900

    Allow toggling TearFree at runtime via output property
    
    Option "TearFree" now sets the default value of the output property.
    See the manpage update for details.
    
    TearFree is now enabled by default for outputs using rotation or other
    RandR transforms, and for RandR 1.4 slave outputs.
    
    Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

diff --git a/man/radeon.man b/man/radeon.man
index 8990ae2..5301dd7 100644
--- a/man/radeon.man
+++ b/man/radeon.man
@@ -281,10 +281,17 @@ Enable DRI2 page flipping.  The default is
 Pageflipping is supported on all radeon hardware.
 .TP
 .BI "Option \*qTearFree\*q \*q" boolean \*q
-Enable tearing prevention using the hardware page flipping mechanism. Requires allocating two
-separate scanout buffers for each CRTC. Enabling this option currently disables Option
-\*qEnablePageFlip\*q. The default is
-.B off.
+Set the default value of the per-output 'TearFree' property, which controls
+tearing prevention using the hardware page flipping mechanism. TearFree is
+on for any CRTC associated with one or more outputs with TearFree on. Two
+separate scanout buffers need to be allocated for each CRTC with TearFree
+on. While TearFree is on for any CRTC, it currently prevents clients from using
+DRI page flipping. If this option is set, the default value of the property is
+'on' or 'off' accordingly. If this option isn't set, the default value of the
+property is
+.B auto,
+which means that TearFree is on for outputs with rotation or other RandR
+transforms, and for RandR 1.4 slave outputs, otherwise off.
 .TP
 .BI "Option \*qAccelMethod\*q \*q" "string" \*q
 Chooses between available acceleration architectures.  Valid values are
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index fcac156..5b0236d 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -670,6 +670,34 @@ drmmode_can_use_hw_cursor(xf86CrtcPtr crtc)
 	return TRUE;
 }
 
+static void
+drmmode_crtc_update_tear_free(xf86CrtcPtr crtc)
+{
+	RADEONInfoPtr info = RADEONPTR(crtc->scrn);
+	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+	int i;
+
+	drmmode_crtc->tear_free = FALSE;
+
+	for (i = 0; i < xf86_config->num_output; i++) {
+		xf86OutputPtr output = xf86_config->output[i];
+		drmmode_output_private_ptr drmmode_output = output->driver_private;
+
+		if (output->crtc != crtc)
+			continue;
+
+		if (drmmode_output->tear_free == 1 ||
+		    (drmmode_output->tear_free == 2 &&
+		     (radeon_is_gpu_screen(crtc->scrn->pScreen) ||
+		      info->shadow_primary ||
+		      crtc->transformPresent || crtc->rotation != RR_Rotate_0))) {
+			drmmode_crtc->tear_free = TRUE;
+			return;
+		}
+	}
+}
+
 #if XF86_CRTC_VERSION >= 4
 
 static Bool
@@ -683,10 +711,11 @@ drmmode_handle_transform(xf86CrtcPtr crtc)
 	else
 	    crtc->driverIsPerformingTransform = XF86DriverTransformNone;
 #else
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
 	RADEONInfoPtr info = RADEONPTR(crtc->scrn);
 
 	crtc->driverIsPerformingTransform = crtc->transformPresent ||
-		(info->tear_free && crtc->rotation != RR_Rotate_0);
+		(drmmode_crtc->tear_free && crtc->rotation != RR_Rotate_0);
 #endif
 
 	ret = xf86CrtcRotate(crtc);
@@ -706,24 +735,87 @@ drmmode_handle_transform(xf86CrtcPtr crtc)
 
 #endif
 
+#ifdef RADEON_PIXMAP_SHARING
+


Reply to: