From 510631ad76b8e10ccbfed2968cbe8622e2203d98 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Mon, 25 May 2020 10:55:17 -0400 Subject: [PATCH] zink: only stall during query destroy for xfb queries xfb queries allocate vk buffer objects in the underlying driver which can be deallocated while an xfb query is in-flight if we attempt to defer it due to the way that gl xfb is translated to vk, so we need to continue forcing this behavior in that case for other query types, we can safely defer here until the current batch has finished rather than block Reviewed-by: Erik Faye-Lund Part-of: --- src/gallium/drivers/zink/zink_query.c | 31 +++++++++++++++++++++------ 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/gallium/drivers/zink/zink_query.c b/src/gallium/drivers/zink/zink_query.c index 1b37f89f74b..8c4e792eb89 100644 --- a/src/gallium/drivers/zink/zink_query.c +++ b/src/gallium/drivers/zink/zink_query.c @@ -23,8 +23,10 @@ struct zink_query { unsigned index; bool use_64bit; bool precise; + bool xfb_running; bool active; /* query is considered active by vk */ + bool dead; /* query should be destroyed when its fence finishes */ unsigned fences; struct list_head active_list; @@ -108,6 +110,14 @@ wait_query(struct pipe_context *pctx, struct zink_query *query) } } +static void +destroy_query(struct zink_screen *screen, struct zink_query *query) +{ + assert(!p_atomic_read(&query->fences)); + vkDestroyQueryPool(screen->dev, query->query_pool, NULL); + FREE(query); +} + static void zink_destroy_query(struct pipe_context *pctx, struct pipe_query *q) @@ -115,11 +125,14 @@ zink_destroy_query(struct pipe_context *pctx, struct zink_screen *screen = zink_screen(pctx->screen); struct zink_query *query = (struct zink_query *)q; - if (p_atomic_read(&query->fences)) - wait_query(pctx, query); + p_atomic_set(&query->dead, true); + if (p_atomic_read(&query->fences)) { + if (query->xfb_running) + wait_query(pctx, query); + return; + } - vkDestroyQueryPool(screen->dev, query->query_pool, NULL); - FREE(query); + destroy_query(screen, query); } void @@ -127,7 +140,10 @@ zink_prune_queries(struct zink_screen *screen, struct zink_fence *fence) { set_foreach(fence->active_queries, entry) { struct zink_query *query = (void*)entry->key; - p_atomic_dec(&query->fences); + if (!p_atomic_dec_return(&query->fences)) { + if (p_atomic_read(&query->dead)) + destroy_query(screen, query); + } } _mesa_set_destroy(fence->active_queries, NULL); fence->active_queries = NULL; @@ -140,13 +156,14 @@ begin_query(struct zink_context *ctx, struct zink_batch *batch, struct zink_quer if (q->precise) flags |= VK_QUERY_CONTROL_PRECISE_BIT; - if (q->vkqtype == VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT) + if (q->vkqtype == VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT) { zink_screen(ctx->base.screen)->vk_CmdBeginQueryIndexedEXT(batch->cmdbuf, q->query_pool, q->curr_query, flags, q->index); - else + q->xfb_running = true; + } else vkCmdBeginQuery(batch->cmdbuf, q->query_pool, q->curr_query, flags); q->active = true; if (!batch->active_queries) -- 2.30.2