我使用sharpdx和c#创建一个directx应用程序。 它大部分时间都可以正常工作,但有时我会收到这个随机错误:
DXGI_ERROR_DEVICE_REMOVED
我用谷歌搜索了一些,但除了与我的板载HD 4400或驱动程序有关之外,其他原因并不合适。
当我想创建缓冲区时会发生,然后发生异常。我可以在调试时看到。
我可能会忘记并需要关心的任何想法?似乎是随机的。我没有物理删除设备。它可能是具有更高负载和时钟频率的东西吗?
答案 0 :(得分:4)
DirectX应用程序需要在两个基本位置检测并处理“已删除设备”:当您转到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);
}
当您调整现有交换链的大小时,可能会发生这种情况:
// 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);
}
}
...
如果在其他情况下遇到DXGI_ERROR_DEVICE_REMOVED
,则可能表示内部驱动程序错误,您应该看看是否有更新的驱动程序。
回到传统的DIrect3D 9,有一个类似的“设备丢失”的想法,但发生频率更高。使用基于DXGI的API(Direct3D9Ex,Direct3D 10等),您只能在特定情况下删除设备。通常,这是因为系统在应用程序运行时更新了视频驱动程序。实际上,您可以在检测到GetDeviceRemovedReason
之后调用{em> 来确定
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
...
我知道的另一个'例外'案例是,如果您在不在“开发者模式”时拨打ID3D12Device::SetStablePowerState,则会触发设备被移除。他们真的不希望你在“零售”游戏和应用程序中调用该功能。