[PATCH v2] wined3d: Avoid ending the renderpass when issuing a query.
Jan Sikorski
jsikorski at codeweavers.com
Mon Jun 28 10:52:41 CDT 2021
Allocate a fresh query index that does not need to be reset.
Reset query pools at creation and when the render pass is ended.
Signed-off-by: Jan Sikorski <jsikorski at codeweavers.com>
---
v2:
- changed list beheading to LIST_FOR_EACH_ENTRY_SAFE
- naming (dirty -> completed)
- added an explanatory comment
- whitespace fix
---
dlls/wined3d/context_vk.c | 19 +++++++++++--
dlls/wined3d/query.c | 50 ++++++++++++++++++++++++++--------
dlls/wined3d/wined3d_private.h | 6 +++-
3 files changed, 60 insertions(+), 15 deletions(-)
diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c
index 43b806a19b5..87fcb868197 100644
--- a/dlls/wined3d/context_vk.c
+++ b/dlls/wined3d/context_vk.c
@@ -1282,12 +1282,12 @@ VkRenderPass wined3d_context_vk_get_render_pass(struct wined3d_context_vk *conte
void wined3d_context_vk_end_current_render_pass(struct wined3d_context_vk *context_vk)
{
+ VkCommandBuffer vk_command_buffer = context_vk->current_command_buffer.vk_command_buffer;
const struct wined3d_vk_info *vk_info = context_vk->vk_info;
- VkCommandBuffer vk_command_buffer;
+ struct wined3d_query_pool_vk *pool_vk, *pool_vk_next;
if (context_vk->vk_render_pass)
{
- vk_command_buffer = context_vk->current_command_buffer.vk_command_buffer;
VK_CALL(vkCmdEndRenderPass(vk_command_buffer));
context_vk->vk_render_pass = VK_NULL_HANDLE;
VK_CALL(vkCmdPipelineBarrier(vk_command_buffer, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
@@ -1300,6 +1300,14 @@ void wined3d_context_vk_end_current_render_pass(struct wined3d_context_vk *conte
context_vk->vk_framebuffer, context_vk->current_command_buffer.id);
context_vk->vk_framebuffer = VK_NULL_HANDLE;
}
+
+ LIST_FOR_EACH_ENTRY_SAFE(pool_vk, pool_vk_next, &context_vk->completed_query_pools,
+ struct wined3d_query_pool_vk, completed_entry)
+ {
+ list_remove(&pool_vk->completed_entry);
+ list_init(&pool_vk->completed_entry);
+ wined3d_query_pool_vk_reset(pool_vk, context_vk, vk_command_buffer);
+ }
}
static void wined3d_context_vk_destroy_render_pass(struct wine_rb_entry *entry, void *ctx)
@@ -1330,6 +1338,7 @@ static void wined3d_context_vk_destroy_query_pools(struct wined3d_context_vk *co
bool wined3d_context_vk_allocate_query(struct wined3d_context_vk *context_vk,
enum wined3d_query_type type, struct wined3d_query_pool_idx_vk *pool_idx)
{
+ const struct wined3d_vk_info *vk_info = context_vk->vk_info;
struct wined3d_query_pool_vk *pool_vk, *entry;
struct list *free_pools;
size_t idx;
@@ -1376,6 +1385,10 @@ bool wined3d_context_vk_allocate_query(struct wined3d_context_vk *context_vk,
return false;
}
+ wined3d_context_vk_end_current_render_pass(context_vk);
+ VK_CALL(vkCmdResetQueryPool(wined3d_context_vk_get_command_buffer(context_vk),
+ pool_vk->vk_query_pool, 0, WINED3D_QUERY_POOL_SIZE));
+
if (!wined3d_query_pool_vk_allocate_query(pool_vk, &idx))
{
wined3d_query_pool_vk_cleanup(pool_vk, context_vk);
@@ -1449,7 +1462,6 @@ void wined3d_context_vk_remove_pending_queries(struct wined3d_context_vk *contex
{
if (p->query_vk != query_vk && !wined3d_query_vk_accumulate_data(p->query_vk, context_vk, &p->pool_idx))
continue;
- wined3d_query_pool_vk_free_query(p->pool_idx.pool_vk, p->pool_idx.idx);
--p->query_vk->pending_count;
}
@@ -3390,6 +3402,7 @@ HRESULT wined3d_context_vk_init(struct wined3d_context_vk *context_vk, struct wi
wined3d_context_vk_init_graphics_pipeline_key(context_vk);
list_init(&context_vk->active_queries);
+ list_init(&context_vk->completed_query_pools);
list_init(&context_vk->free_occlusion_query_pools);
list_init(&context_vk->free_timestamp_query_pools);
list_init(&context_vk->free_pipeline_statistics_query_pools);
diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c
index 81f5ba7d0d7..1e082f8ffae 100644
--- a/dlls/wined3d/query.c
+++ b/dlls/wined3d/query.c
@@ -1348,12 +1348,15 @@ HRESULT wined3d_query_gl_create(struct wined3d_device *device, enum wined3d_quer
}
}
-void wined3d_query_pool_vk_free_query(struct wined3d_query_pool_vk *pool_vk, size_t idx)
+static void wined3d_query_pool_vk_mark_complete(struct wined3d_query_pool_vk *pool_vk, size_t idx,
+ struct wined3d_context_vk *context_vk)
{
- wined3d_bitmap_clear(pool_vk->allocated, idx);
-
- if (list_empty(&pool_vk->entry))
- list_add_tail(pool_vk->free_list, &pool_vk->entry);
+ /* Don't reset completed queries right away, as vkCmdResetQueryPool() needs to happen
+ * outside of a render pass. Queue the query to be reset in wined3d_query_pool_vk_reset()
+ * instead, which is called when the render pass ends. */
+ wined3d_bitmap_set(pool_vk->completed, idx);
+ if (list_empty(&pool_vk->completed_entry))
+ list_add_tail(&context_vk->completed_query_pools, &pool_vk->completed_entry);
}
bool wined3d_query_pool_vk_allocate_query(struct wined3d_query_pool_vk *pool_vk, size_t *idx)
@@ -1372,6 +1375,29 @@ void wined3d_query_pool_vk_cleanup(struct wined3d_query_pool_vk *pool_vk, struct
VK_CALL(vkDestroyQueryPool(device_vk->vk_device, pool_vk->vk_query_pool, NULL));
list_remove(&pool_vk->entry);
+ list_remove(&pool_vk->completed_entry);
+}
+
+void wined3d_query_pool_vk_reset(struct wined3d_query_pool_vk *pool_vk, struct wined3d_context_vk *context_vk,
+ VkCommandBuffer vk_command_buffer)
+{
+ const struct wined3d_vk_info *vk_info = context_vk->vk_info;
+ unsigned int start = 0, idx;
+ struct wined3d_range range;
+
+ for (;;)
+ {
+ if (!wined3d_bitmap_get_range(pool_vk->completed, WINED3D_QUERY_POOL_SIZE, start, &range))
+ break;
+
+ VK_CALL(vkCmdResetQueryPool(vk_command_buffer, pool_vk->vk_query_pool, range.offset, range.size));
+ start = range.offset + range.size;
+ for (idx = range.offset; idx < start; ++idx)
+ wined3d_bitmap_clear(pool_vk->allocated, idx);
+ }
+ memset(pool_vk->completed, 0, sizeof(pool_vk->completed));
+ if (list_empty(&pool_vk->entry))
+ list_add_tail(pool_vk->free_list, &pool_vk->entry);
}
bool wined3d_query_pool_vk_init(struct wined3d_query_pool_vk *pool_vk,
@@ -1383,6 +1409,7 @@ bool wined3d_query_pool_vk_init(struct wined3d_query_pool_vk *pool_vk,
VkResult vr;
list_init(&pool_vk->entry);
+ list_init(&pool_vk->completed_entry);
pool_vk->free_list = free_pools;
pool_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
@@ -1468,6 +1495,8 @@ bool wined3d_query_vk_accumulate_data(struct wined3d_query_vk *query_vk,
if (vr == VK_NOT_READY)
return false;
+ wined3d_query_pool_vk_mark_complete(pool_idx->pool_vk, pool_idx->idx, context_vk);
+
result = (void *)query_vk->q.data;
switch (query_vk->q.type)
{
@@ -1519,8 +1548,7 @@ static void wined3d_query_vk_begin(struct wined3d_query_vk *query_vk,
struct wined3d_query_pool_vk *pool_vk;
size_t idx;
- if (!query_vk->pool_idx.pool_vk
- && !wined3d_context_vk_allocate_query(context_vk, query_vk->q.type, &query_vk->pool_idx))
+ if (!wined3d_context_vk_allocate_query(context_vk, query_vk->q.type, &query_vk->pool_idx))
{
ERR("Failed to allocate new query.\n");
return;
@@ -1528,7 +1556,6 @@ static void wined3d_query_vk_begin(struct wined3d_query_vk *query_vk,
pool_vk = query_vk->pool_idx.pool_vk;
idx = query_vk->pool_idx.idx;
- VK_CALL(vkCmdResetQueryPool(vk_command_buffer, pool_vk->vk_query_pool, idx, 1));
if (query_vk->q.type >= WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM1
&& query_vk->q.type <= WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM3)
VK_CALL(vkCmdBeginQueryIndexedEXT(vk_command_buffer, pool_vk->vk_query_pool, idx,
@@ -1599,6 +1626,7 @@ static BOOL wined3d_query_vk_poll(struct wined3d_query *query, uint32_t flags)
if (query_vk->pool_idx.pool_vk && !wined3d_query_vk_accumulate_data(query_vk, context_vk, &query_vk->pool_idx))
goto unavailable;
+ query_vk->pool_idx.pool_vk = NULL;
context_release(&context_vk->c);
return TRUE;
@@ -1622,7 +1650,6 @@ static BOOL wined3d_query_vk_issue(struct wined3d_query *query, uint32_t flags)
{
context_vk = wined3d_context_vk(context_acquire(&device_vk->d, NULL, 0));
- wined3d_context_vk_end_current_render_pass(context_vk);
list_remove(&query_vk->entry);
if (query_vk->pending_count)
wined3d_context_vk_remove_pending_queries(context_vk, query_vk);
@@ -1633,6 +1660,9 @@ static BOOL wined3d_query_vk_issue(struct wined3d_query *query, uint32_t flags)
wined3d_query_vk_end(query_vk, context_vk, vk_command_buffer);
list_remove(&query_vk->entry);
}
+ if (query_vk->pool_idx.pool_vk)
+ wined3d_query_pool_vk_mark_complete(query_vk->pool_idx.pool_vk,
+ query_vk->pool_idx.idx, context_vk);
wined3d_query_vk_begin(query_vk, context_vk, vk_command_buffer);
list_add_head(&context_vk->active_queries, &query_vk->entry);
query_vk->started = true;
@@ -1669,8 +1699,6 @@ static void wined3d_query_vk_destroy(struct wined3d_query *query)
wined3d_context_vk_remove_pending_queries(context_vk, query_vk);
context_release(&context_vk->c);
}
- if (query_vk->pool_idx.pool_vk)
- wined3d_query_pool_vk_free_query(query_vk->pool_idx.pool_vk, query_vk->pool_idx.idx);
heap_free(query_vk);
}
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 84dad38f0c9..58fbc69ca7c 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2023,16 +2023,19 @@ struct wined3d_pipeline_statistics_query
struct wined3d_query_pool_vk
{
struct list entry;
+ struct list completed_entry;
struct list *free_list;
VkQueryPool vk_query_pool;
uint32_t allocated[WINED3D_BITMAP_SIZE(WINED3D_QUERY_POOL_SIZE)];
+ uint32_t completed[WINED3D_BITMAP_SIZE(WINED3D_QUERY_POOL_SIZE)];
};
bool wined3d_query_pool_vk_allocate_query(struct wined3d_query_pool_vk *pool_vk, size_t *idx) DECLSPEC_HIDDEN;
void wined3d_query_pool_vk_cleanup(struct wined3d_query_pool_vk *pool_vk,
struct wined3d_context_vk *context_vk) DECLSPEC_HIDDEN;
-void wined3d_query_pool_vk_free_query(struct wined3d_query_pool_vk *pool_vk, size_t idx) DECLSPEC_HIDDEN;
+void wined3d_query_pool_vk_reset(struct wined3d_query_pool_vk *pool_vk, struct wined3d_context_vk *context_vk,
+ VkCommandBuffer vk_command_buffer) DECLSPEC_HIDDEN;
bool wined3d_query_pool_vk_init(struct wined3d_query_pool_vk *pool_vk, struct wined3d_context_vk *context_vk,
enum wined3d_query_type type, struct list *free_pools) DECLSPEC_HIDDEN;
@@ -2574,6 +2577,7 @@ struct wined3d_context_vk
struct list active_queries;
struct wined3d_pending_queries_vk pending_queries;
+ struct list completed_query_pools;
struct list free_occlusion_query_pools;
struct list free_timestamp_query_pools;
struct list free_pipeline_statistics_query_pools;
--
2.30.2
More information about the wine-devel
mailing list