mirror of
https://bitbucket.org/CPMADevs/cnq3
synced 2024-11-10 06:31:48 +00:00
fixed D3D11 device resets being sometimes treated as fatal errors
after getting DXGI_ERROR_DEVICE_REMOVED or D3DDDIERR_DEVICEREMOVED, GetDeviceRemovedReason can return DXGI_ERROR_DEVICE_RESET this particular case should trigger a video restart instead of a fatal error
This commit is contained in:
parent
49028a3f36
commit
427172edcf
2 changed files with 33 additions and 4 deletions
|
@ -9,6 +9,8 @@ add: r_alphaToCoverageMipBoost <0.0 to 0.5> (default: 0.125) boosts the alpha va
|
|||
|
||||
chg: with r_backend GL3, alpha to coverage now requires GLSL 4.00 at a minimum
|
||||
|
||||
fix: with r_backend D3D11, some device reset scenarios caused fatal errors instead of video restarts
|
||||
|
||||
fix: CVar slots that have been freed (e.g. through unset/cvar_trim/cvar_reset) can now be re-used
|
||||
|
||||
fix: with alpha to coverage enabled, high r_picmip values should longer cause
|
||||
|
|
|
@ -542,16 +542,17 @@ static qbool D3D11_CreateInputLayout(const D3D11_INPUT_ELEMENT_DESC* pInputEleme
|
|||
return CheckAndName(hr, "CreateInputLayout", *ppInputLayout, name);
|
||||
}
|
||||
|
||||
static const char* GetDeviceRemovedReason()
|
||||
static const char* GetDeviceRemovedReasonString(HRESULT reason)
|
||||
{
|
||||
switch(d3ds.device->GetDeviceRemovedReason())
|
||||
switch(reason)
|
||||
{
|
||||
case DXGI_ERROR_DEVICE_HUNG: return "device hung";
|
||||
case DXGI_ERROR_DEVICE_REMOVED: return "device removed";
|
||||
case DXGI_ERROR_DEVICE_RESET: return "device reset";
|
||||
case DXGI_ERROR_DRIVER_INTERNAL_ERROR: return "internal driver error";
|
||||
case DXGI_ERROR_INVALID_CALL: return "invalid call";
|
||||
default: return "unknown";
|
||||
case S_OK: return "no error";
|
||||
default: return va("unknown error code 0x%08X", (unsigned int)reason);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2090,11 +2091,37 @@ static void GAL_EndFrame()
|
|||
|
||||
const UINT presentFlags = d3ds.flipAndTear && r_swapInterval->integer == 0 ? DXGI_PRESENT_ALLOW_TEARING : 0;
|
||||
const HRESULT hr = d3ds.swapChain->Present(abs(r_swapInterval->integer), presentFlags);
|
||||
|
||||
enum PresentError
|
||||
{
|
||||
PE_NONE,
|
||||
PE_DEVICE_REMOVED,
|
||||
PE_DEVICE_RESET
|
||||
};
|
||||
PresentError presentError = PE_NONE;
|
||||
HRESULT deviceRemovedReason = S_OK;
|
||||
if(hr == DXGI_ERROR_DEVICE_REMOVED || hr == D3DDDIERR_DEVICEREMOVED)
|
||||
{
|
||||
ri.Error(ERR_FATAL, "Direct3D device was removed! Reason: %s", GetDeviceRemovedReason());
|
||||
deviceRemovedReason = d3ds.device->GetDeviceRemovedReason();
|
||||
if(deviceRemovedReason == DXGI_ERROR_DEVICE_RESET)
|
||||
{
|
||||
presentError = PE_DEVICE_RESET;
|
||||
}
|
||||
else
|
||||
{
|
||||
presentError = PE_DEVICE_REMOVED;
|
||||
}
|
||||
}
|
||||
else if(hr == DXGI_ERROR_DEVICE_RESET)
|
||||
{
|
||||
presentError = PE_DEVICE_RESET;
|
||||
}
|
||||
|
||||
if(presentError == PE_DEVICE_REMOVED)
|
||||
{
|
||||
ri.Error(ERR_FATAL, "Direct3D device was removed! Reason: %s", GetDeviceRemovedReasonString(deviceRemovedReason));
|
||||
}
|
||||
else if(presentError == PE_DEVICE_RESET)
|
||||
{
|
||||
ri.Printf(PRINT_ERROR, "Direct3D device was reset! Restarting the video system...");
|
||||
Cmd_ExecuteString("vid_restart;");
|
||||
|
|
Loading…
Reference in a new issue