zink: track last completed batch id to optimize checking states

Acked-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9963>
This commit is contained in:
Mike Blumenkrantz 2020-12-29 12:10:08 -05:00 committed by Marge Bot
parent 122d01e73a
commit a4e34f40a3
4 changed files with 40 additions and 0 deletions

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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)
{