From 846a5ea2244ca365555a20cb8af8ccee850ba0b6 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Mon, 16 Oct 2023 12:05:37 -0400 Subject: [PATCH] zink: add locking for batch refs this is needed to handle unsynchronized access Part-of: --- src/gallium/drivers/zink/zink_batch.c | 15 ++++++++++++--- src/gallium/drivers/zink/zink_context.c | 1 + src/gallium/drivers/zink/zink_types.h | 2 ++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/gallium/drivers/zink/zink_batch.c b/src/gallium/drivers/zink/zink_batch.c index 5051161fd5b..ff41e305edd 100644 --- a/src/gallium/drivers/zink/zink_batch.c +++ b/src/gallium/drivers/zink/zink_batch.c @@ -937,23 +937,29 @@ zink_batch_reference_resource_move(struct zink_batch *batch, struct zink_resourc { struct zink_batch_state *bs = batch->state; + simple_mtx_lock(&batch->ref_lock); /* swapchains are special */ if (zink_is_swapchain(res)) { struct zink_resource_object **swapchains = bs->swapchain_obj.data; unsigned count = util_dynarray_num_elements(&bs->swapchain_obj, struct zink_resource_object*); for (unsigned i = 0; i < count; i++) { - if (swapchains[i] == res->obj) + if (swapchains[i] == res->obj) { + simple_mtx_unlock(&batch->ref_lock); return true; + } } util_dynarray_append(&bs->swapchain_obj, struct zink_resource_object*, res->obj); + simple_mtx_unlock(&batch->ref_lock); return false; } /* Fast exit for no-op calls. * This is very effective with suballocators and linear uploaders that * are outside of the winsys. */ - if (res->obj == bs->last_added_obj) + if (res->obj == bs->last_added_obj) { + simple_mtx_unlock(&batch->ref_lock); return true; + } struct zink_bo *bo = res->obj->bo; struct zink_batch_obj_list *list; @@ -967,8 +973,10 @@ zink_batch_reference_resource_move(struct zink_batch *batch, struct zink_resourc list = &bs->sparse_objs; } int idx = batch_find_resource(bs, res->obj, list); - if (idx >= 0) + if (idx >= 0) { + simple_mtx_unlock(&batch->ref_lock); return true; + } if (list->num_buffers >= list->max_buffers) { unsigned new_max = MAX2(list->max_buffers + 16, (unsigned)(list->max_buffers * 1.3)); @@ -993,6 +1001,7 @@ zink_batch_reference_resource_move(struct zink_batch *batch, struct zink_resourc } check_oom_flush(batch->state->ctx, batch); batch->has_work = true; + simple_mtx_unlock(&batch->ref_lock); return false; } diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index e76259aa5c3..6a282be0670 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -5441,6 +5441,7 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) } } + simple_mtx_init(&ctx->batch.ref_lock, mtx_plain); zink_start_batch(ctx, &ctx->batch); if (!ctx->batch.state) goto fail; diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h index 1c2979fed5f..f05ed5ac91c 100644 --- a/src/gallium/drivers/zink/zink_types.h +++ b/src/gallium/drivers/zink/zink_types.h @@ -675,6 +675,8 @@ struct zink_batch { unsigned work_count; + simple_mtx_t ref_lock; + bool has_work; bool last_was_compute; bool in_rp; //renderpass is currently active