From f0da01aa907d488ae32dfda206ea8a66564bc430 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 25 Oct 2013 14:22:05 +0100 Subject: [PATCH] sna: Remove stale mappings when replacing GPU bo References: https://bugs.freedesktop.org/show_bug.cgi?id=70527 Signed-off-by: Chris Wilson --- src/sna/sna.h | 2 -- src/sna/sna_accel.c | 6 +--- src/sna/sna_blt.c | 23 +++++++------- src/sna/sna_io.c | 74 ++++++++++++++++++++++++--------------------- 4 files changed, 51 insertions(+), 54 deletions(-) diff --git a/src/sna/sna.h b/src/sna/sna.h index 0796a372..243f7958 100644 --- a/src/sna/sna.h +++ b/src/sna/sna.h @@ -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); diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index a1de360a..9a783756 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -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; } diff --git a/src/sna/sna_blt.c b/src/sna/sna_blt.c index c7738684..8a6814cf 100644 --- a/src/sna/sna_blt.c +++ b/src/sna/sna_blt.c @@ -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) { diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c index 78951ca4..ee5debf4 100644 --- a/src/sna/sna_io.c +++ b/src/sna/sna_io.c @@ -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; }