From 85684109b306edc6bcdcf4a93d8d9751873e2199 Mon Sep 17 00:00:00 2001
From: Philip Rebohle <philip.rebohle@tu-dortmund.de>
Date: Wed, 30 Oct 2024 16:01:17 +0100
Subject: [PATCH] [dxvk] Add method to wait for fence as a GPU sync point

---
 src/dxvk/dxvk_device.cpp | 16 ++++++++++++++++
 src/dxvk/dxvk_device.h   | 11 +++++++++++
 2 files changed, 27 insertions(+)

diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp
index 335b92d5d..830f98d87 100644
--- a/src/dxvk/dxvk_device.cpp
+++ b/src/dxvk/dxvk_device.cpp
@@ -292,6 +292,22 @@ namespace dxvk {
   }
 
 
+  void DxvkDevice::waitForFence(sync::Fence& fence, uint64_t value) {
+    if (fence.value() >= value)
+      return;
+
+    auto t0 = dxvk::high_resolution_clock::now();
+
+    fence.wait(value);
+
+    auto t1 = dxvk::high_resolution_clock::now();
+    auto us = std::chrono::duration_cast<std::chrono::microseconds>(t1 - t0);
+
+    m_statCounters.addCtr(DxvkStatCounter::GpuSyncCount, 1);
+    m_statCounters.addCtr(DxvkStatCounter::GpuSyncTicks, us.count());
+  }
+
+
   void DxvkDevice::waitForResource(const DxvkPagedResource& resource, DxvkAccess access) {
     if (resource.isInUse(access)) {
       auto t0 = dxvk::high_resolution_clock::now();
diff --git a/src/dxvk/dxvk_device.h b/src/dxvk/dxvk_device.h
index ec3e02981..1d07cfb6b 100644
--- a/src/dxvk/dxvk_device.h
+++ b/src/dxvk/dxvk_device.h
@@ -518,6 +518,17 @@ namespace dxvk {
      */
     VkResult waitForSubmission(DxvkSubmitStatus* status);
 
+    /**
+     * \brief Waits for a fence to become signaled
+     *
+     * Treats the fence wait as a GPU sync point, which can
+     * be useful for device statistics. Should only be used
+     * if rendering is stalled because of this wait.
+     * \param [in] fence Fence to wait on
+     * \param [in] value Fence value
+     */
+    void waitForFence(sync::Fence& fence, uint64_t value);
+
     /**
      * \brief Waits for resource to become idle
      *