xf86-video-intel: 3 commits - src/sna/sna_accel.c src/sna/sna_display.c src/sna/sna_dri2.c src/sna/sna_driver.c src/sna/sna.h src/sna/sna_present.c

Chris Wilson ickle at kemper.freedesktop.org
Tue Jul 1 09:00:56 PDT 2014


 src/sna/sna.h         |    6 -
 src/sna/sna_accel.c   |  156 +++++++++++++++++---------------------------------
 src/sna/sna_display.c |    5 +
 src/sna/sna_dri2.c    |   84 +++++++++++++++++++++-----
 src/sna/sna_driver.c  |   18 -----
 src/sna/sna_present.c |   10 ++-
 6 files changed, 138 insertions(+), 141 deletions(-)

New commits:
commit b88866aa5ebf813a999e194dec24e9ef2ac4f59d
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Jul 1 16:59:31 2014 +0100

    sna/dri2: Add a DBG option to select copy method
    
    Often when debugging it is useful to force either use of the BLT or 3D
    pipelines for copies.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c
index 5adbd0b..0b343ce 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -55,6 +55,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define DBG_CAN_FLIP 1
 #define DBG_CAN_XCHG 1
 
+#define DBG_FORCE_COPY -1 /* KGEM_BLT or KGEM_3D */
+
 #if DRI2INFOREC_VERSION < 2
 #error DRI2 version supported by the Xserver is too old
 #endif
@@ -772,6 +774,12 @@ static void sna_dri2_select_mode(struct sna *sna, struct kgem_bo *dst, struct kg
 		return;
 	}
 
+	if (DBG_FORCE_COPY != -1) {
+		DBG(("%s: forcing %d\n", __FUNCTION__, DBG_FORCE_COPY));
+		kgem_set_mode(&sna->kgem, DBG_FORCE_COPY, dst);
+		return;
+	}
+
 	if (sna->kgem.mode != KGEM_NONE) {
 		DBG(("%s: busy, not switching\n", __FUNCTION__));
 		return;
commit a10781b70f222f3997928fa979f6292617f79316
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Jul 1 15:11:07 2014 +0100

    sna: Enforce LinearFramebuffer option
    
    This option should only be used for compatibility. Previously this was
    done at a high level, this changes it to enforce the tiling as we apply
    the CRTC.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index 7b89f8c..68a6500 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -254,6 +254,7 @@ struct sna {
 #define SNA_REMOVE_OUTPUTS	0x400
 #define SNA_HAS_FLIP		0x10000
 #define SNA_HAS_ASYNC_FLIP	0x20000
+#define SNA_LINEAR_FB		0x40000
 #define SNA_REPROBE		0x80000000
 
 	unsigned cpu_features;
@@ -360,11 +361,6 @@ struct sna {
 		int num_adaptors;
 	} xv;
 
-	unsigned int tiling;
-#define SNA_TILING_FB		0x1
-#define SNA_TILING_2D		0x2
-#define SNA_TILING_ALL (~0)
-
 	EntityInfoPtr pEnt;
 	const struct intel_device_info *info;
 
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 324107f..02e5920 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -607,12 +607,13 @@ static bool sna_pixmap_free_cpu(struct sna *sna, struct sna_pixmap *priv, bool a
 	return true;
 }
 
-static inline uint32_t default_tiling(PixmapPtr pixmap,
-				      uint32_t tiling)
+static inline uint32_t default_tiling(struct sna *sna, PixmapPtr pixmap)
 {
-	struct sna_pixmap *priv = sna_pixmap(pixmap);
-	struct sna *sna = to_sna_from_pixmap(pixmap);
-
+#if DEFAULT_TILING == I915_TILING_NONE
+	return I915_TILING_NONE;
+#elif DEFAULT_TILING == I915_TILING_X
+	return I915_TILING_X;
+#else
 	/* Try to avoid hitting the Y-tiling GTT mapping bug on 855GM */
 	if (sna->kgem.gen == 021)
 		return I915_TILING_X;
@@ -626,41 +627,26 @@ static inline uint32_t default_tiling(PixmapPtr pixmap,
 	     pixmap->drawable.height > sna->render.max_3d_size))
 		return I915_TILING_X;
 
-	if (tiling == I915_TILING_Y &&
-	    sna_damage_is_all(&priv->cpu_damage,
+	if (sna_damage_is_all(&sna_pixmap(pixmap)->cpu_damage,
 			      pixmap->drawable.width,
 			      pixmap->drawable.height)) {
 		DBG(("%s: entire source is damaged, using Y-tiling\n",
 		     __FUNCTION__));
-		sna_damage_destroy(&priv->gpu_damage);
-
+		sna_damage_destroy(&sna_pixmap(priv)->gpu_damage);
 		return I915_TILING_Y;
 	}
 
-	return tiling;
+	return I915_TILING_Y;
+#endif
 }
 
-pure static uint32_t sna_pixmap_choose_tiling(PixmapPtr pixmap,
-					      uint32_t tiling)
+pure static uint32_t sna_pixmap_default_tiling(struct sna *sna, PixmapPtr pixmap)
 {
-	struct sna *sna = to_sna_from_pixmap(pixmap);
-	uint32_t bit;
-
-	/* Use tiling by default, but disable per user request */
-	if (pixmap->usage_hint == SNA_CREATE_FB) {
-		tiling = -I915_TILING_X;
-		bit = SNA_TILING_FB;
-	} else {
-		tiling = default_tiling(pixmap, tiling);
-		bit = SNA_TILING_2D;
-	}
-	if ((sna->tiling & bit) == 0)
-		tiling = I915_TILING_NONE;
-
 	/* Also adjust tiling if it is not supported or likely to
 	 * slow us down,
 	 */
-	return kgem_choose_tiling(&sna->kgem, tiling,
+	return kgem_choose_tiling(&sna->kgem,
+				  default_tiling(sna, pixmap),
 				  pixmap->drawable.width,
 				  pixmap->drawable.height,
 				  pixmap->drawable.bitsPerPixel);
@@ -1617,6 +1603,28 @@ static inline bool pixmap_inplace(struct sna *sna,
 		sna->kgem.half_cpu_cache_pages;
 }
 
+static bool sna_pixmap_alloc_gpu(struct sna *sna,
+				 PixmapPtr pixmap,
+				 struct sna_pixmap *priv,
+				 unsigned flags)
+{
+	uint32_t tiling;
+
+	/* Use tiling by default, but disable per user request */
+	if (pixmap->usage_hint == SNA_CREATE_FB && (sna->flags & SNA_LINEAR_FB) == 0) {
+		flags |= CREATE_SCANOUT;
+		tiling = -I915_TILING_X;
+	} else
+		tiling = sna_pixmap_default_tiling(sna, pixmap),
+
+	priv->gpu_bo = kgem_create_2d(&sna->kgem,
+				      pixmap->drawable.width,
+				      pixmap->drawable.height,
+				      pixmap->drawable.bitsPerPixel,
+				      tiling, flags);
+	return priv->gpu_bo != NULL;
+}
+
 static bool
 sna_pixmap_create_mappable_gpu(PixmapPtr pixmap,
 			       bool can_replace)
@@ -1643,22 +1651,9 @@ sna_pixmap_create_mappable_gpu(PixmapPtr pixmap,
 	}
 
 	if (priv->gpu_bo == NULL) {
-		unsigned create;
-
 		assert_pixmap_damage(pixmap);
 		assert(priv->gpu_damage == NULL);
-
-		create = CREATE_GTT_MAP | CREATE_INACTIVE;
-		if (pixmap->usage_hint == SNA_CREATE_FB)
-			create |= CREATE_SCANOUT;
-
-		priv->gpu_bo =
-			kgem_create_2d(&sna->kgem,
-				       pixmap->drawable.width,
-				       pixmap->drawable.height,
-				       pixmap->drawable.bitsPerPixel,
-				       sna_pixmap_choose_tiling(pixmap, DEFAULT_TILING),
-				       create);
+		sna_pixmap_alloc_gpu(sna, pixmap, priv, CREATE_GTT_MAP | CREATE_INACTIVE);
 	}
 
 out:
@@ -1874,7 +1869,7 @@ sna_pixmap_undo_cow(struct sna *sna, struct sna_pixmap *priv, unsigned flags)
 		bo = kgem_create_2d(&sna->kgem,
 				    box.x2, box.y2,
 				    pixmap->drawable.bitsPerPixel,
-				    sna_pixmap_choose_tiling(pixmap, DEFAULT_TILING),
+				    sna_pixmap_default_tiling(sna, pixmap),
 				    0);
 		if (bo == NULL) {
 			cow->refcnt++;
@@ -1923,7 +1918,7 @@ sna_pixmap_undo_cow(struct sna *sna, struct sna_pixmap *priv, unsigned flags)
 			bo = kgem_create_2d(&sna->kgem,
 					    box.x2, box.y2,
 					    pixmap->drawable.bitsPerPixel,
-					    sna_pixmap_choose_tiling(pixmap, DEFAULT_TILING),
+					    sna_pixmap_default_tiling(sna, pixmap),
 					    0);
 			if (bo == NULL) {
 				cow->refcnt++;
@@ -2601,8 +2596,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 					RegionTranslate(region, dx, dy);
 
 				if (sna->kgem.has_llc && !priv->pinned &&
-				    sna_pixmap_choose_tiling(pixmap,
-							     DEFAULT_TILING) == I915_TILING_NONE) {
+				    sna_pixmap_default_tiling(sna, pixmap) == I915_TILING_NONE) {
 #ifdef DEBUG_MEMORY
 					sna->debug_memory.cpu_bo_allocs--;
 					sna->debug_memory.cpu_bo_bytes -= kgem_bo_size(priv->cpu_bo);
@@ -3313,24 +3307,8 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int fl
 	if (priv->gpu_bo == NULL) {
 		assert(priv->gpu_damage == NULL);
 
-		if (flags & __MOVE_FORCE ||
-		    priv->create & KGEM_CAN_CREATE_GPU) {
-			unsigned create, tiling;
-
-			create = CREATE_INACTIVE;
-			if (pixmap->usage_hint == SNA_CREATE_FB)
-				create |= CREATE_SCANOUT;
-
-			tiling = (flags & MOVE_SOURCE_HINT) ? I915_TILING_Y : DEFAULT_TILING;
-			tiling = sna_pixmap_choose_tiling(pixmap, tiling);
-
-			assert(!priv->mapped);
-			priv->gpu_bo = kgem_create_2d(&sna->kgem,
-						      pixmap->drawable.width,
-						      pixmap->drawable.height,
-						      pixmap->drawable.bitsPerPixel,
-						      tiling, create);
-		}
+		if (flags & __MOVE_FORCE || priv->create & KGEM_CAN_CREATE_GPU)
+			sna_pixmap_alloc_gpu(sna, pixmap, priv, CREATE_INACTIVE);
 
 		if (priv->gpu_bo == NULL)
 			return NULL;
@@ -4127,16 +4105,13 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags)
 		     priv->create));
 		assert(!priv->mapped);
 		if (flags & __MOVE_FORCE || priv->create & KGEM_CAN_CREATE_GPU) {
-			unsigned create, tiling;
+			unsigned create;
 
 			assert(pixmap->drawable.width > 0);
 			assert(pixmap->drawable.height > 0);
 			assert(pixmap->drawable.bitsPerPixel >= 8);
 
-			tiling = (flags & MOVE_SOURCE_HINT) ? I915_TILING_Y : DEFAULT_TILING;
-			tiling = sna_pixmap_choose_tiling(pixmap, tiling);
-
-			if (tiling == I915_TILING_NONE &&
+			if (sna_pixmap_default_tiling(sna, pixmap) == I915_TILING_NONE &&
 			    priv->cpu_bo && !priv->shm &&
 			    kgem_bo_convert_to_gpu(&sna->kgem, priv->cpu_bo, flags)) {
 				assert(!priv->mapped);
@@ -4157,15 +4132,8 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags)
 			create = 0;
 			if (flags & MOVE_INPLACE_HINT || (priv->cpu_damage && priv->cpu_bo == NULL))
 				create = CREATE_GTT_MAP | CREATE_INACTIVE;
-			if (pixmap->usage_hint == SNA_CREATE_FB)
-				create |= CREATE_SCANOUT;
 
-			priv->gpu_bo =
-				kgem_create_2d(&sna->kgem,
-					       pixmap->drawable.width,
-					       pixmap->drawable.height,
-					       pixmap->drawable.bitsPerPixel,
-					       tiling, create);
+			sna_pixmap_alloc_gpu(sna, pixmap, priv, create);
 		}
 		if (priv->gpu_bo == NULL) {
 			DBG(("%s: not creating GPU bo\n", __FUNCTION__));
@@ -4510,58 +4478,45 @@ static inline void box32_add_rect(Box32Rec *box, const xRectangle *r)
 }
 
 static bool
-can_create_upload_tiled_x(struct kgem *kgem,
+can_create_upload_tiled_x(struct sna *sna,
 			  PixmapPtr pixmap,
 			  struct sna_pixmap *priv,
 			  bool replaces)
 {
-	unsigned tiling;
-
 	if (priv->shm || (priv->cpu && !replaces))
 		return false;
 
 	if ((priv->create & KGEM_CAN_CREATE_GPU) == 0)
 		return false;
 
-	if (kgem->has_llc)
+	if (sna->kgem.has_llc)
 		return true;
 
-	tiling = sna_pixmap_choose_tiling(pixmap, I915_TILING_X);
-	assert(tiling != I915_TILING_Y && tiling != -I915_TILING_Y);
-	if (tiling != I915_TILING_NONE)
+	if (sna_pixmap_default_tiling(sna, pixmap))
 		return false;
 
 	return true;
 }
 
 static bool
-create_upload_tiled_x(struct kgem *kgem,
+create_upload_tiled_x(struct sna *sna,
 		      PixmapPtr pixmap,
 		      struct sna_pixmap *priv,
 		      bool replaces)
 {
 	unsigned create;
 
-	if (!can_create_upload_tiled_x(kgem, pixmap, priv, replaces))
+	if (!can_create_upload_tiled_x(sna, pixmap, priv, replaces))
 		return false;
 
 	assert(priv->gpu_bo == NULL);
 	assert(priv->gpu_damage == NULL);
 
 	create = CREATE_CPU_MAP | CREATE_INACTIVE;
-	if (pixmap->usage_hint == SNA_CREATE_FB)
-		create |= CREATE_SCANOUT;
-	if (!kgem->has_llc)
+	if (!sna->kgem.has_llc)
 		create |= CREATE_CACHED;
 
-	priv->gpu_bo =
-		kgem_create_2d(kgem,
-			       pixmap->drawable.width,
-			       pixmap->drawable.height,
-			       pixmap->drawable.bitsPerPixel,
-			       sna_pixmap_choose_tiling(pixmap, I915_TILING_X),
-			       create);
-	return priv->gpu_bo != NULL;
+	return sna_pixmap_alloc_gpu(sna, pixmap, priv, create);
 }
 
 static bool
@@ -4714,7 +4669,7 @@ try_upload__inplace(PixmapPtr pixmap, RegionRec *region,
 
 	if (priv->gpu_bo && replaces) {
 		if (UNDO) kgem_bo_pair_undo(&sna->kgem, priv->gpu_bo, priv->cpu_bo);
-		if (can_create_upload_tiled_x(&sna->kgem, pixmap, priv, true) &&
+		if (can_create_upload_tiled_x(sna, pixmap, priv, true) &&
 		    (priv->cow ||
 		     __kgem_bo_is_busy(&sna->kgem, priv->gpu_bo) ||
 		     !kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, true))) {
@@ -4737,7 +4692,7 @@ try_upload__inplace(PixmapPtr pixmap, RegionRec *region,
 	if (priv->gpu_damage &&
 	    region_subsumes_damage(region, priv->gpu_damage)) {
 		if (UNDO) kgem_bo_undo(&sna->kgem, priv->gpu_bo);
-		if (can_create_upload_tiled_x(&sna->kgem, pixmap, priv, priv->cpu_damage == NULL) &&
+		if (can_create_upload_tiled_x(sna, pixmap, priv, priv->cpu_damage == NULL) &&
 		    (__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo) ||
 		     !kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, true))) {
 			DBG(("%s: discarding unusable partial target bo (busy? %d, mappable? %d)\n", __FUNCTION__,
@@ -4751,7 +4706,7 @@ try_upload__inplace(PixmapPtr pixmap, RegionRec *region,
 	}
 
 	if (priv->gpu_bo == NULL &&
-	    !create_upload_tiled_x(&sna->kgem, pixmap, priv, ignore_cpu))
+	    !create_upload_tiled_x(sna, pixmap, priv, ignore_cpu))
 		return false;
 
 	DBG(("%s: tiling=%d\n", __FUNCTION__, priv->gpu_bo->tiling));
@@ -5624,8 +5579,7 @@ move_to_gpu(PixmapPtr pixmap, struct sna_pixmap *priv,
 		if (priv->cpu_bo->flush && count > SOURCE_BIAS)
 			return true;
 
-		if (sna_pixmap_choose_tiling(pixmap,
-					     DEFAULT_TILING) == I915_TILING_NONE)
+		if (sna_pixmap_default_tiling(to_sna_from_pixmap(pixmap), pixmap) == I915_TILING_NONE)
 			return false;
 
 		if (priv->cpu)
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 38ebc11..5579585 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -1666,6 +1666,9 @@ static bool use_shadow(struct sna *sna, xf86CrtcPtr crtc)
 	if (priv->gpu_bo->pitch > pitch_limit)
 		return true;
 
+	if (priv->gpu_bo->tiling && sna->flags & SNA_LINEAR_FB)
+		return true;
+
 	transform = NULL;
 	if (crtc->transformPresent)
 		transform = &crtc->transform;
@@ -1779,6 +1782,8 @@ static struct kgem_bo *sna_crtc_attach(xf86CrtcPtr crtc)
 			tiled_limit = 8 * 1024 * 8;
 		if ((unsigned long)crtc->mode.HDisplay * scrn->bitsPerPixel > tiled_limit)
 			tiling = I915_TILING_NONE;
+		if (sna->flags & SNA_LINEAR_FB)
+			tiling = I915_TILING_NONE;
 
 		bo = kgem_create_2d(&sna->kgem,
 				    crtc->mode.HDisplay, crtc->mode.VDisplay,
diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c
index 9b128da..5adbd0b 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -459,7 +459,7 @@ sna_dri2_create_buffer(DrawablePtr draw,
 
 		bo = ref(bo);
 		bpp = pixmap->drawable.bitsPerPixel;
-		if (pixmap == sna->front)
+		if (pixmap == sna->front && !(sna->flags & SNA_LINEAR_FB))
 			flags |= CREATE_SCANOUT;
 		DBG(("%s: attaching to front buffer %dx%d [%p:%d], scanout? %d\n",
 		     __FUNCTION__,
@@ -474,7 +474,7 @@ sna_dri2_create_buffer(DrawablePtr draw,
 				flags |= CREATE_SCANOUT;
 			if (draw->width  == sna->front->drawable.width &&
 			    draw->height == sna->front->drawable.height &&
-			    (sna->flags & (SNA_NO_WAIT | SNA_NO_FLIP)) == 0)
+			    (sna->flags & (SNA_LINEAR_FB | SNA_NO_WAIT | SNA_NO_FLIP)) == 0)
 				flags |= CREATE_SCANOUT;
 		}
 	case DRI2BufferBackRight:
@@ -1644,11 +1644,12 @@ can_flip(struct sna * sna,
 	}
 
 	/* prevent an implicit tiling mode change */
-	if (get_private(front)->bo->tiling != get_private(back)->bo->tiling) {
-		DBG(("%s -- no, tiling mismatch: front %d, back=%d\n",
+	if (get_private(back)->bo->tiling > I915_TILING_X) {
+		DBG(("%s -- no, tiling mismatch: front %d, back=%d, want-tiled?=%d\n",
 		     __FUNCTION__,
 		     get_private(front)->bo->tiling,
-		     get_private(back)->bo->tiling));
+		     get_private(back)->bo->tiling,
+		     !!(sna->flags & SNA_LINEAR_FB)));
 		return false;
 	}
 
diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index c57832b..ce319d2 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -614,22 +614,8 @@ static Bool sna_pre_init(ScrnInfoPtr scrn, int flags)
 		sna->kgem.wedged = true;
 	}
 
-	/* Enable tiling by default */
-	sna->tiling = SNA_TILING_ALL;
-
-	/* Allow user override if they set a value */
-	if (!xf86ReturnOptValBool(sna->Options, OPTION_TILING_2D, TRUE))
-		sna->tiling &= ~SNA_TILING_2D;
 	if (xf86ReturnOptValBool(sna->Options, OPTION_TILING_FB, FALSE))
-		sna->tiling &= ~SNA_TILING_FB;
-
-	if (sna->tiling != SNA_TILING_ALL) {
-		xf86DrvMsg(scrn->scrnIndex, X_CONFIG, "Framebuffer %s, pixmaps %s\n",
-			   sna->tiling & SNA_TILING_FB ? "tiled" : "linear",
-			   sna->tiling & SNA_TILING_2D ? "tiled" : "linear");
-		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
-			   "Tiling disabled, expect poor performance and increased power consumption.\n");
-	}
+		sna->flags |= SNA_LINEAR_FB;
 
 	if (xf86ReturnOptValBool(sna->Options, OPTION_DELETE_DP12, FALSE))
 		sna->flags |= SNA_REMOVE_OUTPUTS;
@@ -665,7 +651,7 @@ static Bool sna_pre_init(ScrnInfoPtr scrn, int flags)
 	}
 	scrn->currentMode = scrn->modes;
 
-	if (sna->flags & SNA_HAS_FLIP &&
+	if ((sna->flags & (SNA_HAS_FLIP | SNA_LINEAR_FB)) == SNA_HAS_FLIP &&
 	    xf86ReturnOptValBool(sna->Options, OPTION_TEAR_FREE, enable_tear_free(sna)))
 		sna->flags |= SNA_TEAR_FREE;
 	xf86DrvMsg(scrn->scrnIndex, X_CONFIG, "TearFree %sabled\n",
diff --git a/src/sna/sna_present.c b/src/sna/sna_present.c
index 5379d1e..dd4771c 100644
--- a/src/sna/sna_present.c
+++ b/src/sna/sna_present.c
@@ -351,6 +351,7 @@ page_flip(ScreenPtr screen,
 static struct kgem_bo *
 get_flip_bo(PixmapPtr pixmap)
 {
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 	struct sna_pixmap *priv;
 
 	DBG(("%s(pixmap=%ld)\n", __FUNCTION__, pixmap->drawable.serialNumber));
@@ -361,9 +362,16 @@ get_flip_bo(PixmapPtr pixmap)
 		return NULL;
 	}
 
+	if (sna->flags & SNA_LINEAR_FB &&
+	    priv->gpu_bo->tiling &&
+	    !sna_pixmap_change_tiling(pixmap, I915_TILING_NONE)) {
+		DBG(("%s: invalid tiling for scanout, user requires linear\n", __FUNCTION__));
+		return NULL;
+	}
+
 	if (priv->gpu_bo->tiling == I915_TILING_Y &&
 	    !sna_pixmap_change_tiling(pixmap, I915_TILING_X)) {
-		DBG(("%s: bad tiling, cannot convert\n", __FUNCTION__));
+		DBG(("%s: invalid Y-tiling, cannot convert\n", __FUNCTION__));
 		return NULL;
 	}
 
commit 75745cd5861481c5a9a31125d357f339349dd0f8
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Jul 1 14:31:32 2014 +0100

    sna/dri2: Use CPU fallback if possible
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c
index b03bf6a..9b128da 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -820,24 +820,64 @@ static void sna_dri2_select_mode(struct sna *sna, struct kgem_bo *dst, struct kg
 	_kgem_set_mode(&sna->kgem, mode);
 }
 
+static bool can_copy_cpu(struct sna *sna,
+			 struct kgem_bo *src,
+			 struct kgem_bo *dst)
+{
+	if (src->tiling != dst->tiling)
+		return false;
+
+	if (src->pitch != dst->pitch)
+		return false;
+
+	if (!kgem_bo_can_map__cpu(&sna->kgem, src, false))
+		return false;
+
+	if (!kgem_bo_can_map__cpu(&sna->kgem, dst, true))
+		return false;
+
+	DBG(("%s -- yes, src handle=%d, dst handle=%d\n", __FUNCTION__, src->handle, dst->handle));
+	return true;
+}
+
 static void
-sna_dri2_copy_fallback(struct sna *sna, int bpp,
+sna_dri2_copy_fallback(struct sna *sna,
+		       const DrawableRec *draw,
 		       struct kgem_bo *src_bo, int sx, int sy,
 		       struct kgem_bo *dst_bo, int dx, int dy,
 		       const BoxRec *box, int n)
 {
-	void *dst = kgem_bo_map__gtt(&sna->kgem, dst_bo);
-	void *src = kgem_bo_map__gtt(&sna->kgem, src_bo);
+	void *dst, *src;
+	bool clipped;
 
-	if (dst == NULL || src == NULL)
-		return;
+	clipped = (n > 1 ||
+		   box->x1 + sx > 0 ||
+		   box->y1 + sy > 0 ||
+		   box->x2 + sx < draw->width ||
+		   box->y2 + sy < draw->height);
+
+	dst = src = NULL;
+	if (!clipped && can_copy_cpu(sna, src_bo, dst_bo)) {
+		dst = kgem_bo_map__cpu(&sna->kgem, dst_bo);
+		src = kgem_bo_map__cpu(&sna->kgem, src_bo);
+	}
+
+	if (dst == NULL || src == NULL) {
+		dst = kgem_bo_map__gtt(&sna->kgem, dst_bo);
+		src = kgem_bo_map__gtt(&sna->kgem, src_bo);
+		if (dst == NULL || src == NULL)
+			return;
+	} else {
+		kgem_bo_sync__cpu_full(&sna->kgem, dst_bo, true);
+		kgem_bo_sync__cpu_full(&sna->kgem, src_bo, false);
+	}
 
 	DBG(("%s: src(%d, %d), dst(%d, %d) x %d\n",
 	     __FUNCTION__, sx, sy, dx, dy, n));
 
 	if (sigtrap_get() == 0) {
 		do {
-			memcpy_blt(src, dst, bpp,
+			memcpy_blt(src, dst, draw->bitsPerPixel,
 				   src_bo->pitch, dst_bo->pitch,
 				   box->x1 + sx, box->y1 + sy,
 				   box->x1 + dx, box->y1 + dy,
@@ -945,6 +985,11 @@ __sna_dri2_copy_region(struct sna *sna, DrawablePtr draw, RegionPtr region,
 	} else
 		sync = false;
 
+	scratch.x = scratch.y = 0;
+	scratch.width = scratch.height = 0;
+	scratch.depth = draw->depth;
+	scratch.bitsPerPixel = draw->bitsPerPixel;
+
 	src_bo = src_priv->bo;
 	assert(src_bo->refcnt);
 	if (is_front(src->attachment)) {
@@ -959,11 +1004,8 @@ __sna_dri2_copy_region(struct sna *sna, DrawablePtr draw, RegionPtr region,
 	} else {
 		RegionRec source;
 
-		scratch.x = scratch.y = 0;
 		scratch.width = src_priv->size & 0xffff;
 		scratch.height = src_priv->size >> 16;
-		scratch.depth = draw->depth;
-		scratch.bitsPerPixel = draw->bitsPerPixel;
 		src_draw = &scratch;
 
 		DBG(("%s: source size %dx%d, region size %dx%d\n",
@@ -1005,11 +1047,8 @@ __sna_dri2_copy_region(struct sna *sna, DrawablePtr draw, RegionPtr region,
 	} else {
 		RegionRec target;
 
-		scratch.x = scratch.y = 0;
 		scratch.width = dst_priv->size & 0xffff;
 		scratch.height = dst_priv->size >> 16;
-		scratch.depth = draw->depth;
-		scratch.bitsPerPixel = draw->bitsPerPixel;
 		dst_draw = &scratch;
 
 		DBG(("%s: target size %dx%d, region size %dx%d\n",
@@ -1056,7 +1095,7 @@ __sna_dri2_copy_region(struct sna *sna, DrawablePtr draw, RegionPtr region,
 
 	if (wedged(sna)) {
 fallback:
-		sna_dri2_copy_fallback(sna, draw->bitsPerPixel,
+		sna_dri2_copy_fallback(sna, src_draw,
 				      src_bo, sx, sy,
 				      dst_bo, dx, dy,
 				      boxes, n);


More information about the xorg-commit mailing list