mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-22 07:54:15 +01:00
[dxvk] Use new worker thread system in state cache
This commit is contained in:
parent
02e6a212bb
commit
f2f1f86500
@ -165,7 +165,9 @@ namespace dxvk {
|
|||||||
DxvkDevice* device)
|
DxvkDevice* device)
|
||||||
: m_device (device),
|
: m_device (device),
|
||||||
m_cache (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() {
|
void DxvkPipelineManager::stopWorkerThreads() {
|
||||||
m_stateCache.stopWorkerThreads();
|
m_workers.stopWorkers();
|
||||||
|
m_stateCache.stopWorkers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -201,7 +201,9 @@ namespace dxvk {
|
|||||||
* \brief Checks whether async compiler is busy
|
* \brief Checks whether async compiler is busy
|
||||||
* \returns \c true if shaders are being compiled
|
* \returns \c true if shaders are being compiled
|
||||||
*/
|
*/
|
||||||
bool isCompilingShaders() const;
|
bool isCompilingShaders() const {
|
||||||
|
return m_workers.isBusy();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Stops async compiler threads
|
* \brief Stops async compiler threads
|
||||||
@ -212,6 +214,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
DxvkDevice* m_device;
|
DxvkDevice* m_device;
|
||||||
DxvkPipelineCache m_cache;
|
DxvkPipelineCache m_cache;
|
||||||
|
DxvkPipelineWorkers m_workers;
|
||||||
DxvkStateCache m_stateCache;
|
DxvkStateCache m_stateCache;
|
||||||
|
|
||||||
std::atomic<uint32_t> m_numComputePipelines = { 0 };
|
std::atomic<uint32_t> m_numComputePipelines = { 0 };
|
||||||
|
@ -214,9 +214,11 @@ namespace dxvk {
|
|||||||
|
|
||||||
DxvkStateCache::DxvkStateCache(
|
DxvkStateCache::DxvkStateCache(
|
||||||
DxvkDevice* device,
|
DxvkDevice* device,
|
||||||
DxvkPipelineManager* pipeManager)
|
DxvkPipelineManager* pipeManager,
|
||||||
|
DxvkPipelineWorkers* pipeWorkers)
|
||||||
: m_device (device),
|
: m_device (device),
|
||||||
m_pipeManager (pipeManager) {
|
m_pipeManager (pipeManager),
|
||||||
|
m_pipeWorkers (pipeWorkers) {
|
||||||
std::string useStateCache = env::getEnvVar("DXVK_STATE_CACHE");
|
std::string useStateCache = env::getEnvVar("DXVK_STATE_CACHE");
|
||||||
m_enable = useStateCache != "0" && device->config().enableStateCache;
|
m_enable = useStateCache != "0" && device->config().enableStateCache;
|
||||||
|
|
||||||
@ -253,7 +255,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
DxvkStateCache::~DxvkStateCache() {
|
DxvkStateCache::~DxvkStateCache() {
|
||||||
this->stopWorkerThreads();
|
this->stopWorkers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -346,12 +348,12 @@ namespace dxvk {
|
|||||||
|
|
||||||
if (workerLock) {
|
if (workerLock) {
|
||||||
m_workerCond.notify_all();
|
m_workerCond.notify_all();
|
||||||
createWorkers();
|
createWorker();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DxvkStateCache::stopWorkerThreads() {
|
void DxvkStateCache::stopWorkers() {
|
||||||
{ std::lock_guard<dxvk::mutex> workerLock(m_workerLock);
|
{ std::lock_guard<dxvk::mutex> workerLock(m_workerLock);
|
||||||
std::lock_guard<dxvk::mutex> writerLock(m_writerLock);
|
std::lock_guard<dxvk::mutex> writerLock(m_writerLock);
|
||||||
|
|
||||||
@ -362,8 +364,8 @@ namespace dxvk {
|
|||||||
m_writerCond.notify_all();
|
m_writerCond.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& worker : m_workerThreads)
|
if (m_workerThread.joinable())
|
||||||
worker.join();
|
m_workerThread.join();
|
||||||
|
|
||||||
if (m_writerThread.joinable())
|
if (m_writerThread.joinable())
|
||||||
m_writerThread.join();
|
m_writerThread.join();
|
||||||
@ -420,7 +422,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
for (auto e = entries.first; e != entries.second; e++) {
|
for (auto e = entries.first; e != entries.second; e++) {
|
||||||
const auto& entry = m_entries[e->second];
|
const auto& entry = m_entries[e->second];
|
||||||
pipeline->compilePipeline(entry.gpState);
|
m_pipeWorkers->compileGraphicsPipeline(pipeline, entry.gpState);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto pipeline = m_pipeManager->createComputePipeline(item.cp);
|
auto pipeline = m_pipeManager->createComputePipeline(item.cp);
|
||||||
@ -428,7 +430,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
for (auto e = entries.first; e != entries.second; e++) {
|
for (auto e = entries.first; e != entries.second; e++) {
|
||||||
const auto& entry = m_entries[e->second];
|
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() {
|
void DxvkStateCache::workerFunc() {
|
||||||
env::setThreadName("dxvk-shader");
|
env::setThreadName("dxvk-worker");
|
||||||
|
|
||||||
while (!m_stopThreads.load()) {
|
while (!m_stopThreads.load()) {
|
||||||
WorkerItem item;
|
WorkerItem item;
|
||||||
@ -712,14 +714,10 @@ namespace dxvk {
|
|||||||
{ std::unique_lock<dxvk::mutex> lock(m_workerLock);
|
{ std::unique_lock<dxvk::mutex> lock(m_workerLock);
|
||||||
|
|
||||||
if (m_workerQueue.empty()) {
|
if (m_workerQueue.empty()) {
|
||||||
m_workerBusy -= 1;
|
|
||||||
m_workerCond.wait(lock, [this] () {
|
m_workerCond.wait(lock, [this] () {
|
||||||
return m_workerQueue.size()
|
return m_workerQueue.size()
|
||||||
|| m_stopThreads.load();
|
|| m_stopThreads.load();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!m_workerQueue.empty())
|
|
||||||
m_workerBusy += 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_workerQueue.empty())
|
if (m_workerQueue.empty())
|
||||||
@ -767,28 +765,9 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DxvkStateCache::createWorkers() {
|
void DxvkStateCache::createWorker() {
|
||||||
if (m_workerThreads.empty()) {
|
if (!m_workerThread.joinable())
|
||||||
// Use half the available CPU cores for pipeline compilation
|
m_workerThread = dxvk::thread([this] () { workerFunc(); });
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
class DxvkDevice;
|
class DxvkDevice;
|
||||||
|
class DxvkPipelineManager;
|
||||||
|
class DxvkPipelineWorkers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief State cache
|
* \brief State cache
|
||||||
@ -29,7 +31,8 @@ namespace dxvk {
|
|||||||
|
|
||||||
DxvkStateCache(
|
DxvkStateCache(
|
||||||
DxvkDevice* device,
|
DxvkDevice* device,
|
||||||
DxvkPipelineManager* pipeManager);
|
DxvkPipelineManager* pipeManager,
|
||||||
|
DxvkPipelineWorkers* pipeWorkers);
|
||||||
|
|
||||||
~DxvkStateCache();
|
~DxvkStateCache();
|
||||||
|
|
||||||
@ -72,15 +75,7 @@ namespace dxvk {
|
|||||||
/**
|
/**
|
||||||
* \brief Explicitly stops worker threads
|
* \brief Explicitly stops worker threads
|
||||||
*/
|
*/
|
||||||
void stopWorkerThreads();
|
void stopWorkers();
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Checks whether compiler threads are busy
|
|
||||||
* \returns \c true if we're compiling shaders
|
|
||||||
*/
|
|
||||||
bool isCompilingShaders() const {
|
|
||||||
return m_workerBusy.load() > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -93,6 +88,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
DxvkDevice* m_device;
|
DxvkDevice* m_device;
|
||||||
DxvkPipelineManager* m_pipeManager;
|
DxvkPipelineManager* m_pipeManager;
|
||||||
|
DxvkPipelineWorkers* m_pipeWorkers;
|
||||||
bool m_enable = false;
|
bool m_enable = false;
|
||||||
|
|
||||||
std::vector<DxvkStateCacheEntry> m_entries;
|
std::vector<DxvkStateCacheEntry> m_entries;
|
||||||
@ -115,8 +111,7 @@ namespace dxvk {
|
|||||||
dxvk::mutex m_workerLock;
|
dxvk::mutex m_workerLock;
|
||||||
dxvk::condition_variable m_workerCond;
|
dxvk::condition_variable m_workerCond;
|
||||||
std::queue<WorkerItem> m_workerQueue;
|
std::queue<WorkerItem> m_workerQueue;
|
||||||
std::atomic<uint32_t> m_workerBusy;
|
dxvk::thread m_workerThread;
|
||||||
std::vector<dxvk::thread> m_workerThreads;
|
|
||||||
|
|
||||||
dxvk::mutex m_writerLock;
|
dxvk::mutex m_writerLock;
|
||||||
dxvk::condition_variable m_writerCond;
|
dxvk::condition_variable m_writerCond;
|
||||||
@ -160,7 +155,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
void writerFunc();
|
void writerFunc();
|
||||||
|
|
||||||
void createWorkers();
|
void createWorker();
|
||||||
|
|
||||||
void createWriter();
|
void createWriter();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user