Module: Mesa Branch: main Commit: 982a2dfbd4a45cfed50e4f7f77702eb27b4f866f URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=982a2dfbd4a45cfed50e4f7f77702eb27b4f866f
Author: Mike Blumenkrantz <[email protected]> Date: Fri May 7 08:39:27 2021 -0400 zink: improve tc fence disambiguation instead of storing separate batch_id values onto the tc fence for matching: * use a fence pointer on the main context to indicate the current deferred fence * add a monotonic counter to each batch state which double-increments on each use, thereby enabling direct determination by the tc fence as to whether this is the same batch state it was created with Acked-by: Dave Airlie <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11437> --- src/gallium/drivers/zink/zink_batch.c | 2 ++ src/gallium/drivers/zink/zink_batch.h | 3 +++ src/gallium/drivers/zink/zink_context.c | 11 ++++++++--- src/gallium/drivers/zink/zink_context.h | 1 + src/gallium/drivers/zink/zink_fence.c | 26 +++++++++++++++----------- src/gallium/drivers/zink/zink_fence.h | 5 ++--- 6 files changed, 31 insertions(+), 17 deletions(-) diff --git a/src/gallium/drivers/zink/zink_batch.c b/src/gallium/drivers/zink/zink_batch.c index b890c4df7c3..deb17fc868c 100644 --- a/src/gallium/drivers/zink/zink_batch.c +++ b/src/gallium/drivers/zink/zink_batch.c @@ -93,6 +93,7 @@ zink_reset_batch_state(struct zink_context *ctx, struct zink_batch_state *bs) bs->has_barriers = false; if (bs->fence.batch_id) zink_screen_update_last_finished(screen, bs->fence.batch_id); + bs->submit_count++; bs->fence.batch_id = 0; bs->draw_count = bs->compute_count = 0; } @@ -353,6 +354,7 @@ submit_queue(void *data, void *gdata, int thread_index) debug_printf("ZINK: vkQueueSubmit() failed\n"); bs->is_device_lost = true; } + bs->submit_count++; p_atomic_set(&bs->fence.submitted, true); } diff --git a/src/gallium/drivers/zink/zink_batch.h b/src/gallium/drivers/zink/zink_batch.h index 9b4057e3199..ebba92c0f3b 100644 --- a/src/gallium/drivers/zink/zink_batch.h +++ b/src/gallium/drivers/zink/zink_batch.h @@ -86,6 +86,9 @@ struct zink_batch_state { VkDeviceSize resource_size; + /* this is a monotonic int used to disambiguate internal fences from their tc fence references */ + unsigned submit_count; + bool is_device_lost; bool have_timelines; bool has_barriers; diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index 087df64418b..377cfd0cc14 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -1796,6 +1796,7 @@ flush_batch(struct zink_context *ctx, bool sync) zink_begin_render_pass(ctx, batch); zink_end_render_pass(ctx, batch); zink_end_batch(ctx, batch); + ctx->deferred_fence = NULL; if (sync) sync_flush(ctx, ctx->batch.state); @@ -2388,6 +2389,7 @@ zink_flush(struct pipe_context *pctx, struct zink_batch *batch = &ctx->batch; struct zink_fence *fence = NULL; struct zink_screen *screen = zink_screen(ctx->base.screen); + unsigned submit_count = 0; /* triggering clears will force has_work */ if (!deferred && ctx->clears_enabled) @@ -2410,6 +2412,7 @@ zink_flush(struct pipe_context *pctx, tc_driver_internal_flush_notify(ctx->tc); } else { fence = &batch->state->fence; + submit_count = batch->state->submit_count; if (deferred && !(flags & PIPE_FLUSH_FENCE_FD) && pfence) deferred_fence = true; else @@ -2429,15 +2432,17 @@ zink_flush(struct pipe_context *pctx, *pfence = (struct pipe_fence_handle *)mfence; } - zink_batch_state_reference(screen, NULL, zink_batch_state(fence)); + struct zink_batch_state *bs = zink_batch_state(fence); + zink_batch_state_reference(screen, NULL, bs); mfence->fence = fence; if (fence) - mfence->batch_id = fence->batch_id; + mfence->submit_count = submit_count; if (deferred_fence) { assert(fence); mfence->deferred_ctx = pctx; - mfence->deferred_id = fence->batch_id; + assert(!ctx->deferred_fence || ctx->deferred_fence == fence); + ctx->deferred_fence = fence; } if (!fence || flags & TC_FLUSH_ASYNC) { diff --git a/src/gallium/drivers/zink/zink_context.h b/src/gallium/drivers/zink/zink_context.h index 57a72e0b6c4..fb5e08faac8 100644 --- a/src/gallium/drivers/zink/zink_context.h +++ b/src/gallium/drivers/zink/zink_context.h @@ -147,6 +147,7 @@ struct zink_context { uint32_t curr_batch; //the current batch id struct zink_batch batch; simple_mtx_t batch_mtx; + struct zink_fence *deferred_fence; struct zink_fence *last_fence; //the last command buffer submitted struct hash_table batch_states; //submitted batch states struct util_dynarray free_batch_states; //unused batch states diff --git a/src/gallium/drivers/zink/zink_fence.c b/src/gallium/drivers/zink/zink_fence.c index aeddfae8e31..338ffcdf217 100644 --- a/src/gallium/drivers/zink/zink_fence.c +++ b/src/gallium/drivers/zink/zink_fence.c @@ -175,30 +175,34 @@ zink_fence_finish(struct zink_screen *screen, struct pipe_context *pctx, struct return true; if (pctx && mfence->deferred_ctx == pctx) { - if (mfence->deferred_id == ctx->curr_batch) { + if (mfence->fence == ctx->deferred_fence) { zink_context(pctx)->batch.has_work = true; /* this must be the current batch */ pctx->flush(pctx, NULL, !timeout_ns ? PIPE_FLUSH_ASYNC : 0); if (!timeout_ns) return false; } - /* this batch is known to have finished */ - if (mfence->deferred_id <= screen->last_finished) - return true; } /* need to ensure the tc mfence has been flushed before we wait */ bool tc_finish = tc_fence_finish(ctx, mfence, &timeout_ns); - struct zink_fence *fence = mfence->fence; - if (!tc_finish || (fence && !fence->submitted)) - return zink_screen_check_last_finished(screen, mfence->batch_id) ? true : - (fence ? p_atomic_read(&fence->completed) : false); - + /* the submit thread hasn't finished yet */ + if (!tc_finish) + return false; /* this was an invalid flush, just return completed */ if (!mfence->fence) return true; - /* if the zink fence has a different batch id then it must have completed and been recycled already */ - if (mfence->fence->batch_id != mfence->batch_id) + + struct zink_fence *fence = mfence->fence; + + unsigned submit_diff = zink_batch_state(mfence->fence)->submit_count - mfence->submit_count; + /* this batch is known to have finished because it has been submitted more than 1 time + * since the tc fence last saw it + */ + if (submit_diff > 1) + return true; + + if (fence->submitted && zink_screen_check_last_finished(screen, fence->batch_id)) return true; return zink_vkfence_wait(screen, fence, timeout_ns); diff --git a/src/gallium/drivers/zink/zink_fence.h b/src/gallium/drivers/zink/zink_fence.h index 5c7fa4d4562..876788e141e 100644 --- a/src/gallium/drivers/zink/zink_fence.h +++ b/src/gallium/drivers/zink/zink_fence.h @@ -41,10 +41,9 @@ struct tc_unflushed_batch_token; struct zink_tc_fence { struct pipe_reference reference; - uint32_t deferred_id; - struct tc_unflushed_batch_token *tc_token; + uint32_t submit_count; struct util_queue_fence ready; - uint32_t batch_id; + struct tc_unflushed_batch_token *tc_token; struct pipe_context *deferred_ctx; struct zink_fence *fence; }; _______________________________________________ mesa-commit mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-commit
