diff --git a/src/gallium/drivers/freedreno/freedreno_context.c b/src/gallium/drivers/freedreno/freedreno_context.c index 1ce2a1148bc..1c7dbfc5d6d 100644 --- a/src/gallium/drivers/freedreno/freedreno_context.c +++ b/src/gallium/drivers/freedreno/freedreno_context.c @@ -77,11 +77,15 @@ fd_context_flush(struct pipe_context *pctx, struct pipe_fence_handle **fencep, fd_fence_set_batch(*fencep, batch); fd_fence_ref(&batch->fence, *fencep); - /* We (a) cannot substitute the provided fence with last_fence, - * and (b) need fd_fence_populate() to be eventually called on - * the fence that was pre-created in frontend-thread: + /* If we have nothing to flush, update the pre-created unflushed + * fence with the current state of the last-fence: */ - fd_fence_ref(&ctx->last_fence, NULL); + if (ctx->last_fence) { + fd_fence_repopulate(*fencep, ctx->last_fence); + fd_fence_ref(&fence, *fencep); + fd_bc_dump(ctx->screen, "%p: (deferred) reuse last_fence, remaining:\n", ctx); + goto out; + } /* async flush is not compatible with deferred flush, since * nothing triggers the batch flush which fence_flush() would diff --git a/src/gallium/drivers/freedreno/freedreno_fence.c b/src/gallium/drivers/freedreno/freedreno_fence.c index dbd58f6da6d..c8f4e3a02f5 100644 --- a/src/gallium/drivers/freedreno/freedreno_fence.c +++ b/src/gallium/drivers/freedreno/freedreno_fence.c @@ -129,6 +129,13 @@ fd_fence_populate(struct pipe_fence_handle *fence, uint32_t timestamp, } } +void +fd_fence_repopulate(struct pipe_fence_handle *fence, struct pipe_fence_handle *last_fence) +{ + int fence_fd = (last_fence->fence_fd == -1) ? -1 : dup(last_fence->fence_fd); + fd_fence_populate(fence, last_fence->timestamp, fence_fd); +} + static void fd_fence_destroy(struct pipe_fence_handle *fence) { diff --git a/src/gallium/drivers/freedreno/freedreno_fence.h b/src/gallium/drivers/freedreno/freedreno_fence.h index 75399961eb1..c359f0999a3 100644 --- a/src/gallium/drivers/freedreno/freedreno_fence.h +++ b/src/gallium/drivers/freedreno/freedreno_fence.h @@ -31,6 +31,8 @@ void fd_fence_populate(struct pipe_fence_handle *fence, uint32_t timestamp, int fence_fd); +void fd_fence_repopulate(struct pipe_fence_handle *fence, + struct pipe_fence_handle *last_fence); void fd_fence_ref(struct pipe_fence_handle **ptr, struct pipe_fence_handle *pfence); bool fd_fence_finish(struct pipe_screen *pscreen, struct pipe_context *ctx,