freedreno: Workaround for UNSYNC+DISCARD_RANGE

Dead-cells (and perhaps others) does MapBufferRange(UNSYNC|DISCARD_RANGE)
to update single buffered VBOs every frame in the opening menu screen,
and because we were considering UNSYNC with higher priority than
DISCARD_RANGE, this would result in the game racing VBO updates between
binning and tile passes, causing visibility stream inconsistency between
the two passes, resulting in "tile flicker".

The letter of the gl spec implies this is undefined behavior (at least
to my reading of it).  But we already hand DISCARD_RANGE in the !UNSYNC
case, so just go down this path instead.  It means we could potentially
end up invalidating (and back-blit) in cases where the app really knows
what it is doing, but oh well.

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/4337
Signed-off-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9223>
This commit is contained in:
Rob Clark 2021-02-23 08:18:13 -08:00 committed by Marge Bot
parent dabec19b05
commit 9d03dc2537

View file

@ -729,6 +729,15 @@ fd_resource_transfer_map(struct pipe_context *pctx,
}
}
/* Sometimes games do silly things like MapBufferRange(UNSYNC|DISCARD_x)
* In this case, the the UNSYNC is a bit redundant, but the games rely
* on us rebinding/replacing the backing storage rather than going down
* the UNSYNC path (ie. honoring DISCARD_x first before UNSYNC). So
* since we handle DISCARD_RANGE inside the !UNSYNC path:
*/
if (usage & (PIPE_MAP_DISCARD_RANGE | PIPE_MAP_DISCARD_WHOLE_RESOURCE))
usage &= ~PIPE_MAP_UNSYNCHRONIZED;
if (ctx->in_shadow && !(usage & PIPE_MAP_READ))
usage |= PIPE_MAP_UNSYNCHRONIZED;