zink: enforce multi-context waiting for unflushed resources on foreign batches

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>
This commit is contained in:
Mike Blumenkrantz 2021-06-16 21:32:14 -04:00 committed by Marge Bot
parent ef418cfc59
commit d4159963e3
3 changed files with 22 additions and 0 deletions

View 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);
}

View file

@ -46,6 +46,8 @@ struct zink_surface;
struct zink_batch_usage {
uint32_t usage;
cnd_t flush;
mtx_t mtx;
bool unflushed;
};

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