From: Michel Dänzer <michel.daenzer@amd.com>
Date: Fri Nov 27 16:53:30 2015 +0900
Subject: [PATCH 12/20]Use drmmode_crtc_scanout_* helpers for RandR 1.4 scanout pixmaps
Patch-mainline: Upstream
Git-repo: git://anongit.freedesktop.org/xorg/driver/xf86-video-ati
Git-commit: 4cfa4615f79f64062e5e771cd45dd7048f48b4f6
References: bsc#990066
Signed-off-by: Max Staudt <mstaudt@suse.de>

This should allow using multiple CRTCs via RandR 1.4 even with xserver
< 1.17. It also simplifies the code a little, and paves the way for
following changes.

Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
---
 src/drmmode_display.c | 71 ++++++++++++++-------------------------------------
 src/drmmode_display.h |  1 -
 src/radeon_kms.c      | 16 +++++++-----
 3 files changed, 28 insertions(+), 60 deletions(-)

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index b9c8097..383c8a0 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -785,11 +785,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) {
-			x = drmmode_crtc->prime_pixmap_x;
-			y = 0;
-
-			drmmode_crtc_scanout_destroy(drmmode, &drmmode_crtc->scanout[0]);
-			drmmode_crtc_scanout_destroy(drmmode, &drmmode_crtc->scanout[1]);
+			fb_id = drmmode_crtc->scanout[0].fb_id;
+			x = y = 0;
 		} else
 #endif
 		if (drmmode_crtc->rotate.fb_id) {
@@ -798,11 +795,12 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,

 			drmmode_crtc_scanout_destroy(drmmode, &drmmode_crtc->scanout[0]);
 			drmmode_crtc_scanout_destroy(drmmode, &drmmode_crtc->scanout[1]);
-		} else if (info->tear_free ||
+		} else if (!pScreen->isGPU &&
+			   (info->tear_free ||
 #if XF86_CRTC_VERSION >= 4
-			   crtc->driverIsPerformingTransform ||
+			    crtc->driverIsPerformingTransform ||
 #endif
-			   info->shadow_primary) {
+			    info->shadow_primary)) {
 			for (i = 0; i < (info->tear_free ? 2 : 1); i++) {
 				drmmode_crtc_scanout_create(crtc,
 							    &drmmode_crtc->scanout[i],
@@ -1114,61 +1112,30 @@ drmmode_crtc_gamma_set(xf86CrtcPtr crtc, uint16_t *red, uint16_t *green,
 static Bool
 drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix)
 {
-	ScreenPtr screen = xf86ScrnToScreen(crtc->scrn);
-	PixmapPtr screenpix = screen->GetScreenPixmap(screen);
-	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
 	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
-	int c, total_width = 0, max_height = 0, this_x = 0;

 	if (!ppix) {
 		if (crtc->randr_crtc->scanout_pixmap)
-			PixmapStopDirtyTracking(crtc->randr_crtc->scanout_pixmap, screenpix);
-		drmmode_crtc->prime_pixmap_x = 0;
+			PixmapStopDirtyTracking(crtc->randr_crtc->scanout_pixmap,
+						drmmode_crtc->scanout[0].pixmap);
+		drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode,
+					     &drmmode_crtc->scanout[0]);
 		return TRUE;
 	}

-	/* iterate over all the attached crtcs -
-	   work out bounding box */
-	for (c = 0; c < xf86_config->num_crtc; c++) {
-		xf86CrtcPtr iter = xf86_config->crtc[c];
-		if (!iter->enabled && iter != crtc)
-			continue;
-		if (iter == crtc) {
-			this_x = total_width;
-			total_width += ppix->drawable.width;
-			if (max_height < ppix->drawable.height)
-				max_height = ppix->drawable.height;
-		} else {
-			total_width += iter->mode.HDisplay;
-			if (max_height < iter->mode.VDisplay)
-				max_height = iter->mode.VDisplay;
-		}
-#if !defined(HAS_DIRTYTRACKING_ROTATION) && !defined(HAS_DIRTYTRACKING2)
-		if (iter != crtc) {
-			ErrorF("Cannot do multiple crtcs without X server dirty tracking 2 interface\n");
-			return FALSE;
-		}
-#endif
-	}
-
-	if (total_width != screenpix->drawable.width ||
-	    max_height != screenpix->drawable.height) {
-		Bool ret;
-		ret = drmmode_xf86crtc_resize(crtc->scrn, total_width, max_height);
-		if (ret == FALSE)
-			return FALSE;
+	if (!drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[0],
+					 ppix->drawable.width,
+					 ppix->drawable.height))
+		return FALSE;

-		screenpix = screen->GetScreenPixmap(screen);
-		screen->width = screenpix->drawable.width = total_width;
-		screen->height = screenpix->drawable.height = max_height;
-	}
-	drmmode_crtc->prime_pixmap_x = this_x;
 #ifdef HAS_DIRTYTRACKING_ROTATION
-	PixmapStartDirtyTracking(ppix, screenpix, 0, 0, this_x, 0, RR_Rotate_0);
+	PixmapStartDirtyTracking(ppix, drmmode_crtc->scanout[0].pixmap,
+				 0, 0, 0, 0, RR_Rotate_0);
 #elif defined(HAS_DIRTYTRACKING2)
-	PixmapStartDirtyTracking2(ppix, screenpix, 0, 0, this_x, 0);
+	PixmapStartDirtyTracking2(ppix, drmmode_crtc->scanout[0].pixmap,
+				  0, 0, 0, 0);
 #else
-	PixmapStartDirtyTracking(ppix, screenpix, 0, 0);
+	PixmapStartDirtyTracking(ppix, drmmode_crtc->scanout[0].pixmap, 0, 0);
 #endif
 	return TRUE;
 }
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
index 63b96ac..53c7926 100644
--- a/src/drmmode_display.h
+++ b/src/drmmode_display.h
@@ -95,7 +95,6 @@ typedef struct {
     int dpms_last_fps;
     uint32_t interpolated_vblanks;
     uint16_t lut_r[256], lut_g[256], lut_b[256];
-    int prime_pixmap_x;

     /* Modeset needed (for DPMS on or after a page flip crossing with a
      * modeset)
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index 136c46c..53994c9 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -696,15 +696,17 @@ static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL)
     (*pScreen->BlockHandler) (BLOCKHANDLER_ARGS);
     pScreen->BlockHandler = RADEONBlockHandler_KMS;

-    for (c = 0; c < xf86_config->num_crtc; c++) {
-	if (info->tear_free)
-	    radeon_scanout_flip(pScreen, info, xf86_config->crtc[c]);
-	else if (info->shadow_primary
+    if (!pScreen->isGPU) {
+	for (c = 0; c < xf86_config->num_crtc; c++) {
+	    if (info->tear_free)
+		radeon_scanout_flip(pScreen, info, xf86_config->crtc[c]);
+	    else if (info->shadow_primary
 #if XF86_CRTC_VERSION >= 4
-		 || xf86_config->crtc[c]->driverIsPerformingTransform
+		     || xf86_config->crtc[c]->driverIsPerformingTransform
 #endif
-	    )
-	    radeon_scanout_update(xf86_config->crtc[c]);
+		)
+		radeon_scanout_update(xf86_config->crtc[c]);
+	}
     }

     radeon_cs_flush_indirect(pScrn);
