From 63e17ccc0a2ed5e762aedfa71d9133672e77aa24 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Thu, 9 May 2024 11:41:34 -0400 Subject: [PATCH] zink: rework sparse semaphore waits previously this reused the swapchain acquire array to add wait semaphores, but doing so failed to synchronize between successive API commits instead, track a single wait semaphore on the batch which can be updated/reused across all sparse operations, though this has the unfortunate side effect of synchronizing sparse binds for unrelated resources Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/10137 Part-of: --- src/gallium/drivers/zink/zink_batch.c | 12 ++++---- src/gallium/drivers/zink/zink_batch.h | 3 -- src/gallium/drivers/zink/zink_bo.c | 38 ++++++++++++------------- src/gallium/drivers/zink/zink_context.c | 10 ++----- src/gallium/drivers/zink/zink_types.h | 1 + 5 files changed, 29 insertions(+), 35 deletions(-) diff --git a/src/gallium/drivers/zink/zink_batch.c b/src/gallium/drivers/zink/zink_batch.c index 569ff3f830b..07c3ef0ed86 100644 --- a/src/gallium/drivers/zink/zink_batch.c +++ b/src/gallium/drivers/zink/zink_batch.c @@ -152,6 +152,7 @@ zink_reset_batch_state(struct zink_context *ctx, struct zink_batch_state *bs) bs->resource_size = 0; bs->signal_semaphore = VK_NULL_HANDLE; + bs->sparse_semaphore = VK_NULL_HANDLE; util_dynarray_clear(&bs->wait_semaphore_stages); bs->present = VK_NULL_HANDLE; @@ -649,6 +650,8 @@ submit_queue(void *data, void *gdata, int thread_index) /* first submit is just for acquire waits since they have a separate array */ for (unsigned i = 0; i < ARRAY_SIZE(si); i++) si[i].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + if (bs->sparse_semaphore) + util_dynarray_append(&ctx->bs->acquires, VkSemaphore, bs->sparse_semaphore); si[ZINK_SUBMIT_WAIT_ACQUIRE].waitSemaphoreCount = util_dynarray_num_elements(&bs->acquires, VkSemaphore); si[ZINK_SUBMIT_WAIT_ACQUIRE].pWaitSemaphores = bs->acquires.data; while (util_dynarray_num_elements(&bs->acquire_flags, VkPipelineStageFlags) < si[ZINK_SUBMIT_WAIT_ACQUIRE].waitSemaphoreCount) { @@ -781,6 +784,9 @@ submit_queue(void *data, void *gdata, int thread_index) } _mesa_set_clear(&bs->dmabuf_exports, NULL); + if (bs->sparse_semaphore) + (void)util_dynarray_pop(&ctx->bs->acquires, VkSemaphore); + bs->usage.submit_count++; end: cnd_broadcast(&bs->usage.flush); @@ -960,12 +966,6 @@ zink_batch_reference_resource_rw(struct zink_context *ctx, struct zink_resource zink_batch_resource_usage_set(ctx->bs, res, write, res->obj->is_buffer); } -void -zink_batch_add_wait_semaphore(struct zink_context *ctx, VkSemaphore sem) -{ - util_dynarray_append(&ctx->bs->acquires, VkSemaphore, sem); -} - static bool batch_ptr_add_usage(struct zink_context *ctx, struct set *s, void *ptr) { diff --git a/src/gallium/drivers/zink/zink_batch.h b/src/gallium/drivers/zink/zink_batch.h index aa24f163c8d..afa8c185fac 100644 --- a/src/gallium/drivers/zink/zink_batch.h +++ b/src/gallium/drivers/zink/zink_batch.h @@ -61,9 +61,6 @@ zink_start_batch(struct zink_context *ctx); void zink_end_batch(struct zink_context *ctx); -void -zink_batch_add_wait_semaphore(struct zink_context *ctx, VkSemaphore sem); - void zink_batch_reference_resource_rw(struct zink_context *ctx, struct zink_resource *res, diff --git a/src/gallium/drivers/zink/zink_bo.c b/src/gallium/drivers/zink/zink_bo.c index dde22193978..63456139959 100644 --- a/src/gallium/drivers/zink/zink_bo.c +++ b/src/gallium/drivers/zink/zink_bo.c @@ -831,12 +831,12 @@ buffer_bo_commit(struct zink_context *ctx, struct zink_resource *res, uint32_t o ok = false; goto out; } - if (cur_sem) - util_dynarray_append(&ctx->bs->tracked_semaphores, VkSemaphore, cur_sem); cur_sem = buffer_commit_single(screen, res, backing->bo, backing_start, (uint64_t)span_va_page * ZINK_SPARSE_BUFFER_PAGE_SIZE, (uint64_t)backing_size * ZINK_SPARSE_BUFFER_PAGE_SIZE, true, cur_sem); - if (!cur_sem) { + if (cur_sem) { + util_dynarray_append(&ctx->bs->tracked_semaphores, VkSemaphore, cur_sem); + } else { ok = sparse_backing_free(screen, bo, backing, backing_start, backing_size); assert(ok && "sufficient memory should already be allocated"); @@ -868,12 +868,12 @@ buffer_bo_commit(struct zink_context *ctx, struct zink_resource *res, uint32_t o } if (!done) { - if (cur_sem) - util_dynarray_append(&ctx->bs->tracked_semaphores, VkSemaphore, cur_sem); cur_sem = buffer_commit_single(screen, res, NULL, 0, (uint64_t)base_page * ZINK_SPARSE_BUFFER_PAGE_SIZE, (uint64_t)(end_va_page - base_page) * ZINK_SPARSE_BUFFER_PAGE_SIZE, false, cur_sem); - if (!cur_sem) { + if (cur_sem) { + util_dynarray_append(&ctx->bs->tracked_semaphores, VkSemaphore, cur_sem); + } else { ok = false; goto out; } @@ -972,7 +972,7 @@ zink_bo_commit(struct zink_context *ctx, struct zink_resource *res, unsigned lev bool ok = true; struct zink_screen *screen = zink_screen(ctx->base.screen); struct zink_bo *bo = res->obj->bo; - VkSemaphore cur_sem = VK_NULL_HANDLE; + VkSemaphore cur_sem = *sem; simple_mtx_lock(&screen->queue_lock); simple_mtx_lock(&bo->lock); @@ -1076,13 +1076,13 @@ zink_bo_commit(struct zink_context *ctx, struct zink_resource *res, unsigned lev } if (level >= res->sparse.imageMipTailFirstLod) { uint32_t offset = res->sparse.imageMipTailOffset; - if (cur_sem) - util_dynarray_append(&ctx->bs->tracked_semaphores, VkSemaphore, cur_sem); cur_sem = texture_commit_miptail(screen, res, backing[i]->bo, backing_start[i], offset, commit, cur_sem); - if (cur_sem) + if (cur_sem) { + util_dynarray_append(&ctx->bs->tracked_semaphores, VkSemaphore, cur_sem); res->obj->miptail_commits++; - else + } else { ok = false; + } goto out; } else { ibind[i].memory = backing[i]->bo->mem ? backing[i]->bo->mem : backing[i]->bo->u.slab.real->mem; @@ -1132,10 +1132,10 @@ zink_bo_commit(struct zink_context *ctx, struct zink_resource *res, unsigned lev assert(res->obj->miptail_commits); res->obj->miptail_commits--; if (!res->obj->miptail_commits) { + cur_sem = texture_commit_miptail(screen, res, NULL, 0, offset, commit, cur_sem); if (cur_sem) util_dynarray_append(&ctx->bs->tracked_semaphores, VkSemaphore, cur_sem); - cur_sem = texture_commit_miptail(screen, res, NULL, 0, offset, commit, cur_sem); - if (!cur_sem) + else ok = false; } goto out; @@ -1146,10 +1146,10 @@ zink_bo_commit(struct zink_context *ctx, struct zink_resource *res, unsigned lev } } if (i == ARRAY_SIZE(ibind)) { - if (cur_sem) - util_dynarray_append(&ctx->bs->tracked_semaphores, VkSemaphore, cur_sem); cur_sem = texture_commit_single(screen, res, ibind, ARRAY_SIZE(ibind), commit, cur_sem); - if (!cur_sem) { + if (cur_sem) { + util_dynarray_append(&ctx->bs->tracked_semaphores, VkSemaphore, cur_sem); + } else { for (unsigned s = 0; s < i; s++) { ok = sparse_backing_free(screen, backing[s]->bo, backing[s], backing_start[s], backing_size[s]); if (!ok) { @@ -1167,10 +1167,10 @@ zink_bo_commit(struct zink_context *ctx, struct zink_resource *res, unsigned lev } } if (commits_pending) { - if (cur_sem) - util_dynarray_append(&ctx->bs->tracked_semaphores, VkSemaphore, cur_sem); cur_sem = texture_commit_single(screen, res, ibind, i, commit, cur_sem); - if (!cur_sem) { + if (cur_sem) { + util_dynarray_append(&ctx->bs->tracked_semaphores, VkSemaphore, cur_sem); + } else { for (unsigned s = 0; s < i; s++) { ok = sparse_backing_free(screen, backing[s]->bo, backing[s], backing_start[s], backing_size[s]); if (!ok) { diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index 30cfe02038b..4fdac4468d0 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -4855,14 +4855,10 @@ zink_resource_commit(struct pipe_context *pctx, struct pipe_resource *pres, unsi if (zink_resource_has_unflushed_usage(res)) zink_flush_queue(ctx); - VkSemaphore sem = VK_NULL_HANDLE; - bool ret = zink_bo_commit(ctx, res, level, box, commit, &sem); + bool ret = zink_bo_commit(ctx, res, level, box, commit, &ctx->bs->sparse_semaphore); if (ret) { - if (sem) { - zink_batch_add_wait_semaphore(ctx, sem); - zink_batch_reference_resource_rw(ctx, res, true); - ctx->bs->has_work = true; - } + zink_batch_reference_resource_rw(ctx, res, true); + ctx->bs->has_work = true; } else { check_device_lost(ctx); } diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h index f36979f0a97..445973ce408 100644 --- a/src/gallium/drivers/zink/zink_types.h +++ b/src/gallium/drivers/zink/zink_types.h @@ -611,6 +611,7 @@ struct zink_batch_state { struct util_dynarray fd_wait_semaphores; //dmabuf wait semaphores struct util_dynarray fd_wait_semaphore_stages; //dmabuf wait semaphores struct util_dynarray tracked_semaphores; //semaphores which are just tracked + VkSemaphore sparse_semaphore; //current sparse wait semaphore struct util_dynarray fences; //zink_tc_fence refs simple_mtx_t ref_lock;