summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>2023-05-11 09:29:34 -0400
committerMarge Bot <emma+marge@anholt.net>2023-05-16 00:54:46 +0000
commit47d9eaa0f1b9bf4215e15bcf446a35a1bd4c0215 (patch)
treecf381f2371949606c89d41aa4488ee8ee0db9c92
parent7ce82f1dec8b6a6beb7d541258015fecc380b742 (diff)
downloadmesa-47d9eaa0f1b9bf4215e15bcf446a35a1bd4c0215.tar.gz
zink: flag batch usage on swapchain images
while swapchains themselves are protected against early deletion during presentation, there is nothing protecting them from deletion while they are rendering if a swapchain updates while rendering but before presentation to address this, add batch usage to swapchains which can be checked during pruning to ensure a rendering swapchain isn't pruned Fixes: dc8c9d20568 ("zink: prune old swapchains on present") Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22962>
-rw-r--r--src/gallium/drivers/zink/zink_batch.c2
-rw-r--r--src/gallium/drivers/zink/zink_kopper.c30
-rw-r--r--src/gallium/drivers/zink/zink_kopper.h5
3 files changed, 36 insertions, 1 deletions
diff --git a/src/gallium/drivers/zink/zink_batch.c b/src/gallium/drivers/zink/zink_batch.c
index c7299ab3f31..3ba9017bc80 100644
--- a/src/gallium/drivers/zink/zink_batch.c
+++ b/src/gallium/drivers/zink/zink_batch.c
@@ -48,6 +48,8 @@ reset_obj(struct zink_screen *screen, struct zink_batch_state *bs, struct zink_r
obj->view_prune_count = 0;
obj->view_prune_timeline = 0;
simple_mtx_unlock(&obj->view_lock);
+ if (obj->dt)
+ zink_kopper_prune_batch_usage(obj->dt, &bs->usage);
} else if (util_dynarray_num_elements(&obj->views, VkBufferView) > MAX_VIEW_COUNT && !zink_bo_has_unflushed_usage(obj->bo)) {
/* avoid ballooning from too many views on always-used resources: */
simple_mtx_lock(&obj->view_lock);
diff --git a/src/gallium/drivers/zink/zink_kopper.c b/src/gallium/drivers/zink/zink_kopper.c
index 24244be81b5..cc946f1ad47 100644
--- a/src/gallium/drivers/zink/zink_kopper.c
+++ b/src/gallium/drivers/zink/zink_kopper.c
@@ -174,6 +174,15 @@ prune_old_swapchains(struct zink_screen *screen, struct kopper_displaytarget *cd
continue;
return;
}
+ struct zink_batch_usage *u = cswap->batch_uses;
+ if (!zink_screen_usage_check_completion(screen, u)) {
+ /* these can't ever be pruned */
+ if (!wait || zink_batch_usage_is_unflushed(u))
+ return;
+
+ zink_screen_timeline_wait(screen, u->usage, UINT64_MAX);
+ cswap->batch_uses = NULL;
+ }
cdt->old_swapchain = cswap->next;
destroy_swapchain(screen, cswap);
}
@@ -601,7 +610,9 @@ zink_kopper_acquire(struct zink_context *ctx, struct zink_resource *res, uint64_
} else if (is_swapchain_kill(ret)) {
kill_swapchain(ctx, res);
}
- return !is_swapchain_kill(ret);
+ bool is_kill = is_swapchain_kill(ret);
+ zink_batch_usage_set(&cdt->swapchain->batch_uses, ctx->batch.state);
+ return !is_kill;
}
VkSemaphore
@@ -836,6 +847,7 @@ zink_kopper_acquire_readback(struct zink_context *ctx, struct zink_resource *res
res->base.b.width0 = ctx->swapchain_size.width;
res->base.b.height0 = ctx->swapchain_size.height;
}
+ zink_batch_usage_set(&cdt->swapchain->batch_uses, ctx->batch.state);
return true;
}
@@ -986,3 +998,19 @@ zink_kopper_query_buffer_age(struct pipe_context *pctx, struct pipe_resource *pr
return cdt->swapchain->images[res->obj->dt_idx].age;
}
+
+static void
+swapchain_prune_batch_usage(struct kopper_swapchain *cswap, const struct zink_batch_usage *u)
+{
+ if (cswap->batch_uses == u)
+ cswap->batch_uses = NULL;
+}
+
+void
+zink_kopper_prune_batch_usage(struct kopper_displaytarget *cdt, const struct zink_batch_usage *u)
+{
+ struct kopper_swapchain *cswap = cdt->swapchain;
+ swapchain_prune_batch_usage(cswap, u);
+ for (cswap = cdt->old_swapchain; cswap; cswap = cswap->next)
+ swapchain_prune_batch_usage(cswap, u);
+}
diff --git a/src/gallium/drivers/zink/zink_kopper.h b/src/gallium/drivers/zink/zink_kopper.h
index 857a9cd5a5d..4b7d2d62ddf 100644
--- a/src/gallium/drivers/zink/zink_kopper.h
+++ b/src/gallium/drivers/zink/zink_kopper.h
@@ -34,6 +34,8 @@
extern "C" {
#endif
+struct zink_batch_usage;
+
struct kopper_swapchain_image {
bool init;
bool acquired;
@@ -56,6 +58,7 @@ struct kopper_swapchain {
unsigned num_acquires;
unsigned max_acquires;
unsigned async_presents;
+ struct zink_batch_usage *batch_uses;
struct kopper_swapchain_image *images;
};
@@ -146,6 +149,8 @@ void
zink_kopper_set_swap_interval(struct pipe_screen *pscreen, struct pipe_resource *pres, int interval);
int
zink_kopper_query_buffer_age(struct pipe_context *pctx, struct pipe_resource *pres);
+void
+zink_kopper_prune_batch_usage(struct kopper_displaytarget *cdt, const struct zink_batch_usage *u);
#ifdef __cplusplus
}