Module: Mesa
Branch: main
Commit: 846a5ea2244ca365555a20cb8af8ccee850ba0b6
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=846a5ea2244ca365555a20cb8af8ccee850ba0b6

Author: Mike Blumenkrantz <[email protected]>
Date:   Mon Oct 16 12:05:37 2023 -0400

zink: add locking for batch refs

this is needed to handle unsynchronized access

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25624>

---

 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

Reply via email to