From f2f1f86500b1dd85ec8ef46806f8bfea1d845be9 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 5 Jul 2022 18:11:42 +0200 Subject: [PATCH] [dxvk] Use new worker thread system in state cache --- src/dxvk/dxvk_pipemanager.cpp | 12 ++++----- src/dxvk/dxvk_pipemanager.h | 5 +++- src/dxvk/dxvk_state_cache.cpp | 51 +++++++++++------------------------ src/dxvk/dxvk_state_cache.h | 23 +++++++--------- 4 files changed, 33 insertions(+), 58 deletions(-) diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index 9c2d96ba2..195528bdc 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -165,7 +165,9 @@ namespace dxvk { DxvkDevice* device) : m_device (device), m_cache (device), - m_stateCache(device, this) { + m_workers (device, &m_cache), + m_stateCache(device, this, &m_workers) { + } @@ -277,13 +279,9 @@ namespace dxvk { } - bool DxvkPipelineManager::isCompilingShaders() const { - return m_stateCache.isCompilingShaders(); - } - - void DxvkPipelineManager::stopWorkerThreads() { - m_stateCache.stopWorkerThreads(); + m_workers.stopWorkers(); + m_stateCache.stopWorkers(); } diff --git a/src/dxvk/dxvk_pipemanager.h b/src/dxvk/dxvk_pipemanager.h index 959259765..c0cc476eb 100644 --- a/src/dxvk/dxvk_pipemanager.h +++ b/src/dxvk/dxvk_pipemanager.h @@ -201,7 +201,9 @@ namespace dxvk { * \brief Checks whether async compiler is busy * \returns \c true if shaders are being compiled */ - bool isCompilingShaders() const; + bool isCompilingShaders() const { + return m_workers.isBusy(); + } /** * \brief Stops async compiler threads @@ -212,6 +214,7 @@ namespace dxvk { DxvkDevice* m_device; DxvkPipelineCache m_cache; + DxvkPipelineWorkers m_workers; DxvkStateCache m_stateCache; std::atomic m_numComputePipelines = { 0 }; diff --git a/src/dxvk/dxvk_state_cache.cpp b/src/dxvk/dxvk_state_cache.cpp index e3a6466f2..8c0412b84 100644 --- a/src/dxvk/dxvk_state_cache.cpp +++ b/src/dxvk/dxvk_state_cache.cpp @@ -214,9 +214,11 @@ namespace dxvk { DxvkStateCache::DxvkStateCache( DxvkDevice* device, - DxvkPipelineManager* pipeManager) + DxvkPipelineManager* pipeManager, + DxvkPipelineWorkers* pipeWorkers) : m_device (device), - m_pipeManager (pipeManager) { + m_pipeManager (pipeManager), + m_pipeWorkers (pipeWorkers) { std::string useStateCache = env::getEnvVar("DXVK_STATE_CACHE"); m_enable = useStateCache != "0" && device->config().enableStateCache; @@ -253,7 +255,7 @@ namespace dxvk { DxvkStateCache::~DxvkStateCache() { - this->stopWorkerThreads(); + this->stopWorkers(); } @@ -346,12 +348,12 @@ namespace dxvk { if (workerLock) { m_workerCond.notify_all(); - createWorkers(); + createWorker(); } } - void DxvkStateCache::stopWorkerThreads() { + void DxvkStateCache::stopWorkers() { { std::lock_guard workerLock(m_workerLock); std::lock_guard writerLock(m_writerLock); @@ -362,8 +364,8 @@ namespace dxvk { m_writerCond.notify_all(); } - for (auto& worker : m_workerThreads) - worker.join(); + if (m_workerThread.joinable()) + m_workerThread.join(); if (m_writerThread.joinable()) m_writerThread.join(); @@ -420,7 +422,7 @@ namespace dxvk { for (auto e = entries.first; e != entries.second; e++) { const auto& entry = m_entries[e->second]; - pipeline->compilePipeline(entry.gpState); + m_pipeWorkers->compileGraphicsPipeline(pipeline, entry.gpState); } } else { auto pipeline = m_pipeManager->createComputePipeline(item.cp); @@ -428,7 +430,7 @@ namespace dxvk { for (auto e = entries.first; e != entries.second; e++) { const auto& entry = m_entries[e->second]; - pipeline->compilePipeline(entry.cpState); + m_pipeWorkers->compileComputePipeline(pipeline, entry.cpState); } } } @@ -704,7 +706,7 @@ namespace dxvk { void DxvkStateCache::workerFunc() { - env::setThreadName("dxvk-shader"); + env::setThreadName("dxvk-worker"); while (!m_stopThreads.load()) { WorkerItem item; @@ -712,14 +714,10 @@ namespace dxvk { { std::unique_lock lock(m_workerLock); if (m_workerQueue.empty()) { - m_workerBusy -= 1; m_workerCond.wait(lock, [this] () { return m_workerQueue.size() || m_stopThreads.load(); }); - - if (!m_workerQueue.empty()) - m_workerBusy += 1; } if (m_workerQueue.empty()) @@ -767,28 +765,9 @@ namespace dxvk { } - void DxvkStateCache::createWorkers() { - if (m_workerThreads.empty()) { - // Use half the available CPU cores for pipeline compilation - uint32_t numCpuCores = dxvk::thread::hardware_concurrency(); - uint32_t numWorkers = ((std::max(1u, numCpuCores) - 1) * 5) / 7; - - if (numWorkers < 1) numWorkers = 1; - if (numWorkers > 32) numWorkers = 32; - - if (m_device->config().numCompilerThreads > 0) - numWorkers = m_device->config().numCompilerThreads; - - Logger::info(str::format("DXVK: Using ", numWorkers, " compiler threads")); - - // Start the worker threads and the file writer - m_workerBusy.store(numWorkers); - - for (uint32_t i = 0; i < numWorkers; i++) { - m_workerThreads.emplace_back([this] () { workerFunc(); }); - m_workerThreads[i].set_priority(ThreadPriority::Lowest); - } - } + void DxvkStateCache::createWorker() { + if (!m_workerThread.joinable()) + m_workerThread = dxvk::thread([this] () { workerFunc(); }); } diff --git a/src/dxvk/dxvk_state_cache.h b/src/dxvk/dxvk_state_cache.h index 9fb6b52a9..1fae1b097 100644 --- a/src/dxvk/dxvk_state_cache.h +++ b/src/dxvk/dxvk_state_cache.h @@ -13,6 +13,8 @@ namespace dxvk { class DxvkDevice; + class DxvkPipelineManager; + class DxvkPipelineWorkers; /** * \brief State cache @@ -29,8 +31,9 @@ namespace dxvk { DxvkStateCache( DxvkDevice* device, - DxvkPipelineManager* pipeManager); - + DxvkPipelineManager* pipeManager, + DxvkPipelineWorkers* pipeWorkers); + ~DxvkStateCache(); /** @@ -72,15 +75,7 @@ namespace dxvk { /** * \brief Explicitly stops worker threads */ - void stopWorkerThreads(); - - /** - * \brief Checks whether compiler threads are busy - * \returns \c true if we're compiling shaders - */ - bool isCompilingShaders() const { - return m_workerBusy.load() > 0; - } + void stopWorkers(); private: @@ -93,6 +88,7 @@ namespace dxvk { DxvkDevice* m_device; DxvkPipelineManager* m_pipeManager; + DxvkPipelineWorkers* m_pipeWorkers; bool m_enable = false; std::vector m_entries; @@ -115,8 +111,7 @@ namespace dxvk { dxvk::mutex m_workerLock; dxvk::condition_variable m_workerCond; std::queue m_workerQueue; - std::atomic m_workerBusy; - std::vector m_workerThreads; + dxvk::thread m_workerThread; dxvk::mutex m_writerLock; dxvk::condition_variable m_writerCond; @@ -160,7 +155,7 @@ namespace dxvk { void writerFunc(); - void createWorkers(); + void createWorker(); void createWriter();