[PATCH 4/5] wined3d: Implement timestamp queries for the Vulkan adapter.
Henri Verbeet
hverbeet at codeweavers.com
Tue May 26 11:10:12 CDT 2020
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
dlls/wined3d/adapter_vk.c | 7 ++--
dlls/wined3d/context_vk.c | 6 ++++
dlls/wined3d/query.c | 66 +++++++++++++++++++++++++++++++++-
dlls/wined3d/wined3d_private.h | 2 ++
4 files changed, 78 insertions(+), 3 deletions(-)
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c
index 84eda1e551b..3cccda3b2c6 100644
--- a/dlls/wined3d/adapter_vk.c
+++ b/dlls/wined3d/adapter_vk.c
@@ -292,7 +292,7 @@ static void adapter_vk_destroy(struct wined3d_adapter *adapter)
}
static HRESULT wined3d_select_vulkan_queue_family(const struct wined3d_adapter_vk *adapter_vk,
- uint32_t *queue_family_index)
+ uint32_t *queue_family_index, uint32_t *timestamp_bits)
{
VkPhysicalDevice physical_device = adapter_vk->physical_device;
const struct wined3d_vk_info *vk_info = &adapter_vk->vk_info;
@@ -311,6 +311,7 @@ static HRESULT wined3d_select_vulkan_queue_family(const struct wined3d_adapter_v
if (queue_properties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
{
*queue_family_index = i;
+ *timestamp_bits = queue_properties[i].timestampValidBits;
heap_free(queue_properties);
return WINED3D_OK;
}
@@ -496,13 +497,14 @@ static HRESULT adapter_vk_create_device(struct wined3d *wined3d, const struct wi
VkPhysicalDevice physical_device;
VkDeviceCreateInfo device_info;
uint32_t queue_family_index;
+ uint32_t timestamp_bits;
VkResult vr;
HRESULT hr;
if (!(device_vk = heap_alloc_zero(sizeof(*device_vk))))
return E_OUTOFMEMORY;
- if (FAILED(hr = wined3d_select_vulkan_queue_family(adapter_vk, &queue_family_index)))
+ if (FAILED(hr = wined3d_select_vulkan_queue_family(adapter_vk, &queue_family_index, ×tamp_bits)))
goto fail;
physical_device = adapter_vk->physical_device;
@@ -564,6 +566,7 @@ static HRESULT adapter_vk_create_device(struct wined3d *wined3d, const struct wi
device_vk->vk_device = vk_device;
VK_CALL(vkGetDeviceQueue(vk_device, queue_family_index, 0, &device_vk->vk_queue));
device_vk->vk_queue_family_index = queue_family_index;
+ device_vk->timestamp_bits = timestamp_bits;
device_vk->vk_info = *vk_info;
#define LOAD_DEVICE_PFN(name) \
diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c
index 2964eb30cc4..af29ef7e7a7 100644
--- a/dlls/wined3d/context_vk.c
+++ b/dlls/wined3d/context_vk.c
@@ -1227,6 +1227,10 @@ bool wined3d_context_vk_allocate_query(struct wined3d_context_vk *context_vk,
free_pools = &context_vk->free_occlusion_query_pools;
break;
+ case WINED3D_QUERY_TYPE_TIMESTAMP:
+ free_pools = &context_vk->free_timestamp_query_pools;
+ break;
+
default:
FIXME("Unhandled query type %#x.\n", type);
return false;
@@ -1286,6 +1290,7 @@ void wined3d_context_vk_cleanup(struct wined3d_context_vk *context_vk)
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);
+ wined3d_context_vk_destroy_query_pools(context_vk, &context_vk->free_timestamp_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);
@@ -3057,6 +3062,7 @@ HRESULT wined3d_context_vk_init(struct wined3d_context_vk *context_vk, struct wi
list_init(&context_vk->active_queries);
list_init(&context_vk->free_occlusion_query_pools);
+ list_init(&context_vk->free_timestamp_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);
diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c
index b72ffd633c5..3b6f442f4a7 100644
--- a/dlls/wined3d/query.c
+++ b/dlls/wined3d/query.c
@@ -1403,6 +1403,11 @@ bool wined3d_query_pool_vk_init(struct wined3d_query_pool_vk *pool_vk,
pool_info.pipelineStatistics = 0;
break;
+ case WINED3D_QUERY_TYPE_TIMESTAMP:
+ pool_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
+ pool_info.pipelineStatistics = 0;
+ break;
+
default:
FIXME("Unhandled query type %#x.\n", type);
return false;
@@ -1428,6 +1433,7 @@ bool wined3d_query_vk_accumulate_data(struct wined3d_query_vk *query_vk,
union
{
uint64_t occlusion;
+ uint64_t timestamp;
} tmp, *result;
if ((vr = VK_CALL(vkGetQueryPoolResults(device_vk->vk_device, pool_idx->pool_vk->vk_query_pool,
@@ -1447,6 +1453,10 @@ bool wined3d_query_vk_accumulate_data(struct wined3d_query_vk *query_vk,
result->occlusion += tmp.occlusion;
break;
+ case WINED3D_QUERY_TYPE_TIMESTAMP:
+ result->timestamp = tmp.timestamp;
+ break;
+
default:
FIXME("Unhandled query type %#x.\n", query_vk->q.type);
return false;
@@ -1607,9 +1617,53 @@ static const struct wined3d_query_ops wined3d_query_vk_ops =
.query_destroy = wined3d_query_vk_destroy,
};
+static BOOL wined3d_query_timestamp_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);
+ const struct wined3d_vk_info *vk_info;
+ struct wined3d_context_vk *context_vk;
+ VkCommandBuffer command_buffer;
+
+ TRACE("query %p, flags %#x.\n", query, flags);
+
+ if (flags & WINED3DISSUE_BEGIN)
+ TRACE("Ignoring WINED3DISSUE_BEGIN.\n");
+
+ if (flags & WINED3DISSUE_END)
+ {
+ context_vk = wined3d_context_vk(context_acquire(&device_vk->d, NULL, 0));
+ vk_info = context_vk->vk_info;
+
+ wined3d_context_vk_end_current_render_pass(context_vk);
+ command_buffer = wined3d_context_vk_get_command_buffer(context_vk);
+ if (!query_vk->pool_idx.pool_vk)
+ wined3d_context_vk_allocate_query(context_vk, query_vk->q.type, &query_vk->pool_idx);
+ VK_CALL(vkCmdResetQueryPool(command_buffer, query_vk->pool_idx.pool_vk->vk_query_pool,
+ query_vk->pool_idx.idx, 1));
+ VK_CALL(vkCmdWriteTimestamp(command_buffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
+ query_vk->pool_idx.pool_vk->vk_query_pool, query_vk->pool_idx.idx));
+ wined3d_context_vk_reference_query(context_vk, query_vk);
+
+ context_release(&context_vk->c);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static const struct wined3d_query_ops wined3d_query_timestamp_vk_ops =
+{
+ .query_poll = wined3d_query_vk_poll,
+ .query_issue = wined3d_query_timestamp_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)
{
+ const struct wined3d_query_ops *ops = &wined3d_query_vk_ops;
struct wined3d_query_vk *query_vk;
unsigned int data_size;
@@ -1622,6 +1676,16 @@ HRESULT wined3d_query_vk_create(struct wined3d_device *device, enum wined3d_quer
data_size = sizeof(uint64_t);
break;
+ case WINED3D_QUERY_TYPE_TIMESTAMP:
+ if (!wined3d_device_vk(device)->timestamp_bits)
+ {
+ WARN("Timestamp queries not supported.\n");
+ return WINED3DERR_NOTAVAILABLE;
+ }
+ ops = &wined3d_query_timestamp_vk_ops;
+ data_size = sizeof(uint64_t);
+ break;
+
default:
FIXME("Unhandled query type %#x.\n", type);
return WINED3DERR_NOTAVAILABLE;
@@ -1630,7 +1694,7 @@ HRESULT wined3d_query_vk_create(struct wined3d_device *device, enum wined3d_quer
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);
+ wined3d_query_init(&query_vk->q, device, type, query_vk + 1, data_size, ops, parent, parent_ops);
list_init(&query_vk->entry);
if (type == WINED3D_QUERY_TYPE_OCCLUSION)
query_vk->control_flags = VK_QUERY_CONTROL_PRECISE_BIT;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 5c92eecbf3e..9f8c212fbf3 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2495,6 +2495,7 @@ struct wined3d_context_vk
struct list active_queries;
struct wined3d_pending_queries_vk pending_queries;
struct list free_occlusion_query_pools;
+ struct list free_timestamp_query_pools;
struct wined3d_retired_objects_vk retired;
struct wine_rb_tree render_passes;
@@ -3857,6 +3858,7 @@ struct wined3d_device_vk
VkDevice vk_device;
VkQueue vk_queue;
uint32_t vk_queue_family_index;
+ uint32_t timestamp_bits;
struct wined3d_vk_info vk_info;
--
2.20.1
More information about the wine-devel
mailing list