xf86-video-intel: 2 commits - src/sna/gen6_common.h src/sna/kgem.c src/sna/kgem.h src/sna/sna_accel.c src/sna/sna_blt.c src/sna/sna_io.c src/sna/sna_present.c

Chris Wilson ickle at kemper.freedesktop.org
Fri Apr 17 03:46:10 PDT 2015


 src/sna/gen6_common.h |    3 +
 src/sna/kgem.c        |  141 +++++++++++++++++++++++++++++++++++++++++++++++++-
 src/sna/kgem.h        |   23 +++++++-
 src/sna/sna_accel.c   |   34 ++++++++++++
 src/sna/sna_blt.c     |   29 +++++++++-
 src/sna/sna_io.c      |   17 +++++-
 src/sna/sna_present.c |   20 ++++++-
 7 files changed, 258 insertions(+), 9 deletions(-)

New commits:
commit 75d87762471e195dddd73056fc6a06e17db1c8b0
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Apr 17 10:29:28 2015 +0100

    sna: Enable blitting with Y-tiled surfaces
    
    Since gen6, there has been a magic register bit to change the
    interpretation of the tiling mode between X and Y for BLT operations.
    With the advent of DRI3 and scanouts supporting Y, enabling support at
    last appears interesting, perhapss even by default for non-scanouts?
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen6_common.h b/src/sna/gen6_common.h
index 409bab3..5da739e 100644
--- a/src/sna/gen6_common.h
+++ b/src/sna/gen6_common.h
@@ -93,6 +93,9 @@ static int prefer_blt_bo(struct sna *sna,
 
 		if (src->rq)
 			return RQ_IS_BLT(src->rq);
+
+		if (src->tiling == I915_TILING_Y)
+			return false;
         } else {
                 if (sna->render_state.gt > 2)
                         return false;
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 05fe407..76e6913 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -84,6 +84,7 @@ search_snoop_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags);
 #define DBG_NO_HANDLE_LUT 0
 #define DBG_NO_WT 0
 #define DBG_NO_WC_MMAP 0
+#define DBG_NO_BLT_Y 0
 #define DBG_NO_SCANOUT_Y 0
 #define DBG_NO_DETILING 0
 #define DBG_DUMP 0
@@ -1244,6 +1245,54 @@ static bool test_has_create2(struct kgem *kgem)
 #endif
 }
 
+static bool test_can_blt_y(struct kgem *kgem)
+{
+	struct drm_i915_gem_exec_object2 object;
+	uint32_t batch[] = {
+#define MI_LOAD_REGISTER_IMM (0x22<<23 | (3-2))
+#define BCS_SWCTRL 0x22200
+#define BCS_SRC_Y (1 << 0)
+#define BCS_DST_Y (1 << 1)
+		MI_LOAD_REGISTER_IMM,
+		BCS_SWCTRL,
+		(BCS_SRC_Y | BCS_DST_Y) << 16 | (BCS_SRC_Y | BCS_DST_Y),
+
+		MI_LOAD_REGISTER_IMM,
+		BCS_SWCTRL,
+		(BCS_SRC_Y | BCS_DST_Y) << 16,
+
+		MI_BATCH_BUFFER_END,
+		0,
+	};
+	int ret;
+
+	if (DBG_NO_BLT_Y)
+		return false;
+
+	if (kgem->gen < 060)
+		return false;
+
+	memset(&object, 0, sizeof(object));
+	object.handle = gem_create(kgem->fd, 1);
+
+	ret = gem_write(kgem->fd, object.handle, 0, sizeof(batch), batch);
+	if (ret == 0) {
+		struct drm_i915_gem_execbuffer2 execbuf;
+
+		memset(&execbuf, 0, sizeof(execbuf));
+		execbuf.buffers_ptr = (uintptr_t)&object;
+		execbuf.buffer_count = 1;
+		execbuf.flags = I915_EXEC_BLT;
+
+		ret = do_ioctl(kgem->fd,
+			       DRM_IOCTL_I915_GEM_EXECBUFFER2,
+			       &execbuf);
+	}
+	gem_close(kgem->fd, object.handle);
+
+	return ret == 0;
+}
+
 static bool test_can_scanout_y(struct kgem *kgem)
 {
 	struct drm_mode_fb_cmd arg;
@@ -1672,12 +1721,16 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, unsigned gen)
 	DBG(("%s: can blt to cpu? %d\n", __FUNCTION__,
 	     kgem->can_blt_cpu));
 
+	kgem->can_blt_y = test_can_blt_y(kgem);
+	DBG(("%s: can blit to Y-tiled surfaces? %d\n", __FUNCTION__,
+	     kgem->can_blt_y));
+
 	kgem->can_render_y = gen != 021 && (gen >> 3) != 4;
 	DBG(("%s: can render to Y-tiled surfaces? %d\n", __FUNCTION__,
 	     kgem->can_render_y));
 
 	kgem->can_scanout_y = test_can_scanout_y(kgem);
-	DBG(("%s: can render to Y-tiled surfaces? %d\n", __FUNCTION__,
+	DBG(("%s: can scanout Y-tiled surfaces? %d\n", __FUNCTION__,
 	     kgem->can_scanout_y));
 
 	kgem->has_secure_batches = test_has_secure_batches(kgem);
@@ -2136,8 +2189,32 @@ static void kgem_add_bo(struct kgem *kgem, struct kgem_bo *bo)
 	kgem->flush |= bo->flush;
 }
 
+static void kgem_clear_swctrl(struct kgem *kgem)
+{
+	uint32_t *b;
+
+	if (kgem->bcs_state == 0)
+		return;
+
+	DBG(("%s: clearin SWCTRL LRI from %x\n",
+	     __FUNCTION__, kgem->bcs_state));
+
+	b = kgem->batch + kgem->nbatch;
+	kgem->nbatch += 7;
+
+	*b++ = MI_FLUSH_DW;
+	*b++ = 0;
+	*b++ = 0;
+	*b++ = 0;
+
+	*b++ = MI_LOAD_REGISTER_IMM;
+	*b++ = BCS_SWCTRL;
+	*b++ = kgem->bcs_state << 16;
+}
+
 static uint32_t kgem_end_batch(struct kgem *kgem)
 {
+	kgem_clear_swctrl(kgem);
 	kgem->batch[kgem->nbatch++] = MI_BATCH_BUFFER_END;
 	if (kgem->nbatch & 1)
 		kgem->batch[kgem->nbatch++] = MI_NOOP;
@@ -3480,6 +3557,7 @@ void kgem_reset(struct kgem *kgem)
 	kgem->needs_reservation = false;
 	kgem->flush = 0;
 	kgem->batch_flags = kgem->batch_flags_base;
+	kgem->bcs_state = 0;
 	assert(kgem->batch);
 
 	kgem->next_request = __kgem_request_alloc(kgem);
@@ -6114,6 +6192,66 @@ bool kgem_check_many_bo_fenced(struct kgem *kgem, ...)
 	return kgem_flush(kgem, flush);
 }
 
+void __kgem_bcs_set_tiling(struct kgem *kgem,
+			   struct kgem_bo *src,
+			   struct kgem_bo *dst)
+{
+	uint32_t state, mask, *b;
+
+	DBG(("%s: src handle=%d:tiling=%d, dst handle=%d:tiling=%d\n",
+	     __FUNCTION__,
+	     src ? src->handle : 0, src ? src->tiling : 0,
+	     dst ? dst->handle : 0, dst ? dst->tiling : 0));
+	assert(kgem->mode == KGEM_BLT);
+
+	mask = state = 0;
+	if (dst && dst->tiling) {
+		assert(kgem_bo_can_blt(kgem, dst));
+		mask |= BCS_DST_Y;
+		if (dst->tiling == I915_TILING_Y)
+			state |= BCS_DST_Y;
+	}
+
+	if (src && src->tiling) {
+		assert(kgem_bo_can_blt(kgem, src));
+		mask |= BCS_SRC_Y;
+		if (src->tiling == I915_TILING_Y)
+			state |= BCS_SRC_Y;
+	}
+
+	if ((kgem->bcs_state & mask) == state)
+		return;
+
+	DBG(("%s: updating SWCTRL %x -> %x\n", __FUNCTION__,
+	     kgem->bcs_state, (kgem->bcs_state & ~mask) | state));
+
+	/* Over-estimate space in case we need to re-emit the cmd packet */
+	if (!kgem_check_batch(kgem, 24)) {
+		_kgem_submit(kgem);
+		_kgem_set_mode(kgem, KGEM_BLT);
+	}
+
+	b = kgem->batch + kgem->nbatch;
+	if (kgem->nbatch) {
+		DBG(("%s: emitting flush before SWCTRL LRI\n",
+		     __FUNCTION__));
+		*b++ = MI_FLUSH_DW;
+		*b++ = 0;
+		*b++ = 0;
+		*b++ = 0;
+	}
+
+	DBG(("%s: emitting SWCTRL LRI to %x\n",
+	     __FUNCTION__, mask << 16 | state));
+	*b++ = MI_LOAD_REGISTER_IMM;
+	*b++ = BCS_SWCTRL;
+	*b++ = mask << 16 | state;
+	kgem->nbatch = b - kgem->batch;
+
+	kgem->bcs_state &= ~mask;
+	kgem->bcs_state |= state;
+}
+
 uint32_t kgem_add_reloc(struct kgem *kgem,
 			uint32_t pos,
 			struct kgem_bo *bo,
@@ -7619,6 +7757,7 @@ kgem_replace_bo(struct kgem *kgem,
 		}
 		_kgem_set_mode(kgem, KGEM_BLT);
 	}
+	kgem_bcs_set_tiling(kgem, src, dst);
 
 	br00 = XY_SRC_COPY_BLT_CMD;
 	br13 = pitch;
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index f1042a0..adc777d 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -158,6 +158,8 @@ struct kgem {
 		int16_t count;
 	} vma[NUM_MAP_TYPES];
 
+	uint32_t bcs_state;
+
 	uint32_t batch_flags;
 	uint32_t batch_flags_base;
 #define I915_EXEC_SECURE (1<<9)
@@ -189,6 +191,7 @@ struct kgem {
 	uint32_t has_wc_mmap :1;
 
 	uint32_t can_blt_cpu :1;
+	uint32_t can_blt_y :1;
 	uint32_t can_render_y :1;
 	uint32_t can_scanout_y :1;
 
@@ -232,7 +235,7 @@ struct kgem {
 
 #define KGEM_MAX_DEFERRED_VBO 16
 
-#define KGEM_BATCH_RESERVED 1
+#define KGEM_BATCH_RESERVED 8 /* LRI(SWCTRL) + END */
 #define KGEM_RELOC_RESERVED (KGEM_MAX_DEFERRED_VBO)
 #define KGEM_EXEC_RESERVED (1+KGEM_MAX_DEFERRED_VBO)
 
@@ -573,7 +576,7 @@ static inline bool kgem_bo_can_blt(struct kgem *kgem,
 {
 	assert(bo->refcnt);
 
-	if (bo->tiling == I915_TILING_Y) {
+	if (bo->tiling == I915_TILING_Y && !kgem->can_blt_y) {
 		DBG(("%s: can not blt to handle=%d, tiling=Y\n",
 		     __FUNCTION__, bo->handle));
 		return false;
@@ -588,6 +591,22 @@ static inline bool kgem_bo_can_blt(struct kgem *kgem,
 	return kgem_bo_blt_pitch_is_ok(kgem, bo);
 }
 
+void __kgem_bcs_set_tiling(struct kgem *kgem,
+			   struct kgem_bo *src,
+			   struct kgem_bo *dst);
+
+inline static void kgem_bcs_set_tiling(struct kgem *kgem,
+				       struct kgem_bo *src,
+				       struct kgem_bo *dst)
+{
+	assert(kgem->mode == KGEM_BLT);
+
+	if (!kgem->can_blt_y)
+		return;
+
+	__kgem_bcs_set_tiling(kgem, src, dst);
+}
+
 static inline bool kgem_bo_is_snoop(struct kgem_bo *bo)
 {
 	assert(bo->refcnt);
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index f76447b..ce09665 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -5297,6 +5297,7 @@ sna_put_xybitmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
 
 	kgem_set_mode(&sna->kgem, KGEM_BLT, bo);
 	assert(kgem_bo_can_blt(&sna->kgem, bo));
+	kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
 
 	/* Region is pre-clipped and translated into pixmap space */
 	box = region_rects(region);
@@ -5318,6 +5319,7 @@ sna_put_xybitmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
 				return false;
 			_kgem_set_mode(&sna->kgem, KGEM_BLT);
 		}
+		kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
 
 		upload = kgem_create_buffer(&sna->kgem,
 					    bstride*bh,
@@ -5461,6 +5463,7 @@ sna_put_xypixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
 
 	kgem_set_mode(&sna->kgem, KGEM_BLT, bo);
 	assert(kgem_bo_can_blt(&sna->kgem, bo));
+	kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
 
 	skip = h * BitmapBytePad(w + left);
 	for (i = 1 << (gc->depth-1); i; i >>= 1, bits += skip) {
@@ -5488,6 +5491,7 @@ sna_put_xypixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
 					return false;
 				_kgem_set_mode(&sna->kgem, KGEM_BLT);
 			}
+			kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
 
 			upload = kgem_create_buffer(&sna->kgem,
 						    bstride*bh,
@@ -8341,6 +8345,7 @@ sna_copy_bitmap_blt(DrawablePtr _bitmap, DrawablePtr drawable, GCPtr gc,
 					return; /* XXX fallback? */
 				_kgem_set_mode(&sna->kgem, KGEM_BLT);
 			}
+			kgem_bcs_set_tiling(&sna->kgem, NULL, arg->bo);
 
 			assert(sna->kgem.mode == KGEM_BLT);
 			if (sna->kgem.gen >= 0100) {
@@ -8408,6 +8413,7 @@ sna_copy_bitmap_blt(DrawablePtr _bitmap, DrawablePtr drawable, GCPtr gc,
 					return; /* XXX fallback? */
 				_kgem_set_mode(&sna->kgem, KGEM_BLT);
 			}
+			kgem_bcs_set_tiling(&sna->kgem, NULL, arg->bo);
 
 			upload = kgem_create_buffer(&sna->kgem,
 						    bstride*bh,
@@ -8558,6 +8564,7 @@ sna_copy_plane_blt(DrawablePtr source, DrawablePtr drawable, GCPtr gc,
 				return; /* XXX fallback? */
 			_kgem_set_mode(&sna->kgem, KGEM_BLT);
 		}
+		kgem_bcs_set_tiling(&sna->kgem, NULL, arg->bo);
 
 		upload = kgem_create_buffer(&sna->kgem,
 					    bstride*bh,
@@ -8674,6 +8681,8 @@ sna_copy_plane_blt(DrawablePtr source, DrawablePtr drawable, GCPtr gc,
 				}
 			}
 
+			kgem_bcs_set_tiling(&sna->kgem, upload, arg->bo);
+
 			assert(sna->kgem.mode == KGEM_BLT);
 			b = sna->kgem.batch + sna->kgem.nbatch;
 			if (sna->kgem.gen >= 0100) {
@@ -12283,6 +12292,7 @@ sna_poly_fill_rect_tiled_8x8_blt(DrawablePtr drawable,
 			return false;
 		_kgem_set_mode(&sna->kgem, KGEM_BLT);
 	}
+	kgem_bcs_set_tiling(&sna->kgem, tile_bo, bo);
 
 	get_drawable_deltas(drawable, pixmap, &dx, &dy);
 	assert(extents->x1 + dx >= 0);
@@ -12426,6 +12436,7 @@ sna_poly_fill_rect_tiled_8x8_blt(DrawablePtr drawable,
 
 			_kgem_submit(&sna->kgem);
 			_kgem_set_mode(&sna->kgem, KGEM_BLT);
+			kgem_bcs_set_tiling(&sna->kgem, tile_bo, bo);
 		} while (1);
 	} else {
 		RegionRec clip;
@@ -12494,6 +12505,7 @@ sna_poly_fill_rect_tiled_8x8_blt(DrawablePtr drawable,
 					if (!kgem_check_batch(&sna->kgem, 3)) {
 						_kgem_submit(&sna->kgem);
 						_kgem_set_mode(&sna->kgem, KGEM_BLT);
+						kgem_bcs_set_tiling(&sna->kgem, tile_bo, bo);
 
 						unwind_batch = sna->kgem.nbatch;
 						unwind_reloc = sna->kgem.nreloc;
@@ -12590,6 +12602,7 @@ sna_poly_fill_rect_tiled_8x8_blt(DrawablePtr drawable,
 							DBG(("%s: emitting split batch\n", __FUNCTION__));
 							_kgem_submit(&sna->kgem);
 							_kgem_set_mode(&sna->kgem, KGEM_BLT);
+							kgem_bcs_set_tiling(&sna->kgem, tile_bo, bo);
 
 							unwind_batch = sna->kgem.nbatch;
 							unwind_reloc = sna->kgem.nreloc;
@@ -13219,6 +13232,7 @@ sna_poly_fill_rect_stippled_8x8_blt(DrawablePtr drawable,
 			return false;
 		_kgem_set_mode(&sna->kgem, KGEM_BLT);
 	}
+	kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
 
 	if (!clipped) {
 		dx += drawable->x;
@@ -13331,6 +13345,7 @@ sna_poly_fill_rect_stippled_8x8_blt(DrawablePtr drawable,
 
 			_kgem_submit(&sna->kgem);
 			_kgem_set_mode(&sna->kgem, KGEM_BLT);
+			kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
 		} while (1);
 	} else {
 		RegionRec clip;
@@ -13388,6 +13403,7 @@ sna_poly_fill_rect_stippled_8x8_blt(DrawablePtr drawable,
 					if (!kgem_check_batch(&sna->kgem, 3)) {
 						_kgem_submit(&sna->kgem);
 						_kgem_set_mode(&sna->kgem, KGEM_BLT);
+						kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
 
 						assert(sna->kgem.mode == KGEM_BLT);
 						b = sna->kgem.batch + sna->kgem.nbatch;
@@ -13460,6 +13476,7 @@ sna_poly_fill_rect_stippled_8x8_blt(DrawablePtr drawable,
 						if (!kgem_check_batch(&sna->kgem, 3)) {
 							_kgem_submit(&sna->kgem);
 							_kgem_set_mode(&sna->kgem, KGEM_BLT);
+							kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
 
 							assert(sna->kgem.mode == KGEM_BLT);
 							b = sna->kgem.batch + sna->kgem.nbatch;
@@ -13590,6 +13607,7 @@ sna_poly_fill_rect_stippled_1_blt(DrawablePtr drawable,
 	get_drawable_deltas(drawable, pixmap, &dx, &dy);
 	kgem_set_mode(&sna->kgem, KGEM_BLT, bo);
 	assert(kgem_bo_can_blt(&sna->kgem, bo));
+	kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
 
 	br00 = 3 << 20;
 	br13 = bo->pitch;
@@ -13634,6 +13652,7 @@ sna_poly_fill_rect_stippled_1_blt(DrawablePtr drawable,
 						return false;
 					_kgem_set_mode(&sna->kgem, KGEM_BLT);
 				}
+				kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
 
 				assert(sna->kgem.mode == KGEM_BLT);
 				b = sna->kgem.batch + sna->kgem.nbatch;
@@ -13697,6 +13716,7 @@ sna_poly_fill_rect_stippled_1_blt(DrawablePtr drawable,
 						return false;
 					_kgem_set_mode(&sna->kgem, KGEM_BLT);
 				}
+				kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
 
 				upload = kgem_create_buffer(&sna->kgem,
 							    bstride*bh,
@@ -13827,6 +13847,7 @@ sna_poly_fill_rect_stippled_1_blt(DrawablePtr drawable,
 							return false;
 						_kgem_set_mode(&sna->kgem, KGEM_BLT);
 					}
+					kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
 
 					assert(sna->kgem.mode == KGEM_BLT);
 					b = sna->kgem.batch + sna->kgem.nbatch;
@@ -13888,6 +13909,7 @@ sna_poly_fill_rect_stippled_1_blt(DrawablePtr drawable,
 							return false;
 						_kgem_set_mode(&sna->kgem, KGEM_BLT);
 					}
+					kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
 
 					upload = kgem_create_buffer(&sna->kgem,
 								    bstride*bh,
@@ -14018,6 +14040,7 @@ sna_poly_fill_rect_stippled_1_blt(DrawablePtr drawable,
 								return false;
 							_kgem_set_mode(&sna->kgem, KGEM_BLT);
 						}
+						kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
 
 						assert(sna->kgem.mode == KGEM_BLT);
 						b = sna->kgem.batch + sna->kgem.nbatch;
@@ -14078,6 +14101,7 @@ sna_poly_fill_rect_stippled_1_blt(DrawablePtr drawable,
 								return false;
 							_kgem_set_mode(&sna->kgem, KGEM_BLT);
 						}
+						kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
 
 						upload = kgem_create_buffer(&sna->kgem,
 									    bstride*bh,
@@ -14217,6 +14241,7 @@ sna_poly_fill_rect_stippled_n_box__imm(struct sna *sna,
 					return; /* XXX fallback? */
 				_kgem_set_mode(&sna->kgem, KGEM_BLT);
 			}
+			kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
 
 			assert(sna->kgem.mode == KGEM_BLT);
 			b = sna->kgem.batch + sna->kgem.nbatch;
@@ -14342,6 +14367,7 @@ sna_poly_fill_rect_stippled_n_box(struct sna *sna,
 					return; /* XXX fallback? */
 				_kgem_set_mode(&sna->kgem, KGEM_BLT);
 			}
+			kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
 
 			assert(sna->kgem.mode == KGEM_BLT);
 			b = sna->kgem.batch + sna->kgem.nbatch;
@@ -14505,6 +14531,7 @@ sna_poly_fill_rect_stippled_n_blt__imm(DrawablePtr drawable,
 	get_drawable_deltas(drawable, pixmap, &dx, &dy);
 	kgem_set_mode(&sna->kgem, KGEM_BLT, bo);
 	assert(kgem_bo_can_blt(&sna->kgem, bo));
+	kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
 
 	br00 = XY_MONO_SRC_COPY_IMM | 3 << 20;
 	br13 = bo->pitch;
@@ -14650,6 +14677,7 @@ sna_poly_fill_rect_stippled_n_blt(DrawablePtr drawable,
 	get_drawable_deltas(drawable, pixmap, &dx, &dy);
 	kgem_set_mode(&sna->kgem, KGEM_BLT, bo);
 	assert(kgem_bo_can_blt(&sna->kgem, bo));
+	kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
 
 	br00 = XY_MONO_SRC_COPY | 3 << 20;
 	br13 = bo->pitch;
@@ -15372,6 +15400,7 @@ sna_glyph_blt(DrawablePtr drawable, GCPtr gc,
 		}
 		_kgem_set_mode(&sna->kgem, KGEM_BLT);
 	}
+	kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
 
 	DBG(("%s: glyph clip box (%d, %d), (%d, %d)\n",
 	     __FUNCTION__,
@@ -15459,6 +15488,7 @@ sna_glyph_blt(DrawablePtr drawable, GCPtr gc,
 			if (!kgem_check_batch(&sna->kgem, 3+len)) {
 				_kgem_submit(&sna->kgem);
 				_kgem_set_mode(&sna->kgem, KGEM_BLT);
+				kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
 
 				DBG(("%s: new batch, glyph clip box (%d, %d), (%d, %d)\n",
 				     __FUNCTION__,
@@ -16093,6 +16123,7 @@ sna_reversed_glyph_blt(DrawablePtr drawable, GCPtr gc,
 		}
 		_kgem_set_mode(&sna->kgem, KGEM_BLT);
 	}
+	kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
 
 	unwind_batch = sna->kgem.nbatch;
 	unwind_reloc = sna->kgem.nreloc;
@@ -16202,6 +16233,7 @@ sna_reversed_glyph_blt(DrawablePtr drawable, GCPtr gc,
 			if (!kgem_check_batch(&sna->kgem, 3+len)) {
 				_kgem_submit(&sna->kgem);
 				_kgem_set_mode(&sna->kgem, KGEM_BLT);
+				kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
 
 				unwind_batch = sna->kgem.nbatch;
 				unwind_reloc = sna->kgem.nreloc;
@@ -16541,6 +16573,7 @@ sna_push_pixels_solid_blt(GCPtr gc,
 
 	kgem_set_mode(&sna->kgem, KGEM_BLT, bo);
 	assert(kgem_bo_can_blt(&sna->kgem, bo));
+	kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
 
 	/* Region is pre-clipped and translated into pixmap space */
 	box = region_rects(region);
@@ -16562,6 +16595,7 @@ sna_push_pixels_solid_blt(GCPtr gc,
 				return false;
 			_kgem_set_mode(&sna->kgem, KGEM_BLT);
 		}
+		kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
 
 		upload = kgem_create_buffer(&sna->kgem,
 					    bstride*bh,
diff --git a/src/sna/sna_blt.c b/src/sna/sna_blt.c
index b62d7fd..9bb3267 100644
--- a/src/sna/sna_blt.c
+++ b/src/sna/sna_blt.c
@@ -129,7 +129,6 @@ static bool sna_blt_fill_init(struct sna *sna,
 	struct kgem *kgem = &sna->kgem;
 
 	assert(kgem_bo_can_blt (kgem, bo));
-	assert(bo->tiling != I915_TILING_Y);
 	blt->bo[0] = bo;
 
 	blt->br13 = bo->pitch;
@@ -183,6 +182,7 @@ static bool sna_blt_fill_init(struct sna *sna,
 				return false;
 			_kgem_set_mode(kgem, KGEM_BLT);
 		}
+		kgem_bcs_set_tiling(kgem, NULL, bo);
 
 		assert(sna->kgem.mode == KGEM_BLT);
 		b = kgem->batch + kgem->nbatch;
@@ -243,6 +243,8 @@ noinline static void __sna_blt_fill_begin(struct sna *sna,
 	struct kgem *kgem = &sna->kgem;
 	uint32_t *b;
 
+	kgem_bcs_set_tiling(&sna->kgem, NULL, blt->bo[0]);
+
 	assert(kgem->mode == KGEM_BLT);
 	b = kgem->batch + kgem->nbatch;
 	if (sna->kgem.gen >= 0100) {
@@ -338,8 +340,8 @@ static bool sna_blt_copy_init(struct sna *sna,
 {
 	struct kgem *kgem = &sna->kgem;
 
-	assert(kgem_bo_can_blt (kgem, src));
-	assert(kgem_bo_can_blt (kgem, dst));
+	assert(kgem_bo_can_blt(kgem, src));
+	assert(kgem_bo_can_blt(kgem, dst));
 
 	blt->bo[0] = src;
 	blt->bo[1] = dst;
@@ -378,6 +380,7 @@ static bool sna_blt_copy_init(struct sna *sna,
 			return false;
 		_kgem_set_mode(kgem, KGEM_BLT);
 	}
+	kgem_bcs_set_tiling(&sna->kgem, src, dst);
 
 	sna->blt_state.fill_bo = 0;
 	return true;
@@ -432,6 +435,7 @@ static bool sna_blt_alpha_fixup_init(struct sna *sna,
 			return false;
 		_kgem_set_mode(kgem, KGEM_BLT);
 	}
+	kgem_bcs_set_tiling(&sna->kgem, src, dst);
 
 	sna->blt_state.fill_bo = 0;
 	return true;
@@ -463,6 +467,7 @@ static void sna_blt_alpha_fixup_one(struct sna *sna,
 		_kgem_submit(kgem);
 		_kgem_set_mode(kgem, KGEM_BLT);
 	}
+	kgem_bcs_set_tiling(&sna->kgem, blt->bo[1], blt->bo[0]);
 
 	assert(sna->kgem.mode == KGEM_BLT);
 	b = kgem->batch + kgem->nbatch;
@@ -591,6 +596,7 @@ static void sna_blt_copy_one(struct sna *sna,
 		_kgem_submit(kgem);
 		_kgem_set_mode(kgem, KGEM_BLT);
 	}
+	kgem_bcs_set_tiling(&sna->kgem, blt->bo[1], blt->bo[0]);
 
 	assert(sna->kgem.mode == KGEM_BLT);
 	b = kgem->batch + kgem->nbatch;
@@ -1432,6 +1438,7 @@ begin_blt(struct sna *sna,
 
 		_kgem_set_mode(&sna->kgem, KGEM_BLT);
 	}
+	kgem_bcs_set_tiling(&sna->kgem, NULL, op->dst.bo);
 
 	return true;
 }
@@ -1695,6 +1702,7 @@ static void blt_composite_copy_boxes__thread(struct sna *sna,
 
 			_kgem_submit(kgem);
 			_kgem_set_mode(kgem, KGEM_BLT);
+			kgem_bcs_set_tiling(&sna->kgem, src_bo, dst_bo);
 		} while (1);
 	} else {
 		do {
@@ -1751,6 +1759,7 @@ static void blt_composite_copy_boxes__thread(struct sna *sna,
 
 			_kgem_submit(kgem);
 			_kgem_set_mode(kgem, KGEM_BLT);
+			kgem_bcs_set_tiling(&sna->kgem, src_bo, dst_bo);
 		} while (1);
 	}
 	sna_vertex_unlock(&sna->render);
@@ -1833,6 +1842,7 @@ static void blt_composite_copy_boxes__thread64(struct sna *sna,
 
 			_kgem_submit(kgem);
 			_kgem_set_mode(kgem, KGEM_BLT);
+			kgem_bcs_set_tiling(&sna->kgem, src_bo, dst_bo);
 		} while (1);
 	} else {
 		do {
@@ -1891,6 +1901,7 @@ static void blt_composite_copy_boxes__thread64(struct sna *sna,
 
 			_kgem_submit(kgem);
 			_kgem_set_mode(kgem, KGEM_BLT);
+			kgem_bcs_set_tiling(&sna->kgem, src_bo, dst_bo);
 		} while (1);
 	}
 	sna_vertex_unlock(&sna->render);
@@ -2000,6 +2011,7 @@ prepare_blt_copy(struct sna *sna,
 		}
 		_kgem_set_mode(&sna->kgem, KGEM_BLT);
 	}
+	kgem_bcs_set_tiling(&sna->kgem, bo, op->dst.bo);
 
 	DBG(("%s\n", __FUNCTION__));
 
@@ -3046,6 +3058,7 @@ sna_blt_composite__convert(struct sna *sna,
 		}
 		_kgem_set_mode(&sna->kgem, KGEM_BLT);
 	}
+	kgem_bcs_set_tiling(&sna->kgem, tmp->src.bo, tmp->dst.bo);
 
 	if (alpha_fixup) {
 		tmp->blt   = blt_composite_copy_with_alpha;
@@ -3387,6 +3400,7 @@ static bool sna_blt_fill_box(struct sna *sna, uint8_t alu,
 
 		_kgem_set_mode(kgem, KGEM_BLT);
 	}
+	kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
 
 	assert(kgem_check_batch(kgem, 6));
 	assert(kgem_check_reloc(kgem, 1));
@@ -3493,6 +3507,8 @@ bool sna_blt_fill_boxes(struct sna *sna, uint8_t alu,
 			_kgem_set_mode(kgem, KGEM_BLT);
 		}
 
+		kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
+
 		assert(sna->kgem.mode == KGEM_BLT);
 		b = kgem->batch + kgem->nbatch;
 		if (kgem->gen >= 0100) {
@@ -3581,6 +3597,7 @@ bool sna_blt_fill_boxes(struct sna *sna, uint8_t alu,
 
 			_kgem_submit(kgem);
 			_kgem_set_mode(kgem, KGEM_BLT);
+			kgem_bcs_set_tiling(&sna->kgem, NULL, bo);
 
 			assert(sna->kgem.mode == KGEM_BLT);
 			b = kgem->batch + kgem->nbatch;
@@ -3727,6 +3744,7 @@ bool sna_blt_copy_boxes(struct sna *sna, uint8_t alu,
 		}
 		_kgem_set_mode(kgem, KGEM_BLT);
 	}
+	kgem_bcs_set_tiling(&sna->kgem, src_bo, dst_bo);
 
 	if ((dst_dx | dst_dy) == 0) {
 		if (kgem->gen >= 0100) {
@@ -3787,6 +3805,7 @@ bool sna_blt_copy_boxes(struct sna *sna, uint8_t alu,
 
 				_kgem_submit(kgem);
 				_kgem_set_mode(kgem, KGEM_BLT);
+				kgem_bcs_set_tiling(&sna->kgem, src_bo, dst_bo);
 			} while (1);
 		} else {
 			uint64_t hdr = (uint64_t)br13 << 32 | cmd | 6;
@@ -3844,6 +3863,7 @@ bool sna_blt_copy_boxes(struct sna *sna, uint8_t alu,
 
 				_kgem_submit(kgem);
 				_kgem_set_mode(kgem, KGEM_BLT);
+				kgem_bcs_set_tiling(&sna->kgem, src_bo, dst_bo);
 			} while (1);
 		}
 	} else {
@@ -3905,6 +3925,7 @@ bool sna_blt_copy_boxes(struct sna *sna, uint8_t alu,
 
 				_kgem_submit(kgem);
 				_kgem_set_mode(kgem, KGEM_BLT);
+				kgem_bcs_set_tiling(&sna->kgem, src_bo, dst_bo);
 			} while (1);
 		} else {
 			cmd |= 6;
@@ -3962,6 +3983,7 @@ bool sna_blt_copy_boxes(struct sna *sna, uint8_t alu,
 
 				_kgem_submit(kgem);
 				_kgem_set_mode(kgem, KGEM_BLT);
+				kgem_bcs_set_tiling(&sna->kgem, src_bo, dst_bo);
 			} while (1);
 		}
 	}
@@ -4069,6 +4091,7 @@ bool sna_blt_copy_boxes__with_alpha(struct sna *sna, uint8_t alu,
 			_kgem_submit(kgem);
 			_kgem_set_mode(kgem, KGEM_BLT);
 		}
+		kgem_bcs_set_tiling(&sna->kgem, src_bo, dst_bo);
 
 		assert(sna->kgem.mode == KGEM_BLT);
 		b = kgem->batch + kgem->nbatch;
diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c
index 4250f9e..db317ee 100644
--- a/src/sna/sna_io.c
+++ b/src/sna/sna_io.c
@@ -105,8 +105,10 @@ read_boxes_inplace__cpu(struct kgem *kgem,
 	if (!download_inplace__cpu(kgem, dst, bo, box, n))
 		return false;
 
+	if (bo->tiling == I915_TILING_Y)
+		return false;
+
 	assert(kgem_bo_can_map__cpu(kgem, bo, false));
-	assert(bo->tiling != I915_TILING_Y);
 
 	src = kgem_bo_map__cpu(kgem, bo);
 	if (src == NULL)
@@ -480,6 +482,7 @@ fallback:
 			goto fallback;
 		_kgem_set_mode(kgem, KGEM_BLT);
 	}
+	kgem_bcs_set_tiling(&sna->kgem, src_bo, NULL);
 
 	tmp_nbox = nbox;
 	tmp_box = box;
@@ -542,6 +545,7 @@ fallback:
 				break;
 
 			_kgem_set_mode(kgem, KGEM_BLT);
+			kgem_bcs_set_tiling(&sna->kgem, src_bo, NULL);
 			tmp_box += nbox_this_time;
 		} while (1);
 	} else {
@@ -600,6 +604,7 @@ fallback:
 				break;
 
 			_kgem_set_mode(kgem, KGEM_BLT);
+			kgem_bcs_set_tiling(&sna->kgem, src_bo, NULL);
 			tmp_box += nbox_this_time;
 		} while (1);
 	}
@@ -669,8 +674,10 @@ write_boxes_inplace__tiled(struct kgem *kgem,
 {
 	uint8_t *dst;
 
+	if (bo->tiling == I915_TILING_Y)
+		return false;
+
 	assert(kgem->has_wc_mmap || kgem_bo_can_map__cpu(kgem, bo, true));
-	assert(bo->tiling != I915_TILING_Y);
 
 	if (kgem_bo_can_map__cpu(kgem, bo, true)) {
 		dst = kgem_bo_map__cpu(kgem, bo);
@@ -1043,6 +1050,7 @@ tile:
 			goto fallback;
 		_kgem_set_mode(kgem, KGEM_BLT);
 	}
+	kgem_bcs_set_tiling(&sna->kgem, NULL, dst_bo);
 
 	if (kgem->gen >= 0100) {
 		cmd |= 8;
@@ -1134,6 +1142,7 @@ tile:
 			if (nbox) {
 				_kgem_submit(kgem);
 				_kgem_set_mode(kgem, KGEM_BLT);
+				kgem_bcs_set_tiling(&sna->kgem, NULL, dst_bo);
 			}
 
 			kgem_bo_destroy(kgem, src_bo);
@@ -1229,6 +1238,7 @@ tile:
 			if (nbox) {
 				_kgem_submit(kgem);
 				_kgem_set_mode(kgem, KGEM_BLT);
+				kgem_bcs_set_tiling(&sna->kgem, NULL, dst_bo);
 			}
 
 			kgem_bo_destroy(kgem, src_bo);
@@ -1546,6 +1556,7 @@ tile:
 			goto fallback;
 		_kgem_set_mode(kgem, KGEM_BLT);
 	}
+	kgem_bcs_set_tiling(&sna->kgem, NULL, dst_bo);
 
 	if (sna->kgem.gen >= 0100) {
 		cmd |= 8;
@@ -1641,6 +1652,7 @@ tile:
 			if (nbox) {
 				_kgem_submit(kgem);
 				_kgem_set_mode(kgem, KGEM_BLT);
+				kgem_bcs_set_tiling(&sna->kgem, NULL, dst_bo);
 			}
 
 			kgem_bo_destroy(kgem, src_bo);
@@ -1737,6 +1749,7 @@ tile:
 			if (nbox) {
 				_kgem_submit(kgem);
 				_kgem_set_mode(kgem, KGEM_BLT);
+				kgem_bcs_set_tiling(&sna->kgem, NULL, dst_bo);
 			}
 
 			kgem_bo_destroy(kgem, src_bo);
commit 432e0775ee26a81e8e00f04c6864205d9f0bc2a2
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Apr 17 10:21:30 2015 +0100

    sna/present: Check earlier for an incompatilble tiled Pixmap
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_present.c b/src/sna/sna_present.c
index 82f772f..a344dac 100644
--- a/src/sna/sna_present.c
+++ b/src/sna/sna_present.c
@@ -444,6 +444,24 @@ sna_present_check_flip(RRCrtcPtr crtc,
 		return FALSE;
 	}
 
+	if (flip->pinned) {
+		assert(flip->gpu_bo);
+		if (sna->flags & SNA_LINEAR_FB) {
+			if (flip->gpu_bo->tiling != I915_TILING_NONE) {
+				DBG(("%s: pined bo, tilng=%d needs NONE\n",
+				     __FUNCTION__, flip->gpu_bo->tiling));
+				return FALSE;
+			}
+		} else {
+			if (!sna->kgem.can_scanout_y &&
+			    flip->gpu_bo->tiling == I915_TILING_Y) {
+				DBG(("%s: pined bo, tilng=%d and can't scanout Y\n",
+				     __FUNCTION__, flip->gpu_bo->tiling));
+				return FALSE;
+			}
+		}
+	}
+
 	return TRUE;
 }
 
@@ -560,7 +578,7 @@ get_flip_bo(PixmapPtr pixmap)
 	if (priv->gpu_bo->scanout)
 		return priv->gpu_bo;
 
-	if (sna->kgem.has_llc && !wedged(sna)) {
+	if (sna->kgem.has_llc && !wedged(sna) && !priv->pinned) {
 		struct kgem_bo *bo;
 		uint32_t tiling;
 


More information about the xorg-commit mailing list