Commit f165b911 authored by Jan Sikorski's avatar Jan Sikorski Committed by Alexandre Julliard

wined3d: Avoid ending the renderpass when issuing a query.

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: 's avatarJan Sikorski <jsikorski@codeweavers.com> Signed-off-by: 's avatarHenri Verbeet <hverbeet@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent cc63b768
......@@ -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);
......
......@@ -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);
}
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment