From 2f64f5b4e706d9825e4809afd72e90365012675b Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 4 Jul 2019 21:37:17 +0200 Subject: [PATCH] [dxvk] Check whether CS thread is busy before synchronizing with it Reduces unnecessary locking overhead, which may be relevant if this function gets called frequently by GetData or WaitForResource. --- src/d3d11/d3d11_context_imm.cpp | 3 ++- src/dxvk/dxvk_cs.cpp | 2 +- src/dxvk/dxvk_cs.h | 15 +++++++++++++-- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index b1200e684..d164f4c03 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -487,7 +487,8 @@ namespace dxvk { // recorded prior to this function will be run FlushCsChunk(); - m_csThread.synchronize(); + if (m_csThread.isBusy()) + m_csThread.synchronize(); } diff --git a/src/dxvk/dxvk_cs.cpp b/src/dxvk/dxvk_cs.cpp index 2ada434d2..704e5bb18 100644 --- a/src/dxvk/dxvk_cs.cpp +++ b/src/dxvk/dxvk_cs.cpp @@ -127,7 +127,7 @@ namespace dxvk { std::unique_lock lock(m_mutex); m_condOnSync.wait(lock, [this] { - return m_chunksPending == 0; + return !m_chunksPending.load(); }); } diff --git a/src/dxvk/dxvk_cs.h b/src/dxvk/dxvk_cs.h index f1dec1eff..b22108c03 100644 --- a/src/dxvk/dxvk_cs.h +++ b/src/dxvk/dxvk_cs.h @@ -407,6 +407,18 @@ namespace dxvk { */ void synchronize(); + /** + * \brief Checks whether the worker thread is busy + * + * Note that this information is only reliable if + * only the calling thread dispatches jobs to the + * worker queue and if the result is \c false. + * \returns \c true if there is still work to do + */ + bool isBusy() const { + return m_chunksPending.load() != 0; + } + private: const Rc m_context; @@ -416,10 +428,9 @@ namespace dxvk { std::condition_variable m_condOnAdd; std::condition_variable m_condOnSync; std::queue m_chunksQueued; + std::atomic m_chunksPending = { 0u }; dxvk::thread m_thread; - uint32_t m_chunksPending = 0; - void threadFunc(); };