Skip to content

Commit 68ae075

Browse files
committed
Improve CProxyDirect3DDevice9::Reset
1 parent c540c65 commit 68ae075

File tree

1 file changed

+22
-130
lines changed

1 file changed

+22
-130
lines changed

Client/core/DXHook/CProxyDirect3DDevice9.cpp

Lines changed: 22 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,8 @@ CProxyDirect3DDevice9::CProxyDirect3DDevice9(IDirect3DDevice9* pDevice)
2121
{
2222
WriteDebugEvent(SString("CProxyDirect3DDevice9::CProxyDirect3DDevice9 %08x (device: %08x)", this, pDevice));
2323

24-
// Set wrapped device - DO NOT AddRef here since we'll do it in AddRef method
24+
// Set our wrapped device.
2525
m_pDevice = pDevice;
26-
27-
// Initialize reference count to 1 (the creator holds a reference)
28-
m_ulRefCount = 1;
29-
30-
// Now add a reference to the underlying device to match initial ref count
31-
if (m_pDevice)
32-
{
33-
m_pDevice->AddRef();
34-
}
3526

3627
// Get CDirect3DData pointer.
3728
m_pData = CDirect3DData::GetSingletonPtr();
@@ -48,18 +39,12 @@ CProxyDirect3DDevice9::CProxyDirect3DDevice9(IDirect3DDevice9* pDevice)
4839
int iAdapter = creationParameters.AdapterOrdinal;
4940

5041
IDirect3D9* pD3D9 = CProxyDirect3D9::StaticGetDirect3D();
51-
bool bNeedRelease = false;
5242
if (!pD3D9)
53-
{
5443
m_pDevice->GetDirect3D(&pD3D9);
55-
bNeedRelease = true; // GetDirect3D increments reference count
56-
}
5744

58-
if (pD3D9)
59-
{
60-
D3DADAPTER_IDENTIFIER9 adaptIdent;
61-
ZeroMemory(&adaptIdent, sizeof(D3DADAPTER_IDENTIFIER9));
62-
pD3D9->GetAdapterIdentifier(iAdapter, 0, &adaptIdent);
45+
D3DADAPTER_IDENTIFIER9 adaptIdent;
46+
ZeroMemory(&adaptIdent, sizeof(D3DADAPTER_IDENTIFIER9));
47+
pD3D9->GetAdapterIdentifier(iAdapter, 0, &adaptIdent);
6348

6449
int iVideoCardMemoryKBTotal = GetWMIVideoAdapterMemorySize(adaptIdent.VendorId, adaptIdent.DeviceId) / 1024;
6550

@@ -74,25 +59,6 @@ CProxyDirect3DDevice9::CProxyDirect3DDevice9(IDirect3DDevice9* pDevice)
7459
//
7560
g_pDeviceState->AdapterState.Name = adaptIdent.Description;
7661

77-
// Clipping is required for some graphic configurations
78-
g_pDeviceState->AdapterState.bRequiresClipping = SStringX(adaptIdent.Description).Contains("Intel");
79-
80-
// Release D3D9 interface if we obtained it via GetDirect3D
81-
if (bNeedRelease)
82-
{
83-
SAFE_RELEASE(pD3D9);
84-
}
85-
}
86-
else
87-
{
88-
WriteDebugEvent("Warning: Could not obtain IDirect3D9 interface for adapter info");
89-
90-
// Set default values
91-
g_pDeviceState->AdapterState.InstalledMemoryKB = m_pDevice->GetAvailableTextureMem() / 1024;
92-
g_pDeviceState->AdapterState.Name = "Unknown";
93-
g_pDeviceState->AdapterState.bRequiresClipping = false;
94-
}
95-
9662
//
9763
// Get max anisotropic setting
9864
//
@@ -108,6 +74,9 @@ CProxyDirect3DDevice9::CProxyDirect3DDevice9(IDirect3DDevice9* pDevice)
10874
g_pDeviceState->AdapterState.MaxAnisotropicSetting++;
10975
}
11076

77+
// Clipping is required for some graphic configurations
78+
g_pDeviceState->AdapterState.bRequiresClipping = SStringX(adaptIdent.Description).Contains("Intel");
79+
11180
WriteDebugEvent(SString("*** Using adapter: %s (Mem:%d KB, MaxAnisotropy:%d)", (const char*)g_pDeviceState->AdapterState.Name,
11281
g_pDeviceState->AdapterState.InstalledMemoryKB, g_pDeviceState->AdapterState.MaxAnisotropicSetting));
11382

@@ -122,89 +91,42 @@ CProxyDirect3DDevice9::CProxyDirect3DDevice9(IDirect3DDevice9* pDevice)
12291
CProxyDirect3DDevice9::~CProxyDirect3DDevice9()
12392
{
12493
WriteDebugEvent(SString("CProxyDirect3DDevice9::~CProxyDirect3DDevice9 %08x", this));
125-
126-
// Release our reference to the wrapped device
127-
// Note: We don't check m_ulRefCount here because destructor is only called
128-
// when Release() determined the count reached 0
129-
if (m_pDevice)
130-
{
131-
m_pDevice->Release();
132-
m_pDevice = nullptr;
133-
}
134-
135-
if (g_pProxyDevice == this)
136-
{
137-
g_pDeviceState = NULL;
138-
g_pProxyDevice = NULL;
139-
}
94+
g_pDeviceState = NULL;
95+
g_pProxyDevice = NULL;
14096
}
14197

14298
/*** IUnknown methods ***/
14399
HRESULT CProxyDirect3DDevice9::QueryInterface(REFIID riid, void** ppvObj)
144100
{
145-
if (!ppvObj)
146-
return E_POINTER;
147-
148-
*ppvObj = nullptr;
149-
150-
// Check if its for IUnknown or IDirect3DDevice9
151-
if (riid == IID_IUnknown || riid == IID_IDirect3DDevice9)
152-
{
153-
*ppvObj = static_cast<IDirect3DDevice9*>(this);
154-
AddRef();
155-
return S_OK;
156-
}
157-
158-
// For any other interface, forward to underlying device
159-
// But this means the caller gets the underlying device, not our proxy
160101
return m_pDevice->QueryInterface(riid, ppvObj);
161102
}
162103

163104
ULONG CProxyDirect3DDevice9::AddRef()
164105
{
165-
// Only increment proxy reference count
166-
// We keep a single reference to the underlying device throughout the lifetime
167-
return InterlockedIncrement(&m_ulRefCount);
106+
return m_pDevice->AddRef();
168107
}
169108

170109
ULONG CProxyDirect3DDevice9::Release()
171110
{
172-
// Only decrement proxy reference count
173-
ULONG ulNewRefCount = InterlockedDecrement(&m_ulRefCount);
174-
175-
if (ulNewRefCount == 0)
111+
// Check if will be final release
112+
m_pDevice->AddRef();
113+
ULONG ulRefCount = m_pDevice->Release();
114+
if (ulRefCount == 1)
176115
{
177116
WriteDebugEvent("Releasing IDirect3DDevice9 Proxy...");
178117
// Call event handler
179118
CDirect3DEvents9::OnDirect3DDeviceDestroy(m_pDevice);
180119
delete this;
181-
return 0;
120+
return ulRefCount - 1;
182121
}
183122

184-
return ulNewRefCount;
123+
return m_pDevice->Release();
185124
}
186125

187126
/*** IDirect3DDevice9 methods ***/
188127
HRESULT CProxyDirect3DDevice9::TestCooperativeLevel()
189128
{
190-
HRESULT hResult = m_pDevice->TestCooperativeLevel();
191-
192-
// Log device state transitions for debugging GPU driver issues
193-
static HRESULT lastResult = D3D_OK;
194-
if (hResult != lastResult)
195-
{
196-
WriteDebugEvent(SString("CProxyDirect3DDevice9::TestCooperativeLevel - Device state changed: %08x -> %08x", lastResult, hResult));
197-
lastResult = hResult;
198-
199-
// Additional safety for when transitioning to/from lost states
200-
if (hResult == D3DERR_DEVICELOST || hResult == D3DERR_DEVICENOTRESET)
201-
{
202-
// Give the driver a moment to stabilize
203-
Sleep(1);
204-
}
205-
}
206-
207-
return hResult;
129+
return m_pDevice->TestCooperativeLevel();
208130
}
209131

210132
UINT CProxyDirect3DDevice9::GetAvailableTextureMem()
@@ -373,19 +295,6 @@ HRESULT CProxyDirect3DDevice9::Reset(D3DPRESENT_PARAMETERS* pPresentationParamet
373295
WriteDebugEvent("CProxyDirect3DDevice9::Reset - Invalid presentation parameters");
374296
return D3DERR_INVALIDCALL;
375297
}
376-
377-
// Check cooperative level before attempting reset
378-
HRESULT hCoopLevel = m_pDevice->TestCooperativeLevel();
379-
if (hCoopLevel == D3DERR_DEVICELOST)
380-
{
381-
WriteDebugEvent("CProxyDirect3DDevice9::Reset - Device still lost, cannot reset yet");
382-
return hCoopLevel;
383-
}
384-
else if (hCoopLevel != D3DERR_DEVICENOTRESET && hCoopLevel != D3D_OK)
385-
{
386-
WriteDebugEvent(SString("CProxyDirect3DDevice9::Reset - Device in unexpected state: %08x", hCoopLevel));
387-
return hCoopLevel;
388-
}
389298

390299
// Save presentation parameters
391300
D3DPRESENT_PARAMETERS presentationParametersOrig = *pPresentationParameters;
@@ -397,9 +306,6 @@ HRESULT CProxyDirect3DDevice9::Reset(D3DPRESENT_PARAMETERS* pPresentationParamet
397306
// Call our event handler.
398307
CDirect3DEvents9::OnInvalidate(m_pDevice);
399308

400-
// Give GPU driver time to complete any pending operations
401-
Sleep(1);
402-
403309
// Call the real reset routine.
404310
hResult = DoResetDevice(m_pDevice, pPresentationParameters, presentationParametersOrig);
405311

@@ -408,24 +314,15 @@ HRESULT CProxyDirect3DDevice9::Reset(D3DPRESENT_PARAMETERS* pPresentationParamet
408314
// Store actual present parameters used
409315
IDirect3DSwapChain9* pSwapChain = nullptr;
410316
HRESULT hrSwapChain = m_pDevice->GetSwapChain(0, &pSwapChain);
411-
if (SUCCEEDED(hrSwapChain))
317+
if (SUCCEEDED(hrSwapChain) && pSwapChain)
412318
{
413-
if (pSwapChain)
414-
{
415-
pSwapChain->GetPresentParameters(&g_pDeviceState->CreationState.PresentationParameters);
416-
}
417-
else
418-
{
419-
WriteDebugEvent("Warning: GetSwapChain succeeded but returned null swap chain");
420-
}
319+
pSwapChain->GetPresentParameters(&g_pDeviceState->CreationState.PresentationParameters);
320+
SAFE_RELEASE(pSwapChain);
421321
}
422322
else
423323
{
424324
WriteDebugEvent(SString("Warning: Failed to get swap chain for parameter storage: %08x", hrSwapChain));
425325
}
426-
427-
// Always release the swap chain if it was obtained, regardless of success/failure
428-
SAFE_RELEASE(pSwapChain);
429326

430327
// Store device creation parameters as well
431328
HRESULT hrCreationParams = m_pDevice->GetCreationParameters(&g_pDeviceState->CreationState.CreationParameters);
@@ -441,13 +338,8 @@ HRESULT CProxyDirect3DDevice9::Reset(D3DPRESENT_PARAMETERS* pPresentationParamet
441338
// Update our data.
442339
m_pData->StoreViewport(0, 0, pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight);
443340

444-
// Ensure scene state is properly restored
445-
// Call our event handler.
446-
CDirect3DEvents9::OnRestore(m_pDevice);
447-
448-
// Additional sync point for GPU driver
449-
m_pDevice->BeginScene();
450-
m_pDevice->EndScene();
341+
// Call our event handler.
342+
CDirect3DEvents9::OnRestore(m_pDevice);
451343

452344
WriteDebugEvent(SString(" BackBufferWidth:%d Height:%d Format:%d Count:%d", pPresentationParameters->BackBufferWidth,
453345
pPresentationParameters->BackBufferHeight, pPresentationParameters->BackBufferFormat, pPresentationParameters->BackBufferCount));

0 commit comments

Comments
 (0)