From c5292710c4f999ac855478239c40d789e79b179f Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Wed, 30 Sep 2020 09:51:55 -0400 Subject: [PATCH] zink: handle PIPE_FLUSH_DEFERRED these flushes queue the fence to be submitted on the next finish call, so we have to store the context to the fence to be able to handle threaded calls Reviewed-by: Dave Airlie Part-of: --- src/gallium/drivers/zink/zink_batch.c | 2 +- src/gallium/drivers/zink/zink_context.c | 20 +++++++++++++------- src/gallium/drivers/zink/zink_fence.c | 12 ++++++++++-- src/gallium/drivers/zink/zink_fence.h | 5 ++++- 4 files changed, 28 insertions(+), 11 deletions(-) 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