From d43e3b39d22af7325f91c8a380fafc7374c5d01b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 2 Jun 2014 22:51:47 +0100 Subject: [PATCH] sna: Only promote an upload to the GPU if there is no CPU damage to discard 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 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 | 5 ++++- src/sna/sna_damage.c | 31 +++++++++++++++++++++++++++++++ src/sna/sna_damage.h | 2 ++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index 2513b8b..3f24e85 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -4562,9 +4562,12 @@ try_upload_tiled_x(PixmapPtr pixmap, RegionRec *region, 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__)); + sna_damage_transfer(&priv->cpu_damage, + &priv->gpu_damage); sna_pixmap_free_gpu(sna, priv); } - replaces = true; /* Mark it all GPU damaged afterwards */ + replaces = (priv->cpu_damage == NULL || + region_subsumes_damage(region, priv->cpu_damage)); } if (priv->gpu_bo == NULL && diff --git a/src/sna/sna_damage.c b/src/sna/sna_damage.c index d4b3515..6d1ff30 100644 --- a/src/sna/sna_damage.c +++ b/src/sna/sna_damage.c @@ -1573,6 +1573,37 @@ int _sna_damage_get_boxes(struct sna_damage *damage, BoxPtr *boxes) } #endif +void sna_damage_transfer(struct sna_damage **dst, + struct sna_damage **src) +{ + if (*src == NULL) + return; + + if (*dst == NULL) { + *dst = *src; + *src = NULL; + return; + } + + if (DAMAGE_IS_ALL(*dst)) { + sna_damage_destroy(src); + return; + } + + if (DAMAGE_IS_ALL(*src)) { + sna_damage_destroy(dst); + *dst = *src; + *src = NULL; + return; + } + + if ((*src)->dirty) + __sna_damage_reduce(*src); + + *dst = _sna_damage_add(*dst, &(*src)->region); + sna_damage_destroy(src); +} + struct sna_damage *_sna_damage_combine(struct sna_damage *l, struct sna_damage *r, int dx, int dy) diff --git a/src/sna/sna_damage.h b/src/sna/sna_damage.h index 187d312..92f0444 100644 --- a/src/sna/sna_damage.h +++ b/src/sna/sna_damage.h @@ -28,6 +28,8 @@ struct sna_damage { struct sna_damage *sna_damage_create(void); +void sna_damage_transfer(struct sna_damage **dst, + struct sna_damage **src); struct sna_damage *_sna_damage_combine(struct sna_damage *l, struct sna_damage *r, int dx, int dy); -- 1.9.3