diff options
author | Boris Brezillon <boris.brezillon@collabora.com> | 2019-11-09 00:02:54 +0100 |
---|---|---|
committer | Dylan Baker <dylan@pnwbakers.com> | 2019-12-04 13:43:32 -0800 |
commit | a39d364af3515b9b2df22f583b7b6835d0fc34b3 (patch) | |
tree | be3c6e3b55fcae7d9fcf3a439e6709607c1b51ef | |
parent | c166435dc24656cf36a30184d42eaa980e2d1575 (diff) |
gallium: Fix the ->set_damage_region() implementation
BACK_LEFT attachment can be outdated when the user calls
KHR_partial_update() (->lastStamp != ->texture_stamp), leading to a
damage region update on the wrong pipe_resource object.
Let's delay the ->set_damage_region() call until the attachments are
updated when we're in that case.
Reported-by: Carsten Haitzler <raster@rasterman.com>
Fixes: 492ffbed63a2 ("st/dri2: Implement DRI2bufferDamageExtension")
Cc: <mesa-stable@lists.freedesktop.org>
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
(cherry picked from commit b196e1a8cfbd2c6b53f688542bcda5bb8f7f8888)
-rw-r--r-- | src/gallium/state_trackers/dri/dri2.c | 23 | ||||
-rw-r--r-- | src/gallium/state_trackers/dri/dri_drawable.c | 13 | ||||
-rw-r--r-- | src/gallium/state_trackers/dri/dri_drawable.h | 3 |
3 files changed, 35 insertions, 4 deletions
diff --git a/src/gallium/state_trackers/dri/dri2.c b/src/gallium/state_trackers/dri/dri2.c index 755396a60be..2c51508b4ac 100644 --- a/src/gallium/state_trackers/dri/dri2.c +++ b/src/gallium/state_trackers/dri/dri2.c @@ -1861,8 +1861,6 @@ static void dri2_set_damage_region(__DRIdrawable *dPriv, unsigned int nrects, int *rects) { struct dri_drawable *drawable = dri_drawable(dPriv); - struct pipe_resource *resource = drawable->textures[ST_ATTACHMENT_BACK_LEFT]; - struct pipe_screen *screen = resource->screen; struct pipe_box *boxes = NULL; if (nrects) { @@ -1876,8 +1874,25 @@ dri2_set_damage_region(__DRIdrawable *dPriv, unsigned int nrects, int *rects) } } - screen->set_damage_region(screen, resource, nrects, boxes); - FREE(boxes); + FREE(drawable->damage_rects); + drawable->damage_rects = boxes; + drawable->num_damage_rects = nrects; + + /* Only apply the damage region if the BACK_LEFT texture is up-to-date. */ + if (drawable->texture_stamp == drawable->dPriv->lastStamp && + (drawable->texture_mask & (1 << ST_ATTACHMENT_BACK_LEFT))) { + struct pipe_screen *screen = drawable->screen->base.screen; + struct pipe_resource *resource; + + if (drawable->stvis.samples > 1) + resource = drawable->msaa_textures[ST_ATTACHMENT_BACK_LEFT]; + else + resource = drawable->textures[ST_ATTACHMENT_BACK_LEFT]; + + screen->set_damage_region(screen, resource, + drawable->num_damage_rects, + drawable->damage_rects); + } } static __DRI2bufferDamageExtension dri2BufferDamageExtension = { diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c index f27396195ec..c5eb633fca4 100644 --- a/src/gallium/state_trackers/dri/dri_drawable.c +++ b/src/gallium/state_trackers/dri/dri_drawable.c @@ -95,6 +95,18 @@ dri_st_framebuffer_validate(struct st_context_iface *stctx, } } while (lastStamp != drawable->dPriv->lastStamp); + /* Flush the pending set_damage_region request. */ + struct pipe_screen *pscreen = screen->base.screen; + + if (new_mask & (1 << ST_ATTACHMENT_BACK_LEFT) && + pscreen->set_damage_region) { + struct pipe_resource *resource = textures[ST_ATTACHMENT_BACK_LEFT]; + + pscreen->set_damage_region(pscreen, resource, + drawable->num_damage_rects, + drawable->damage_rects); + } + if (!out) return true; @@ -202,6 +214,7 @@ dri_destroy_buffer(__DRIdrawable * dPriv) /* Notify the st manager that this drawable is no longer valid */ stapi->destroy_drawable(stapi, &drawable->base); + FREE(drawable->damage_rects); FREE(drawable); } diff --git a/src/gallium/state_trackers/dri/dri_drawable.h b/src/gallium/state_trackers/dri/dri_drawable.h index 3a142144f44..e868a4189ca 100644 --- a/src/gallium/state_trackers/dri/dri_drawable.h +++ b/src/gallium/state_trackers/dri/dri_drawable.h @@ -56,6 +56,9 @@ struct dri_drawable unsigned old_w; unsigned old_h; + struct pipe_box *damage_rects; + unsigned int num_damage_rects; + struct pipe_resource *textures[ST_ATTACHMENT_COUNT]; struct pipe_resource *msaa_textures[ST_ATTACHMENT_COUNT]; unsigned int texture_mask, texture_stamp; |