From 97cc8576b3248057e815d4b74b0b2b41b08a1934 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 2 Jun 2014 22:51:47 +0100 Subject: [PATCH] sna: Do not assume that the partial upload will be a suitable replacement Regression from commit 65301412ecf2d55ab55a2d7faeaa048d4ee8b1d0 Author: Chris Wilson Date: Sat May 17 20:59:38 2014 +0100 sna: Discard active GPU buffers before uploading into them We lose track of the damage - most likely the clear hint - resulting in corruption as the browser scrolls through a large image uploading bits at a time. Reported-by: Jan Alexander Steffens Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=79517 Signed-off-by: Chris Wilson --- src/sna/sna_accel.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index cb29813..3d9c797 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -4521,6 +4521,7 @@ try_upload_tiled_x(PixmapPtr pixmap, RegionRec *region, { struct sna *sna = to_sna_from_pixmap(pixmap); struct sna_pixmap *priv = sna_pixmap(pixmap); + bool ignore_cpu = false; bool replaces; BoxRec *box; uint8_t *dst; @@ -4550,6 +4551,7 @@ try_upload_tiled_x(PixmapPtr pixmap, RegionRec *region, kgem_bo_is_busy(priv->gpu_bo), kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, true))); sna_pixmap_free_gpu(sna, priv); + ignore_cpu = true; } } assert(priv->gpu_bo == NULL || priv->gpu_bo->proxy == NULL); @@ -4564,15 +4566,18 @@ try_upload_tiled_x(PixmapPtr pixmap, RegionRec *region, region_subsumes_damage(region, priv->gpu_damage)) { if (UNDO) kgem_bo_undo(&sna->kgem, priv->gpu_bo); - if (__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo)) { - DBG(("%s: discarding dirty pixmap\n", __FUNCTION__)); + if (__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo) || + !kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, true)) { + DBG(("%s: discarding unusable partial target bo (busy? %d, mappable? %d)\n", __FUNCTION__, + kgem_bo_is_busy(priv->gpu_bo), + kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, true))); sna_pixmap_free_gpu(sna, priv); + ignore_cpu = true; } - replaces = true; /* Mark it all GPU damaged afterwards */ } if (priv->gpu_bo == NULL && - !create_upload_tiled_x(&sna->kgem, pixmap, priv, replaces)) + !create_upload_tiled_x(&sna->kgem, pixmap, priv, ignore_cpu)) return false; DBG(("%s: tiling=%d\n", __FUNCTION__, priv->gpu_bo->tiling)); @@ -4699,6 +4704,7 @@ try_upload_tiled_x(PixmapPtr pixmap, RegionRec *region, if (priv->cpu_damage == NULL) { list_del(&priv->flush_list); sna_pixmap_free_cpu(sna, priv, priv->cpu); + priv->cpu = false; } } -- 1.9.3