From c6bab1fcea6135c29ea145ace3dfebc583e4baa3 Mon Sep 17 00:00:00 2001 From: tintinhamans <5984296+tintinhamans@users.noreply.github.com> Date: Sun, 18 Oct 2026 00:27:41 +0200 Subject: [PATCH] bugfix(dx8): Unbind device resources before Reset --- .../Source/WWVegas/WW3D2/dx8wrapper.cpp | 126 +++++++++++------- .../Source/WWVegas/WW3D2/dx8wrapper.h | 2 + 2 files changed, 79 insertions(+), 49 deletions(-) diff --git a/Core/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp b/Core/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp index 42b363db04e..a6fa9852e98 100644 --- a/Core/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp +++ b/Core/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp @@ -157,6 +157,7 @@ bool DX8Wrapper::IsRenderToTexture = false; unsigned DX8Wrapper::_MainThreadID = 0; bool DX8Wrapper::CurrentDX8LightEnables[4]; bool DX8Wrapper::IsDeviceLost; +bool DX8Wrapper::DeviceResetFailed = false; int DX8Wrapper::ZBias; float DX8Wrapper::ZNear; float DX8Wrapper::ZFar; @@ -432,7 +433,7 @@ void DX8Wrapper::Invalidate_Cached_Render_States() } //Need to explicitly set texture to null, otherwise app will not be able to //set it to null because of redundant state checker. MW - if (_Get_D3D_Device8()) + if (_Get_D3D_Device8() && !DeviceResetFailed) _Get_D3D_Device8()->SetTexture(a,nullptr); if (Textures[a] != nullptr) { Textures[a]->Release(); @@ -486,6 +487,7 @@ void DX8Wrapper::Do_Onetime_Device_Dependent_Shutdowns() bool DX8Wrapper::Create_Device() { WWASSERT(D3DDevice==nullptr); // for now, once you've created a device, you're stuck with it! + DeviceResetFailed = false; D3DCAPS8 caps; if @@ -606,67 +608,93 @@ bool DX8Wrapper::Reset_Device(bool reload_assets) { WWDEBUG_SAY(("Resetting device.")); DX8_THREAD_ASSERT(); - if ((IsInitted) && (D3DDevice != nullptr)) { - // Release all non-MANAGED stuff - WW3D::_Invalidate_Textures(); + if (!IsInitted || D3DDevice == nullptr) { + WWDEBUG_SAY(("Device reset failed")); + return false; + } - for (unsigned i=0;iReleaseResources(); + } + DynamicVBAccessClass::_Deinit(); + DynamicIBAccessClass::_Deinit(); + DX8TextureManagerClass::Release_Textures(); + SHD_SHUTDOWN_SHADERS; + + // Reset frame count to reflect the flipping chain being reset by Reset() + FrameCount = 0; + + memset(Vertex_Shader_Constants,0,sizeof(Vector4)*MAX_VERTEX_SHADER_CONSTANTS); + memset(Pixel_Shader_Constants,0,sizeof(Vector4)*MAX_PIXEL_SHADER_CONSTANTS); + + HRESULT hr=_Get_D3D_Device8()->TestCooperativeLevel(); + if (hr == D3DERR_DEVICELOST) { + return false; //device is lost and can't be reset. + } + + // TheSuperHackers @bugfix arcticdolphin 09/10/2026 Reset() fails while resources are still bound + if (!DeviceResetFailed) { + Unbind_Device_Buffers(); + } + Invalidate_Cached_Render_States(); + Set_Render_Target((IDirect3DSurface8*)nullptr); + + hr = _Get_D3D_Device8()->Reset(&_PresentParameters); + Increment_DX8_CallCount(); + DeviceResetFailed = (hr != D3D_OK); + if (DeviceResetFailed) { + Non_Fatal_Log_DX8_ErrorCode(hr,__FILE__,__LINE__); + return false; //reset failed. + } + + if (reload_assets) + { + DX8TextureManagerClass::Recreate_Textures(); if (m_pCleanupHook) { - m_pCleanupHook->ReleaseResources(); + m_pCleanupHook->ReAcquireResources(); } - DynamicVBAccessClass::_Deinit(); - DynamicIBAccessClass::_Deinit(); - DX8TextureManagerClass::Release_Textures(); - SHD_SHUTDOWN_SHADERS; - - // Reset frame count to reflect the flipping chain being reset by Reset() - FrameCount = 0; - - memset(Vertex_Shader_Constants,0,sizeof(Vector4)*MAX_VERTEX_SHADER_CONSTANTS); - memset(Pixel_Shader_Constants,0,sizeof(Vector4)*MAX_PIXEL_SHADER_CONSTANTS); - - HRESULT hr=_Get_D3D_Device8()->TestCooperativeLevel(); - if (hr != D3DERR_DEVICELOST ) - { DX8CALL_HRES(Reset(&_PresentParameters),hr) - if (hr != D3D_OK) - return false; //reset failed. - } - else - return false; //device is lost and can't be reset. + } + Invalidate_Cached_Render_States(); + Set_Default_Global_Render_States(); + SHD_INIT_SHADERS; + WWDEBUG_SAY(("Device reset completed")); + return true; +} - if (reload_assets) - { - DX8TextureManagerClass::Recreate_Textures(); - if (m_pCleanupHook) { - m_pCleanupHook->ReAcquireResources(); - } - } - Invalidate_Cached_Render_States(); - Set_Default_Global_Render_States(); - SHD_INIT_SHADERS; - WWDEBUG_SAY(("Device reset completed")); - return true; +// Set_Vertex_Buffer and Set_Index_Buffer are deferred +void DX8Wrapper::Unbind_Device_Buffers() +{ + for (unsigned stream = 0; stream < MAX_VERTEX_STREAMS; ++stream) + { + DX8CALL(SetStreamSource(stream, nullptr, 0)); } - WWDEBUG_SAY(("Device reset failed")); - return false; + DX8CALL(SetIndices(nullptr, 0)); } void DX8Wrapper::Release_Device() { if (D3DDevice) { - for (int a=0;a