diff --git a/src/gallium/drivers/zink/zink_batch.c b/src/gallium/drivers/zink/zink_batch.c index 183c149c51d..a20c9a820a2 100644 --- a/src/gallium/drivers/zink/zink_batch.c +++ b/src/gallium/drivers/zink/zink_batch.c @@ -22,7 +22,7 @@ zink_reset_batch(struct zink_context *ctx, struct zink_batch *batch) // cmdbuf hasn't been submitted before if (batch->submitted) - zink_fence_finish(screen, batch->fence, PIPE_TIMEOUT_INFINITE); + zink_fence_finish(screen, &ctx->base, batch->fence, PIPE_TIMEOUT_INFINITE); zink_framebuffer_reference(screen, &batch->fb, NULL); set_foreach(batch->programs, entry) { diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index 53998f2d74a..2f075f5af7b 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -1349,20 +1349,26 @@ zink_flush(struct pipe_context *pctx, enum pipe_flush_flags flags) { struct zink_context *ctx = zink_context(pctx); - + bool deferred = flags & PIPE_FLUSH_DEFERRED; struct zink_batch *batch = zink_curr_batch(ctx); - if (batch->has_work) { + + if (deferred) + batch->fence->deferred_ctx = pctx; + else if (batch->has_work) { flush_batch(ctx); if (zink_screen(pctx->screen)->info.have_EXT_transform_feedback && ctx->num_so_targets) ctx->dirty_so_targets = true; } - if (pfence) - zink_fence_reference(zink_screen(pctx->screen), - (struct zink_fence **)pfence, - batch->fence); - + if (!pfence) + return; + if (deferred && !batch->has_work) { + batch = zink_prev_batch(ctx); + } + zink_fence_reference(zink_screen(pctx->screen), + (struct zink_fence **)pfence, + batch->fence); /* HACK: * For some strange reason, we need to finish before presenting, or else * we start rendering on top of the back-buffer for the next frame. This diff --git a/src/gallium/drivers/zink/zink_fence.c b/src/gallium/drivers/zink/zink_fence.c index 091ed4ae9a3..2e1408a5346 100644 --- a/src/gallium/drivers/zink/zink_fence.c +++ b/src/gallium/drivers/zink/zink_fence.c @@ -22,6 +22,7 @@ */ #include "zink_batch.h" +#include "zink_context.h" #include "zink_fence.h" #include "zink_query.h" @@ -84,6 +85,7 @@ zink_fence_init(struct zink_fence *fence, struct zink_batch *batch) pipe_resource_reference(&r, pres); util_dynarray_append(&fence->resources, struct pipe_resource*, pres); } + fence->deferred_ctx = NULL; fence->submitted = true; } @@ -114,9 +116,15 @@ fence_remove_resource_access(struct zink_fence *fence, struct zink_resource *res } bool -zink_fence_finish(struct zink_screen *screen, struct zink_fence *fence, +zink_fence_finish(struct zink_screen *screen, struct pipe_context *pctx, struct zink_fence *fence, uint64_t timeout_ns) { + if (pctx && fence->deferred_ctx == pctx) { + zink_curr_batch(zink_context(pctx))->has_work = true; + /* this must be the current batch */ + pctx->flush(pctx, NULL, 0); + } + if (!fence->submitted) return true; bool success; @@ -151,7 +159,7 @@ static bool fence_finish(struct pipe_screen *pscreen, struct pipe_context *pctx, struct pipe_fence_handle *pfence, uint64_t timeout_ns) { - return zink_fence_finish(zink_screen(pscreen), zink_fence(pfence), + return zink_fence_finish(zink_screen(pscreen), pctx, zink_fence(pfence), timeout_ns); } diff --git a/src/gallium/drivers/zink/zink_fence.h b/src/gallium/drivers/zink/zink_fence.h index c34259571ac..2a5334b82a9 100644 --- a/src/gallium/drivers/zink/zink_fence.h +++ b/src/gallium/drivers/zink/zink_fence.h @@ -29,7 +29,9 @@ #include +struct pipe_context; struct pipe_screen; +struct zink_context; struct zink_screen; struct zink_fence { @@ -38,6 +40,7 @@ struct zink_fence { VkFence fence; struct set *active_queries; /* zink_query objects which were active at some point in this batch */ struct util_dynarray resources; + struct pipe_context *deferred_ctx; bool submitted; }; @@ -58,7 +61,7 @@ zink_fence_reference(struct zink_screen *screen, struct zink_fence *fence); bool -zink_fence_finish(struct zink_screen *screen, struct zink_fence *fence, +zink_fence_finish(struct zink_screen *screen, struct pipe_context *pctx, struct zink_fence *fence, uint64_t timeout_ns); void