Skip to content

Commit 6765ec0

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 b6e3f45 commit 6765ec0

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;
@@ -345,6 +368,8 @@ HRESULT CDirect3DEvents9::DrawPrimitiveShader(IDirect3DDevice9* pDevice, D3DPRIM
345368
pDevice->SetVertexShader(pOriginalVertexShader);
346369
pDevice->SetPixelShader(NULL);
347370
}
371+
372+
SAFE_RELEASE(pOriginalVertexShader);
348373
}
349374

350375
return D3D_OK;
@@ -532,6 +557,7 @@ HRESULT CDirect3DEvents9::DrawIndexedPrimitiveShader(IDirect3DDevice9* pDevice,
532557
// Make this the active shader for possible reuse
533558
dassert(dwFlags == D3DXFX_DONOTSAVESHADERSTATE);
534559
g_pActiveShader = pShaderItem;
560+
SAFE_RELEASE(pOriginalVertexShader);
535561
return D3D_OK;
536562
}
537563

@@ -549,6 +575,8 @@ HRESULT CDirect3DEvents9::DrawIndexedPrimitiveShader(IDirect3DDevice9* pDevice,
549575
// Unset additional vertex stream
550576
if (CAdditionalVertexStreamManager* pAdditionalStreamManager = CAdditionalVertexStreamManager::GetExistingSingleton())
551577
pAdditionalStreamManager->MaybeUnsetAdditionalVertexStream();
578+
579+
SAFE_RELEASE(pOriginalVertexShader);
552580
}
553581

554582
return D3D_OK;

0 commit comments

Comments
 (0)