diff options
author | Boris Brezillon <[email protected]> | 2019-11-09 00:02:54 +0100 |
---|---|---|
committer | Boris Brezillon <[email protected]> | 2019-11-29 10:20:29 +0100 |
commit | b196e1a8cfbd2c6b53f688542bcda5bb8f7f8888 (patch) | |
tree | 7d0488a1b62ddd5d21edfc262f6e393f10c7f7f8 | |
parent | 5fcb503c730e556714cc395f8c6ab76bc3acd179 (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 <[email protected]>
Fixes: 492ffbed63a2 ("st/dri2: Implement DRI2bufferDamageExtension")
Cc: <[email protected]>
Signed-off-by: Boris Brezillon <[email protected]>
Reviewed-by: Marek Olšák <[email protected]>
-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 620a972917a..d62cf89f737 100644 --- a/src/gallium/state_trackers/dri/dri2.c +++ b/src/gallium/state_trackers/dri/dri2.c @@ -1879,8 +1879,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) { @@ -1894,8 +1892,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 4b0ba5f6719..88eb6c01c1b 100644 --- a/src/gallium/state_trackers/dri/dri_drawable.c +++ b/src/gallium/state_trackers/dri/dri_drawable.c @@ -92,6 +92,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; @@ -197,6 +209,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 05c82056697..d57ff1d84e0 100644 --- a/src/gallium/state_trackers/dri/dri_drawable.h +++ b/src/gallium/state_trackers/dri/dri_drawable.h @@ -52,6 +52,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; |