Skip to content

Commit d064fcf

Browse files
committed
D3D fix-ups #2 (Performance)
1 parent f1ed5e3 commit d064fcf

File tree

3 files changed

+73
-116
lines changed

3 files changed

+73
-116
lines changed

Client/core/DXHook/CDirect3DEvents9.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,10 +219,18 @@ bool BorderlessToneMapPass::EnsureStateBlock(IDirect3DDevice9* device)
219219
if (m_restoreStateBlock)
220220
return true;
221221

222+
// Create and capture state block once on initialization
222223
IDirect3DStateBlock9* stateBlock = nullptr;
223224
if (FAILED(device->CreateStateBlock(D3DSBT_ALL, &stateBlock)) || !stateBlock)
224225
return false;
225226

227+
// Capture current state immediately after creation
228+
if (FAILED(stateBlock->Capture()))
229+
{
230+
stateBlock->Release();
231+
return false;
232+
}
233+
226234
m_restoreStateBlock = stateBlock;
227235
return true;
228236
}
@@ -296,8 +304,7 @@ bool BorderlessToneMapPass::Apply(IDirect3DDevice9* device, float gammaPower, fl
296304
return false;
297305
}
298306

299-
m_restoreStateBlock->Capture();
300-
307+
// State block is already captured during creation, just apply before drawing
301308
device->SetRenderState(D3DRS_ZENABLE, FALSE);
302309
device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
303310
device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);

Client/core/DXHook/CProxyDirect3D9.cpp

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,14 @@ extern HINSTANCE g_hModule;
2121

2222
namespace
2323
{
24+
// Cached static Direct3D pointer for lockless fast-path access
25+
std::atomic<IDirect3D9*> g_cachedStaticDirect3D{nullptr};
26+
std::atomic<bool> g_cachedDirect3DValid{false};
2427

2528
IDirect3D9* GetFirstValidTrackedDirect3D(std::vector<IDirect3D9*>& trackedList)
2629
{
27-
for (auto iter = trackedList.begin(); iter != trackedList.end();)
28-
{
29-
IDirect3D9* candidate = *iter;
30-
if (candidate && IsValidComInterfacePointer(candidate, ComPtrValidation::ValidationMode::ForceRefresh))
31-
return candidate;
32-
33-
SString message;
34-
message.Format("CProxyDirect3D9: removing invalid tracked IDirect3D9 pointer %p", candidate);
35-
AddReportLog(8756, message, 5);
36-
ComPtrValidation::Invalidate(candidate);
37-
iter = trackedList.erase(iter);
38-
}
39-
40-
return nullptr;
30+
// Return first element without expensive COM validation (called frequently)
31+
return trackedList.empty() ? nullptr : trackedList.front();
4132
}
4233
} // unnamed namespace
4334

@@ -56,7 +47,7 @@ CProxyDirect3D9::CProxyDirect3D9(IDirect3D9* pInterface)
5647
{
5748
WriteDebugEvent(SString("CProxyDirect3D9::CProxyDirect3D9 %08x", this));
5849

59-
if (!IsValidComInterfacePointer(pInterface, ComPtrValidation::ValidationMode::ForceRefresh))
50+
if (!IsValidComInterfacePointer(pInterface, ComPtrValidation::ValidationMode::Default))
6051
{
6152
SString message;
6253
message.Format("CProxyDirect3D9 ctor: received invalid IDirect3D9 pointer %p, proxy will be non-functional", pInterface);
@@ -71,10 +62,13 @@ CProxyDirect3D9::CProxyDirect3D9(IDirect3D9* pInterface)
7162
// Track this Direct3D9 instance for StaticGetDirect3D() lookups
7263
if (m_pDevice)
7364
{
74-
if (IsValidComInterfacePointer(m_pDevice, ComPtrValidation::ValidationMode::ForceRefresh))
65+
if (IsValidComInterfacePointer(m_pDevice, ComPtrValidation::ValidationMode::Default))
7566
{
7667
std::lock_guard<std::mutex> lock(ms_Direct3D9ListMutex);
7768
ms_CreatedDirect3D9List.push_back(m_pDevice);
69+
// Update cache for lockless StaticGetDirect3D access
70+
g_cachedStaticDirect3D.store(m_pDevice, std::memory_order_release);
71+
g_cachedDirect3DValid.store(true, std::memory_order_release);
7872
}
7973
else
8074
{
@@ -91,6 +85,8 @@ CProxyDirect3D9::~CProxyDirect3D9()
9185
{
9286
std::lock_guard<std::mutex> lock(ms_Direct3D9ListMutex);
9387
ListRemove(ms_CreatedDirect3D9List, m_pDevice);
88+
// Invalidate cache when removing this device
89+
g_cachedDirect3DValid.store(false, std::memory_order_release);
9490
}
9591
ReleaseInterface(m_pDevice, 8752);
9692
}
@@ -246,8 +242,23 @@ HMONITOR CProxyDirect3D9::StaticGetAdapterMonitor(UINT Adapter)
246242

247243
IDirect3D9* CProxyDirect3D9::StaticGetDirect3D()
248244
{
245+
// Fast path: use cached pointer without lock (called frequently)
246+
if (g_cachedDirect3DValid.load(std::memory_order_acquire))
247+
{
248+
IDirect3D9* pDirect3D = g_cachedStaticDirect3D.load(std::memory_order_acquire);
249+
if (pDirect3D)
250+
return pDirect3D;
251+
}
252+
253+
// Slow path: refresh cache under lock
249254
std::lock_guard<std::mutex> lock(ms_Direct3D9ListMutex);
250-
return GetFirstValidTrackedDirect3D(ms_CreatedDirect3D9List);
255+
IDirect3D9* pDirect3D = GetFirstValidTrackedDirect3D(ms_CreatedDirect3D9List);
256+
if (pDirect3D)
257+
{
258+
g_cachedStaticDirect3D.store(pDirect3D, std::memory_order_release);
259+
g_cachedDirect3DValid.store(true, std::memory_order_release);
260+
}
261+
return pDirect3D;
251262
}
252263

253264
HRESULT CProxyDirect3D9::CreateDevice(UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags,

0 commit comments

Comments
 (0)