Signed-off-by: Henri Verbeet hverbeet@codeweavers.com --- dlls/wined3d/adapter_vk.c | 15 +- dlls/wined3d/context_vk.c | 157 +++++++++++++++++- dlls/wined3d/query.c | 287 +++++++++++++++++++++++++++++++++ dlls/wined3d/wined3d_private.h | 86 ++++++++++ 4 files changed, 539 insertions(+), 6 deletions(-)
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c index 8cbd8206617..84eda1e551b 100644 --- a/dlls/wined3d/adapter_vk.c +++ b/dlls/wined3d/adapter_vk.c @@ -1609,12 +1609,23 @@ static HRESULT adapter_vk_create_query(struct wined3d_device *device, enum wined TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n", device, type, parent, parent_ops, query);
- return WINED3DERR_NOTAVAILABLE; + return wined3d_query_vk_create(device, type, parent, parent_ops, query); +} + +static void wined3d_query_vk_destroy_object(void *object) +{ + struct wined3d_query_vk *query_vk = object; + + query_vk->q.query_ops->query_destroy(&query_vk->q); }
static void adapter_vk_destroy_query(struct wined3d_query *query) { - TRACE("query %p.\n", query); + struct wined3d_query_vk *query_vk = wined3d_query_vk(query); + + TRACE("query_vk %p.\n", query_vk); + + wined3d_cs_destroy_object(query->device->cs, wined3d_query_vk_destroy_object, query_vk); }
static void adapter_vk_flush_context(struct wined3d_context *context) diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c index 3a6671036e2..2964eb30cc4 100644 --- a/dlls/wined3d/context_vk.c +++ b/dlls/wined3d/context_vk.c @@ -813,14 +813,11 @@ void wined3d_context_vk_destroy_bo(struct wined3d_context_vk *context_vk, const wined3d_context_vk_destroy_memory(context_vk, bo->vk_memory, bo->command_buffer_id); }
-static void wined3d_context_vk_cleanup_resources(struct wined3d_context_vk *context_vk) +void wined3d_context_vk_poll_command_buffers(struct wined3d_context_vk *context_vk) { struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device); - struct wined3d_retired_objects_vk *retired = &context_vk->retired; const struct wined3d_vk_info *vk_info = context_vk->vk_info; struct wined3d_command_buffer_vk *buffer; - struct wined3d_retired_object_vk *o; - uint64_t command_buffer_id; SIZE_T i = 0;
while (i < context_vk->submitted.buffer_count) @@ -842,6 +839,18 @@ static void wined3d_context_vk_cleanup_resources(struct wined3d_context_vk *cont context_vk->completed_command_buffer_id = buffer->id; *buffer = context_vk->submitted.buffers[--context_vk->submitted.buffer_count]; } +} + +static void wined3d_context_vk_cleanup_resources(struct wined3d_context_vk *context_vk) +{ + struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device); + struct wined3d_retired_objects_vk *retired = &context_vk->retired; + const struct wined3d_vk_info *vk_info = context_vk->vk_info; + struct wined3d_retired_object_vk *o; + uint64_t command_buffer_id; + SIZE_T i = 0; + + wined3d_context_vk_poll_command_buffers(context_vk); command_buffer_id = context_vk->completed_command_buffer_id;
retired->free = NULL; @@ -1194,6 +1203,64 @@ static void wined3d_shader_descriptor_writes_vk_cleanup(struct wined3d_shader_de heap_free(writes->writes); }
+static void wined3d_context_vk_destroy_query_pools(struct wined3d_context_vk *context_vk, struct list *free_pools) +{ + struct wined3d_query_pool_vk *pool_vk, *entry; + + LIST_FOR_EACH_ENTRY_SAFE(pool_vk, entry, free_pools, struct wined3d_query_pool_vk, entry) + { + wined3d_query_pool_vk_cleanup(pool_vk, context_vk); + heap_free(pool_vk); + } +} + +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) +{ + struct wined3d_query_pool_vk *pool_vk, *entry; + struct list *free_pools; + size_t idx; + + switch (type) + { + case WINED3D_QUERY_TYPE_OCCLUSION: + free_pools = &context_vk->free_occlusion_query_pools; + break; + + default: + FIXME("Unhandled query type %#x.\n", type); + return false; + } + + LIST_FOR_EACH_ENTRY_SAFE(pool_vk, entry, free_pools, struct wined3d_query_pool_vk, entry) + { + if (wined3d_query_pool_vk_allocate_query(pool_vk, &idx)) + goto done; + list_remove(&pool_vk->entry); + } + + if (!(pool_vk = heap_alloc_zero(sizeof(*pool_vk)))) + return false; + if (!wined3d_query_pool_vk_init(pool_vk, context_vk, type, free_pools)) + { + heap_free(pool_vk); + return false; + } + + if (!wined3d_query_pool_vk_allocate_query(pool_vk, &idx)) + { + wined3d_query_pool_vk_cleanup(pool_vk, context_vk); + heap_free(pool_vk); + return false; + } + +done: + pool_idx->pool_vk = pool_vk; + pool_idx->idx = idx; + + return true; +} + void wined3d_context_vk_cleanup(struct wined3d_context_vk *context_vk) { struct wined3d_command_buffer_vk *buffer = &context_vk->current_command_buffer; @@ -1218,7 +1285,9 @@ void wined3d_context_vk_cleanup(struct wined3d_context_vk *context_vk) VK_CALL(vkDestroyFramebuffer(device_vk->vk_device, context_vk->vk_framebuffer, NULL)); VK_CALL(vkDestroyCommandPool(device_vk->vk_device, context_vk->vk_command_pool, NULL)); wined3d_context_vk_cleanup_resources(context_vk); + wined3d_context_vk_destroy_query_pools(context_vk, &context_vk->free_occlusion_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);
@@ -1230,6 +1299,70 @@ 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; + wined3d_query_pool_vk_free_query(p->pool_idx.pool_vk, p->pool_idx.idx); + --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); @@ -1237,6 +1370,7 @@ VkCommandBuffer wined3d_context_vk_get_command_buffer(struct wined3d_context_vk VkCommandBufferAllocateInfo command_buffer_info; struct wined3d_command_buffer_vk *buffer; VkCommandBufferBeginInfo begin_info; + struct wined3d_query_vk *query_vk; VkResult vr;
TRACE("context_vk %p.\n", context_vk); @@ -1273,6 +1407,12 @@ 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) + { + wined3d_query_vk_resume(query_vk, context_vk); + } + TRACE("Created new command buffer %p with id 0x%s.\n", buffer->vk_command_buffer, wine_dbgstr_longlong(buffer->id));
@@ -1286,6 +1426,7 @@ void wined3d_context_vk_submit_command_buffer(struct wined3d_context_vk *context struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device); const struct wined3d_vk_info *vk_info = context_vk->vk_info; struct wined3d_command_buffer_vk *buffer; + struct wined3d_query_vk *query_vk; VkFenceCreateInfo fence_desc; VkSubmitInfo submit_info; VkResult vr; @@ -1302,6 +1443,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); context_vk->graphics.vk_pipeline = VK_NULL_HANDLE; context_vk->update_compute_pipeline = 1; @@ -2909,6 +3055,9 @@ 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->free_occlusion_query_pools); + wine_rb_init(&context_vk->render_passes, wined3d_render_pass_vk_compare); wine_rb_init(&context_vk->pipeline_layouts, wined3d_pipeline_layout_vk_compare); wine_rb_init(&context_vk->graphics_pipelines, wined3d_graphics_pipeline_vk_compare); diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c index ab3bb743809..b72ffd633c5 100644 --- a/dlls/wined3d/query.c +++ b/dlls/wined3d/query.c @@ -1354,6 +1354,293 @@ 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) +{ + wined3d_bitmap_clear(pool_vk->allocated, idx); + + if (list_empty(&pool_vk->entry)) + list_add_tail(pool_vk->free_list, &pool_vk->entry); +} + +bool wined3d_query_pool_vk_allocate_query(struct wined3d_query_pool_vk *pool_vk, size_t *idx) +{ + if ((*idx = wined3d_bitmap_ffz(pool_vk->allocated, WINED3D_QUERY_POOL_SIZE, 0)) > WINED3D_QUERY_POOL_SIZE) + return false; + wined3d_bitmap_set(pool_vk->allocated, *idx); + + return true; +} + +void wined3d_query_pool_vk_cleanup(struct wined3d_query_pool_vk *pool_vk, struct wined3d_context_vk *context_vk) +{ + struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device); + const struct wined3d_vk_info *vk_info = context_vk->vk_info; + + VK_CALL(vkDestroyQueryPool(device_vk->vk_device, pool_vk->vk_query_pool, NULL)); + list_remove(&pool_vk->entry); +} + +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) +{ + struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device); + const struct wined3d_vk_info *vk_info = context_vk->vk_info; + VkQueryPoolCreateInfo pool_info; + VkResult vr; + + list_init(&pool_vk->entry); + pool_vk->free_list = free_pools; + + pool_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO; + pool_info.pNext = NULL; + pool_info.flags = 0; + pool_info.queryCount = WINED3D_QUERY_POOL_SIZE; + + switch (type) + { + case WINED3D_QUERY_TYPE_OCCLUSION: + pool_info.queryType = VK_QUERY_TYPE_OCCLUSION; + pool_info.pipelineStatistics = 0; + break; + + default: + FIXME("Unhandled query type %#x.\n", type); + return false; + } + + if ((vr = VK_CALL(vkCreateQueryPool(device_vk->vk_device, &pool_info, NULL, &pool_vk->vk_query_pool))) < 0) + { + ERR("Failed to create Vulkan query pool, vr %s.\n", wined3d_debug_vkresult(vr)); + return false; + } + + list_add_head(free_pools, &pool_vk->entry); + + return true; +} + +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 = wined3d_device_vk(context_vk->c.device); + const struct wined3d_vk_info *vk_info = context_vk->vk_info; + VkResult vr; + union + { + uint64_t occlusion; + } tmp, *result; + + if ((vr = VK_CALL(vkGetQueryPoolResults(device_vk->vk_device, pool_idx->pool_vk->vk_query_pool, + pool_idx->idx, 1, sizeof(tmp), &tmp, sizeof(tmp), VK_QUERY_RESULT_64_BIT))) < 0) + { + ERR("Failed to get query results, vr %s.\n", wined3d_debug_vkresult(vr)); + return false; + } + + if (vr == VK_NOT_READY) + return false; + + result = (void *)query_vk->q.data; + switch (query_vk->q.type) + { + case WINED3D_QUERY_TYPE_OCCLUSION: + result->occlusion += tmp.occlusion; + break; + + default: + FIXME("Unhandled query type %#x.\n", query_vk->q.type); + return false; + } + + return true; +} + +static void wined3d_query_vk_begin(struct wined3d_query_vk *query_vk, + struct wined3d_context_vk *context_vk, VkCommandBuffer vk_command_buffer) +{ + const struct wined3d_vk_info *vk_info = context_vk->vk_info; + 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)) + { + ERR("Failed to allocate new query.\n"); + return; + } + 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)); + VK_CALL(vkCmdBeginQuery(vk_command_buffer, pool_vk->vk_query_pool, idx, query_vk->control_flags)); + wined3d_context_vk_reference_query(context_vk, query_vk); +} + +static void wined3d_query_vk_end(struct wined3d_query_vk *query_vk, + struct wined3d_context_vk *context_vk, VkCommandBuffer vk_command_buffer) +{ + const struct wined3d_vk_info *vk_info = context_vk->vk_info; + struct wined3d_query_pool_vk *pool_vk; + size_t idx; + + pool_vk = query_vk->pool_idx.pool_vk; + idx = query_vk->pool_idx.idx; + + VK_CALL(vkCmdEndQuery(vk_command_buffer, pool_vk->vk_query_pool, idx)); +} + +void wined3d_query_vk_resume(struct wined3d_query_vk *query_vk, struct wined3d_context_vk *context_vk) +{ + VkCommandBuffer vk_command_buffer = context_vk->current_command_buffer.vk_command_buffer; + + wined3d_query_vk_begin(query_vk, context_vk, vk_command_buffer); +} + +void wined3d_query_vk_suspend(struct wined3d_query_vk *query_vk, struct wined3d_context_vk *context_vk) +{ + 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); + query_vk->pool_idx.pool_vk = NULL; +} + +static BOOL wined3d_query_vk_poll(struct wined3d_query *query, uint32_t flags) +{ + struct wined3d_query_vk *query_vk = wined3d_query_vk(query); + struct wined3d_context_vk *context_vk; + + 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; + + if (!wined3d_query_vk_accumulate_data(query_vk, context_vk, &query_vk->pool_idx)) + goto unavailable; + + context_release(&context_vk->c); + + return TRUE; + +unavailable: + context_release(&context_vk->c); + return FALSE; +} + +static BOOL wined3d_query_vk_issue(struct wined3d_query *query, uint32_t flags) +{ + struct wined3d_device_vk *device_vk = wined3d_device_vk(query->device); + struct wined3d_query_vk *query_vk = wined3d_query_vk(query); + struct wined3d_context_vk *context_vk; + VkCommandBuffer vk_command_buffer; + bool poll = false; + + TRACE("query %p, flags %#x.\n", query, flags); + + if (flags & WINED3DISSUE_BEGIN) + { + 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); + memset((void *)query->data, 0, query->data_size); + vk_command_buffer = wined3d_context_vk_get_command_buffer(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; + + context_release(&context_vk->c); + } + if (flags & WINED3DISSUE_END && query_vk->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)) + wined3d_query_vk_end(query_vk, context_vk, vk_command_buffer); + list_remove(&query_vk->entry); + query_vk->started = false; + poll = true; + + context_release(&context_vk->c); + } + + return poll; +} + +static void wined3d_query_vk_destroy(struct wined3d_query *query) +{ + struct wined3d_query_vk *query_vk = wined3d_query_vk(query); + struct wined3d_context_vk *context_vk; + + 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); + } + 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); +} + +static const struct wined3d_query_ops wined3d_query_vk_ops = +{ + .query_poll = wined3d_query_vk_poll, + .query_issue = wined3d_query_vk_issue, + .query_destroy = wined3d_query_vk_destroy, +}; + +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) +{ + struct wined3d_query_vk *query_vk; + unsigned int data_size; + + TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n", + device, type, parent, parent_ops, query); + + switch (type) + { + case WINED3D_QUERY_TYPE_OCCLUSION: + data_size = sizeof(uint64_t); + break; + + default: + FIXME("Unhandled query type %#x.\n", type); + return WINED3DERR_NOTAVAILABLE; + } + + if (!(query_vk = heap_alloc_zero(sizeof(*query_vk) + data_size))) + return E_OUTOFMEMORY; + + wined3d_query_init(&query_vk->q, device, type, query_vk + 1, data_size, &wined3d_query_vk_ops, parent, parent_ops); + list_init(&query_vk->entry); + if (type == WINED3D_QUERY_TYPE_OCCLUSION) + query_vk->control_flags = VK_QUERY_CONTROL_PRECISE_BIT; + + TRACE("Created query %p.\n", query_vk); + *query = &query_vk->q; + + return WINED3D_OK; +} + HRESULT CDECL wined3d_query_create(struct wined3d_device *device, enum wined3d_query_type type, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_query **query) { diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index e9081e5d17d..5c92eecbf3e 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -86,6 +86,7 @@ struct wined3d_fragment_pipe_ops; struct wined3d_adapter; struct wined3d_buffer_vk; struct wined3d_context; +struct wined3d_context_vk; struct wined3d_gl_info; struct wined3d_state; struct wined3d_swapchain_gl; @@ -1952,6 +1953,54 @@ struct wined3d_pipeline_statistics_query BOOL started; };
+#define WINED3D_QUERY_POOL_SIZE 256 + +struct wined3d_query_pool_vk +{ + struct list entry; + + struct list *free_list; + VkQueryPool vk_query_pool; + uint32_t allocated[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; +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; + +struct wined3d_query_pool_idx_vk +{ + struct wined3d_query_pool_vk *pool_vk; + size_t idx; +}; + +struct wined3d_query_vk +{ + struct wined3d_query q; + + struct list entry; + struct wined3d_query_pool_idx_vk pool_idx; + bool started; + uint64_t command_buffer_id; + uint32_t control_flags; + size_t pending_count; +}; + +static inline struct wined3d_query_vk *wined3d_query_vk(struct wined3d_query *query) +{ + 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, + 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; +void wined3d_query_vk_resume(struct wined3d_query_vk *query_vk, struct wined3d_context_vk *context_vk) DECLSPEC_HIDDEN; +void wined3d_query_vk_suspend(struct wined3d_query_vk *query_vk, struct wined3d_context_vk *context_vk) DECLSPEC_HIDDEN; + struct wined3d_gl_view { GLenum target; @@ -2382,6 +2431,20 @@ 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; @@ -2429,6 +2492,10 @@ struct wined3d_context_vk VkSampleCountFlagBits sample_count; unsigned int rt_count;
+ struct list active_queries; + struct wined3d_pending_queries_vk pending_queries; + struct list free_occlusion_query_pools; + struct wined3d_retired_objects_vk retired; struct wine_rb_tree render_passes; struct wine_rb_tree pipeline_layouts; @@ -2441,8 +2508,13 @@ 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; struct wined3d_allocator_block *wined3d_context_vk_allocate_memory(struct wined3d_context_vk *context_vk, unsigned int memory_type, VkDeviceSize size, VkDeviceMemory *vk_memory) 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, unsigned int pool, size_t size) DECLSPEC_HIDDEN; VkCommandBuffer wined3d_context_vk_apply_compute_state(struct wined3d_context_vk *context_vk, @@ -2481,6 +2553,9 @@ void wined3d_context_vk_image_barrier(struct wined3d_context_vk *context_vk, VkImageLayout new_layout, VkImage image, VkImageAspectFlags aspect_mask) DECLSPEC_HIDDEN; 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; @@ -5780,6 +5855,12 @@ static inline void wined3d_context_vk_reference_texture(const struct wined3d_con texture_vk->command_buffer_id = context_vk->current_command_buffer.id; }
+static inline void wined3d_context_vk_reference_query(const struct wined3d_context_vk *context_vk, + struct wined3d_query_vk *query_vk) +{ + query_vk->command_buffer_id = context_vk->current_command_buffer.id; +} + static inline void wined3d_context_vk_reference_sampler(const struct wined3d_context_vk *context_vk, struct wined3d_sampler_vk *sampler_vk) { @@ -5859,6 +5940,11 @@ static inline void wined3d_viewport_get_z_range(const struct wined3d_viewport *v *max_z = max(vp->max_z, vp->min_z + 0.001f); }
+static inline BOOL wined3d_bitmap_clear(uint32_t *map, unsigned int idx) +{ + return map[idx >> 5] &= ~(1u << (idx & 0x1f)); +} + static inline BOOL wined3d_bitmap_set(uint32_t *map, unsigned int idx) { return map[idx >> 5] |= (1u << (idx & 0x1f));