diff --git a/dxvk.conf b/dxvk.conf index 6d0aba1e..d029dce2 100644 --- a/dxvk.conf +++ b/dxvk.conf @@ -236,6 +236,14 @@ # d3d11.cachedDynamicResources = "" +# Force-enables the D3D11 context lock via the ID3D10Multithread +# interface. This may be useful to debug race conditions. +# +# Supported values: True, False + +# d3d11.enableContextLock = False + + # Sets number of pipeline compiler threads. # # If the graphics pipeline library feature is enabled, the given diff --git a/src/d3d10/d3d10_multithread.cpp b/src/d3d10/d3d10_multithread.cpp index 65932b53..20a97eef 100644 --- a/src/d3d10/d3d10_multithread.cpp +++ b/src/d3d10/d3d10_multithread.cpp @@ -6,9 +6,12 @@ namespace dxvk { D3D10Multithread::D3D10Multithread( IUnknown* pParent, - BOOL Protected) + BOOL Protected, + BOOL Force) : m_parent (pParent), - m_protected (Protected) { + m_protected (Protected || Force), + m_enabled (Protected), + m_forced (Force) { } @@ -49,12 +52,18 @@ namespace dxvk { BOOL STDMETHODCALLTYPE D3D10Multithread::SetMultithreadProtected( BOOL bMTProtect) { - return std::exchange(m_protected, bMTProtect); + BOOL result = m_enabled; + m_enabled = bMTProtect; + + if (!m_forced) + m_protected = m_enabled; + + return result; } BOOL STDMETHODCALLTYPE D3D10Multithread::GetMultithreadProtected() { - return m_protected; + return m_enabled; } } diff --git a/src/d3d10/d3d10_multithread.h b/src/d3d10/d3d10_multithread.h index 39a736cc..75d4060f 100644 --- a/src/d3d10/d3d10_multithread.h +++ b/src/d3d10/d3d10_multithread.h @@ -64,7 +64,8 @@ namespace dxvk { D3D10Multithread( IUnknown* pParent, - BOOL Protected); + BOOL Protected, + BOOL Force); ~D3D10Multithread(); @@ -95,6 +96,8 @@ namespace dxvk { IUnknown* m_parent; BOOL m_protected; + BOOL m_enabled; + BOOL m_forced; sync::RecursiveSpinlock m_mutex; diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index e754ca60..3aa4d361 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -18,7 +18,7 @@ namespace dxvk { : D3D11CommonContext(pParent, Device, 0, DxvkCsChunkFlag::SingleUse), m_csThread(Device, Device->createContext(DxvkContextType::Primary)), m_maxImplicitDiscardSize(pParent->GetOptions()->maxImplicitDiscardSize), - m_multithread(this, false), + m_multithread(this, false, pParent->GetOptions()->enableContextLock), m_videoContext(this, Device) { EmitCs([ cDevice = m_device, diff --git a/src/d3d11/d3d11_options.cpp b/src/d3d11/d3d11_options.cpp index 4874e114..83c321de 100644 --- a/src/d3d11/d3d11_options.cpp +++ b/src/d3d11/d3d11_options.cpp @@ -25,6 +25,7 @@ namespace dxvk { this->invariantPosition = config.getOption("d3d11.invariantPosition", true); this->floatControls = config.getOption("d3d11.floatControls", true); this->disableMsaa = config.getOption("d3d11.disableMsaa", false); + this->enableContextLock = config.getOption("d3d11.enableContextLock", false); this->deferSurfaceCreation = config.getOption("dxgi.deferSurfaceCreation", false); this->numBackBuffers = config.getOption("dxgi.numBackBuffers", 0); this->maxFrameLatency = config.getOption("dxgi.maxFrameLatency", 0); diff --git a/src/d3d11/d3d11_options.h b/src/d3d11/d3d11_options.h index dcbef7c3..67bceaa5 100644 --- a/src/d3d11/d3d11_options.h +++ b/src/d3d11/d3d11_options.h @@ -111,6 +111,11 @@ namespace dxvk { /// in cached system memory. Enabled automatically when recording /// an api trace. uint32_t cachedDynamicResources; + + /// Always lock immediate context on every API call. May be + /// useful for debugging purposes or when applications have + /// race conditions. + bool enableContextLock; }; } \ No newline at end of file