[PATCH vkd3d 2/2] vkd3d: Implement ID3D12CommandQueue::GetClockCalibration().

Conor McCarthy cmccarthy at codeweavers.com
Mon Nov 25 05:58:19 CST 2019


Implemented on top of VK_EXT_calibrated_timestamps.

Signed-off-by: Conor McCarthy <cmccarthy at codeweavers.com>
---
 libs/vkd3d/command.c       | 64 ++++++++++++++++++++++++++++++++++++--
 libs/vkd3d/device.c        |  1 +
 libs/vkd3d/vkd3d_private.h |  1 +
 libs/vkd3d/vulkan_procs.h  |  3 ++
 4 files changed, 67 insertions(+), 2 deletions(-)

diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c
index 1686f0e..bb85bf3 100644
--- a/libs/vkd3d/command.c
+++ b/libs/vkd3d/command.c
@@ -5962,10 +5962,70 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_queue_GetTimestampFrequency(ID3D1
 static HRESULT STDMETHODCALLTYPE d3d12_command_queue_GetClockCalibration(ID3D12CommandQueue *iface,
         UINT64 *gpu_timestamp, UINT64 *cpu_timestamp)
 {
-    FIXME("iface %p, gpu_timestamp %p, cpu_timestamp %p stub!\n",
+    struct d3d12_command_queue *command_queue = impl_from_ID3D12CommandQueue(iface);
+    const struct vkd3d_vk_device_procs *vk_procs = &command_queue->device->vk_procs;
+    const struct vkd3d_vulkan_info *vk_info = &command_queue->device->vk_info;
+    VkCalibratedTimestampInfoEXT infos[4];
+    uint64_t timestamps[4];
+    uint64_t deviations[4];
+    VkResult vr;
+    size_t i;
+
+    TRACE("iface %p, gpu_timestamp %p, cpu_timestamp %p.\n",
             iface, gpu_timestamp, cpu_timestamp);
 
-    return E_NOTIMPL;
+    if (!command_queue->vkd3d_queue->timestamp_bits)
+    {
+        WARN("Timestamp queries not supported.\n");
+        return E_FAIL;
+    }
+
+    if (!gpu_timestamp || !cpu_timestamp)
+        return E_INVALIDARG;
+
+    if (!vk_info->EXT_calibrated_timestamps)
+    {
+        FIXME("VK_EXT_calibrated_timestamps was not found. Calibrated timestamps are not available.\n");
+        return E_NOTIMPL;
+    }
+
+    /* vkGetPhysicalDeviceCalibrateableTimeDomainsEXT() is missing from RADV. */
+    infos[0].sType = VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT;
+    infos[0].pNext = NULL;
+    infos[0].timeDomain = VK_TIME_DOMAIN_DEVICE_EXT;
+    infos[1].sType = VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT;
+    infos[1].pNext = NULL;
+    infos[1].timeDomain = VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT;
+    infos[2].sType = VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT;
+    infos[2].pNext = NULL;
+    infos[2].timeDomain = VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT;
+    infos[3].sType = VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT;
+    infos[3].pNext = NULL;
+    infos[3].timeDomain = VK_TIME_DOMAIN_QUERY_PERFORMANCE_COUNTER_EXT;
+
+    memset(timestamps, 0, sizeof(timestamps));
+    if ((vr = VK_CALL(vkGetCalibratedTimestampsEXT(command_queue->device->vk_device,
+            ARRAY_SIZE(infos), infos, timestamps, deviations))) < 0)
+    {
+        WARN("Failed to get calibrated timestamps, vr %d.\n", vr);
+        return E_FAIL;
+    }
+    /* Convert monotonic clock to Windows ticks. */
+    timestamps[1] /= 100;
+    timestamps[2] /= 100;
+
+    for (i = 1; i < ARRAY_SIZE(infos) && !timestamps[i]; ++i)
+        ;
+    if (i == ARRAY_SIZE(infos))
+    {
+        WARN("Failed to get CPU timestamp.\n");
+        return E_FAIL;
+    }
+
+    *gpu_timestamp = timestamps[0];
+    *cpu_timestamp = timestamps[i];
+
+    return S_OK;
 }
 
 static D3D12_COMMAND_QUEUE_DESC * STDMETHODCALLTYPE d3d12_command_queue_GetDesc(ID3D12CommandQueue *iface,
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c
index 0404b76..119b789 100644
--- a/libs/vkd3d/device.c
+++ b/libs/vkd3d/device.c
@@ -128,6 +128,7 @@ static const struct vkd3d_optional_extension_info optional_device_extensions[] =
     VK_EXTENSION(KHR_MAINTENANCE3, KHR_maintenance3),
     VK_EXTENSION(KHR_PUSH_DESCRIPTOR, KHR_push_descriptor),
     /* EXT extensions */
+    VK_EXTENSION(EXT_CALIBRATED_TIMESTAMPS, EXT_calibrated_timestamps),
     VK_EXTENSION(EXT_CONDITIONAL_RENDERING, EXT_conditional_rendering),
     VK_EXTENSION(EXT_DEBUG_MARKER, EXT_debug_marker),
     VK_EXTENSION(EXT_DEPTH_CLIP_ENABLE, EXT_depth_clip_enable),
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
index 7ba1db4..d1861ce 100644
--- a/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/vkd3d_private.h
@@ -101,6 +101,7 @@ struct vkd3d_vulkan_info
     bool KHR_maintenance3;
     bool KHR_push_descriptor;
     /* EXT device extensions */
+    bool EXT_calibrated_timestamps;
     bool EXT_conditional_rendering;
     bool EXT_debug_marker;
     bool EXT_depth_clip_enable;
diff --git a/libs/vkd3d/vulkan_procs.h b/libs/vkd3d/vulkan_procs.h
index ec29eb4..77ceb71 100644
--- a/libs/vkd3d/vulkan_procs.h
+++ b/libs/vkd3d/vulkan_procs.h
@@ -192,6 +192,9 @@ VK_DEVICE_EXT_PFN(vkGetDescriptorSetLayoutSupportKHR)
 /* VK_KHR_push_descriptor */
 VK_DEVICE_EXT_PFN(vkCmdPushDescriptorSetKHR)
 
+/* VK_EXT_calibrated_timestamps */
+VK_DEVICE_EXT_PFN(vkGetCalibratedTimestampsEXT)
+
 /* VK_EXT_conditional_rendering */
 VK_DEVICE_EXT_PFN(vkCmdBeginConditionalRenderingEXT)
 VK_DEVICE_EXT_PFN(vkCmdEndConditionalRenderingEXT)
-- 
2.24.0




More information about the wine-devel mailing list