sna: Remove stale mappings when replacing GPU bo

References: https://bugs.freedesktop.org/show_bug.cgi?id=70527
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
Chris Wilson 2013-10-25 14:22:05 +01:00
parent 4e4d643794
commit f0da01aa90
4 changed files with 51 additions and 54 deletions

View File

@ -892,11 +892,9 @@ bool sna_write_boxes__xor(struct sna *sna, PixmapPtr dst,
bool sna_replace(struct sna *sna,
PixmapPtr pixmap,
struct kgem_bo **bo,
const void *src, int stride);
bool sna_replace__xor(struct sna *sna,
PixmapPtr pixmap,
struct kgem_bo **bo,
const void *src, int stride,
uint32_t and, uint32_t or);

View File

@ -3110,7 +3110,6 @@ sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int fl
box->x2 >= pixmap->drawable.width &&
box->y2 >= pixmap->drawable.height) {
ok = sna_replace(sna, pixmap,
&priv->gpu_bo,
pixmap->devPrivate.ptr,
pixmap->devKind);
} else {
@ -3857,7 +3856,6 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags)
(box->x2 - box->x1) >= pixmap->drawable.width &&
(box->y2 - box->y1) >= pixmap->drawable.height) {
ok = sna_replace(sna, pixmap,
&priv->gpu_bo,
pixmap->devPrivate.ptr,
pixmap->devKind);
} else {
@ -5891,9 +5889,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
bits = src_pixmap->devPrivate.ptr;
bits += (src_dy + box->y1) * stride + (src_dx + box->x1) * bpp / 8;
if (!sna_replace(sna, dst_pixmap,
&dst_priv->gpu_bo,
bits, stride)) {
if (!sna_replace(sna, dst_pixmap, bits, stride)) {
DBG(("%s: replace failed, fallback\n", __FUNCTION__));
goto fallback;
}

View File

@ -1710,8 +1710,7 @@ blt_put_composite(struct sna *sna,
data += (src_y - dst_y) * pitch;
assert(op->dst.bo == dst_priv->gpu_bo);
sna_replace(sna, op->dst.pixmap, &dst_priv->gpu_bo,
data, pitch);
sna_replace(sna, op->dst.pixmap, data, pitch);
} else {
BoxRec box;
bool ok;
@ -1752,8 +1751,7 @@ fastcall static void blt_put_composite_box(struct sna *sna,
data += (box->x1 + op->u.blt.sx) * bpp;
assert(op->dst.bo == dst_priv->gpu_bo);
sna_replace(sna, op->dst.pixmap, &dst_priv->gpu_bo,
data, pitch);
sna_replace(sna, op->dst.pixmap, data, pitch);
} else {
bool ok;
@ -1791,8 +1789,7 @@ static void blt_put_composite_boxes(struct sna *sna,
data += (box->x1 + op->u.blt.sx) * bpp;
assert(op->dst.bo == dst_priv->gpu_bo);
sna_replace(sna, op->dst.pixmap, &dst_priv->gpu_bo,
data, pitch);
sna_replace(sna, op->dst.pixmap, data, pitch);
} else {
bool ok;
@ -1833,8 +1830,8 @@ blt_put_composite_with_alpha(struct sna *sna,
data += (src_y - dst_y) * pitch;
assert(op->dst.bo == dst_priv->gpu_bo);
sna_replace__xor(sna, op->dst.pixmap, &dst_priv->gpu_bo,
data, pitch, 0xffffffff, op->u.blt.pixel);
sna_replace__xor(sna, op->dst.pixmap, data, pitch,
0xffffffff, op->u.blt.pixel);
} else {
BoxRec box;
@ -1874,8 +1871,8 @@ blt_put_composite_box_with_alpha(struct sna *sna,
data += (box->x1 + op->u.blt.sx) * bpp;
assert(op->dst.bo == dst_priv->gpu_bo);
sna_replace__xor(sna, op->dst.pixmap, &dst_priv->gpu_bo,
data, pitch, 0xffffffff, op->u.blt.pixel);
sna_replace__xor(sna, op->dst.pixmap, data, pitch,
0xffffffff, op->u.blt.pixel);
} else {
sna_write_boxes__xor(sna, op->dst.pixmap,
op->dst.bo, op->dst.x, op->dst.y,
@ -1911,8 +1908,8 @@ blt_put_composite_boxes_with_alpha(struct sna *sna,
data += (box->x1 + op->u.blt.sx) * bpp;
assert(dst_priv->gpu_bo == op->dst.bo);
sna_replace__xor(sna, op->dst.pixmap, &dst_priv->gpu_bo,
data, pitch, 0xffffffff, op->u.blt.pixel);
sna_replace__xor(sna, op->dst.pixmap, data, pitch,
0xffffffff, op->u.blt.pixel);
} else {
sna_write_boxes__xor(sna, op->dst.pixmap,
op->dst.bo, op->dst.x, op->dst.y,
@ -1931,6 +1928,8 @@ prepare_blt_put(struct sna *sna,
{
DBG(("%s\n", __FUNCTION__));
assert(!sna_pixmap(op->dst.pixmap)->clear);
if (op->dst.bo) {
assert(op->dst.bo == sna_pixmap(op->dst.pixmap)->gpu_bo);
if (alpha_fixup) {

View File

@ -1472,13 +1472,11 @@ indirect_replace(struct sna *sna,
return ret;
}
bool sna_replace(struct sna *sna,
PixmapPtr pixmap,
struct kgem_bo **_bo,
bool sna_replace(struct sna *sna, PixmapPtr pixmap,
const void *src, int stride)
{
struct kgem_bo *bo = *_bo;
struct kgem *kgem = &sna->kgem;
struct sna_pixmap *priv = sna_pixmap(pixmap);
struct kgem_bo *bo = priv->gpu_bo;
void *dst;
assert(bo);
@ -1488,19 +1486,19 @@ bool sna_replace(struct sna *sna,
pixmap->drawable.height,
pixmap->drawable.bitsPerPixel,
bo->tiling,
__kgem_bo_is_busy(kgem, bo)));
__kgem_bo_is_busy(&sna->kgem, bo)));
assert(!sna_pixmap(pixmap)->pinned);
assert(!priv->pinned);
kgem_bo_undo(kgem, bo);
kgem_bo_undo(&sna->kgem, bo);
if (__kgem_bo_is_busy(kgem, bo)) {
if (__kgem_bo_is_busy(&sna->kgem, bo)) {
struct kgem_bo *new_bo;
if (indirect_replace(sna, pixmap, bo, src, stride))
return true;
new_bo = kgem_create_2d(kgem,
new_bo = kgem_create_2d(&sna->kgem,
pixmap->drawable.width,
pixmap->drawable.height,
pixmap->drawable.bitsPerPixel,
@ -1511,26 +1509,26 @@ bool sna_replace(struct sna *sna,
}
if (bo->tiling == I915_TILING_NONE && bo->pitch == stride &&
kgem_bo_write(kgem, bo, src,
kgem_bo_write(&sna->kgem, bo, src,
(pixmap->drawable.height-1)*stride + pixmap->drawable.width*pixmap->drawable.bitsPerPixel/8))
goto done;
if (upload_inplace__tiled(kgem, bo)) {
if (upload_inplace__tiled(&sna->kgem, bo)) {
BoxRec box;
box.x1 = box.y1 = 0;
box.x2 = pixmap->drawable.width;
box.y2 = pixmap->drawable.height;
if (write_boxes_inplace__tiled(kgem, src,
if (write_boxes_inplace__tiled(&sna->kgem, src,
stride, pixmap->drawable.bitsPerPixel, 0, 0,
bo, 0, 0, &box, 1))
goto done;
}
sigtrap_assert();
if (kgem_bo_is_mappable(kgem, bo) &&
(dst = kgem_bo_map(kgem, bo)) != NULL &&
if (kgem_bo_is_mappable(&sna->kgem, bo) &&
(dst = kgem_bo_map(&sna->kgem, bo)) != NULL &&
sigtrap_get() == 0) {
memcpy_blt(src, dst, pixmap->drawable.bitsPerPixel,
stride, bo->pitch,
@ -1554,26 +1552,27 @@ bool sna_replace(struct sna *sna,
}
done:
if (bo != *_bo)
kgem_bo_destroy(kgem, *_bo);
*_bo = bo;
if (bo != priv->gpu_bo) {
sna_pixmap_unmap(pixmap, priv);
kgem_bo_destroy(&sna->kgem, priv->gpu_bo);
priv->gpu_bo = bo;
}
return true;
err:
if (bo != *_bo)
kgem_bo_destroy(kgem, bo);
if (bo != priv->gpu_bo)
kgem_bo_destroy(&sna->kgem, bo);
return false;
}
bool
sna_replace__xor(struct sna *sna,
PixmapPtr pixmap,
struct kgem_bo **_bo,
sna_replace__xor(struct sna *sna, PixmapPtr pixmap,
const void *src, int stride,
uint32_t and, uint32_t or)
{
struct kgem_bo *bo = *_bo;
struct kgem *kgem = &sna->kgem;
struct sna_pixmap *priv = sna_pixmap(pixmap);
struct kgem_bo *bo = priv->gpu_bo;
void *dst;
DBG(("%s(handle=%d, %dx%d, bpp=%d, tiling=%d)\n",
@ -1583,25 +1582,27 @@ sna_replace__xor(struct sna *sna,
pixmap->drawable.bitsPerPixel,
bo->tiling));
assert(!sna_pixmap(pixmap)->pinned);
assert(!priv->pinned);
kgem_bo_undo(&sna->kgem, bo);
if (kgem_bo_is_busy(bo)) {
struct kgem_bo *new_bo;
new_bo = kgem_create_2d(kgem,
new_bo = kgem_create_2d(&sna->kgem,
pixmap->drawable.width,
pixmap->drawable.height,
pixmap->drawable.bitsPerPixel,
bo->tiling,
CREATE_GTT_MAP | CREATE_INACTIVE);
if (new_bo) {
kgem_bo_destroy(kgem, bo);
kgem_bo_destroy(&sna->kgem, bo);
bo = new_bo;
}
}
if (kgem_bo_is_mappable(kgem, bo) &&
(dst = kgem_bo_map(kgem, bo)) != NULL &&
if (kgem_bo_is_mappable(&sna->kgem, bo) &&
(dst = kgem_bo_map(&sna->kgem, bo)) != NULL &&
sigtrap_get() == 0) {
memcpy_xor(src, dst, pixmap->drawable.bitsPerPixel,
stride, bo->pitch,
@ -1626,13 +1627,16 @@ sna_replace__xor(struct sna *sna,
goto err;
}
if (bo != *_bo)
kgem_bo_destroy(kgem, *_bo);
*_bo = bo;
if (bo != priv->gpu_bo) {
sna_pixmap_unmap(pixmap, priv);
kgem_bo_destroy(&sna->kgem, priv->gpu_bo);
priv->gpu_bo = bo;
}
return true;
err:
if (bo != *_bo)
kgem_bo_destroy(kgem, bo);
if (bo != priv->gpu_bo)
kgem_bo_destroy(&sna->kgem, bo);
return false;
}