diff --git a/src/gallium/drivers/zink/zink_resource.c b/src/gallium/drivers/zink/zink_resource.c index d03babee456..9fc0161684b 100644 --- a/src/gallium/drivers/zink/zink_resource.c +++ b/src/gallium/drivers/zink/zink_resource.c @@ -676,13 +676,31 @@ zink_transfer_map(struct pipe_context *pctx, } static void -zink_transfer_flush_region(struct pipe_context *ctx, +zink_transfer_flush_region(struct pipe_context *pctx, struct pipe_transfer *ptrans, const struct pipe_box *box) { + struct zink_context *ctx = zink_context(pctx); struct zink_resource *res = zink_resource(ptrans->resource); - if (res->base.target == PIPE_BUFFER) - util_range_add(&res->base, &res->valid_buffer_range, box->x, box->x + box->width); + struct zink_transfer *trans = (struct zink_transfer *)ptrans; + + if (trans->base.usage & PIPE_MAP_WRITE) { + if (trans->staging_res) { + uint32_t batch_uses = zink_get_resource_usage(res); + if (batch_uses & (ZINK_RESOURCE_ACCESS_WRITE << ZINK_COMPUTE_BATCH_ID)) { + zink_wait_on_batch(ctx, ZINK_COMPUTE_BATCH_ID); + batch_uses &= ~(ZINK_RESOURCE_ACCESS_WRITE << ZINK_COMPUTE_BATCH_ID); + batch_uses &= ~(ZINK_RESOURCE_ACCESS_READ << ZINK_COMPUTE_BATCH_ID); + } + + struct zink_resource *staging_res = zink_resource(trans->staging_res); + zink_transfer_copy_bufimage(ctx, res, staging_res, trans, true); + if (batch_uses) + pctx->flush(pctx, NULL, 0); + } + if (res->base.target == PIPE_BUFFER) + util_range_add(&res->base, &res->valid_buffer_range, box->x, box->x + box->width); + } } static void @@ -696,19 +714,6 @@ zink_transfer_unmap(struct pipe_context *pctx, if (trans->staging_res) { struct zink_resource *staging_res = zink_resource(trans->staging_res); vkUnmapMemory(screen->dev, staging_res->mem); - - if (trans->base.usage & PIPE_MAP_WRITE) { - struct zink_context *ctx = zink_context(pctx); - uint32_t batch_uses = zink_get_resource_usage(res); - if (batch_uses >= ZINK_RESOURCE_ACCESS_WRITE) { - if (batch_uses & (ZINK_RESOURCE_ACCESS_WRITE << ZINK_COMPUTE_BATCH_ID)) - zink_wait_on_batch(ctx, ZINK_COMPUTE_BATCH_ID); - zink_fence_wait(pctx); - } - zink_transfer_copy_bufimage(ctx, res, staging_res, trans, true); - } - - pipe_resource_reference(&trans->staging_res, NULL); } else vkUnmapMemory(screen->dev, res->mem); if ((trans->base.usage & PIPE_MAP_PERSISTENT) && !(trans->base.usage & PIPE_MAP_COHERENT)) @@ -716,6 +721,9 @@ zink_transfer_unmap(struct pipe_context *pctx, if (!(trans->base.usage & (PIPE_MAP_FLUSH_EXPLICIT | PIPE_MAP_COHERENT))) { zink_transfer_flush_region(pctx, ptrans, &ptrans->box); } + + if (trans->staging_res) + pipe_resource_reference(&trans->staging_res, NULL); pipe_resource_reference(&trans->base.resource, NULL); slab_free(&ctx->transfer_pool, ptrans); }