diff --git a/src/gallium/drivers/zink/zink_batch.c b/src/gallium/drivers/zink/zink_batch.c index 705cd53be4f..3fb4cc6eabd 100644 --- a/src/gallium/drivers/zink/zink_batch.c +++ b/src/gallium/drivers/zink/zink_batch.c @@ -128,6 +128,9 @@ zink_batch_state_destroy(struct zink_screen *screen, struct zink_batch_state *bs util_queue_fence_destroy(&bs->flush_completed); + cnd_destroy(&bs->usage.flush); + mtx_destroy(&bs->usage.mtx); + if (bs->fence.fence) vkDestroyFence(screen->dev, bs->fence.fence, NULL); @@ -191,6 +194,9 @@ create_batch_state(struct zink_context *ctx) util_dynarray_init(&bs->zombie_samplers, NULL); util_dynarray_init(&bs->persistent_resources, NULL); + cnd_init(&bs->usage.flush); + mtx_init(&bs->usage.mtx, mtx_plain); + if (!screen->batch_descriptor_init(screen, bs)) goto fail; @@ -369,6 +375,8 @@ submit_queue(void *data, void *gdata, int thread_index) bs->is_device_lost = true; } bs->submit_count++; + cnd_broadcast(&bs->usage.flush); + p_atomic_set(&bs->fence.submitted, true); } @@ -682,5 +690,14 @@ zink_batch_usage_wait(struct zink_context *ctx, struct zink_batch_usage *u) { if (!zink_batch_usage_exists(u)) return; + if (zink_batch_usage_is_unflushed(u)) { + if (likely(u == &ctx->batch.state->usage)) + ctx->base.flush(&ctx->base, NULL, PIPE_FLUSH_HINT_FINISH); + else { //multi-context + mtx_lock(&u->mtx); + cnd_wait(&u->flush, &u->mtx); + mtx_unlock(&u->mtx); + } + } zink_wait_on_batch(ctx, u->usage); } diff --git a/src/gallium/drivers/zink/zink_batch.h b/src/gallium/drivers/zink/zink_batch.h index 8df4385fa38..04827bfb7e5 100644 --- a/src/gallium/drivers/zink/zink_batch.h +++ b/src/gallium/drivers/zink/zink_batch.h @@ -46,6 +46,8 @@ struct zink_surface; struct zink_batch_usage { uint32_t usage; + cnd_t flush; + mtx_t mtx; bool unflushed; }; diff --git a/src/gallium/drivers/zink/zink_resource.c b/src/gallium/drivers/zink/zink_resource.c index fc60c7690b5..8c4ffe3efa5 100644 --- a/src/gallium/drivers/zink/zink_resource.c +++ b/src/gallium/drivers/zink/zink_resource.c @@ -1025,6 +1025,9 @@ zink_transfer_map(struct pipe_context *pctx, struct zink_resource *staging_res = zink_resource(trans->staging_res); if (usage & PIPE_MAP_READ) { + /* force multi-context sync */ + if (zink_batch_usage_is_unflushed(res->obj->writes)) + zink_batch_usage_wait(ctx, res->obj->writes); zink_transfer_copy_bufimage(ctx, staging_res, res, trans); /* need to wait for rendering to finish */ zink_fence_wait(pctx);