From a4e34f40a3053bf7570eed26efd55d31a10041e6 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Tue, 29 Dec 2020 12:10:08 -0500 Subject: [PATCH] zink: track last completed batch id to optimize checking states Acked-by: Erik Faye-Lund Part-of: --- src/gallium/drivers/zink/zink_batch.c | 1 + src/gallium/drivers/zink/zink_context.c | 2 ++ src/gallium/drivers/zink/zink_fence.c | 1 + src/gallium/drivers/zink/zink_screen.h | 36 +++++++++++++++++++++++++ 4 files changed, 40 insertions(+) diff --git a/src/gallium/drivers/zink/zink_batch.c b/src/gallium/drivers/zink/zink_batch.c index 9a399e1888f..6e01b9162b3 100644 --- a/src/gallium/drivers/zink/zink_batch.c +++ b/src/gallium/drivers/zink/zink_batch.c @@ -97,6 +97,7 @@ zink_reset_batch_state(struct zink_context *ctx, struct zink_batch_state *bs) * before the state is reused */ bs->fence.submitted = false; + zink_screen_update_last_finished(screen, bs->fence.batch_id); bs->fence.batch_id = 0; } diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index 4d40a05cf1e..ba78cf37cb3 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -2042,6 +2042,8 @@ zink_check_batch_completion(struct zink_context *ctx, uint32_t batch_id) /* not submitted yet */ return false; + if (zink_screen_check_last_finished(zink_screen(ctx->base.screen), batch_id)) + return true; struct zink_fence *fence; simple_mtx_lock(&ctx->batch_mtx); diff --git a/src/gallium/drivers/zink/zink_fence.c b/src/gallium/drivers/zink/zink_fence.c index 4f5a097f486..515edf456e0 100644 --- a/src/gallium/drivers/zink/zink_fence.c +++ b/src/gallium/drivers/zink/zink_fence.c @@ -156,6 +156,7 @@ zink_vkfence_wait(struct zink_screen *screen, struct zink_fence *fence, uint64_t if (success) { p_atomic_set(&fence->completed, true); zink_fence_clear_resources(screen, fence); + zink_screen_update_last_finished(screen, fence->batch_id); } return success; } diff --git a/src/gallium/drivers/zink/zink_screen.h b/src/gallium/drivers/zink/zink_screen.h index d8677404428..d44415a5fe1 100644 --- a/src/gallium/drivers/zink/zink_screen.h +++ b/src/gallium/drivers/zink/zink_screen.h @@ -53,6 +53,7 @@ struct zink_screen { struct pipe_screen base; bool threaded; uint32_t curr_batch; //the current batch id + uint32_t last_finished; //this is racy but ultimately doesn't matter struct sw_winsys *winsys; @@ -148,6 +149,41 @@ struct zink_screen { } null_descriptor_hashes; }; + +/* update last_finished to account for batch_id wrapping */ +static inline void +zink_screen_update_last_finished(struct zink_screen *screen, uint32_t batch_id) +{ + /* last_finished may have wrapped */ + if (screen->last_finished < UINT_MAX / 2) { + /* last_finished has wrapped, batch_id has not */ + if (batch_id > UINT_MAX / 2) + return; + } else if (batch_id < UINT_MAX / 2) { + /* batch_id has wrapped, last_finished has not */ + screen->last_finished = batch_id; + return; + } + /* neither have wrapped */ + screen->last_finished = MAX2(batch_id, screen->last_finished); +} + +/* check a batch_id against last_finished while accounting for wrapping */ +static inline bool +zink_screen_check_last_finished(struct zink_screen *screen, uint32_t batch_id) +{ + /* last_finished may have wrapped */ + if (screen->last_finished < UINT_MAX / 2) { + /* last_finished has wrapped, batch_id has not */ + if (batch_id > UINT_MAX / 2) + return true; + } else if (batch_id < UINT_MAX / 2) { + /* batch_id has wrapped, last_finished has not */ + return false; + } + return screen->last_finished >= batch_id; +} + static inline struct zink_screen * zink_screen(struct pipe_screen *pipe) {