wined3d: Track queries started inside/outside of a render pass separately.
Signed-off-by: Jan Sikorski <jsikorski@codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
626afcad71
commit
ba67dfe8c8
|
@ -1285,13 +1285,26 @@ void wined3d_context_vk_end_current_render_pass(struct wined3d_context_vk *conte
|
|||
VkCommandBuffer vk_command_buffer = context_vk->current_command_buffer.vk_command_buffer;
|
||||
const struct wined3d_vk_info *vk_info = context_vk->vk_info;
|
||||
struct wined3d_query_pool_vk *pool_vk, *pool_vk_next;
|
||||
struct wined3d_query_vk *query_vk;
|
||||
|
||||
if (context_vk->vk_render_pass)
|
||||
{
|
||||
LIST_FOR_EACH_ENTRY(query_vk, &context_vk->render_pass_queries, struct wined3d_query_vk, entry)
|
||||
wined3d_query_vk_suspend(query_vk, context_vk);
|
||||
|
||||
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,
|
||||
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, NULL, 0, NULL, 0, NULL));
|
||||
|
||||
LIST_FOR_EACH_ENTRY(query_vk, &context_vk->render_pass_queries, struct wined3d_query_vk, entry)
|
||||
{
|
||||
if (!wined3d_context_vk_allocate_query(context_vk, query_vk->q.type, &query_vk->pool_idx))
|
||||
{
|
||||
ERR("Failed to allocate new query.\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (context_vk->vk_framebuffer)
|
||||
|
@ -1561,6 +1574,12 @@ VkCommandBuffer wined3d_context_vk_get_command_buffer(struct wined3d_context_vk
|
|||
wined3d_context_vk_accumulate_pending_queries(context_vk);
|
||||
LIST_FOR_EACH_ENTRY(query_vk, &context_vk->active_queries, struct wined3d_query_vk, entry)
|
||||
{
|
||||
if (!wined3d_context_vk_allocate_query(context_vk, query_vk->q.type, &query_vk->pool_idx))
|
||||
{
|
||||
ERR("Failed to allocate new query.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
wined3d_query_vk_resume(query_vk, context_vk);
|
||||
}
|
||||
|
||||
|
@ -1594,12 +1613,11 @@ void wined3d_context_vk_submit_command_buffer(struct wined3d_context_vk *context
|
|||
TRACE("Submitting command buffer %p with id 0x%s.\n",
|
||||
buffer->vk_command_buffer, wine_dbgstr_longlong(buffer->id));
|
||||
|
||||
LIST_FOR_EACH_ENTRY(query_vk, &context_vk->active_queries, struct wined3d_query_vk, entry)
|
||||
{
|
||||
wined3d_query_vk_suspend(query_vk, context_vk);
|
||||
}
|
||||
|
||||
wined3d_context_vk_end_current_render_pass(context_vk);
|
||||
|
||||
LIST_FOR_EACH_ENTRY(query_vk, &context_vk->active_queries, struct wined3d_query_vk, entry)
|
||||
wined3d_query_vk_suspend(query_vk, context_vk);
|
||||
|
||||
context_vk->graphics.vk_pipeline = VK_NULL_HANDLE;
|
||||
context_vk->update_compute_pipeline = 1;
|
||||
context_vk->update_stream_output = 1;
|
||||
|
@ -2323,6 +2341,7 @@ static bool wined3d_context_vk_begin_render_pass(struct wined3d_context_vk *cont
|
|||
struct wined3d_rendertarget_view_vk *rtv_vk;
|
||||
struct wined3d_rendertarget_view *view;
|
||||
const VkPhysicalDeviceLimits *limits;
|
||||
struct wined3d_query_vk *query_vk;
|
||||
VkRenderPassBeginInfo begin_info;
|
||||
unsigned int attachment_count, i;
|
||||
VkFramebufferCreateInfo fb_desc;
|
||||
|
@ -2409,6 +2428,8 @@ static bool wined3d_context_vk_begin_render_pass(struct wined3d_context_vk *cont
|
|||
begin_info.pClearValues = NULL;
|
||||
VK_CALL(vkCmdBeginRenderPass(vk_command_buffer, &begin_info, VK_SUBPASS_CONTENTS_INLINE));
|
||||
|
||||
LIST_FOR_EACH_ENTRY(query_vk, &context_vk->render_pass_queries, struct wined3d_query_vk, entry)
|
||||
wined3d_query_vk_resume(query_vk, context_vk);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -3460,6 +3481,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->render_pass_queries);
|
||||
list_init(&context_vk->active_queries);
|
||||
list_init(&context_vk->completed_query_pools);
|
||||
list_init(&context_vk->free_occlusion_query_pools);
|
||||
|
|
|
@ -1548,11 +1548,6 @@ static void wined3d_query_vk_begin(struct wined3d_query_vk *query_vk,
|
|||
struct wined3d_query_pool_vk *pool_vk;
|
||||
size_t 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;
|
||||
}
|
||||
pool_vk = query_vk->pool_idx.pool_vk;
|
||||
idx = query_vk->pool_idx.idx;
|
||||
|
||||
|
@ -1588,6 +1583,7 @@ void wined3d_query_vk_resume(struct wined3d_query_vk *query_vk, struct wined3d_c
|
|||
VkCommandBuffer vk_command_buffer = context_vk->current_command_buffer.vk_command_buffer;
|
||||
|
||||
wined3d_query_vk_begin(query_vk, context_vk, vk_command_buffer);
|
||||
query_vk->flags |= WINED3D_QUERY_VK_FLAG_ACTIVE;
|
||||
}
|
||||
|
||||
void wined3d_query_vk_suspend(struct wined3d_query_vk *query_vk, struct wined3d_context_vk *context_vk)
|
||||
|
@ -1597,6 +1593,7 @@ void wined3d_query_vk_suspend(struct wined3d_query_vk *query_vk, struct wined3d_
|
|||
wined3d_query_vk_end(query_vk, context_vk, vk_command_buffer);
|
||||
wined3d_context_vk_add_pending_query(context_vk, query_vk);
|
||||
query_vk->pool_idx.pool_vk = NULL;
|
||||
query_vk->flags &= ~WINED3D_QUERY_VK_FLAG_ACTIVE;
|
||||
}
|
||||
|
||||
static BOOL wined3d_query_vk_poll(struct wined3d_query *query, uint32_t flags)
|
||||
|
@ -1655,30 +1652,69 @@ static BOOL wined3d_query_vk_issue(struct wined3d_query *query, uint32_t flags)
|
|||
wined3d_context_vk_remove_pending_queries(context_vk, query_vk);
|
||||
memset((void *)query->data, 0, query->data_size);
|
||||
vk_command_buffer = wined3d_context_vk_get_command_buffer(context_vk);
|
||||
if (query_vk->started)
|
||||
if (query_vk->flags & WINED3D_QUERY_VK_FLAG_STARTED)
|
||||
{
|
||||
wined3d_query_vk_end(query_vk, context_vk, vk_command_buffer);
|
||||
if (query_vk->flags & WINED3D_QUERY_VK_FLAG_ACTIVE)
|
||||
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;
|
||||
|
||||
if (!wined3d_context_vk_allocate_query(context_vk, query_vk->q.type, &query_vk->pool_idx))
|
||||
{
|
||||
ERR("Failed to allocate new query.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* A query need to either begin and end inside a single render pass,
|
||||
* or begin and end ouside of a render pass. Occlusion queries, if issued
|
||||
* ouside of a render pass, are queued up and only begun when a render
|
||||
* pass is started, to avoid interrupting it when the query ends. */
|
||||
if (context_vk->vk_render_pass)
|
||||
{
|
||||
wined3d_query_vk_begin(query_vk, context_vk, vk_command_buffer);
|
||||
list_add_head(&context_vk->render_pass_queries, &query_vk->entry);
|
||||
query_vk->flags |= WINED3D_QUERY_VK_FLAG_ACTIVE | WINED3D_QUERY_VK_FLAG_RENDER_PASS;
|
||||
}
|
||||
else if (query->type == WINED3D_QUERY_TYPE_OCCLUSION)
|
||||
{
|
||||
list_add_head(&context_vk->render_pass_queries, &query_vk->entry);
|
||||
query_vk->flags |= WINED3D_QUERY_VK_FLAG_RENDER_PASS;
|
||||
}
|
||||
else
|
||||
{
|
||||
wined3d_query_vk_begin(query_vk, context_vk, vk_command_buffer);
|
||||
list_add_head(&context_vk->active_queries, &query_vk->entry);
|
||||
query_vk->flags |= WINED3D_QUERY_VK_FLAG_ACTIVE;
|
||||
}
|
||||
|
||||
query_vk->flags |= WINED3D_QUERY_VK_FLAG_STARTED;
|
||||
context_release(&context_vk->c);
|
||||
}
|
||||
if (flags & WINED3DISSUE_END && query_vk->started)
|
||||
if (flags & WINED3DISSUE_END && query_vk->flags & WINED3D_QUERY_VK_FLAG_STARTED)
|
||||
{
|
||||
context_vk = wined3d_context_vk(context_acquire(&device_vk->d, NULL, 0));
|
||||
|
||||
/* If the query was already ended because the command buffer was
|
||||
* flushed, we don't need to end it here. */
|
||||
if ((vk_command_buffer = context_vk->current_command_buffer.vk_command_buffer))
|
||||
* flushed or the render pass ended, we don't need to end it here. */
|
||||
if (query_vk->flags & WINED3D_QUERY_VK_FLAG_ACTIVE)
|
||||
{
|
||||
vk_command_buffer = wined3d_context_vk_get_command_buffer(context_vk);
|
||||
if (!(query_vk->flags & WINED3D_QUERY_VK_FLAG_RENDER_PASS))
|
||||
wined3d_context_vk_end_current_render_pass(context_vk);
|
||||
wined3d_query_vk_end(query_vk, context_vk, vk_command_buffer);
|
||||
}
|
||||
else if (query_vk->pool_idx.pool_vk)
|
||||
{
|
||||
/* It was queued, but never activated. */
|
||||
wined3d_query_pool_vk_mark_complete(query_vk->pool_idx.pool_vk,
|
||||
query_vk->pool_idx.idx, context_vk);
|
||||
query_vk->pool_idx.pool_vk = NULL;
|
||||
}
|
||||
list_remove(&query_vk->entry);
|
||||
query_vk->started = false;
|
||||
query_vk->flags = 0;
|
||||
poll = true;
|
||||
|
||||
context_release(&context_vk->c);
|
||||
|
|
|
@ -2050,13 +2050,17 @@ struct wined3d_query_pool_idx_vk
|
|||
size_t idx;
|
||||
};
|
||||
|
||||
#define WINED3D_QUERY_VK_FLAG_ACTIVE 0x00000001
|
||||
#define WINED3D_QUERY_VK_FLAG_STARTED 0x00000002
|
||||
#define WINED3D_QUERY_VK_FLAG_RENDER_PASS 0x00000004
|
||||
|
||||
struct wined3d_query_vk
|
||||
{
|
||||
struct wined3d_query q;
|
||||
|
||||
struct list entry;
|
||||
struct wined3d_query_pool_idx_vk pool_idx;
|
||||
bool started;
|
||||
uint8_t flags;
|
||||
uint64_t command_buffer_id;
|
||||
uint32_t control_flags;
|
||||
size_t pending_count;
|
||||
|
@ -2580,6 +2584,7 @@ struct wined3d_context_vk
|
|||
VkDeviceSize vk_so_offsets[WINED3D_MAX_STREAM_OUTPUT_BUFFERS];
|
||||
struct wined3d_bo_vk vk_so_counter_bo;
|
||||
|
||||
struct list render_pass_queries;
|
||||
struct list active_queries;
|
||||
struct wined3d_pending_queries_vk pending_queries;
|
||||
struct list completed_query_pools;
|
||||
|
|
Loading…
Reference in New Issue