=?UTF-8?Q?J=C3=B3zef=20Kucia=20?=: vkd3d: Implement SO statistics queries.

Alexandre Julliard julliard at winehq.org
Wed Feb 20 16:34:06 CST 2019


Module: vkd3d
Branch: master
Commit: 2ce7b2305a70eb299d3fccca8cdd0fb62d2e0e02
URL:    https://source.winehq.org/git/vkd3d.git/?a=commit;h=2ce7b2305a70eb299d3fccca8cdd0fb62d2e0e02

Author: Józef Kucia <jkucia at codeweavers.com>
Date:   Wed Feb 20 13:42:50 2019 +0100

vkd3d: Implement SO statistics queries.

Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 include/vkd3d_d3d12.idl    |  6 ++++++
 libs/vkd3d/command.c       | 35 +++++++++++++++++++++++++++++++----
 libs/vkd3d/device.c        |  1 +
 libs/vkd3d/resource.c      | 13 ++++++++++---
 libs/vkd3d/vkd3d_private.h |  1 +
 tests/d3d12.c              | 11 ++++++++---
 6 files changed, 57 insertions(+), 10 deletions(-)

diff --git a/include/vkd3d_d3d12.idl b/include/vkd3d_d3d12.idl
index 8b2e70f..231123b 100644
--- a/include/vkd3d_d3d12.idl
+++ b/include/vkd3d_d3d12.idl
@@ -1749,6 +1749,12 @@ typedef struct D3D12_QUERY_DATA_PIPELINE_STATISTICS
     UINT64 CSInvocations;
 } D3D12_QUERY_DATA_PIPELINE_STATISTICS;
 
+typedef struct D3D12_QUERY_DATA_SO_STATISTICS
+{
+    UINT64 NumPrimitivesWritten;
+    UINT64 PrimitivesStorageNeeded;
+} D3D12_QUERY_DATA_SO_STATISTICS;
+
 typedef enum D3D12_PREDICATION_OP
 {
     D3D12_PREDICATION_OP_EQUAL_ZERO = 0,
diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c
index 7457ae3..5b11c3c 100644
--- a/libs/vkd3d/command.c
+++ b/libs/vkd3d/command.c
@@ -4080,10 +4080,19 @@ static void STDMETHODCALLTYPE d3d12_command_list_BeginQuery(ID3D12GraphicsComman
 
     d3d12_command_list_end_current_render_pass(list);
 
+    VK_CALL(vkCmdResetQueryPool(list->vk_command_buffer, query_heap->vk_query_pool, index, 1));
+
     if (type == D3D12_QUERY_TYPE_OCCLUSION)
         flags = VK_QUERY_CONTROL_PRECISE_BIT;
 
-    VK_CALL(vkCmdResetQueryPool(list->vk_command_buffer, query_heap->vk_query_pool, index, 1));
+    if (D3D12_QUERY_TYPE_SO_STATISTICS_STREAM0 <= type && type <= D3D12_QUERY_TYPE_SO_STATISTICS_STREAM3)
+    {
+        unsigned int stream_index = type - D3D12_QUERY_TYPE_SO_STATISTICS_STREAM0;
+        VK_CALL(vkCmdBeginQueryIndexedEXT(list->vk_command_buffer,
+                query_heap->vk_query_pool, index, flags, stream_index));
+        return;
+    }
+
     VK_CALL(vkCmdBeginQuery(list->vk_command_buffer, query_heap->vk_query_pool, index, flags));
 }
 
@@ -4110,9 +4119,28 @@ static void STDMETHODCALLTYPE d3d12_command_list_EndQuery(ID3D12GraphicsCommandL
         return;
     }
 
+    if (D3D12_QUERY_TYPE_SO_STATISTICS_STREAM0 <= type && type <= D3D12_QUERY_TYPE_SO_STATISTICS_STREAM3)
+    {
+        unsigned int stream_index = type - D3D12_QUERY_TYPE_SO_STATISTICS_STREAM0;
+        VK_CALL(vkCmdEndQueryIndexedEXT(list->vk_command_buffer,
+                query_heap->vk_query_pool, index, stream_index));
+        return;
+    }
+
     VK_CALL(vkCmdEndQuery(list->vk_command_buffer, query_heap->vk_query_pool, index));
 }
 
+static size_t get_query_stride(D3D12_QUERY_TYPE type)
+{
+    if (type == D3D12_QUERY_TYPE_PIPELINE_STATISTICS)
+        return sizeof(D3D12_QUERY_DATA_PIPELINE_STATISTICS);
+
+    if (D3D12_QUERY_TYPE_SO_STATISTICS_STREAM0 <= type && type <= D3D12_QUERY_TYPE_SO_STATISTICS_STREAM3)
+        return sizeof(D3D12_QUERY_DATA_SO_STATISTICS);
+
+    return sizeof(uint64_t);
+}
+
 static void STDMETHODCALLTYPE d3d12_command_list_ResolveQueryData(ID3D12GraphicsCommandList *iface,
         ID3D12QueryHeap *heap, D3D12_QUERY_TYPE type, UINT start_index, UINT query_count,
         ID3D12Resource *dst_buffer, UINT64 aligned_dst_buffer_offset)
@@ -4120,9 +4148,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResolveQueryData(ID3D12Graphics
     const struct d3d12_query_heap *query_heap = unsafe_impl_from_ID3D12QueryHeap(heap);
     struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList(iface);
     struct d3d12_resource *buffer = unsafe_impl_from_ID3D12Resource(dst_buffer);
-    VkDeviceSize offset, stride = sizeof(uint64_t);
     const struct vkd3d_vk_device_procs *vk_procs;
     unsigned int i, first, count;
+    VkDeviceSize offset, stride;
 
     TRACE("iface %p, heap %p, type %#x, start_index %u, query_count %u, "
             "dst_buffer %p, aligned_dst_buffer_offset %#"PRIx64".\n",
@@ -4149,8 +4177,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResolveQueryData(ID3D12Graphics
 
     d3d12_command_list_end_current_render_pass(list);
 
-    if (type == D3D12_QUERY_TYPE_PIPELINE_STATISTICS)
-        stride = sizeof(struct D3D12_QUERY_DATA_PIPELINE_STATISTICS);
+    stride = get_query_stride(type);
 
     count = 0;
     first = start_index;
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c
index df59a49..3d9b8c9 100644
--- a/libs/vkd3d/device.c
+++ b/libs/vkd3d/device.c
@@ -945,6 +945,7 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device,
     vulkan_info->device_limits = device_properties2.properties.limits;
     vulkan_info->sparse_properties = device_properties2.properties.sparseProperties;
     vulkan_info->rasterization_stream = xfb_properties.transformFeedbackRasterizationStreamSelect;
+    vulkan_info->transform_feedback_queries = xfb_properties.transformFeedbackQueries;
     vulkan_info->max_vertex_attrib_divisor = max(vertex_divisor_properties.maxVertexAttribDivisor, 1);
 
     device->feature_options.DoublePrecisionFloatShaderOps = features->shaderFloat64;
diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c
index 34f558d..1176538 100644
--- a/libs/vkd3d/resource.c
+++ b/libs/vkd3d/resource.c
@@ -2835,9 +2835,16 @@ HRESULT d3d12_query_heap_create(struct d3d12_device *device, const D3D12_QUERY_H
             break;
 
         case D3D12_QUERY_HEAP_TYPE_SO_STATISTICS:
-            FIXME("Unsupported query heap type SO_STATISTICS.\n");
-            vkd3d_free(object);
-            return E_NOTIMPL;
+            if (!device->vk_info.transform_feedback_queries)
+            {
+                FIXME("Transform feedback queries are not supported by Vulkan implementation.\n");
+                vkd3d_free(object);
+                return E_NOTIMPL;
+            }
+
+            pool_info.queryType = VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT;
+            pool_info.pipelineStatistics = 0;
+            break;
 
         default:
             WARN("Invalid query heap type %u.\n", desc->Type);
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
index dee129e..9b2fbaf 100644
--- a/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/vkd3d_private.h
@@ -93,6 +93,7 @@ struct vkd3d_vulkan_info
     bool EXT_vertex_attribute_divisor;
 
     bool rasterization_stream;
+    bool transform_feedback_queries;
 
     bool vertex_attrib_zero_divisor;
     unsigned int max_vertex_attrib_divisor;
diff --git a/tests/d3d12.c b/tests/d3d12.c
index 259f0ca..e83ea48 100644
--- a/tests/d3d12.c
+++ b/tests/d3d12.c
@@ -19007,10 +19007,15 @@ static void test_create_query_heap(void)
     heap_desc.NodeMask = 0;
 
     hr = ID3D12Device_CreateQueryHeap(device, &heap_desc, &IID_ID3D12QueryHeap, (void **)&query_heap);
-    todo ok(hr == S_OK, "Failed to create query heap, type %u, hr %#x.\n", heap_desc.Type, hr);
-
-    if (hr == S_OK)
+    if (hr != E_NOTIMPL)
+    {
+        ok(hr == S_OK, "Failed to create query heap, type %u, hr %#x.\n", heap_desc.Type, hr);
         ID3D12QueryHeap_Release(query_heap);
+    }
+    else
+    {
+        skip("Stream output is not supported.\n");
+    }
 
     refcount = ID3D12Device_Release(device);
     ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);




More information about the wine-cvs mailing list