zink: enforce multi-context waiting for unflushed resources on foreign batches
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>
Thu, 17 Jun 2021 01:32:14 +0000 (21:32 -0400)
committerMarge Bot <eric+marge@anholt.net>
Tue, 22 Jun 2021 20:57:33 +0000 (20:57 +0000)
this doesn't seem to be a real issue now that tc doesn't break makeCurrent
anymore, but if such a thing were to once again become a problem, at least
there will be handling for it

Acked-by: Dave Airlie <airlied@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11437>

src/gallium/drivers/zink/zink_batch.c
src/gallium/drivers/zink/zink_batch.h
src/gallium/drivers/zink/zink_resource.c

index 705cd53..3fb4cc6 100644 (file)
@@ -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);
 }
index 8df4385..04827bf 100644 (file)
@@ -46,6 +46,8 @@ struct zink_surface;
 
 struct zink_batch_usage {
    uint32_t usage;
+   cnd_t flush;
+   mtx_t mtx;
    bool unflushed;
 };
 
index fc60c76..8c4ffe3 100644 (file)
@@ -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);