From 4db5c21ec5b983334431e9e8f21b9cbaa2ac7d2a Mon Sep 17 00:00:00 2001
From: Philip Rebohle <philip.rebohle@tu-dortmund.de>
Date: Tue, 13 Nov 2018 17:05:37 +0100
Subject: [PATCH] [dxvk] Use ticket lock to synchronize access to query objects

Lowers overhead in the uncontested case compared to std::mutex, and
prevents the main rendering thread from blocking updates for too long.
---
 src/dxvk/dxvk_include.h |  1 +
 src/dxvk/dxvk_query.cpp | 12 ++++++------
 src/dxvk/dxvk_query.h   |  2 +-
 3 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/src/dxvk/dxvk_include.h b/src/dxvk/dxvk_include.h
index 722c37a0..34ef9be6 100644
--- a/src/dxvk/dxvk_include.h
+++ b/src/dxvk/dxvk_include.h
@@ -15,6 +15,7 @@
 #include "../util/sha1/sha1_util.h"
 
 #include "../util/sync/sync_spinlock.h"
+#include "../util/sync/sync_ticketlock.h"
 
 #include "../vulkan/vulkan_loader.h"
 #include "../vulkan/vulkan_names.h"
diff --git a/src/dxvk/dxvk_query.cpp b/src/dxvk/dxvk_query.cpp
index 39c0c5cd..efbecb84 100644
--- a/src/dxvk/dxvk_query.cpp
+++ b/src/dxvk/dxvk_query.cpp
@@ -24,7 +24,7 @@ namespace dxvk {
 
 
   uint32_t DxvkQuery::reset() {
-    std::unique_lock<std::mutex> lock(m_mutex);
+    std::unique_lock<sync::TicketLock> lock(m_mutex);
     
     m_status = DxvkQueryStatus::Reset;
     m_data = DxvkQueryData { };
@@ -37,7 +37,7 @@ namespace dxvk {
   
   
   DxvkQueryStatus DxvkQuery::getData(DxvkQueryData& data) {
-    std::unique_lock<std::mutex> lock(m_mutex);
+    std::unique_lock<sync::TicketLock> lock(m_mutex);
     
     if (m_status == DxvkQueryStatus::Available)
       data = m_data;
@@ -52,7 +52,7 @@ namespace dxvk {
   
   
   void DxvkQuery::beginRecording(uint32_t revision) {
-    std::unique_lock<std::mutex> lock(m_mutex);
+    std::unique_lock<sync::TicketLock> lock(m_mutex);
     
     if (m_revision == revision)
       m_status = DxvkQueryStatus::Active;
@@ -60,7 +60,7 @@ namespace dxvk {
   
   
   void DxvkQuery::endRecording(uint32_t revision) {
-    std::unique_lock<std::mutex> lock(m_mutex);
+    std::unique_lock<sync::TicketLock> lock(m_mutex);
     
     if (m_revision == revision) {
       m_status = m_queryIndex < m_queryCount
@@ -72,7 +72,7 @@ namespace dxvk {
   
   
   void DxvkQuery::associateQuery(uint32_t revision, DxvkQueryHandle handle) {
-    std::unique_lock<std::mutex> lock(m_mutex);
+    std::unique_lock<sync::TicketLock> lock(m_mutex);
     
     if (m_revision == revision)
       m_queryCount += 1;
@@ -86,7 +86,7 @@ namespace dxvk {
   void DxvkQuery::updateData(
           uint32_t       revision,
     const DxvkQueryData& data) {
-    std::unique_lock<std::mutex> lock(m_mutex);
+    std::unique_lock<sync::TicketLock> lock(m_mutex);
     
     if (m_revision == revision) {
       switch (m_type) {
diff --git a/src/dxvk/dxvk_query.h b/src/dxvk/dxvk_query.h
index e1da5912..b5543747 100644
--- a/src/dxvk/dxvk_query.h
+++ b/src/dxvk/dxvk_query.h
@@ -224,7 +224,7 @@ namespace dxvk {
     const VkQueryControlFlags m_flags;
     const uint32_t            m_index;
     
-    std::mutex m_mutex;
+    sync::TicketLock m_mutex;
     
     DxvkQueryStatus m_status   = DxvkQueryStatus::Created;
     DxvkQueryData   m_data     = {};