Skip to content

Commit 8be676e

Browse files
committed
Fix ResetD9Device() when device reset fails
1 parent 7a07fa8 commit 8be676e

File tree

5 files changed

+55
-22
lines changed

5 files changed

+55
-22
lines changed

Dllmain/BuildNo.rc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
#define BUILD_NUMBER 8106
1+
#define BUILD_NUMBER 8107

d3d9/IDirect3DDevice9Ex.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ struct DEVICEDETAILS
1010
{
1111
if (!InitializeCriticalSectionAndSpinCount(&d9cs, 4000))
1212
{
13+
Logging::Log() << __FUNCTION__ << " Warning: failed to initialize CriticalSectionAndSpinCount for d9cs. Failing over to CriticalSection!";
1314
InitializeCriticalSection(&d9cs);
1415
}
1516
}

ddraw/IDirectDrawSurfaceX.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3853,6 +3853,7 @@ void m_IDirectDrawSurfaceX::InitInterface(DWORD DirectXVersion)
38533853

38543854
if (!InitializeCriticalSectionAndSpinCount(&ddscs, 4000))
38553855
{
3856+
Logging::Log() << __FUNCTION__ << " Warning: failed to initialize CriticalSectionAndSpinCount for ddscs. Failing over to CriticalSection!";
38563857
InitializeCriticalSection(&ddscs);
38573858
}
38583859

ddraw/IDirectDrawX.cpp

Lines changed: 50 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2252,6 +2252,13 @@ HRESULT m_IDirectDrawX::RestoreAllSurfaces()
22522252
// Check device status
22532253
if (hr == DD_OK || hr == DDERR_NOEXCLUSIVEMODE)
22542254
{
2255+
// Recreate device, if needed
2256+
if (!d3d9Device)
2257+
{
2258+
CreateD9Device(__FUNCTION__);
2259+
}
2260+
2261+
// Restore all surfaces
22552262
for (const auto& pDDraw : DDrawVector)
22562263
{
22572264
for (const auto& pSurface : pDDraw->SurfaceList)
@@ -2622,6 +2629,17 @@ void m_IDirectDrawX::ReleaseInterface()
26222629
DisplayMode.SetBy = Exclusive.SetBy;
26232630
Device.IsWindowed = false;
26242631
FullScreenWindowed = false;
2632+
2633+
if (d3d9Device)
2634+
{
2635+
const HWND hWnd = GetHwnd();
2636+
if (IsWindow(hWnd) && GetWindowThreadProcessId(hWnd, nullptr) == GetCurrentThreadId())
2637+
{
2638+
LOG_LIMIT(100, __FUNCTION__ << " Warning: creating d3d9Device from ReleaseInterface()!");
2639+
2640+
Exclusive.SetBy->CreateD9Device(__FUNCTION__);
2641+
}
2642+
}
26252643
}
26262644

26272645
// Clear SetBy handles
@@ -3275,37 +3293,37 @@ HRESULT m_IDirectDrawX::ResetD9Device()
32753293
LOG_LIMIT(100, __FUNCTION__ << " Error: Reset failed: " << (D3DERR)hr);
32763294
ReleaseAllD9Resources(false, false); // Cannot backup surface after a failed Reset
32773295
ReleaseD9Device();
3296+
return DDERR_GENERIC;
32783297
}
3279-
else
3280-
{
3281-
CreationInterface = this;
3282-
IsDeviceLost = false;
3283-
WndProc::SwitchingResolution = false;
3284-
IsDeviceVerticesSet = false;
3285-
EnableWaitVsync = false;
32863298

3287-
// Copy GDI data to back buffer
3288-
if (PrimarySurface && !presParams.Windowed)
3289-
{
3290-
PrimarySurface->CopyGDIToPrimaryAndBackbuffer();
3291-
}
3292-
CopyGDISurface = false;
3299+
CreationInterface = this;
3300+
IsDeviceLost = false;
3301+
WndProc::SwitchingResolution = false;
3302+
IsDeviceVerticesSet = false;
3303+
EnableWaitVsync = false;
32933304

3294-
// Create default state block
3295-
GetDefaultStates();
3305+
// Copy GDI data to back buffer
3306+
if (PrimarySurface && !presParams.Windowed)
3307+
{
3308+
PrimarySurface->CopyGDIToPrimaryAndBackbuffer();
3309+
}
3310+
CopyGDISurface = false;
32963311

3297-
// Set render target
3298-
SetCurrentRenderTarget();
3312+
// Create default state block
3313+
GetDefaultStates();
32993314

3300-
// Reset D3D device settings
3301-
RestoreD3DDeviceState();
3302-
}
3315+
// Set render target
3316+
SetCurrentRenderTarget();
3317+
3318+
// Reset D3D device settings
3319+
RestoreD3DDeviceState();
33033320
}
33043321
// Release and recreate device
33053322
else
33063323
{
33073324
ReleaseAllD9Resources(true, false);
33083325
ReleaseD9Device();
3326+
return DDERR_GENERIC;
33093327
}
33103328

33113329
// Return
@@ -5464,6 +5482,8 @@ HRESULT m_IDirectDrawX::Present(RECT* pSourceRect, RECT* pDestRect)
54645482
presentTime = std::chrono::high_resolution_clock::now();
54655483
#endif
54665484

5485+
const HWND hWnd = GetHwnd();
5486+
54675487
// Test cooperative level
54685488
if (hr == D3DERR_DEVICELOST)
54695489
{
@@ -5475,6 +5495,16 @@ HRESULT m_IDirectDrawX::Present(RECT* pSourceRect, RECT* pDestRect)
54755495
if (hr == D3DERR_DEVICENOTRESET)
54765496
{
54775497
hr = ResetD9Device();
5498+
5499+
if (!d3d9Device)
5500+
{
5501+
if (IsWindow(hWnd) && GetWindowThreadProcessId(hWnd, nullptr) == GetCurrentThreadId())
5502+
{
5503+
LOG_LIMIT(100, __FUNCTION__ << " Warning: creating d3d9Device from Present()!");
5504+
5505+
hr = CreateD9Device(__FUNCTION__);
5506+
}
5507+
}
54785508
}
54795509

54805510
// Present failure
@@ -5485,7 +5515,6 @@ HRESULT m_IDirectDrawX::Present(RECT* pSourceRect, RECT* pDestRect)
54855515
}
54865516

54875517
// Redraw window if it has moved from its last location
5488-
HWND hWnd = GetHwnd();
54895518
RECT ClientRect = {};
54905519
if (ReDrawNextPresent || (presParams.Windowed && !ExclusiveMode && !IsIconic(hWnd) && GetWindowRect(hWnd, &ClientRect) && LastWindowRect.right > 0 && LastWindowRect.bottom > 0))
54915520
{

ddraw/ddraw.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,10 +741,12 @@ void InitDDraw()
741741
{
742742
if (!InitializeCriticalSectionAndSpinCount(&ddcs, 4000))
743743
{
744+
Logging::Log() << __FUNCTION__ << " Warning: failed to initialize CriticalSectionAndSpinCount for ddcs. Failing over to CriticalSection!";
744745
InitializeCriticalSection(&ddcs);
745746
}
746747
if (!InitializeCriticalSectionAndSpinCount(&pecs, 4000))
747748
{
749+
Logging::Log() << __FUNCTION__ << " Warning: failed to initialize CriticalSectionAndSpinCount for pecs. Failing over to CriticalSection!";
748750
InitializeCriticalSection(&pecs);
749751
}
750752
IsInitialized = true;

0 commit comments

Comments
 (0)