xf86-video-intel: src/intel_options.c src/intel_options.h src/sna/sna_display.c src/sna/sna_driver.c src/sna/sna.h

Chris Wilson ickle at kemper.freedesktop.org
Thu Jul 5 05:01:02 PDT 2012


 src/intel_options.c   |    5 ++-
 src/intel_options.h   |    1 
 src/sna/sna.h         |    2 -
 src/sna/sna_display.c |   72 +++++++++++++++++++++++++++++---------------------
 src/sna/sna_driver.c  |    4 ++
 5 files changed, 51 insertions(+), 33 deletions(-)

New commits:
commit 0f086acb259d7732560c5d0d642308de028a4445
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jul 4 12:26:18 2012 +0100

    sna: Fallback to attaching a shadow fb if we fail to setup the crtc
    
    As we've chosen to fix the kernel to handle CRTC offsets > 4096, drop
    the automatic workaround. However, allow the user to force creation of
    PerCrtcPixmaps for the purpose of debugging (and to workaround the bug
    in older kernels) and to fallback to trying a shadow fb if the setcrtc
    fails with the composite fb.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/intel_options.c b/src/intel_options.c
index d8455f9..2e112f9 100644
--- a/src/intel_options.c
+++ b/src/intel_options.c
@@ -20,9 +20,10 @@ const OptionInfoRec intel_options[] = {
 #endif
 #ifdef USE_SNA
 	{OPTION_THROTTLE,	"Throttle",	OPTV_BOOLEAN,	{0},	1},
-	{OPTION_ZAPHOD,	"ZaphodHeads",	OPTV_STRING,	{0},	0},
+	{OPTION_ZAPHOD,		"ZaphodHeads",	OPTV_STRING,	{0},	0},
 	{OPTION_DELAYED_FLUSH,	"DelayedFlush",	OPTV_BOOLEAN,	{0},	1},
-	{OPTION_TEAR_FREE,	"TearFree",	OPTV_BOOLEAN,	{0},	1},
+	{OPTION_TEAR_FREE,	"TearFree",	OPTV_BOOLEAN,	{0},	0},
+	{OPTION_CRTC_PIXMAPS,	"PerCrtcPixmaps", OPTV_BOOLEAN,	{0},	0},
 #endif
 #ifdef USE_UXA
 	{OPTION_FALLBACKDEBUG,	"FallbackDebug",OPTV_BOOLEAN,	{0},	0},
diff --git a/src/intel_options.h b/src/intel_options.h
index c3e4999..8d0312c 100644
--- a/src/intel_options.h
+++ b/src/intel_options.h
@@ -29,6 +29,7 @@ enum intel_options {
 	OPTION_ZAPHOD,
 	OPTION_DELAYED_FLUSH,
 	OPTION_TEAR_FREE,
+	OPTION_CRTC_PIXMAPS,
 #endif
 #ifdef USE_UXA
 	OPTION_FALLBACKDEBUG,
diff --git a/src/sna/sna.h b/src/sna/sna.h
index 218a882..bda3cb8 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -213,6 +213,7 @@ struct sna {
 #define SNA_NO_WAIT		0x4
 #define SNA_NO_FLIP		0x8
 #define SNA_TEAR_FREE		0x10
+#define SNA_FORCE_SHADOW	0x20
 
 	unsigned watch_flush;
 	unsigned flush;
@@ -232,7 +233,6 @@ struct sna {
 
 	struct sna_mode {
 		drmModeResPtr kmode;
-		int max_tile_offset;
 
 		int shadow_active;
 		DamagePtr shadow_damage;
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index f59eed5..fb38c25 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -69,6 +69,7 @@ struct sna_crtc {
 	struct kgem_bo *bo;
 	uint32_t cursor;
 	bool shadow;
+	bool fallback_shadow;
 	uint8_t id;
 	uint8_t pipe;
 	uint8_t plane;
@@ -540,9 +541,6 @@ sna_crtc_apply(xf86CrtcPtr crtc)
 		output_count++;
 	}
 
-	crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green,
-			       crtc->gamma_blue, crtc->gamma_size);
-
 	VG_CLEAR(arg);
 	arg.crtc_id = sna_crtc->id;
 	arg.fb_id = fb_id(sna_crtc->bo);
@@ -558,12 +556,6 @@ sna_crtc_apply(xf86CrtcPtr crtc)
 	arg.mode = sna_crtc->kmode;
 	arg.mode_valid = 1;
 
-	xf86DrvMsg(crtc->scrn->scrnIndex, X_INFO,
-		   "switch to mode %dx%d on crtc %d (pipe %d)\n",
-		   sna_crtc->kmode.hdisplay,
-		   sna_crtc->kmode.vdisplay,
-		   sna_crtc->id, sna_crtc->pipe);
-
 	DBG(("%s: applying crtc [%d] mode=%dx%d+%d+%d@%d, fb=%d%s update to %d outputs\n",
 	     __FUNCTION__, sna_crtc->id,
 	     arg.mode.hdisplay,
@@ -575,14 +567,8 @@ sna_crtc_apply(xf86CrtcPtr crtc)
 	     output_count));
 
 	ret = drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETCRTC, &arg);
-	if (ret) {
-		xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
-			   "failed to set mode: %s\n", strerror(errno));
+	if (ret)
 		return FALSE;
-	}
-
-	if (crtc->scrn->pScreen)
-		xf86_reload_cursors(crtc->scrn->pScreen);
 
 	sna_crtc_force_outputs_on(crtc);
 	return TRUE;
@@ -649,6 +635,7 @@ static bool sna_crtc_enable_shadow(struct sna *sna, struct sna_crtc *crtc)
 
 static void sna_crtc_disable_shadow(struct sna *sna, struct sna_crtc *crtc)
 {
+	crtc->fallback_shadow = false;
 	if (!crtc->shadow)
 		return;
 
@@ -856,6 +843,16 @@ static bool use_shadow(struct sna *sna, xf86CrtcPtr crtc)
 
 	assert(sna->scrn->virtualX && sna->scrn->virtualY);
 
+	if (sna->flags & SNA_FORCE_SHADOW) {
+		DBG(("%s: forcing shadow\n", __FUNCTION__));
+		return true;
+	}
+
+	if (to_sna_crtc(crtc)->fallback_shadow) {
+		DBG(("%s: fallback shadow\n", __FUNCTION__));
+		return true;
+	}
+
 	if (sna->scrn->virtualX > sna->mode.kmode->max_width ||
 	    sna->scrn->virtualY > sna->mode.kmode->max_height) {
 		DBG(("%s: framebuffer too large (%dx%d) > (%dx%d)\n",
@@ -866,14 +863,6 @@ static bool use_shadow(struct sna *sna, xf86CrtcPtr crtc)
 		return true;
 	}
 
-	if (crtc->x >= sna->mode.max_tile_offset ||
-	    crtc->y >= sna->mode.max_tile_offset) {
-		DBG(("%s: offset too large (%d, %d) >= %d\n",
-		    __FUNCTION__,
-		    crtc->x, crtc->y, sna->mode.max_tile_offset));
-		return true;
-	}
-
 	transform = NULL;
 	if (crtc->transformPresent)
 		transform = &crtc->transform;
@@ -1084,6 +1073,11 @@ sna_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 	struct kgem_bo *saved_bo, *bo;
 	struct drm_mode_modeinfo saved_kmode;
 
+	xf86DrvMsg(crtc->scrn->scrnIndex, X_INFO,
+		   "switch to mode %dx%d on crtc %d (pipe %d)\n",
+		   mode->HDisplay, mode->VDisplay,
+		   sna_crtc->id, sna_crtc->pipe);
+
 	DBG(("%s(crtc=%d [pipe=%d] rotation=%d, x=%d, y=%d, mode=%dx%d@%d)\n",
 	     __FUNCTION__, sna_crtc->id, sna_crtc->pipe, rotation, x, y,
 	     mode->HDisplay, mode->VDisplay, mode->Clock));
@@ -1091,20 +1085,36 @@ sna_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 	assert(mode->HDisplay <= sna->mode.kmode->max_width &&
 	       mode->VDisplay <= sna->mode.kmode->max_height);
 
-	/* Attach per-crtc pixmap or direct */
+	crtc->funcs->gamma_set(crtc,
+			       crtc->gamma_red,
+			       crtc->gamma_green,
+			       crtc->gamma_blue,
+			       crtc->gamma_size);
+
+	saved_kmode = sna_crtc->kmode;
+	saved_bo = sna_crtc->bo;
+
+	sna_crtc->fallback_shadow = false;
+retry: /* Attach per-crtc pixmap or direct */
 	bo = sna_crtc_attach(crtc);
 	if (bo == NULL)
 		return FALSE;
 
-	saved_kmode = sna_crtc->kmode;
-	saved_bo = sna_crtc->bo;
 	sna_crtc->bo = bo;
 	mode_to_kmode(&sna_crtc->kmode, mode);
-
 	if (!sna_crtc_apply(crtc)) {
+		kgem_bo_destroy(&sna->kgem, bo);
+
+		if (!sna_crtc->shadow) {
+			sna_crtc->fallback_shadow = true;
+			goto retry;
+		}
+
+		xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
+			   "failed to set mode: %s\n", strerror(errno));
+
 		sna_crtc->bo = saved_bo;
 		sna_crtc->kmode = saved_kmode;
-		kgem_bo_destroy(&sna->kgem, bo);
 		return FALSE;
 	}
 	if (saved_bo)
@@ -1116,6 +1126,9 @@ sna_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 	if (sna_crtc->shadow)
 		sna_crtc_damage(crtc);
 
+	if (scrn->pScreen)
+		xf86_reload_cursors(scrn->pScreen);
+
 	return TRUE;
 }
 
@@ -2287,7 +2300,6 @@ Bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna)
 			   "failed to get resources: %s\n", strerror(errno));
 		return FALSE;
 	}
-	mode->max_tile_offset = 4096;
 
 	set_size_range(sna);
 
diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index 6476d1a..eb4776b 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -518,6 +518,8 @@ static Bool sna_pre_init(ScrnInfoPtr scrn, int flags)
 			sna->flags |= SNA_TEAR_FREE;
 	} else
 		sna->flags |= SNA_NO_FLIP;
+	if (xf86ReturnOptValBool(sna->Options, OPTION_CRTC_PIXMAPS, FALSE))
+		sna->flags |= SNA_FORCE_SHADOW;
 
 	xf86DrvMsg(scrn->scrnIndex, X_CONFIG, "Framebuffer %s\n",
 		   sna->tiling & SNA_TILING_FB ? "tiled" : "linear");
@@ -531,6 +533,8 @@ static Bool sna_pre_init(ScrnInfoPtr scrn, int flags)
 		   sna->flags & SNA_NO_DELAYED_FLUSH ? "dis" : "en");
 	xf86DrvMsg(scrn->scrnIndex, X_CONFIG, "\"Tear free\" %sabled\n",
 		   sna->flags & SNA_TEAR_FREE ? "en" : "dis");
+	xf86DrvMsg(scrn->scrnIndex, X_CONFIG, "Forcing per-crtc-pixmaps? %s\n",
+		   sna->flags & SNA_FORCE_SHADOW ? "yes" : "no");
 
 	if (!sna_mode_pre_init(scrn, sna)) {
 		PreInitCleanup(scrn);


More information about the xorg-commit mailing list