一个有趣的错误出现了,我没有运气。在使用本机代码的窗口化 Direct3D9 程序中,我使用类似于以下内容处理丢失的设备:
void MyClass::RecoverFromDeviceLost(LPDIRECT3DDEVICE9 deviceToRecover, D3DPRESENT_PARAMETERS devicePresentParams )
{
HRESULT hr = deviceToRecover->TestCooperativeLevel();
if(hr == D3DERR_DEVICELOST ) {
//Code to shutdown all D3DPOOL_DEFAULT allocated objects
}else if(hr == D3DERR_DEVICENOTRESET){
hr = deviceToRecover->Reset(&devicePresentParams);
if(SUCCEEDED(hr))
{
//Code to rebuild all D3DPOOL_DEFAULT objects
}
}
}
这在 Vista 上运行良好,但在 XP 上似乎存在重大问题。如果显示器被拔下,或通过 KVM 从 PC 上切换,我永远不会收到D3DERR_DEVICELOST
. 我收到的来自 TestCooperativeLevel 的唯一返回值是D3DERR_DEVICENOTRESET
. 并且每次对 Reset 的调用都会给出一个 D3DERR_INVALIDCALL。我尝试通过执行以下操作强制程序使用关闭代码:
...
else if(hr == D3DERR_DEVICENOTRESET){
hr = deviceToRecover->Reset(&devicePresentParams);
if(SUCCEEDED(hr))
{
//Code to rebuild all D3DPOOL_DEFAULT objects
}else {
//Duplicate of code to shutdown all D3DPOOL_DEFAULT objects
}
}
...
但没有任何变化。这个问题似乎只影响 Windows XP(目前在 SP2、SP3 上测试过)。我正在使用 2007 年 8 月的 DXSDK,目前无法更新。有没有人见过这个问题,或者知道为什么我不能重置我的设备?
更新:我相信我找到了解决方案,但仍然对上面列出的第二个代码段的失败感到困惑。在让 DirectX Debug 运行时通过远程调试工作后,我意识到 Reset 功能一直失败的原因是因为有未释放的资源。但是,如答案中所示应用完全相同的发布代码时,解决了该问题。我确实验证了程序在调用恢复函数之间没有创建 D3DPOOL_DEFAULT 对象。如果执行此问题的代码段中所示的重置,Direct3D 的结构中是否存在可能导致问题的东西?