summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2015-04-17 10:29:28 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2015-04-17 11:45:03 +0100
commit75d87762471e195dddd73056fc6a06e17db1c8b0 (patch)
tree1212dd384e8ab1d6d7b18ac8ec68fa883ce09e8a
parent432e0775ee26a81e8e00f04c6864205d9f0bc2a2 (diff)
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@chris-wilson.co.uk>
-rw-r--r--src/sna/gen6_common.h3
-rw-r--r--src/sna/kgem.c141
-rw-r--r--src/sna/kgem.h23
-rw-r--r--src/sna/sna_accel.c34
-rw-r--r--src/sna/sna_blt.c29
-rw-r--r--src/sna/sna_io.c17
6 files changed, 239 insertions, 8 deletions
diff --git a/src/sna/gen6_common.h b/src/sna/gen6_common.h
index 409bab3b..5da739e2 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 05fe4070..76e69135 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 f1042a02..adc777de 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 f76447bd..ce096650 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 b62d7fd7..9bb32674 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 4250f9ee..db317ee4 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);