On D3D check for hook recursion thread-locally

This commit is contained in:
baldurk
2022-02-23 10:18:06 +00:00
parent b17ea43b65
commit ccf80e82c7
2 changed files with 36 additions and 10 deletions
+18 -5
View File
@@ -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;
}
+18 -5
View File
@@ -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;
}