freedreno/fence: Hold a strong ref to batch

We don't want a unflushed fence to outlive it's batch, otherwise we run
into trouble when it comes time to wait on the fence.  For ex:

1. Create a fence before framebuffer state is set, with the
   PIPE_FLUSH_DEFERRED flags.  This creates a new batch, to which the
   ctx holds the only reference (unless the fence also holds a ref)
2. set_framebuffer_state() creates a new batch and drops the ctx->batch
   reference.
3. Later something tries to wait on the fence

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/8621
Signed-off-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25337>
This commit is contained in:
Rob Clark 2023-09-21 14:27:44 -07:00 committed by Marge Bot
parent 86f5077538
commit 9510af0f60
2 changed files with 4 additions and 4 deletions

View file

@ -289,10 +289,10 @@ fd_pipe_fence_set_batch(struct pipe_fence_handle *fence, struct fd_batch *batch)
{
if (batch) {
assert(!fence->batch);
fence->batch = batch;
fd_batch_reference(&fence->batch, batch);
fd_batch_needs_flush(batch);
} else {
fence->batch = NULL;
fd_batch_reference(&fence->batch, NULL);
/* When the batch is dis-associated with the fence, we can signal TC
* that the fence is flushed

View file

@ -44,13 +44,13 @@ struct pipe_fence_handle {
*/
struct pipe_fence_handle *last_fence;
/* fence holds a weak reference to the batch until the batch is flushed, to
/* fence holds a reference to the batch until the batch is flushed, to
* accommodate PIPE_FLUSH_DEFERRED. When the batch is actually flushed, it
* is cleared (before the batch reference is dropped). If we need to wait
* on a fence, and the batch is not NULL, we need to flush it.
*
* Note that with u_threaded_context async flushes, if a fence is requested
* by the frontend, the fence is initially created without a weak reference
* by the frontend, the fence is initially created without a reference
* to the batch, which is filled in later when fd_context_flush() is called
* from the driver thread. In this case tc_token will be non-null, in
* which case threaded_context_flush() should be called in fd_fence_finish()