From 7f1473e4beab6f1a6128f431cb8af74b634208d8 Mon Sep 17 00:00:00 2001 From: Jan Sikorski Date: Fri, 4 Mar 2022 18:12:57 +0100 Subject: [PATCH] wined3d: Track pending Vulkan queries separately for each query. This is mostly to enable polling queries from the application thread by removing the need to access the shared context. Signed-off-by: Jan Sikorski Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- dlls/wined3d/context_vk.c | 65 ------------------------------------------ dlls/wined3d/query.c | 45 +++++++++++++++++++++-------- dlls/wined3d/wined3d_private.h | 23 ++------------- 3 files changed, 35 insertions(+), 98 deletions(-) diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c index a3489c23f1d..dcb94eb7c1a 100644 --- a/dlls/wined3d/context_vk.c +++ b/dlls/wined3d/context_vk.c @@ -1577,7 +1577,6 @@ void wined3d_context_vk_cleanup(struct wined3d_context_vk *context_vk) wined3d_context_vk_destroy_query_pools(context_vk, &context_vk->free_pipeline_statistics_query_pools); wined3d_context_vk_destroy_query_pools(context_vk, &context_vk->free_stream_output_statistics_query_pools); wine_rb_destroy(&context_vk->bo_slab_available, wined3d_context_vk_destroy_bo_slab, context_vk); - heap_free(context_vk->pending_queries.queries); heap_free(context_vk->submitted.buffers); heap_free(context_vk->retired.objects); @@ -1589,69 +1588,6 @@ void wined3d_context_vk_cleanup(struct wined3d_context_vk *context_vk) wined3d_context_cleanup(&context_vk->c); } -void wined3d_context_vk_remove_pending_queries(struct wined3d_context_vk *context_vk, - struct wined3d_query_vk *query_vk) -{ - struct wined3d_pending_queries_vk *pending = &context_vk->pending_queries; - struct wined3d_pending_query_vk *p; - size_t i; - - pending->free_idx = ~(size_t)0; - for (i = pending->count; i; --i) - { - p = &pending->queries[i - 1]; - - if (p->query_vk) - { - if (p->query_vk != query_vk && !wined3d_query_vk_accumulate_data(p->query_vk, context_vk, &p->pool_idx)) - continue; - --p->query_vk->pending_count; - } - - if (i == pending->count) - { - --pending->count; - continue; - } - - p->query_vk = NULL; - p->pool_idx.pool_vk = NULL; - p->pool_idx.idx = pending->free_idx; - pending->free_idx = i - 1; - } -} - -void wined3d_context_vk_accumulate_pending_queries(struct wined3d_context_vk *context_vk) -{ - wined3d_context_vk_remove_pending_queries(context_vk, NULL); -} - -void wined3d_context_vk_add_pending_query(struct wined3d_context_vk *context_vk, struct wined3d_query_vk *query_vk) -{ - struct wined3d_pending_queries_vk *pending = &context_vk->pending_queries; - struct wined3d_pending_query_vk *p; - - if (pending->free_idx != ~(size_t)0) - { - p = &pending->queries[pending->free_idx]; - pending->free_idx = p->pool_idx.idx; - } - else - { - if (!wined3d_array_reserve((void **)&pending->queries, &pending->size, - pending->count + 1, sizeof(*pending->queries))) - { - ERR("Failed to allocate entry.\n"); - return; - } - p = &pending->queries[pending->count++]; - } - - p->query_vk = query_vk; - p->pool_idx = query_vk->pool_idx; - ++query_vk->pending_count; -} - VkCommandBuffer wined3d_context_vk_get_command_buffer(struct wined3d_context_vk *context_vk) { struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device); @@ -1701,7 +1637,6 @@ VkCommandBuffer wined3d_context_vk_get_command_buffer(struct wined3d_context_vk return buffer->vk_command_buffer = VK_NULL_HANDLE; } - 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)) diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c index 093b412bf18..7309b7a68df 100644 --- a/dlls/wined3d/query.c +++ b/dlls/wined3d/query.c @@ -1598,7 +1598,15 @@ void wined3d_query_vk_suspend(struct wined3d_query_vk *query_vk, struct wined3d_ VkCommandBuffer vk_command_buffer = context_vk->current_command_buffer.vk_command_buffer; wined3d_query_vk_end(query_vk, context_vk, vk_command_buffer); - wined3d_context_vk_add_pending_query(context_vk, query_vk); + + if (!wined3d_array_reserve((void **)&query_vk->pending, &query_vk->pending_size, + query_vk->pending_count + 1, sizeof(*query_vk->pending))) + { + ERR("Failed to allocate entry.\n"); + return; + } + + query_vk->pending[query_vk->pending_count++] = query_vk->pool_idx; query_vk->pool_idx.pool_vk = NULL; query_vk->flags &= ~WINED3D_QUERY_VK_FLAG_ACTIVE; } @@ -1615,10 +1623,12 @@ static BOOL wined3d_query_vk_poll(struct wined3d_query *query, uint32_t flags) if (query_vk->command_buffer_id == context_vk->current_command_buffer.id) goto unavailable; - if (query_vk->pending_count) - wined3d_context_vk_accumulate_pending_queries(context_vk); - if (query_vk->pending_count) - goto unavailable; + while (query_vk->pending_count) + { + if (!wined3d_query_vk_accumulate_data(query_vk, context_vk, &query_vk->pending[query_vk->pending_count - 1])) + goto unavailable; + query_vk->pending_count--; + } /* If the query was suspended, and then ended before it was resumed, * there's no data to accumulate here. */ @@ -1635,6 +1645,17 @@ unavailable: return FALSE; } +static void wined3d_query_vk_remove_pending_queries(struct wined3d_context_vk *context_vk, + struct wined3d_query_vk *query_vk) +{ + size_t i; + + for (i = 0; i < query_vk->pending_count; ++i) + wined3d_query_pool_vk_mark_complete(query_vk->pending[i].pool_vk, query_vk->pending[i].idx, context_vk); + + query_vk->pending_count = 0; +} + static BOOL wined3d_query_vk_issue(struct wined3d_query *query, uint32_t flags) { struct wined3d_device_vk *device_vk = wined3d_device_vk(query->device); @@ -1650,7 +1671,7 @@ 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)); if (query_vk->pending_count) - wined3d_context_vk_remove_pending_queries(context_vk, query_vk); + wined3d_query_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->flags & WINED3D_QUERY_VK_FLAG_STARTED) @@ -1732,12 +1753,12 @@ static void wined3d_query_vk_destroy(struct wined3d_query *query) if (query_vk->flags & WINED3D_QUERY_VK_FLAG_STARTED) list_remove(&query_vk->entry); - if (query_vk->pending_count) - { - context_vk = wined3d_context_vk(context_acquire(query_vk->q.device, NULL, 0)); - wined3d_context_vk_remove_pending_queries(context_vk, query_vk); - context_release(&context_vk->c); - } + context_vk = wined3d_context_vk(context_acquire(query_vk->q.device, NULL, 0)); + wined3d_query_vk_remove_pending_queries(context_vk, query_vk); + 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); + context_release(&context_vk->c); + heap_free(query_vk->pending); heap_free(query_vk); } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index b6f2cf060d4..d035b89a5e5 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2086,7 +2086,8 @@ struct wined3d_query_vk uint8_t flags; uint64_t command_buffer_id; uint32_t control_flags; - size_t pending_count; + SIZE_T pending_count, pending_size; + struct wined3d_query_pool_idx_vk *pending; }; static inline struct wined3d_query_vk *wined3d_query_vk(struct wined3d_query *query) @@ -2550,20 +2551,6 @@ struct wined3d_shader_descriptor_writes_vk SIZE_T size, count; }; -struct wined3d_pending_query_vk -{ - struct wined3d_query_vk *query_vk; - struct wined3d_query_pool_idx_vk pool_idx; -}; - -struct wined3d_pending_queries_vk -{ - struct wined3d_pending_query_vk *queries; - SIZE_T free_idx; - SIZE_T size; - SIZE_T count; -}; - struct wined3d_context_vk { struct wined3d_context c; @@ -2619,7 +2606,6 @@ struct wined3d_context_vk struct list render_pass_queries; 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; @@ -2638,9 +2624,6 @@ static inline struct wined3d_context_vk *wined3d_context_vk(struct wined3d_conte return CONTAINING_RECORD(context, struct wined3d_context_vk, c); } -void wined3d_context_vk_accumulate_pending_queries(struct wined3d_context_vk *context_vk) DECLSPEC_HIDDEN; -void wined3d_context_vk_add_pending_query(struct wined3d_context_vk *context_vk, - struct wined3d_query_vk *query_vk) DECLSPEC_HIDDEN; 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) DECLSPEC_HIDDEN; VkDeviceMemory wined3d_context_vk_allocate_vram_chunk_memory(struct wined3d_context_vk *context_vk, @@ -2688,8 +2671,6 @@ void wined3d_context_vk_image_barrier(struct wined3d_context_vk *context_vk, HRESULT wined3d_context_vk_init(struct wined3d_context_vk *context_vk, struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; void wined3d_context_vk_poll_command_buffers(struct wined3d_context_vk *context_vk) DECLSPEC_HIDDEN; -void wined3d_context_vk_remove_pending_queries(struct wined3d_context_vk *context_vk, - struct wined3d_query_vk *query_vk) DECLSPEC_HIDDEN; void wined3d_context_vk_submit_command_buffer(struct wined3d_context_vk *context_vk, unsigned int wait_semaphore_count, const VkSemaphore *wait_semaphores, const VkPipelineStageFlags *wait_stages, unsigned int signal_semaphore_count, const VkSemaphore *signal_semaphores) DECLSPEC_HIDDEN; -- 2.11.4.GIT