sna: Add a tiled fallback for large BLT copies
If we are attempting to copy between two large bo, larger than we can fit into the aperture, break the copy into smaller steps and use an intermediatory. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
parent
df148c9621
commit
3aee521bf2
|
|
@ -153,6 +153,7 @@ static bool sna_blt_fill_init(struct sna *sna,
|
|||
if (!kgem_check_bo_fenced(kgem, bo, NULL) ||
|
||||
!kgem_check_batch(kgem, 12)) {
|
||||
_kgem_submit(kgem);
|
||||
assert(kgem_check_bo_fenced(kgem, bo, NULL));
|
||||
_kgem_set_mode(kgem, KGEM_BLT);
|
||||
}
|
||||
|
||||
|
|
@ -290,6 +291,8 @@ static Bool sna_blt_copy_init(struct sna *sna,
|
|||
kgem_set_mode(kgem, KGEM_BLT);
|
||||
if (!kgem_check_bo_fenced(kgem, src, dst, NULL)) {
|
||||
_kgem_submit(kgem);
|
||||
if (!kgem_check_bo_fenced(kgem, src, dst, NULL))
|
||||
return FALSE;
|
||||
_kgem_set_mode(kgem, KGEM_BLT);
|
||||
}
|
||||
|
||||
|
|
@ -337,6 +340,8 @@ static Bool sna_blt_alpha_fixup_init(struct sna *sna,
|
|||
kgem_set_mode(kgem, KGEM_BLT);
|
||||
if (!kgem_check_bo_fenced(kgem, src, dst, NULL)) {
|
||||
_kgem_submit(kgem);
|
||||
if (!kgem_check_bo_fenced(kgem, src, dst, NULL))
|
||||
return FALSE;
|
||||
_kgem_set_mode(kgem, KGEM_BLT);
|
||||
}
|
||||
|
||||
|
|
@ -1109,8 +1114,11 @@ prepare_blt_copy(struct sna *sna,
|
|||
if (!kgem_bo_can_blt(&sna->kgem, priv->gpu_bo))
|
||||
return FALSE;
|
||||
|
||||
if (!kgem_check_bo_fenced(&sna->kgem, priv->gpu_bo, NULL)) {
|
||||
if (!kgem_check_bo_fenced(&sna->kgem, op->dst.bo, priv->gpu_bo, NULL)) {
|
||||
_kgem_submit(&sna->kgem);
|
||||
if (!kgem_check_bo_fenced(&sna->kgem,
|
||||
op->dst.bo, priv->gpu_bo, NULL))
|
||||
return FALSE;
|
||||
_kgem_set_mode(&sna->kgem, KGEM_BLT);
|
||||
}
|
||||
|
||||
|
|
@ -1594,6 +1602,7 @@ sna_blt_composite(struct sna *sna,
|
|||
|
||||
if (!kgem_check_bo_fenced(&sna->kgem, priv->gpu_bo, NULL)) {
|
||||
_kgem_submit(&sna->kgem);
|
||||
assert(kgem_check_bo_fenced(&sna->kgem, priv->gpu_bo, NULL));
|
||||
_kgem_set_mode(&sna->kgem, KGEM_BLT);
|
||||
}
|
||||
|
||||
|
|
@ -1891,6 +1900,7 @@ static bool sna_blt_fill_box(struct sna *sna, uint8_t alu,
|
|||
!kgem_check_reloc(kgem, 1) ||
|
||||
!kgem_check_bo_fenced(kgem, bo, NULL)) {
|
||||
_kgem_submit(kgem);
|
||||
assert(kgem_check_bo_fenced(&sna->kgem, bo, NULL));
|
||||
_kgem_set_mode(kgem, KGEM_BLT);
|
||||
}
|
||||
|
||||
|
|
@ -1964,6 +1974,7 @@ Bool sna_blt_fill_boxes(struct sna *sna, uint8_t alu,
|
|||
if (!kgem_check_bo_fenced(kgem, bo, NULL) ||
|
||||
!kgem_check_batch(kgem, 12)) {
|
||||
_kgem_submit(kgem);
|
||||
assert(kgem_check_bo_fenced(&sna->kgem, bo, NULL));
|
||||
_kgem_set_mode(kgem, KGEM_BLT);
|
||||
}
|
||||
|
||||
|
|
@ -2127,6 +2138,11 @@ Bool sna_blt_copy_boxes(struct sna *sna, uint8_t alu,
|
|||
!kgem_check_reloc(kgem, 2) ||
|
||||
!kgem_check_bo_fenced(kgem, dst_bo, src_bo, NULL)) {
|
||||
_kgem_submit(kgem);
|
||||
if (!kgem_check_bo_fenced(kgem, dst_bo, src_bo, NULL))
|
||||
return sna_tiling_copy_boxes(sna, alu,
|
||||
src_bo, src_dx, src_dy,
|
||||
dst_bo, dst_dx, dst_dy,
|
||||
bpp, box, nbox);
|
||||
_kgem_set_mode(kgem, KGEM_BLT);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -507,6 +507,10 @@ Bool sna_tiling_fill_boxes(struct sna *sna,
|
|||
const xRenderColor *color,
|
||||
PixmapPtr dst, struct kgem_bo *dst_bo,
|
||||
const BoxRec *box, int n);
|
||||
Bool sna_tiling_copy_boxes(struct sna *sna, uint8_t alu,
|
||||
struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy,
|
||||
struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy,
|
||||
int bpp, const BoxRec *box, int nbox);
|
||||
|
||||
Bool sna_blt_composite(struct sna *sna,
|
||||
uint32_t op,
|
||||
|
|
|
|||
|
|
@ -417,3 +417,99 @@ done:
|
|||
pixman_region_fini(®ion);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Bool sna_tiling_copy_boxes(struct sna *sna, uint8_t alu,
|
||||
struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy,
|
||||
struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy,
|
||||
int bpp, const BoxRec *box, int nbox)
|
||||
{
|
||||
RegionRec region, tile, this;
|
||||
struct kgem_bo *bo;
|
||||
int step;
|
||||
Bool ret = FALSE;
|
||||
|
||||
if (!kgem_bo_can_blt(&sna->kgem, src_bo) ||
|
||||
!kgem_bo_can_blt(&sna->kgem, dst_bo)) {
|
||||
/* XXX */
|
||||
DBG(("%s: tiling blt fail: src?=%d, dst?=%d\n",
|
||||
__FUNCTION__,
|
||||
kgem_bo_can_blt(&sna->kgem, src_bo),
|
||||
kgem_bo_can_blt(&sna->kgem, dst_bo)));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pixman_region_init_rects(®ion, box, nbox);
|
||||
|
||||
step = sna->render.max_3d_size;
|
||||
while (step * step * 4 > sna->kgem.max_tile_size)
|
||||
step /= 2;
|
||||
|
||||
DBG(("%s (alu=%d), tile.size=%d, box=%dx[(%d, %d), (%d, %d)])\n",
|
||||
__FUNCTION__, alu, step, nbox,
|
||||
region.extents.x1, region.extents.y1,
|
||||
region.extents.x2, region.extents.y2));
|
||||
|
||||
for (tile.extents.y1 = tile.extents.y2 = region.extents.y1;
|
||||
tile.extents.y2 < region.extents.y2;
|
||||
tile.extents.y1 = tile.extents.y2) {
|
||||
tile.extents.y2 = tile.extents.y1 + step;
|
||||
if (tile.extents.y2 > region.extents.y2)
|
||||
tile.extents.y2 = region.extents.y2;
|
||||
|
||||
for (tile.extents.x1 = tile.extents.x2 = region.extents.x1;
|
||||
tile.extents.x2 < region.extents.x2;
|
||||
tile.extents.x1 = tile.extents.x2) {
|
||||
int w, h;
|
||||
|
||||
tile.extents.x2 = tile.extents.x1 + step;
|
||||
if (tile.extents.x2 > region.extents.x2)
|
||||
tile.extents.x2 = region.extents.x2;
|
||||
|
||||
tile.data = NULL;
|
||||
|
||||
RegionNull(&this);
|
||||
RegionIntersect(&this, ®ion, &tile);
|
||||
if (!RegionNotEmpty(&this))
|
||||
continue;
|
||||
|
||||
w = this.extents.x2 - this.extents.x1;
|
||||
h = this.extents.y2 - this.extents.y1;
|
||||
bo = kgem_create_2d(&sna->kgem, w, h, bpp,
|
||||
kgem_choose_tiling(&sna->kgem,
|
||||
I915_TILING_X,
|
||||
w, h, bpp),
|
||||
0);
|
||||
if (bo) {
|
||||
int16_t dx = this.extents.x1;
|
||||
int16_t dy = this.extents.y1;
|
||||
|
||||
assert(bo->pitch <= 8192);
|
||||
assert(bo->tiling != I915_TILING_Y);
|
||||
|
||||
if (!sna_blt_copy_boxes(sna, alu,
|
||||
src_bo, src_dx, src_dy,
|
||||
bo, -dx, -dy,
|
||||
bpp, REGION_RECTS(&this), REGION_NUM_RECTS(&this)))
|
||||
goto err;
|
||||
|
||||
if (!sna_blt_copy_boxes(sna, alu,
|
||||
bo, -dx, -dy,
|
||||
dst_bo, dst_dx, dst_dy,
|
||||
bpp, REGION_RECTS(&this), REGION_NUM_RECTS(&this)))
|
||||
goto err;
|
||||
|
||||
kgem_bo_destroy(&sna->kgem, bo);
|
||||
}
|
||||
RegionUninit(&this);
|
||||
}
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
goto done;
|
||||
err:
|
||||
kgem_bo_destroy(&sna->kgem, bo);
|
||||
RegionUninit(&this);
|
||||
done:
|
||||
pixman_region_fini(®ion);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue