mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-29 13:20:54 +00:00
On D3D check for hook recursion thread-locally
This commit is contained in:
@@ -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<PFN_D3D11_CREATE_DEVICE> 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;
|
||||
}
|
||||
|
||||
@@ -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<PFNGetD3D11On12On7Interface> 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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user