1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-12-04 16:24:29 +01:00

[dxvk] Explicitly stop state cache worker threads on device destruction

Otherwise, the workers may access objects that are being destroyed an
app thread.
This commit is contained in:
Philip Rebohle 2021-10-07 20:32:41 +02:00
parent 24eb875f02
commit 3e64e1b3f5
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
5 changed files with 40 additions and 14 deletions

View File

@ -29,6 +29,10 @@ namespace dxvk {
// Wait for all pending Vulkan commands to be // Wait for all pending Vulkan commands to be
// executed before we destroy any resources. // executed before we destroy any resources.
this->waitForIdle(); this->waitForIdle();
// Stop workers explicitly in order to prevent
// access to structures that are being destroyed.
m_objects.pipelineManager().stopWorkerThreads();
} }

View File

@ -79,4 +79,10 @@ namespace dxvk {
&& m_stateCache->isCompilingShaders(); && m_stateCache->isCompilingShaders();
} }
void DxvkPipelineManager::stopWorkerThreads() const {
if (m_stateCache != nullptr)
m_stateCache->stopWorkerThreads();
}
} }

View File

@ -90,6 +90,11 @@ namespace dxvk {
*/ */
bool isCompilingShaders() const; bool isCompilingShaders() const;
/**
* \brief Stops async compiler threads
*/
void stopWorkerThreads() const;
private: private:
const DxvkDevice* m_device; const DxvkDevice* m_device;

View File

@ -210,19 +210,7 @@ namespace dxvk {
DxvkStateCache::~DxvkStateCache() { DxvkStateCache::~DxvkStateCache() {
{ std::lock_guard<dxvk::mutex> workerLock(m_workerLock); this->stopWorkerThreads();
std::lock_guard<dxvk::mutex> writerLock(m_writerLock);
m_stopThreads.store(true);
m_workerCond.notify_all();
m_writerCond.notify_all();
}
for (auto& worker : m_workerThreads)
worker.join();
m_writerThread.join();
} }
@ -314,6 +302,24 @@ namespace dxvk {
} }
void DxvkStateCache::stopWorkerThreads() {
{ std::lock_guard<dxvk::mutex> workerLock(m_workerLock);
std::lock_guard<dxvk::mutex> writerLock(m_writerLock);
if (m_stopThreads.exchange(true))
return;
m_workerCond.notify_all();
m_writerCond.notify_all();
}
for (auto& worker : m_workerThreads)
worker.join();
m_writerThread.join();
}
DxvkShaderKey DxvkStateCache::getShaderKey(const Rc<DxvkShader>& shader) const { DxvkShaderKey DxvkStateCache::getShaderKey(const Rc<DxvkShader>& shader) const {
return shader != nullptr ? shader->getShaderKey() : g_nullShaderKey; return shader != nullptr ? shader->getShaderKey() : g_nullShaderKey;
} }

View File

@ -71,6 +71,11 @@ namespace dxvk {
void registerShader( void registerShader(
const Rc<DxvkShader>& shader); const Rc<DxvkShader>& shader);
/**
* \brief Explicitly stops worker threads
*/
void stopWorkerThreads();
/** /**
* \brief Checks whether compiler threads are busy * \brief Checks whether compiler threads are busy
* \returns \c true if we're compiling shaders * \returns \c true if we're compiling shaders