[dxvk] Don't synchronize device if going for DLL shutdown

All our other threads have been destroyed and we can no longer synchronize with them properly.

Co-authored-by: Paul Gofman <pgofman@codeweavers.com>
This commit is contained in:
Joshua Ashton 2022-07-06 17:11:58 +01:00 committed by Philip Rebohle
parent 5ae5476d71
commit e884413c49
7 changed files with 49 additions and 1 deletions

View File

@ -39,6 +39,11 @@ namespace dxvk {
D3D11ImmediateContext::~D3D11ImmediateContext() {
// Avoids hanging when in this state, see comment
// in DxvkDevice::~DxvkDevice.
if (this_thread::isInModuleDetachment())
return;
Flush();
SynchronizeCsThread(DxvkCsThread::SynchronizeAll);
SynchronizeDevice();

View File

@ -35,6 +35,11 @@ namespace dxvk {
D3D11SwapChain::~D3D11SwapChain() {
// Avoids hanging when in this state, see comment
// in DxvkDevice::~DxvkDevice.
if (this_thread::isInModuleDetachment())
return;
m_device->waitForSubmission(&m_presentStatus);
m_device->waitForIdle();

View File

@ -145,6 +145,11 @@ namespace dxvk {
D3D9DeviceEx::~D3D9DeviceEx() {
// Avoids hanging when in this state, see comment
// in DxvkDevice::~DxvkDevice.
if (this_thread::isInModuleDetachment())
return;
Flush();
SynchronizeCsThread(DxvkCsThread::SynchronizeAll);

View File

@ -215,6 +215,11 @@ namespace dxvk {
D3D9SwapChainEx::~D3D9SwapChainEx() {
// Avoids hanging when in this state, see comment
// in DxvkDevice::~DxvkDevice.
if (this_thread::isInModuleDetachment())
return;
DestroyBackBuffers();
ResetWindowProc(m_window);

View File

@ -26,6 +26,13 @@ namespace dxvk {
DxvkDevice::~DxvkDevice() {
// If we are being destroyed during/after DLL process detachment
// from TerminateProcess, etc, our CS threads are already destroyed
// and we cannot synchronize against them.
// The best we can do is just wait for the Vulkan device to be idle.
if (this_thread::isInModuleDetachment())
return;
// Wait for all pending Vulkan commands to be
// executed before we destroy any resources.
this->waitForIdle();

View File

@ -3,7 +3,22 @@
#include <atomic>
#ifndef _WIN32
#ifdef _WIN32
namespace dxvk::this_thread {
bool isInModuleDetachment() {
using PFN_RtlDllShutdownInProgress = BOOLEAN (WINAPI *)();
static auto RtlDllShutdownInProgress = reinterpret_cast<PFN_RtlDllShutdownInProgress>(
::GetProcAddress(::GetModuleHandleW(L"ntdll.dll"), "RtlDllShutdownInProgress"));
return RtlDllShutdownInProgress();
}
}
#else
namespace dxvk::this_thread {

View File

@ -153,6 +153,8 @@ namespace dxvk {
inline uint32_t get_id() {
return uint32_t(GetCurrentThreadId());
}
bool isInModuleDetachment();
}
@ -341,6 +343,10 @@ namespace dxvk {
}
uint32_t get_id();
inline bool isInModuleDetachment() {
return false;
}
}
#endif