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

Michel Dänzer daenzer at kemper.freedesktop.org
Fri Mar 3 07:16:09 UTC 2017


 autogen.sh            |    3 
 man/amdgpu.man        |   15 +-
 src/amdgpu_dri2.c     |   38 ++++-
 src/amdgpu_drv.h      |    2 
 src/amdgpu_kms.c      |  119 +++++++++-------
 src/drmmode_display.c |  358 +++++++++++++++++++++++++++++++++-----------------
 src/drmmode_display.h |    2 
 7 files changed, 354 insertions(+), 183 deletions(-)

New commits:
commit af0b24c1aca4cba2692d5aa410e63cb536478dbe
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Thu Mar 2 17:24:03 2017 +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.
    
    (Ported from radeon commit 58cd1600057e41aade0106d4acf78e23eac6e44f)
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/man/amdgpu.man b/man/amdgpu.man
index 0e5c291..53bd768 100644
--- a/man/amdgpu.man
+++ b/man/amdgpu.man
@@ -73,10 +73,17 @@ Enable DRI2 page flipping.  The default is
 .B on.
 .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
 Setting this option to
diff --git a/src/amdgpu_dri2.c b/src/amdgpu_dri2.c
index a83d217..8dde293 100644
--- a/src/amdgpu_dri2.c
+++ b/src/amdgpu_dri2.c
@@ -51,6 +51,7 @@
 #include "amdgpu_list.h"
 
 #include <xf86Priv.h>
+#include <X11/extensions/dpmsconst.h>
 
 #if DRI2INFOREC_VERSION >= 9
 #define USE_DRI2_PRIME
@@ -637,13 +638,34 @@ can_flip(ScrnInfoPtr pScrn, DrawablePtr draw,
 	 DRI2BufferPtr front, DRI2BufferPtr back)
 {
 	AMDGPUInfoPtr info = AMDGPUPTR(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/amdgpu_drv.h b/src/amdgpu_drv.h
index 3a24fa7..2aaafe4 100644
--- a/src/amdgpu_drv.h
+++ b/src/amdgpu_drv.h
@@ -221,7 +221,7 @@ typedef struct {
 	Bool use_glamor;
 	Bool force_accel;
 	Bool shadow_primary;
-	Bool tear_free;
+	int tear_free;
 
 	/* general */
 	OptionInfoPtr Options;
diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c
index 10a68fb..bafcb9b 100644
--- a/src/amdgpu_kms.c
+++ b/src/amdgpu_kms.c
@@ -575,7 +575,6 @@ amdgpu_prime_scanout_do_update(xf86CrtcPtr crtc, unsigned scanout_id)
 {
 	ScrnInfoPtr scrn = crtc->scrn;
 	ScreenPtr screen = scrn->pScreen;
-	AMDGPUInfoPtr info = AMDGPUPTR(scrn);
 	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
 	PixmapPtr scanoutpix = crtc->randr_crtc->scanout_pixmap;
 	PixmapDirtyUpdatePtr dirty;
@@ -583,7 +582,7 @@ amdgpu_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))
@@ -593,7 +592,7 @@ amdgpu_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);
 				amdgpu_sync_scanout_pixmaps(crtc, region, scanout_id);
 				amdgpu_glamor_flush(scrn);
@@ -730,7 +729,6 @@ amdgpu_prime_scanout_flip(PixmapDirtyUpdatePtr ent)
 static void
 amdgpu_dirty_update(ScrnInfoPtr scrn)
 {
-	AMDGPUInfoPtr info = AMDGPUPTR(scrn);
 	ScreenPtr screen = scrn->pScreen;
 	PixmapDirtyUpdatePtr ent;
 	RegionPtr region;
@@ -751,7 +749,13 @@ amdgpu_dirty_update(ScrnInfoPtr scrn)
 			region = dirty_region(region_ent);
 
 			if (RegionNotEmpty(region)) {
-				if (info->tear_free)
+				xf86CrtcPtr crtc = amdgpu_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)
 					amdgpu_prime_scanout_flip(ent);
 				else
 					amdgpu_prime_scanout_update(ent);
@@ -779,7 +783,6 @@ amdgpu_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id)
 	RegionPtr pRegion = DamageRegion(drmmode_crtc->scanout_damage);
 	ScrnInfoPtr scrn = xf86_crtc->scrn;
 	ScreenPtr pScreen = scrn->pScreen;
-	AMDGPUInfoPtr info = AMDGPUPTR(scrn);
 	DrawablePtr pDraw;
 	BoxRec extents;
 
@@ -796,7 +799,7 @@ amdgpu_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id)
 	if (!amdgpu_scanout_extents_intersect(xf86_crtc, &extents))
 		return FALSE;
 
-	if (info->tear_free) {
+	if (drmmode_crtc->tear_free) {
 		amdgpu_sync_scanout_pixmaps(xf86_crtc, pRegion, scanout_id);
 		RegionCopy(&drmmode_crtc->scanout_last_region, pRegion);
 	}
@@ -1014,14 +1017,17 @@ static void AMDGPUBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL)
 	if (!amdgpu_is_gpu_screen(pScreen))
 	{
 		for (c = 0; c < xf86_config->num_crtc; c++) {
-			if (info->tear_free)
-				amdgpu_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)
+				amdgpu_scanout_flip(pScreen, info, crtc);
 			else if (info->shadow_primary
 #if XF86_CRTC_VERSION >= 4
-					 || xf86_config->crtc[c]->driverIsPerformingTransform
+				 || crtc->driverIsPerformingTransform
 #endif
 				)
-				amdgpu_scanout_update(xf86_config->crtc[c]);
+				amdgpu_scanout_update(crtc);
 		}
 	}
 
@@ -1265,6 +1271,7 @@ Bool AMDGPUPreInit_KMS(ScrnInfoPtr pScrn, int flags)
 	AMDGPUInfoPtr info;
 	AMDGPUEntPtr pAMDGPUEnt;
 	struct amdgpu_gpu_info gpu_info;
+	MessageType from;
 	DevUnion *pPriv;
 	Gamma zeros = { 0.0, 0.0, 0.0 };
 	int cpp;
@@ -1359,12 +1366,14 @@ Bool AMDGPUPreInit_KMS(ScrnInfoPtr pScrn, int flags)
 	}
 
 	if (info->use_glamor) {
-		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"));
 
 		info->shadow_primary =
 			xf86ReturnOptValBool(info->Options, OPTION_SHADOW_PRIMARY, FALSE);
@@ -1378,14 +1387,14 @@ Bool AMDGPUPreInit_KMS(ScrnInfoPtr pScrn, int flags)
 	info->allowPageFlip = xf86ReturnOptValBool(info->Options,
 						   OPTION_PAGE_FLIP,
 						   TRUE);
-	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 ?
-			       (sw_cursor ? " because of SWcursor" :
-				" because of ShadowPrimary/TearFree") : "");
-		    info->allowPageFlip = FALSE;
+	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",
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 303848f..40439dd 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -587,6 +587,34 @@ drmmode_can_use_hw_cursor(xf86CrtcPtr crtc)
 	return TRUE;
 }
 
+static void
+drmmode_crtc_update_tear_free(xf86CrtcPtr crtc)
+{
+	AMDGPUInfoPtr info = AMDGPUPTR(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 &&
+		     (amdgpu_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
 
 #if XF86_CRTC_VERSION < 7
@@ -621,24 +649,86 @@ drmmode_handle_transform(xf86CrtcPtr crtc)
 
 #endif
 
+#ifdef AMDGPU_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);
+			amdgpu_glamor_finish(scrn);
+		}
+	}
+
+	*fb_id = drmmode_crtc->scanout[scanout_id].fb_id;
+	*x = *y = 0;
+	drmmode_crtc->scanout_id = scanout_id;
+}
+	
+#endif /* AMDGPU_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;
-	AMDGPUInfoPtr info = AMDGPUPTR(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;
 
@@ -678,7 +768,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(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;
@@ -722,6 +812,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);
 
@@ -730,8 +824,8 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 		fb_id = drmmode->fb_id;
 #ifdef AMDGPU_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) {
@@ -739,7 +833,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 			x = y = 0;
 
 		} else if (!amdgpu_is_gpu_screen(pScreen) &&
-			   (info->tear_free ||
+			   (drmmode_crtc->tear_free ||
 #if XF86_CRTC_VERSION >= 4
 			    crtc->driverIsPerformingTransform ||
 #endif
@@ -828,6 +922,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]);
+		}
 	}
 
 	return ret;
@@ -1086,7 +1184,6 @@ static Bool drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix)
 {
 	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
 	unsigned scanout_id = drmmode_crtc->scanout_id;
-	AMDGPUInfoPtr info = AMDGPUPTR(crtc->scrn);
 	ScreenPtr screen = crtc->scrn->pScreen;
 	PixmapDirtyUpdatePtr dirty;
 
@@ -1107,7 +1204,7 @@ static Bool 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)) {
@@ -1354,14 +1451,15 @@ static Bool drmmode_property_ignore(drmModePropertyPtr prop)
 
 static void drmmode_output_create_resources(xf86OutputPtr output)
 {
+	AMDGPUInfoPtr info = AMDGPUPTR(output->scrn);
 	drmmode_output_private_ptr drmmode_output = output->driver_private;
 	drmModeConnectorPtr mode_output = drmmode_output->mode_output;
 	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(output->scrn);
-	drmModePropertyPtr drmmode_prop;
+	drmModePropertyPtr drmmode_prop, tearfree_prop;
 	int i, j, err;
 
 	drmmode_output->props =
-	    calloc(mode_output->count_props, sizeof(drmmode_prop_rec));
+		calloc(mode_output->count_props + 1, sizeof(drmmode_prop_rec));
 	if (!drmmode_output->props)
 		return;
 
@@ -1379,6 +1477,23 @@ static void 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;
@@ -1504,11 +1619,26 @@ 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(pAMDGPUEnt->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(pAMDGPUEnt->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 e9967a2..fa15a4f 100644
--- a/src/drmmode_display.h
+++ b/src/drmmode_display.h
@@ -85,6 +85,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;
@@ -117,6 +118,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;
 
 
commit 77853f02e5b879e7042f55c672cf2d8e6955309f
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Thu Mar 2 17:19:59 2017 +0900

    Factor out drmmode_crtc_scanout_update helper
    
    Cleanup in preparation for following change, no functional change
    intended.
    
    (Ported from radeon commit 305e2cbf335837a2ab6a24e9ff65815afe038296)
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 463759b..303848f 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -621,6 +621,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;
+	AMDGPUInfoPtr info = AMDGPUPTR(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(amdgpu_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;
+
+		amdgpu_scanout_do_update(crtc, scanout_id);
+		amdgpu_glamor_finish(scrn);
+	}
+}
+
 static Bool
 drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 		       Rotation rotation, int x, int y)
@@ -697,42 +744,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(amdgpu_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;
-
-				amdgpu_scanout_do_update(crtc, scanout_id);
-				amdgpu_glamor_finish(pScrn);
-			}
+			drmmode_crtc_scanout_update(crtc, mode, scanout_id,
+						    &fb_id, &x, &y);
 		}
 
 		if (fb_id == 0) {
commit d25cc3b2b3b2d257aea247b85fea405d7e84e5b1
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Thu Mar 2 17:15:03 2017 +0900

    Factor out amdgpu_prime_dirty_to_crtc helper
    
    Cleanup in preparation for the following change, no functional change
    intended.
    
    (Ported from radeon commit 649644a88347a6d03de68f8c41db03a82deeb23b)
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c
index b2d098a..10a68fb 100644
--- a/src/amdgpu_kms.c
+++ b/src/amdgpu_kms.c
@@ -549,6 +549,27 @@ call_sync_shared_pixmap(PixmapDirtyUpdatePtr dirty)
 #endif /* HAS_SYNC_SHARED_PIXMAPS */
 
 
+static xf86CrtcPtr
+amdgpu_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
 amdgpu_prime_scanout_do_update(xf86CrtcPtr crtc, unsigned scanout_id)
 {
@@ -608,24 +629,16 @@ amdgpu_prime_scanout_update(PixmapDirtyUpdatePtr dirty)
 	ScreenPtr screen = dirty->slave_dst->drawable.pScreen;
 	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
 	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn);
-	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
-	xf86CrtcPtr xf86_crtc = NULL;
-	drmmode_crtc_private_ptr drmmode_crtc = NULL;
+	xf86CrtcPtr xf86_crtc = amdgpu_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;
@@ -671,25 +684,16 @@ amdgpu_prime_scanout_flip(PixmapDirtyUpdatePtr ent)
 	ScreenPtr screen = ent->slave_dst->drawable.pScreen;
 	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
 	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn);
-	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
-	xf86CrtcPtr crtc = NULL;
-	drmmode_crtc_private_ptr drmmode_crtc = NULL;
+	xf86CrtcPtr crtc = amdgpu_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;
commit a6d363008e2b55f0aa6151be1a99f01b97870e91
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Thu Mar 2 17:13:06 2017 +0900

    Don't destroy current FB if drmModeAddFB fails
    
    It would probably result in a black screen.
    
    (Ported from radeon commit 1351e48efe7a2c28eab447e16f36a00fbd02ae48)
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index bc7b9c3..463759b 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -2679,7 +2679,8 @@ flip_error:
 		   strerror(errno));
 
 error:
-	if (flipdata && flipdata->flip_count <= 1) {
+	if (flipdata && flipdata->flip_count <= 1 &&
+	    drmmode->fb_id != flipdata->old_fb_id) {
 		drmModeRmFB(pAMDGPUEnt->fd, drmmode->fb_id);
 		drmmode->fb_id = flipdata->old_fb_id;
 	}
commit 53926db2355de0a324c205703a0377b498136f65
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Thu Mar 2 17:08:19 2017 +0900

    Fix flip event data leak if calloc or drmModeAddFB fails
    
    (Ported from radeon commit 481394e3c9f9f7d88bb66fe9ae8834c87952a8ab)
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/src/amdgpu_dri2.c b/src/amdgpu_dri2.c
index ede6c0e..a83d217 100644
--- a/src/amdgpu_dri2.c
+++ b/src/amdgpu_dri2.c
@@ -465,9 +465,9 @@ xf86CrtcPtr amdgpu_dri2_drawable_crtc(DrawablePtr pDraw, Bool consider_disabled)
 static void
 amdgpu_dri2_flip_event_abort(xf86CrtcPtr crtc, void *event_data)
 {
-	AMDGPUInfoPtr info = AMDGPUPTR(crtc->scrn);
+	if (crtc)
+		AMDGPUPTR(crtc->scrn)->drmmode.dri2_flipping = FALSE;
 
-	info->drmmode.dri2_flipping = FALSE;
 	free(event_data);
 }
 
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 67dd61b..bc7b9c3 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -2688,8 +2688,10 @@ error:
 		amdgpu_drm_abort_entry(drm_queue_seq);
 	else if (crtc)
 		drmmode_flip_abort(crtc, flipdata);
-	else if (flipdata && flipdata->flip_count <= 1)
+	else {
+		abort(NULL, data);
 		free(flipdata);
+	}
 
 	xf86DrvMsg(scrn->scrnIndex, X_WARNING, "Page flip failed: %s\n",
 		   strerror(errno));
commit 45a8ec6257c370eecf43b6b8010863e37b704872
Author: Mihail Konev <k.mvc at ya.ru>
Date:   Thu Mar 2 17:04:36 2017 +0900

    autogen: add default patch prefix
    
    (Ported from radeon commit 8e6a4e96b7b27559e186f71b5547abb0a80b96dd)
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/autogen.sh b/autogen.sh
index 0006de8..c814d5c 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -9,6 +9,9 @@ cd "$srcdir"
 autoreconf -v --install || exit 1
 cd "$ORIGDIR" || exit $?
 
+git config --local --get format.subjectPrefix >/dev/null 2>&1 ||
+    git config --local format.subjectPrefix "PATCH xf86-video-amdgpu"
+
 if test -z "$NOCONFIGURE"; then
     exec "$srcdir"/configure "$@"
 fi
commit ba2aa0a8c12a2bea1e8be01ca3134b518d4cb0f2
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Thu Mar 2 16:55:38 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.
    
    (Ported from radeon commit f2bc882f1c1082bed9f496cfab6c8f07a76bc122)
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index b3c850c..67dd61b 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -589,22 +589,20 @@ drmmode_can_use_hw_cursor(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
-	AMDGPUInfoPtr info = AMDGPUPTR(crtc->scrn);
-
-	crtc->driverIsPerformingTransform = crtc->transformPresent ||
-		(info->tear_free && crtc->rotation != RR_Rotate_0);
-#endif
 
 	ret = xf86CrtcRotate(crtc);
 
commit 7f3abf35a2e1225ffd6a777b23f6a7a6355c1691
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Thu Mar 2 16:47:06 2017 +0900

    Fold drmmode_crtc_scanout_allocate into drmmode_crtc_scanout_create
    
    Not used anywhere else anymore.
    
    (Ported from radeon commit ae921a3150f69c38b5b3c88a9e37d54fdf0d5093)
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index c7c9f17..b3c850c 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -494,71 +494,39 @@ 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;
 	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn);
 	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
 	drmmode_ptr drmmode = drmmode_crtc->drmmode;
-	int ret;
 	union gbm_bo_handle bo_handle;
+	int pitch;
 
-	if (scanout->bo) {
+	if (scanout->pixmap) {
 		if (scanout->width == width && scanout->height == height)
-			return scanout->bo;
+			return scanout->pixmap;
 
 		drmmode_crtc_scanout_destroy(drmmode, scanout);
 	}
 
 	scanout->bo = amdgpu_alloc_pixmap_bo(pScrn, width, height,
 					     pScrn->depth, 0,
-					     pScrn->bitsPerPixel, pitch);
+					     pScrn->bitsPerPixel, &pitch);
 	if (!scanout->bo) {
 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-			   "Failed to allocate rotation buffer memory\n");
-		return NULL;
+			   "Failed to allocate scanout buffer memory\n");
+		goto error;
 	}
 
 	bo_handle = gbm_bo_get_handle(scanout->bo->bo.gbm);
-	ret = drmModeAddFB(pAMDGPUEnt->fd, width, height, pScrn->depth,
-			   pScrn->bitsPerPixel, *pitch,
-			   bo_handle.u32, &scanout->fb_id);
-	if (ret) {
-		ErrorF("failed to add rotate fb\n");
-		amdgpu_bo_unref(&scanout->bo);
-		scanout->bo = NULL;
-		return NULL;
-	}
-
-	scanout->width = width;
-	scanout->height = height;
-	return scanout->bo;
-}
-
-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;
+	if (drmModeAddFB(pAMDGPUEnt->fd, width, height, pScrn->depth,
+			 pScrn->bitsPerPixel, pitch,
+			 bo_handle.u32, &scanout->fb_id) != 0) {
+		ErrorF("failed to add scanout fb\n");
+		goto error;
 	}
 
 	scanout->pixmap = drmmode_create_bo_pixmap(pScrn,
@@ -566,12 +534,17 @@ drmmode_crtc_scanout_create(xf86CrtcPtr crtc,
 						 pScrn->depth,
 						 pScrn->bitsPerPixel,
 						 pitch, scanout->bo);
-	if (scanout->pixmap == NULL) {
+	if (scanout->pixmap) {
+		scanout->width = width;
+		scanout->height = height;
+	} else {
 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-			   "Couldn't allocate shadow pixmap for rotated CRTC\n");
+			   "Couldn't allocate scanout pixmap for CRTC\n");
+error:
+		drmmode_crtc_scanout_destroy(drmmode, scanout);
 	}
-	return scanout->pixmap;
 
+	return scanout->pixmap;
 }
 
 static void
commit 03c2db3c67bf5ad3c0744add9e0bb611b6cd3df7
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Thu Mar 2 16:42:04 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: 5f7123808833 ("Pass pitch from drmmode_crtc_scanout_allocate to
                          drmmode_create_bo_pixmap")
    (Ported from radeon commit 987a34adb319923ad36e2b47a26837248f187c3e)
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 4c35657..c7c9f17 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -1047,14 +1047,20 @@ static void drmmode_show_cursor(xf86CrtcPtr crtc)
 			 info->cursor_w, info->cursor_h);
 }
 
-static void *drmmode_crtc_shadow_allocate(xf86CrtcPtr crtc, int width,
-					  int height)
+/* 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
@@ -1062,11 +1068,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


More information about the xorg-commit mailing list