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

Michel Dänzer daenzer at kemper.freedesktop.org
Wed Feb 22 09:29:01 UTC 2017


 man/radeon.man        |   15 ++-
 src/drmmode_display.c |  240 ++++++++++++++++++++++++++++++++++++++++----------
 src/drmmode_display.h |    2 
 src/radeon.h          |    2 
 src/radeon_dri2.c     |   35 +++++--
 src/radeon_kms.c      |  105 ++++++++++++---------
 6 files changed, 295 insertions(+), 104 deletions(-)

New commits:
commit 58cd1600057e41aade0106d4acf78e23eac6e44f
Author: Michel Dänzer <michel.daenzer at 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 at 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
+
 static void
+drmmode_crtc_prime_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode,
+				  unsigned scanout_id, int *fb_id, int *x,
+				  int *y)
+{
+	ScrnInfoPtr scrn = crtc->scrn;
+	ScreenPtr screen = scrn->pScreen;
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+
+	if (drmmode_crtc->tear_free &&
+	    !drmmode_crtc->scanout[1].pixmap) {
+		RegionPtr region;
+		BoxPtr box;
+
+		drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[1],
+					    mode->HDisplay,
+					    mode->VDisplay);
+		region = &drmmode_crtc->scanout_last_region;
+		RegionUninit(region);
+		region->data = NULL;
+		box = RegionExtents(region);
+		box->x1 = crtc->x;
+		box->y1 = crtc->y;
+		box->x2 = crtc->x + mode->HDisplay;
+		box->y2 = crtc->y + mode->VDisplay;
+	}
+
+	if (scanout_id != drmmode_crtc->scanout_id) {
+		PixmapDirtyUpdatePtr dirty = NULL;
+
+		xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list,
+					 ent) {
+			if (dirty->src == crtc->randr_crtc->scanout_pixmap &&
+			    dirty->slave_dst ==
+			    drmmode_crtc->scanout[drmmode_crtc->scanout_id].pixmap) {
+				dirty->slave_dst =
+					drmmode_crtc->scanout[scanout_id].pixmap;
+				break;
+			}
+		}
+
+		if (!drmmode_crtc->tear_free) {
+			GCPtr gc = GetScratchGC(scrn->depth, screen);
+
+			ValidateGC(&drmmode_crtc->scanout[0].pixmap->drawable, gc);
+			gc->ops->CopyArea(&drmmode_crtc->scanout[1].pixmap->drawable,
+					  &drmmode_crtc->scanout[0].pixmap->drawable,
+					  gc, 0, 0, mode->HDisplay, mode->VDisplay,
+					  0, 0);
+			FreeScratchGC(gc);
+			radeon_cs_flush_indirect(scrn);
+			radeon_bo_wait(drmmode_crtc->scanout[0].bo);
+		}
+	}
+
+	*fb_id = drmmode_crtc->scanout[scanout_id].fb_id;
+	*x = *y = 0;
+	drmmode_crtc->scanout_id = scanout_id;
+}
+	
+#endif /* RADEON_PIXMAP_SHARING */
+
+			static void
 drmmode_crtc_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode,
 			    unsigned scanout_id, int *fb_id, int *x, int *y)
 {
 	ScrnInfoPtr scrn = crtc->scrn;
 	ScreenPtr screen = scrn->pScreen;
-	RADEONInfoPtr info = RADEONPTR(scrn);
 	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
 
 	drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[0],
 				    mode->HDisplay, mode->VDisplay);
-	if (info->tear_free) {
+	if (drmmode_crtc->tear_free) {
 		drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[1],
 					    mode->HDisplay, mode->VDisplay);
 	}
 
 	if (drmmode_crtc->scanout[0].pixmap &&
-	    (!info->tear_free || drmmode_crtc->scanout[1].pixmap)) {
+	    (!drmmode_crtc->tear_free || drmmode_crtc->scanout[1].pixmap)) {
 		RegionPtr region;
 		BoxPtr box;
 
@@ -762,7 +854,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 	RADEONInfoPtr info = RADEONPTR(pScrn);
 	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
 	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
-	unsigned scanout_id = drmmode_crtc->scanout_id ^ info->tear_free;
+	unsigned scanout_id = 0;
 	drmmode_ptr drmmode = drmmode_crtc->drmmode;
 	int saved_x, saved_y;
 	Rotation saved_rotation;
@@ -804,6 +896,10 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 		if (!drmmode_handle_transform(crtc))
 			goto done;
 
+		drmmode_crtc_update_tear_free(crtc);
+		if (drmmode_crtc->tear_free)
+			scanout_id = drmmode_crtc->scanout_id;
+
 		crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green,
 				       crtc->gamma_blue, crtc->gamma_size);
 
@@ -812,8 +908,8 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 		fb_id = drmmode->fb_id;
 #ifdef RADEON_PIXMAP_SHARING
 		if (crtc->randr_crtc && crtc->randr_crtc->scanout_pixmap) {
-			fb_id = drmmode_crtc->scanout[scanout_id].fb_id;
-			x = y = 0;
+			drmmode_crtc_prime_scanout_update(crtc, mode, scanout_id,
+							  &fb_id, &x, &y);
 		} else
 #endif
 		if (drmmode_crtc->rotate.fb_id) {
@@ -821,7 +917,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 			x = y = 0;
 
 		} else if (!radeon_is_gpu_screen(pScreen) &&
-			   (info->tear_free ||
+			   (drmmode_crtc->tear_free ||
 #if XF86_CRTC_VERSION >= 4
 			    crtc->driverIsPerformingTransform ||
 #endif
@@ -905,6 +1001,10 @@ done:
 
 		if (fb_id != drmmode_crtc->scanout[scanout_id].fb_id)
 			drmmode_crtc_scanout_free(drmmode_crtc);
+		else if (!drmmode_crtc->tear_free) {
+			drmmode_crtc_scanout_destroy(drmmode,
+						     &drmmode_crtc->scanout[1]);
+		}
 	}
 
 	free(output_ids);
@@ -1142,7 +1242,6 @@ drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix)
 {
 	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
 	unsigned scanout_id = drmmode_crtc->scanout_id;
-	RADEONInfoPtr info = RADEONPTR(crtc->scrn);
 	ScreenPtr screen = crtc->scrn->pScreen;
 	PixmapDirtyUpdatePtr dirty;
 
@@ -1163,7 +1262,7 @@ drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix)
 					 ppix->drawable.height))
 		return FALSE;
 
-	if (info->tear_free &&
+	if (drmmode_crtc->tear_free &&
 	    !drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[1],
 					 ppix->drawable.width,
 					 ppix->drawable.height)) {
@@ -1418,13 +1517,14 @@ drmmode_property_ignore(drmModePropertyPtr prop)
 static void
 drmmode_output_create_resources(xf86OutputPtr output)
 {
+    RADEONInfoPtr info = RADEONPTR(output->scrn);
     drmmode_output_private_ptr drmmode_output = output->driver_private;
     drmModeConnectorPtr mode_output = drmmode_output->mode_output;
     drmmode_ptr drmmode = drmmode_output->drmmode;
-    drmModePropertyPtr drmmode_prop;
+    drmModePropertyPtr drmmode_prop, tearfree_prop;
     int i, j, err;
 
-    drmmode_output->props = calloc(mode_output->count_props, sizeof(drmmode_prop_rec));
+    drmmode_output->props = calloc(mode_output->count_props + 1, sizeof(drmmode_prop_rec));
     if (!drmmode_output->props)
 	return;
     
@@ -1441,6 +1541,23 @@ drmmode_output_create_resources(xf86OutputPtr output)
 	j++;
     }
 
+    /* Userspace-only property for TearFree */
+    tearfree_prop = calloc(1, sizeof(*tearfree_prop));
+    tearfree_prop->flags = DRM_MODE_PROP_ENUM;
+    strncpy(tearfree_prop->name, "TearFree", 8);
+    tearfree_prop->count_enums = 3;
+    tearfree_prop->enums = calloc(tearfree_prop->count_enums,
+				  sizeof(*tearfree_prop->enums));
+    strncpy(tearfree_prop->enums[0].name, "off", 3);
+    strncpy(tearfree_prop->enums[1].name, "on", 2);
+    tearfree_prop->enums[1].value = 1;
+    strncpy(tearfree_prop->enums[2].name, "auto", 4);
+    tearfree_prop->enums[2].value = 2;
+    drmmode_output->props[j].mode_prop = tearfree_prop;
+    drmmode_output->props[j].value = info->tear_free;
+    drmmode_output->tear_free = info->tear_free;
+    drmmode_output->num_props++;
+
     for (i = 0; i < drmmode_output->num_props; i++) {
 	drmmode_prop_ptr p = &drmmode_output->props[i];
 	drmmode_prop = p->mode_prop;
@@ -1540,8 +1657,24 @@ drmmode_output_set_property(xf86OutputPtr output, Atom property,
 	    /* search for matching name string, then set its value down */
 	    for (j = 0; j < p->mode_prop->count_enums; j++) {
 		if (!strcmp(p->mode_prop->enums[j].name, name)) {
-		    drmModeConnectorSetProperty(drmmode->fd, drmmode_output->output_id,
-			    p->mode_prop->prop_id, p->mode_prop->enums[j].value);
+		    if (i == (drmmode_output->num_props - 1)) {
+			if (drmmode_output->tear_free != j) {
+			    xf86CrtcPtr crtc = output->crtc;
+
+			    drmmode_output->tear_free = j;
+			    if (crtc) {
+				drmmode_set_mode_major(crtc, &crtc->mode,
+						       crtc->rotation,
+						       crtc->x, crtc->y);
+			    }
+			}
+		    } else {
+			drmModeConnectorSetProperty(drmmode->fd,
+						    drmmode_output->output_id,
+						    p->mode_prop->prop_id,
+						    p->mode_prop->enums[j].value);
+		    }
+
 		    return TRUE;
 		}
 	    }
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
index 6bbf71c..bd3f5f9 100644
--- a/src/drmmode_display.h
+++ b/src/drmmode_display.h
@@ -89,6 +89,7 @@ typedef struct {
     RegionRec scanout_last_region;
     unsigned scanout_id;
     Bool scanout_update_pending;
+    Bool tear_free;
     int dpms_mode;
     /* For when a flip is pending when DPMS off requested */
     int pending_dpms_mode;
@@ -124,6 +125,7 @@ typedef struct {
     drmmode_prop_ptr props;
     int enc_mask;
     int enc_clone_mask;
+    int tear_free;
 } drmmode_output_private_rec, *drmmode_output_private_ptr;
 
 
diff --git a/src/radeon.h b/src/radeon.h
index 039a620..bfff232 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -507,7 +507,7 @@ typedef struct {
     Bool              accelOn;
     Bool              use_glamor;
     Bool              shadow_primary;
-    Bool              tear_free;
+    int               tear_free;
     Bool	      exa_pixmaps;
     Bool              exa_force_create;
     XF86ModReqInfo    exaReq;
diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
index d0dcf89..c108cea 100644
--- a/src/radeon_dri2.c
+++ b/src/radeon_dri2.c
@@ -47,6 +47,7 @@
 #include "radeon_bo_gem.h"
 
 #include <xf86Priv.h>
+#include <X11/extensions/dpmsconst.h>
 
 #if DRI2INFOREC_VERSION >= 9
 #define USE_DRI2_PRIME
@@ -756,14 +757,34 @@ can_flip(ScrnInfoPtr pScrn, DrawablePtr draw,
 	 DRI2BufferPtr front, DRI2BufferPtr back)
 {
     RADEONInfoPtr info = RADEONPTR(pScrn);
+    xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+    int num_crtcs_on;
+    int i;
+
+    if (draw->type != DRAWABLE_WINDOW ||
+	!info->allowPageFlip ||
+	info->hwcursor_disabled ||
+	info->drmmode.present_flipping ||
+	!pScrn->vtSema ||
+	!DRI2CanFlip(draw))
+	return FALSE;
+
+    for (i = 0, num_crtcs_on = 0; i < config->num_crtc; i++) {
+	xf86CrtcPtr crtc = config->crtc[i];
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+
+	if (!crtc->enabled)
+	    continue;
+
+	if (!drmmode_crtc || drmmode_crtc->rotate.bo ||
+	    drmmode_crtc->scanout[0].bo)
+	    return FALSE;
+
+	if (drmmode_crtc->pending_dpms_mode == DPMSModeOn)
+	    num_crtcs_on++;
+    }
 
-    return draw->type == DRAWABLE_WINDOW &&
-	   info->allowPageFlip &&
-	   !info->hwcursor_disabled &&
-	   !info->drmmode.present_flipping &&
-	   pScrn->vtSema &&
-	   DRI2CanFlip(draw) &&
-	   can_exchange(pScrn, draw, front, back);
+    return num_crtcs_on > 0 && can_exchange(pScrn, draw, front, back);
 }
 
 static void
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index 0ed7680..331f3f1 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -669,7 +669,6 @@ radeon_prime_scanout_do_update(xf86CrtcPtr crtc, unsigned scanout_id)
 {
     ScrnInfoPtr scrn = crtc->scrn;
     ScreenPtr screen = scrn->pScreen;
-    RADEONInfoPtr info = RADEONPTR(scrn);
     drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
     PixmapPtr scanoutpix = crtc->randr_crtc->scanout_pixmap;
     PixmapDirtyUpdatePtr dirty;
@@ -677,7 +676,7 @@ radeon_prime_scanout_do_update(xf86CrtcPtr crtc, unsigned scanout_id)
 
     xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, ent) {
 	if (dirty->src == scanoutpix && dirty->slave_dst ==
-	    drmmode_crtc->scanout[scanout_id ^ info->tear_free].pixmap) {
+	    drmmode_crtc->scanout[scanout_id ^ drmmode_crtc->tear_free].pixmap) {
 	    RegionPtr region;
 
 	    if (master_has_sync_shared_pixmap(scrn, dirty))
@@ -687,7 +686,7 @@ radeon_prime_scanout_do_update(xf86CrtcPtr crtc, unsigned scanout_id)
 	    if (RegionNil(region))
 		goto destroy;
 
-	    if (info->tear_free) {
+	    if (drmmode_crtc->tear_free) {
 		RegionTranslate(region, crtc->x, crtc->y);
 		radeon_sync_scanout_pixmaps(crtc, region, scanout_id);
 		radeon_cs_flush_indirect(scrn);
@@ -823,7 +822,6 @@ radeon_prime_scanout_flip(PixmapDirtyUpdatePtr ent)
 static void
 radeon_dirty_update(ScrnInfoPtr scrn)
 {
-	RADEONInfoPtr info = RADEONPTR(scrn);
 	ScreenPtr screen = scrn->pScreen;
 	PixmapDirtyUpdatePtr ent;
 	RegionPtr region;
@@ -844,7 +842,13 @@ radeon_dirty_update(ScrnInfoPtr scrn)
 			region = dirty_region(region_ent);
 
 			if (RegionNotEmpty(region)) {
-				if (info->tear_free)
+				xf86CrtcPtr crtc = radeon_prime_dirty_to_crtc(ent);
+				drmmode_crtc_private_ptr drmmode_crtc = NULL;
+
+				if (crtc)
+				    drmmode_crtc = crtc->driver_private;
+
+				if (drmmode_crtc && drmmode_crtc->tear_free)
 					radeon_prime_scanout_flip(ent);
 				else
 					radeon_prime_scanout_update(ent);
@@ -890,7 +894,7 @@ radeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id)
     if (!radeon_scanout_extents_intersect(xf86_crtc, &extents))
 	return FALSE;
 
-    if (info->tear_free) {
+    if (drmmode_crtc->tear_free) {
 	radeon_sync_scanout_pixmaps(xf86_crtc, pRegion, scanout_id);
 	RegionCopy(&drmmode_crtc->scanout_last_region, pRegion);
     }
@@ -1112,14 +1116,17 @@ static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL)
     if (!radeon_is_gpu_screen(pScreen))
     {
 	for (c = 0; c < xf86_config->num_crtc; c++) {
-	    if (info->tear_free)
-		radeon_scanout_flip(pScreen, info, xf86_config->crtc[c]);
+	    xf86CrtcPtr crtc = xf86_config->crtc[c];
+	    drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+
+	    if (drmmode_crtc->tear_free)
+		radeon_scanout_flip(pScreen, info, crtc);
 	    else if (info->shadow_primary
 #if XF86_CRTC_VERSION >= 4
-		     || xf86_config->crtc[c]->driverIsPerformingTransform
+		     || crtc->driverIsPerformingTransform
 #endif
 		)
-		radeon_scanout_update(xf86_config->crtc[c]);
+		radeon_scanout_update(crtc);
 	}
     }
 
@@ -1633,6 +1640,7 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
 {
     RADEONInfoPtr     info;
     RADEONEntPtr pRADEONEnt;
+    MessageType from;
     DevUnion* pPriv;
     Gamma  zeros = { 0.0, 0.0, 0.0 };
     uint32_t tiling = 0;
@@ -1778,11 +1786,14 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
 #endif
 
     if (!info->r600_shadow_fb) {
-	info->tear_free = xf86ReturnOptValBool(info->Options, OPTION_TEAR_FREE,
-					       FALSE);
+	from = X_DEFAULT;
 
-	if (info->tear_free)
-	    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TearFree enabled\n");
+	info->tear_free = 2;
+	if (xf86GetOptValBool(info->Options, OPTION_TEAR_FREE,
+			      &info->tear_free))
+	    from = X_CONFIG;
+	xf86DrvMsg(pScrn->scrnIndex, from, "TearFree property default: %s\n",
+		   info->tear_free == 2 ? "auto" : (info->tear_free ? "on" : "off"));
     }
 
     if (info->dri2.pKernelDRMVersion->version_minor >= 8) {
@@ -1791,13 +1802,13 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
 	info->allowPageFlip = xf86ReturnOptValBool(info->Options,
 						   OPTION_PAGE_FLIP, TRUE);
 
-	if (sw_cursor || info->tear_free || info->shadow_primary) {
+	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/TearFree") : "");
+			" because of ShadowPrimary") : "");
 	    info->allowPageFlip = FALSE;
 	} else {
 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
commit 305e2cbf335837a2ab6a24e9ff65815afe038296
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Tue Feb 21 15:55:13 2017 +0900

    Factor out drmmode_crtc_scanout_update helper
    
    Cleanup in preparation for following change, no functional change
    intended.
    
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 2258e7a..fcac156 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -706,6 +706,53 @@ drmmode_handle_transform(xf86CrtcPtr crtc)
 
 #endif
 
+static void
+drmmode_crtc_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode,
+			    unsigned scanout_id, int *fb_id, int *x, int *y)
+{
+	ScrnInfoPtr scrn = crtc->scrn;
+	ScreenPtr screen = scrn->pScreen;
+	RADEONInfoPtr info = RADEONPTR(scrn);
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+
+	drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[0],
+				    mode->HDisplay, mode->VDisplay);
+	if (info->tear_free) {
+		drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[1],
+					    mode->HDisplay, mode->VDisplay);
+	}
+
+	if (drmmode_crtc->scanout[0].pixmap &&
+	    (!info->tear_free || drmmode_crtc->scanout[1].pixmap)) {
+		RegionPtr region;
+		BoxPtr box;
+
+		if (!drmmode_crtc->scanout_damage) {
+			drmmode_crtc->scanout_damage =
+				DamageCreate(radeon_screen_damage_report,
+					     NULL, DamageReportRawRegion,
+					     TRUE, screen, NULL);
+			DamageRegister(&screen->GetScreenPixmap(screen)->drawable,
+				       drmmode_crtc->scanout_damage);
+		}
+
+		region = DamageRegion(drmmode_crtc->scanout_damage);
+		RegionUninit(region);
+		region->data = NULL;
+		box = RegionExtents(region);
+		box->x1 = 0;
+		box->y1 = 0;
+		box->x2 = max(box->x2, scrn->virtualX);
+		box->y2 = max(box->y2, scrn->virtualY);
+
+		*fb_id = drmmode_crtc->scanout[scanout_id].fb_id;
+		*x = *y = 0;
+
+		radeon_scanout_do_update(crtc, scanout_id);
+		radeon_bo_wait(drmmode_crtc->scanout[scanout_id].bo);
+	}
+}
+
 static Bool
 drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 		     Rotation rotation, int x, int y)
@@ -779,42 +826,8 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 			    crtc->driverIsPerformingTransform ||
 #endif
 			    info->shadow_primary)) {
-			for (i = 0; i < (info->tear_free ? 2 : 1); i++) {
-				drmmode_crtc_scanout_create(crtc,
-							    &drmmode_crtc->scanout[i],
-							    mode->HDisplay,
-							    mode->VDisplay);
-			}
-
-			if (drmmode_crtc->scanout[0].pixmap &&
-			    (!info->tear_free || drmmode_crtc->scanout[1].pixmap)) {
-				RegionPtr pRegion;
-				BoxPtr pBox;
-
-				if (!drmmode_crtc->scanout_damage) {
-					drmmode_crtc->scanout_damage =
-						DamageCreate(radeon_screen_damage_report,
-							     NULL, DamageReportRawRegion,
-							     TRUE, pScreen, NULL);
-					DamageRegister(&pScreen->GetScreenPixmap(pScreen)->drawable,
-						       drmmode_crtc->scanout_damage);
-				}
-
-				pRegion = DamageRegion(drmmode_crtc->scanout_damage);
-				RegionUninit(pRegion);
-				pRegion->data = NULL;
-				pBox = RegionExtents(pRegion);
-				pBox->x1 = 0;
-				pBox->y1 = 0;
-				pBox->x2 = max(pBox->x2, pScrn->virtualX);
-				pBox->y2 = max(pBox->y2, pScrn->virtualY);
-
-				fb_id = drmmode_crtc->scanout[scanout_id].fb_id;
-				x = y = 0;
-
-				radeon_scanout_do_update(crtc, scanout_id);
-				radeon_bo_wait(drmmode_crtc->scanout[scanout_id].bo);
-			}
+			drmmode_crtc_scanout_update(crtc, mode, scanout_id,
+						    &fb_id, &x, &y);
 		}
 
 		if (fb_id == 0) {
commit 649644a88347a6d03de68f8c41db03a82deeb23b
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Tue Feb 14 17:36:31 2017 +0900

    Factor out radeon_prime_dirty_to_crtc helper
    
    Cleanup in preparation for the following change, no functional change
    intended.
    
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index a95b51a..0ed7680 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -643,6 +643,27 @@ call_sync_shared_pixmap(PixmapDirtyUpdatePtr dirty)
 #endif /* HAS_SYNC_SHARED_PIXMAPS */
 
 
+static xf86CrtcPtr
+radeon_prime_dirty_to_crtc(PixmapDirtyUpdatePtr dirty)
+{
+    ScreenPtr screen = dirty->slave_dst->drawable.pScreen;
+    ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+    int c;
+
+    /* Find the CRTC which is scanning out from this slave pixmap */
+    for (c = 0; c < xf86_config->num_crtc; c++) {
+	xf86CrtcPtr xf86_crtc = xf86_config->crtc[c];
+	drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private;
+
+	if (drmmode_crtc->scanout[0].pixmap == dirty->slave_dst ||
+	    drmmode_crtc->scanout[1].pixmap == dirty->slave_dst)
+	    return xf86_crtc;
+    }
+
+    return NULL;
+}
+
 static Bool
 radeon_prime_scanout_do_update(xf86CrtcPtr crtc, unsigned scanout_id)
 {
@@ -701,24 +722,16 @@ radeon_prime_scanout_update(PixmapDirtyUpdatePtr dirty)
 {
     ScreenPtr screen = dirty->slave_dst->drawable.pScreen;
     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
-    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
-    xf86CrtcPtr xf86_crtc = NULL;
-    drmmode_crtc_private_ptr drmmode_crtc = NULL;
+    xf86CrtcPtr xf86_crtc = radeon_prime_dirty_to_crtc(dirty);
+    drmmode_crtc_private_ptr drmmode_crtc;
     uintptr_t drm_queue_seq;
     drmVBlank vbl;
-    int c;
 
-    /* Find the CRTC which is scanning out from this slave pixmap */
-    for (c = 0; c < xf86_config->num_crtc; c++) {
-	xf86_crtc = xf86_config->crtc[c];
-	drmmode_crtc = xf86_crtc->driver_private;
-	if (drmmode_crtc->scanout[0].pixmap == dirty->slave_dst)
-	    break;
-    }
+    if (!xf86_crtc || !xf86_crtc->enabled)
+	return;
 
-    if (c == xf86_config->num_crtc ||
-	!xf86_crtc->enabled ||
-	drmmode_crtc->scanout_update_pending ||
+    drmmode_crtc = xf86_crtc->driver_private;
+    if (drmmode_crtc->scanout_update_pending ||
 	!drmmode_crtc->scanout[0].pixmap ||
 	drmmode_crtc->pending_dpms_mode != DPMSModeOn)
 	return;
@@ -764,25 +777,16 @@ radeon_prime_scanout_flip(PixmapDirtyUpdatePtr ent)
     ScreenPtr screen = ent->slave_dst->drawable.pScreen;
     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
     RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn);
-    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
-    xf86CrtcPtr crtc = NULL;
-    drmmode_crtc_private_ptr drmmode_crtc = NULL;
+    xf86CrtcPtr crtc = radeon_prime_dirty_to_crtc(ent);
+    drmmode_crtc_private_ptr drmmode_crtc;
     uintptr_t drm_queue_seq;
     unsigned scanout_id;
-    int c;
 
-    /* Find the CRTC which is scanning out from this slave pixmap */
-    for (c = 0; c < xf86_config->num_crtc; c++) {
-	crtc = xf86_config->crtc[c];
-	drmmode_crtc = crtc->driver_private;
-	scanout_id = drmmode_crtc->scanout_id;
-	if (drmmode_crtc->scanout[scanout_id].pixmap == ent->slave_dst)
-	    break;
-    }
+    if (!crtc || !crtc->enabled)
+	return;
 
-    if (c == xf86_config->num_crtc ||
-	!crtc->enabled ||
-	drmmode_crtc->scanout_update_pending ||
+    drmmode_crtc = crtc->driver_private;
+    if (drmmode_crtc->scanout_update_pending ||
 	!drmmode_crtc->scanout[drmmode_crtc->scanout_id].pixmap ||
 	drmmode_crtc->pending_dpms_mode != DPMSModeOn)
 	return;


More information about the xorg-commit mailing list