Skip to content

Commit 96e88e8

Browse files
committed
- Fix leaked vertex-shader references in the shader helpers
- Fix Begin/EndScene mismatch in OnPresent (potentially calling EndScene() with no active scene > D3DERR_INVALIDCALL > messed up render queue) - Fix OnInvalidate()’s EndScene() call to be effective (Before, it just returned D3DERR_INVALIDCALL and didn't properly flush)
1 parent 95216c2 commit 96e88e8

File tree

1 file changed

+34
-6
lines changed

1 file changed

+34
-6
lines changed

Client/core/DXHook/CDirect3DEvents9.cpp

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "Graphics/CRenderItem.EffectTemplate.h"
2323

2424
bool g_bInMTAScene = false;
25+
extern bool g_bInGTAScene;
2526

2627
// Other variables
2728
static uint ms_RequiredAnisotropicLevel = 1;
@@ -91,8 +92,20 @@ void CDirect3DEvents9::OnInvalidate(IDirect3DDevice9* pDevice)
9192
g_pCore->GetGraphics()->GetRenderItemManager()->SaveReadableDepthBuffer();
9293
g_pCore->GetGraphics()->GetRenderItemManager()->FlushNonAARenderTarget();
9394

94-
// Force completion of all GPU operations
95-
pDevice->EndScene(); // Ensure we're not in scene during invalidation
95+
// Force completion of all GPU operations if a scene is currently active
96+
if (g_bInMTAScene || g_bInGTAScene)
97+
{
98+
const HRESULT hEndScene = pDevice->EndScene();
99+
if (SUCCEEDED(hEndScene))
100+
{
101+
g_bInMTAScene = false;
102+
g_bInGTAScene = false;
103+
}
104+
else
105+
{
106+
WriteDebugEvent(SString("OnInvalidate: EndScene failed: %08x", hEndScene));
107+
}
108+
}
96109

97110
// Invalidate the VMR9 Manager
98111
// CVideoManager::GetSingleton ().OnLostDevice ();
@@ -125,8 +138,15 @@ void CDirect3DEvents9::OnPresent(IDirect3DDevice9* pDevice)
125138
// Start a new scene. This isn't ideal and is not really recommended by MSDN.
126139
// I tried disabling EndScene from GTA and just end it after this code ourselves
127140
// before present, but that caused graphical issues randomly with the sky.
128-
if (pDevice->BeginScene() == D3D_OK)
129-
g_bInMTAScene = true;
141+
const HRESULT hBeginScene = pDevice->BeginScene();
142+
if (FAILED(hBeginScene))
143+
{
144+
WriteDebugEvent(SString("OnPresent: BeginScene failed: %08x", hBeginScene));
145+
g_bInMTAScene = false;
146+
return;
147+
}
148+
149+
g_bInMTAScene = true;
130150

131151
// Reset samplers on first call
132152
static bool bDoneReset = false;
@@ -192,8 +212,11 @@ void CDirect3DEvents9::OnPresent(IDirect3DDevice9* pDevice)
192212
CGraphics::GetSingleton().LeavingMTARenderZone();
193213

194214
// End the scene that we started.
195-
pDevice->EndScene();
196-
g_bInMTAScene = false;
215+
if (g_bInMTAScene)
216+
{
217+
pDevice->EndScene();
218+
g_bInMTAScene = false;
219+
}
197220

198221
// Update incase settings changed
199222
int iAnisotropic;
@@ -347,6 +370,8 @@ HRESULT CDirect3DEvents9::DrawPrimitiveShader(IDirect3DDevice9* pDevice, D3DPRIM
347370
pDevice->SetVertexShader(pOriginalVertexShader);
348371
pDevice->SetPixelShader(NULL);
349372
}
373+
374+
SAFE_RELEASE(pOriginalVertexShader);
350375
}
351376

352377
return D3D_OK;
@@ -534,6 +559,7 @@ HRESULT CDirect3DEvents9::DrawIndexedPrimitiveShader(IDirect3DDevice9* pDevice,
534559
// Make this the active shader for possible reuse
535560
dassert(dwFlags == D3DXFX_DONOTSAVESHADERSTATE);
536561
g_pActiveShader = pShaderItem;
562+
SAFE_RELEASE(pOriginalVertexShader);
537563
return D3D_OK;
538564
}
539565

@@ -551,6 +577,8 @@ HRESULT CDirect3DEvents9::DrawIndexedPrimitiveShader(IDirect3DDevice9* pDevice,
551577
// Unset additional vertex stream
552578
if (CAdditionalVertexStreamManager* pAdditionalStreamManager = CAdditionalVertexStreamManager::GetExistingSingleton())
553579
pAdditionalStreamManager->MaybeUnsetAdditionalVertexStream();
580+
581+
SAFE_RELEASE(pOriginalVertexShader);
554582
}
555583

556584
return D3D_OK;

0 commit comments

Comments
 (0)