[PATCH 2/3] wined3d: Poll Vulkan queries directly on the application thread.

Jan Sikorski jsikorski at codeweavers.com
Mon Nov 22 06:46:18 CST 2021


Signed-off-by: Jan Sikorski <jsikorski at codeweavers.com>
---
 dlls/wined3d/context_vk.c      |  64 -----------------
 dlls/wined3d/query.c           | 121 ++++++++++++---------------------
 dlls/wined3d/wined3d_private.h |  12 ++--
 3 files changed, 48 insertions(+), 149 deletions(-)

diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c
index ec3554ddc30..dce78e1bc43 100644
--- a/dlls/wined3d/context_vk.c
+++ b/dlls/wined3d/context_vk.c
@@ -1524,69 +1524,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);
@@ -1636,7 +1573,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 193f62cd265..6cfa5d73da0 100644
--- a/dlls/wined3d/query.c
+++ b/dlls/wined3d/query.c
@@ -1432,26 +1432,12 @@ HRESULT wined3d_query_gl_create(struct wined3d_device *device, enum wined3d_quer
 static void wined3d_query_pool_vk_mark_complete(struct wined3d_query_pool_vk *pool_vk, size_t idx,
         struct wined3d_context_vk *context_vk)
 {
-    const struct wined3d_vk_info *vk_info = context_vk->vk_info;
-
-    if (vk_info->supported[WINED3D_VK_EXT_HOST_QUERY_RESET])
-    {
-        VK_CALL(vkResetQueryPoolEXT(wined3d_device_vk(context_vk->c.device)->vk_device,
-                pool_vk->vk_query_pool, idx, 1));
-
-        wined3d_bitmap_clear(pool_vk->allocated, idx);
-        if (list_empty(&pool_vk->entry))
-            list_add_tail(pool_vk->free_list, &pool_vk->entry);
-    }
-    else
-    {
-        /* 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);
-    }
+    /* 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)
@@ -1565,11 +1551,10 @@ bool wined3d_query_pool_vk_init(struct wined3d_query_pool_vk *pool_vk,
 }
 
 bool wined3d_query_vk_accumulate_data(struct wined3d_query_vk *query_vk,
-        struct wined3d_context_vk *context_vk, const struct wined3d_query_pool_idx_vk *pool_idx)
+        struct wined3d_device_vk *device_vk, const struct wined3d_query_pool_idx_vk *pool_idx)
 {
-    struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
     const struct wined3d_query_data_pipeline_statistics *ps_tmp;
-    const struct wined3d_vk_info *vk_info = context_vk->vk_info;
+    const struct wined3d_vk_info *vk_info = &device_vk->vk_info;
     struct wined3d_query_data_pipeline_statistics *ps_result;
     VkResult vr;
     union
@@ -1590,8 +1575,6 @@ 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)
     {
@@ -1686,65 +1669,48 @@ 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;
 }
 
-static void wined3d_query_vk_poll_cs(void *object)
+static BOOL wined3d_query_vk_poll(struct wined3d_query *query, uint32_t flags)
 {
-    struct wined3d_poll_callback_data *data = object;
-    struct wined3d_query *query = data->query;
-    struct wined3d_context_vk *context_vk;
-    struct wined3d_query_vk *query_vk;
-    uint32_t flags = data->flags;
-
-    query_vk = wined3d_query_vk(query);
-
-    context_vk = wined3d_context_vk(context_acquire(query->device, NULL, 0));
-
-    if (flags & WINED3DGETDATA_FLUSH)
-        wined3d_context_vk_submit_command_buffer(context_vk, 0, NULL, NULL, 0, NULL);
-    if (query_vk->command_buffer_id == context_vk->current_command_buffer.id)
-        goto unavailable;
-
-    if (query_vk->command_buffer_id > context_vk->completed_command_buffer_id)
-        wined3d_context_vk_poll_command_buffers(context_vk);
-    if (query_vk->command_buffer_id > context_vk->completed_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;
+    struct wined3d_device_vk *device_vk = wined3d_device_vk(query->device);
+    struct wined3d_query_vk *query_vk = wined3d_query_vk(query);
+    size_t i;
 
-    /* If the query was suspended, and then ended before it was resumed,
-     * there's no data to accumulate here. */
-    if (query_vk->pool_idx.pool_vk && !wined3d_query_vk_accumulate_data(query_vk, context_vk, &query_vk->pool_idx))
-        goto unavailable;
+    memset((void *)query_vk->q.data, 0, query_vk->q.data_size);
 
-    query_vk->pool_idx.pool_vk = NULL;
-    context_release(&context_vk->c);
+    if (query_vk->pool_idx.pool_vk && !wined3d_query_vk_accumulate_data(query_vk, device_vk, &query_vk->pool_idx))
+        return FALSE;
 
-    data->result = TRUE;
-    return;
+    for (i = 0; i < query_vk->pending_count; ++i)
+    {
+        if (!wined3d_query_vk_accumulate_data(query_vk, device_vk, &query_vk->pending[i]))
+            return FALSE;
+    }
 
-unavailable:
-    context_release(&context_vk->c);
-    data->result = FALSE;
+    return TRUE;
 }
 
-static BOOL wined3d_query_vk_poll(struct wined3d_query *query, uint32_t flags)
+static void wined3d_query_vk_remove_pending_queries(struct wined3d_context_vk *context_vk,
+        struct wined3d_query_vk *query_vk)
 {
-    struct wined3d_cs *cs = query->device->cs;
-    struct wined3d_poll_callback_data data;
+    size_t i;
 
-    data.query = query;
-    data.flags = flags;
+    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);
 
-    wined3d_cs_run_priority_callback(cs, wined3d_query_vk_poll_cs, &data);
-
-    return data.result;
+    query_vk->pending_count = 0;
 }
 
 static void wined3d_query_vk_issue(struct wined3d_query *query, uint32_t flags)
@@ -1761,8 +1727,7 @@ static void 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);
-        memset((void *)query->data, 0, query->data_size);
+            wined3d_query_vk_remove_pending_queries(context_vk, query_vk);
         vk_command_buffer = wined3d_context_vk_get_command_buffer(context_vk);
         if (query_vk->flags & WINED3D_QUERY_VK_FLAG_STARTED)
         {
@@ -1839,12 +1804,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 6b885036260..7185893e894 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2102,7 +2102,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)
@@ -2110,7 +2111,9 @@ static inline struct wined3d_query_vk *wined3d_query_vk(struct wined3d_query *qu
     return CONTAINING_RECORD(query, struct wined3d_query_vk, q);
 }
 
-bool wined3d_query_vk_accumulate_data(struct wined3d_query_vk *query_vk, struct wined3d_context_vk *context_vk,
+struct wined3d_device_vk;
+
+bool wined3d_query_vk_accumulate_data(struct wined3d_query_vk *query_vk, struct wined3d_device_vk *device_vk,
         const struct wined3d_query_pool_idx_vk *pool_idx) DECLSPEC_HIDDEN;
 HRESULT wined3d_query_vk_create(struct wined3d_device *device, enum wined3d_query_type type, void *parent,
         const struct wined3d_parent_ops *parent_ops, struct wined3d_query **query) DECLSPEC_HIDDEN;
@@ -2646,9 +2649,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,
@@ -2696,8 +2696,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.32.0




More information about the wine-devel mailing list