From 7e54209c21c5db0bc4c471c18f6180098a0cce9d Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Tue, 25 Jan 2022 11:49:17 +1100 Subject: [PATCH] Direct3D11: Survive device resets/removed situation Now just recreates the device and swapchain instead of crashing --- src/Graphics_D3D11.c | 15 +++++++++++---- src/LScreens.h | 3 ++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/Graphics_D3D11.c b/src/Graphics_D3D11.c index 458b51bbe..e6de5b0fc 100644 --- a/src/Graphics_D3D11.c +++ b/src/Graphics_D3D11.c @@ -93,9 +93,9 @@ void Gfx_Free(void) { Gfx_FreeState(); IDXGISwapChain_Release(swapchain); ID3D11DeviceContext_Release(context); + #ifndef _DEBUG ID3D11Device_Release(device); - #else ULONG refCount = ID3D11Device_Release(device); if (refCount == 0) return; // device destroyed with no issues @@ -112,6 +112,9 @@ void Gfx_Free(void) { static cc_bool inited; cc_bool Gfx_TryRestoreContext(void) { + // https://docs.microsoft.com/en-us/windows/uwp/gaming/handling-device-lost-scenarios + Gfx_Free(); + Gfx_Create(); return true; } @@ -1029,9 +1032,13 @@ void Gfx_EndFrame(void) { if (hr == DXGI_STATUS_OCCLUDED) { TickReducedPerformance(); return; } - EndReducedPerformance(); - if (hr) Logger_Abort2(hr, "Failed to swap buffers"); + + if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET) { + Gfx_LoseContext(" (Direct3D11 device lost)"); + } else if (hr) { + Logger_Abort2(hr, "Failed to swap buffers"); + } if (gfx_minFrameMs) LimitFPS(); } @@ -1097,6 +1104,6 @@ static void FreePipeline(void) { // https://stackoverflow.com/questions/44155133/directx11-com-object-with-0-references-not-released // https://stackoverflow.com/questions/20032816/can-someone-explain-why-i-still-have-live-objects-after-releasing-the-pointers-t // https://www.gamedev.net/forums/topic/659651-dxgi-leak-warnings/5172345/ - //ID3D11DeviceContext_Flush(context); + ID3D11DeviceContext_Flush(context); } #endif \ No newline at end of file diff --git a/src/LScreens.h b/src/LScreens.h index a555b596b..4cfe59c46 100644 --- a/src/LScreens.h +++ b/src/LScreens.h @@ -4,11 +4,12 @@ /* Implements screens/menus for the launcher. Copyright 2014-2021 ClassiCube | Licensed under BSD-3 */ +struct Bitmap; struct LWidget; struct LScreen; typedef void (*LScreen_Func)(struct LScreen* s); -typedef void(*LWidget_Func)(struct LScreen* s, struct LWidget* w); +typedef void (*LWidget_Func)(struct LScreen* s, struct LWidget* w); #define LScreen_Layout \ LScreen_Func Init; /* Initialises widgets and other data. Only called once. */ \