etnaviv: fix tile status interaction with write mappings

This fixes a longstanding bug in the interaction between TS and a write
mapping. The write does not update TS regardless of the way the update
is done. Update via etna_copy_resource would just set the target ts_valid
to false without actually writing back any dirty TS to the resource.
Writes via the CPU would update the resource, but keep ts_valid at true
even if the tile status may now not match the actually written tiles of
the resource anymore.

Fix this by writing back a dirty TS to the target resource if needed
before updating the level with the write data. Always invalidate TS,
even when the update is done by the CPU.

Cc: mesa-stable
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Reviewed-by: Christian Gmeiner <christian.gmeiner@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19846>
(cherry picked from commit 0fb813526e)
This commit is contained in:
Lucas Stach 2022-11-18 12:24:58 +01:00 committed by Dylan Baker
parent 39e9ea1419
commit 2e6fd24b7c
3 changed files with 11 additions and 2 deletions

View file

@ -2335,7 +2335,7 @@
"description": "etnaviv: fix tile status interaction with write mappings",
"nominated": true,
"nomination_type": 0,
"resolution": 0,
"resolution": 1,
"main_sha": null,
"because_sha": null
},

View file

@ -230,6 +230,7 @@ etna_copy_resource_box(struct pipe_context *pctx, struct pipe_resource *dst,
{
assert(src->format == dst->format);
assert(src->array_size == dst->array_size);
assert(!etna_resource_needs_flush(etna_resource(dst)));
struct pipe_blit_info blit = {};
blit.mask = util_format_get_mask(dst->format);

View file

@ -124,10 +124,17 @@ etna_transfer_unmap(struct pipe_context *pctx, struct pipe_transfer *ptrans)
etna_bo_cpu_fini(etna_resource(trans->rsc)->bo);
if (ptrans->usage & PIPE_MAP_WRITE) {
if (etna_resource_needs_flush(rsc)) {
if (ptrans->usage & PIPE_MAP_DISCARD_WHOLE_RESOURCE)
rsc->flush_seqno = rsc->seqno;
else
etna_copy_resource(pctx, &rsc->base, &rsc->base, 0, rsc->base.last_level);
}
if (trans->rsc) {
/* We have a temporary resource due to either tile status or
* tiling format. Write back the updated buffer contents.
* FIXME: we need to invalidate the tile status. */
*/
etna_copy_resource_box(pctx, ptrans->resource, trans->rsc, ptrans->level, &ptrans->box);
} else if (trans->staging) {
/* map buffer object */
@ -156,6 +163,7 @@ etna_transfer_unmap(struct pipe_context *pctx, struct pipe_transfer *ptrans)
FREE(trans->staging);
}
rsc->levels[ptrans->level].ts_valid = false;
rsc->seqno++;
if (rsc->base.bind & PIPE_BIND_SAMPLER_VIEW) {