From 85f51aae8813ee549d7a3b24430530e575911425 Mon Sep 17 00:00:00 2001 From: Elisha Riedlinger Date: Mon, 8 Jul 2024 23:08:13 -0700 Subject: [PATCH] Better handling of ClearD3DDevice() --- ddraw/IDirectDrawX.cpp | 41 +++++++++++++++++++++++++++++++---------- ddraw/IDirectDrawX.h | 2 +- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/ddraw/IDirectDrawX.cpp b/ddraw/IDirectDrawX.cpp index a2356ca0..dcd56333 100644 --- a/ddraw/IDirectDrawX.cpp +++ b/ddraw/IDirectDrawX.cpp @@ -3050,11 +3050,7 @@ HRESULT m_IDirectDrawX::CreateD3D9Device() d3d9RenderTarget = nullptr; if (RenderTargetSurface) { - if (SUCCEEDED(d3d9Device->GetRenderTarget(0, &d3d9RenderTarget))) - { - d3d9RenderTarget->Release(); - } - hr = SetRenderTargetSurface(RenderTargetSurface); + SetRenderTargetSurface(RenderTargetSurface); } // Reset D3D device settings @@ -3397,10 +3393,22 @@ HRESULT m_IDirectDrawX::TestD3D9CooperativeLevel() HRESULT m_IDirectDrawX::SetRenderTargetSurface(m_IDirectDrawSurfaceX* lpSurface) { + // Remove render target if (!lpSurface) { - LOG_LIMIT(100, __FUNCTION__ << " Error: Direct3D surface does not exist!"); - return DDERR_INVALIDPARAMS; + RenderTargetSurface = lpSurface; + + SetDepthStencilSurface(nullptr); + + if (d3d9Device && d3d9RenderTarget) + { + if (SUCCEEDED(d3d9Device->SetRenderTarget(0, d3d9RenderTarget))) + { + d3d9RenderTarget = nullptr; + } + } + + return D3D_OK; } // Check for Direct3D surface @@ -3410,10 +3418,21 @@ HRESULT m_IDirectDrawX::SetRenderTargetSurface(m_IDirectDrawSurfaceX* lpSurface) return DDERR_INVALIDPARAMS; } + // Backup original render target + if (d3d9Device && !d3d9RenderTarget) + { + if (SUCCEEDED(d3d9Device->GetRenderTarget(0, &d3d9RenderTarget))) + { + d3d9RenderTarget->Release(); + } + } + // Set surface as render target RenderTargetSurface = lpSurface; RenderTargetSurface->SetAsRenderTarget(); + Logging::LogDebug() << __FUNCTION__ << " Setting 3D Device Surface: " << RenderTargetSurface; + HRESULT hr = D3D_OK; if (d3d9Device) { @@ -3427,8 +3446,6 @@ HRESULT m_IDirectDrawX::SetRenderTargetSurface(m_IDirectDrawSurfaceX* lpSurface) return hr; } - Logging::LogDebug() << __FUNCTION__ << " Setting 3D Device Surface: " << RenderTargetSurface; - m_IDirectDrawSurfaceX* pSurfaceZBuffer = RenderTargetSurface->GetAttachedZBuffer(); hr = SetDepthStencilSurface(pSurfaceZBuffer); @@ -3445,7 +3462,11 @@ HRESULT m_IDirectDrawX::SetDepthStencilSurface(m_IDirectDrawSurfaceX* lpSurface) { HRESULT hr = D3D_OK; - if (!lpSurface) + if (lpSurface == DepthStencilSurface) + { + return hr; + } + else if (!lpSurface) { DepthStencilSurface = nullptr; diff --git a/ddraw/IDirectDrawX.h b/ddraw/IDirectDrawX.h index 8686e0f6..b120017b 100644 --- a/ddraw/IDirectDrawX.h +++ b/ddraw/IDirectDrawX.h @@ -179,7 +179,7 @@ class m_IDirectDrawX : public IUnknown, public AddressLookupTableDdrawObject inline void ClearD3D() { D3DInterface = nullptr; } void SetD3DDevice(m_IDirect3DDeviceX* D3DDevice); inline m_IDirect3DDeviceX** GetCurrentD3DDevice() { return &D3DDeviceInterface; } - inline void ClearD3DDevice() { D3DDeviceInterface = nullptr; RenderTargetSurface = nullptr; Using3D = false; } + inline void ClearD3DDevice() { Using3D = false; D3DDeviceInterface = nullptr; SetRenderTargetSurface(nullptr); } inline void Enable3D() { Using3D = true; } inline bool IsUsing3D() { return Using3D; } inline bool IsPrimaryRenderTarget() { return PrimarySurface ? RenderTargetSurface->IsRenderTarget() : false; }