Reputation: 183
I create a directx application with sharpdx and c#. It works fine most of the time, but sometimes i get this random error:
DXGI_ERROR_DEVICE_REMOVED
I googled some, but couldn't fine a reason other than it has to do with my onboard HD 4400 or the driver.
It happens when i want to create a buffer, then the exception occurs. I can see that while debugging.
any ideas what i may forget and need to care about? Seems so random. I do not physically remove the device ofc. Could it be something with higher load and the clock rate?
Upvotes: 1
Views: 2399
Reputation: 41127
A DirectX application is expected to detect and handle 'device removed' in two basic places: It can happen when you go to Present
:
HRESULT hr = m_swapChain->Present(1, 0);
// If the device was reset we must completely reinitialize the renderer.
if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
{
OnDeviceLost();
}
else
{
DX::ThrowIfFailed(hr);
}
And it can happen when you go to resize an existing swapchain:
// If the swap chain already exists, resize it, otherwise create one.
if (m_swapChain)
{
HRESULT hr = m_swapChain->ResizeBuffers(backBufferCount,
backBufferWidth, backBufferHeight, backBufferFormat, 0);
if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
{
// If the device was removed for any reason, a new device
// and swap chain will need to be created.
OnDeviceLost();
}
else
{
DX::ThrowIfFailed(hr);
}
}
...
If you encounter DXGI_ERROR_DEVICE_REMOVED
in other cases, it is likely indicates an internal driver error and you should see if a newer driver is available.
Back in legacy DIrect3D 9, there was an idea of 'device lost' which was similar, but happened with a lot more frequency. With DXGI-based APIs (Direct3D9Ex, Direct3D 10, etc.) you only get device removed in specific cases. Typically it's because the system updated the video driver while your application was running. You can actually determine why it was removed by calling GetDeviceRemovedReason
after you detect it.
if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
{
#ifdef _DEBUG
char buff[64] = {};
sprintf_s(buff, "Device Lost on ResizeBuffers: Reason code 0x%08X\n",
(hr == DXGI_ERROR_DEVICE_REMOVED) ? m_d3dDevice->GetDeviceRemovedReason() : hr);
OutputDebugStringA(buff);
#endif
...
The one other 'excepted' case I'm aware of is if you call ID3D12Device::SetStablePowerState while not in a "Developer Mode", it will trigger a device removed. They really don't want you to call that function in 'retail' games and apps.
For more see Handle device removed scenarios in Direct3D 11
Upvotes: 4