diff --git a/renderdoc/driver/d3d11/d3d11_hooks.cpp b/renderdoc/driver/d3d11/d3d11_hooks.cpp index d2fdce747..54f1a934b 100644 --- a/renderdoc/driver/d3d11/d3d11_hooks.cpp +++ b/renderdoc/driver/d3d11/d3d11_hooks.cpp @@ -57,6 +57,9 @@ public: CreateDevice.Register("d3d11.dll", "D3D11CreateDevice", D3D11CreateDevice_hook); CreateDeviceAndSwapChain.Register("d3d11.dll", "D3D11CreateDeviceAndSwapChain", D3D11CreateDeviceAndSwapChain_hook); + + m_RecurseSlot = Threading::AllocateTLSSlot(); + Threading::SetTLSValue(m_RecurseSlot, NULL); } private: @@ -66,7 +69,19 @@ private: HookedFunction CreateDevice; // re-entrancy detection (can happen in rare cases with e.g. fraps) - bool m_InsideCreate = false; + uint64_t m_RecurseSlot = 0; + + void EndRecurse() { Threading::SetTLSValue(m_RecurseSlot, NULL); } + bool CheckRecurse() + { + if(Threading::GetTLSValue(m_RecurseSlot) == NULL) + { + Threading::SetTLSValue(m_RecurseSlot, (void *)1); + return false; + } + + return true; + } friend HRESULT CreateD3D11_Internal(RealD3D11CreateFunction real, __in_opt IDXGIAdapter *pAdapter, D3D_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags, @@ -89,14 +104,12 @@ private: __out_opt ID3D11DeviceContext **ppImmediateContext) { // if we're already inside a wrapped create, then DON'T do anything special. Just call onwards - if(m_InsideCreate) + if(CheckRecurse()) { return real(pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, SDKVersion, pSwapChainDesc, ppSwapChain, ppDevice, pFeatureLevel, ppImmediateContext); } - m_InsideCreate = true; - RDCDEBUG("Call to Create_Internal Flags %x", Flags); // we should no longer go through here in the replay application @@ -185,7 +198,7 @@ private: RDCDEBUG("failed. HRESULT: %s", ToStr(ret).c_str()); } - m_InsideCreate = false; + EndRecurse(); return ret; } diff --git a/renderdoc/driver/d3d12/d3d12_hooks.cpp b/renderdoc/driver/d3d12/d3d12_hooks.cpp index b0c7a1ec3..9184648db 100644 --- a/renderdoc/driver/d3d12/d3d12_hooks.cpp +++ b/renderdoc/driver/d3d12/d3d12_hooks.cpp @@ -195,6 +195,9 @@ public: D3D12EnableExperimentalFeatures_hook); GetD3D11On12On7.Register("d3d11on12.dll", "GetD3D11On12On7Interface", GetD3D11On12On7Interface_hook); + + m_RecurseSlot = Threading::AllocateTLSSlot(); + Threading::SetTLSValue(m_RecurseSlot, NULL); } private: @@ -206,7 +209,19 @@ private: HookedFunction GetD3D11On12On7; // re-entrancy detection (can happen in rare cases with e.g. fraps) - bool m_InsideCreate = false; + uint64_t m_RecurseSlot = 0; + + void EndRecurse() { Threading::SetTLSValue(m_RecurseSlot, NULL); } + bool CheckRecurse() + { + if(Threading::GetTLSValue(m_RecurseSlot) == NULL) + { + Threading::SetTLSValue(m_RecurseSlot, (void *)1); + return false; + } + + return true; + } friend HRESULT CreateD3D12_Internal(RealD3D12CreateFunction real, IUnknown *pAdapter, D3D_FEATURE_LEVEL MinimumFeatureLevel, REFIID riid, @@ -217,11 +232,9 @@ private: { // if we're already inside a wrapped create i.e. this function, then DON'T do anything // special. Just grab the trampolined function and call it. - if(m_InsideCreate) + if(CheckRecurse()) return real(pAdapter, MinimumFeatureLevel, riid, ppDevice); - m_InsideCreate = true; - if(riid != __uuidof(ID3D12Device) && riid != __uuidof(ID3D12Device1) && riid != __uuidof(ID3D12Device2) && riid != __uuidof(ID3D12Device3) && riid != __uuidof(ID3D12Device4) && riid != __uuidof(ID3D12Device5) && @@ -340,7 +353,7 @@ private: RDCDEBUG("failed. HRESULT: %s", ToStr(ret).c_str()); } - m_InsideCreate = false; + EndRecurse(); return ret; }