D3D中设备丢失的处理

什么是设备丢失

D3D中设备(Device)有两种状态,一种是可操作状态,也就是正常状态,另一种是丢失状态(Lost),处于丢失状态的设备是不能进行渲染操作的。简单的说,设备丢失是只应用程序(Device)与显卡失去了联系,因此无法使用显存。这里的Device不是只硬件,而是我们在程序中创建的Device对象,可以理解为上下文环境。

什么情况会导致设备丢失

当某些事件发生时,设备会由正常状态转换到丢失状态。这些事件包括

  • 程序在全屏状态下失去键盘焦点(全屏时按下Alt+Tab或Win+D键或Win+L键)
  • 其他程序进入全屏状态
  • 电源管理事件,比如屏保等

设备丢失的现象

  • 渲染窗口内模型丢失
  • 渲染窗口背景色变黑或者干脆没有背景色
  • 程序失去响应或者Crash

如何检测设备丢失

设备丢失以后,大多数渲染操作都只是silent failure,所以仍然会返回正确代码,但是Present函数会返回D3DERR_DEVICELOST,所以可以检测该函数的返回值,如果该函数失败,那么就重置设备。当然失败可能还有其他原因,不仅仅是设备丢失而已,这些情况我们都在ResetDevie函数里面一并处理。

复制代码
// Present the back buffer contents to the display
HRESULT hr = g_pd3dDevice->Present(NULL, NULL, NULL, NULL);

// Render failed, try to reset device
if(FAILED(hr))
{
    ResetDevice(d3dpp) ;
}
复制代码

如何处理设备丢失

设备丢失以后,应该进行重置(Reset),可以使用Reset函数来重置设备,Reset函数是设备丢失以后唯一起作用的函数,也是唯一能将设备从丢失状态恢复到正常状态的函数。由于设备丢失后,设备与显卡就失去了联系,所以一切与显卡有关的资源也都无法再通过设备访问了,那么这些资源必须释放并重新创建,一般来说,以D3DPOOL_DEFAULT为参数创建的资源,都是在显卡中分配的内存,所以,在重置设备之前要保证所有D3DPOOL_DEFAULT类型的资源都必须释放掉,而且如果程序中使用了额外的SwapChain,那么也要重新创建之,否则Reset函数会失败。设备丢失的处理可以大致分成如下三个步骤

  1. 使用TestCooperativeLevel函数检测当前设备状态,如果可以重置,则重置,并重建使用D3DPOOL_DEFAULT创建的资源及SwapChain。
  2. 如果设备仍然处于丢失状态,则等待一段时间
  3. 如果是其他状态,比如驱动内部错误,则告知用户(比如显示错误框)

处理设备丢失的代码如下

复制代码
// Reset device
HRESULT ResetDevice(D3DPRESENT_PARAMETERS d3dpp)
{
    // Check device state
    HRESULT hr = g_pd3dDevice->TestCooperativeLevel() ;

    // Device can be reset now
    if (SUCCEEDED(hr) || hr == D3DERR_DEVICENOTRESET)
    {
        // Release resource allocated as D3DPOOL_DEFAULT

        // Reset device
        HRESULT hr = g_pd3dDevice->Reset(&d3dpp) ;
        if (SUCCEEDED(hr))
        {
            ResizeD3DScene(d3dpp.BackBufferWidth, d3dpp.BackBufferHeight) ;
        }
        else// Reset device failed, show error box
        {
            const WCHAR* errorString = DXGetErrorString(hr) ;
            DXTRACE_ERR_MSGBOX(errorString, hr) ;
        }
    }
    // Device is still in lost state, wait
    elseif (hr == D3DERR_DEVICELOST)
    {
        Sleep(25) ;
    }
    else// Other error, Show error box
    {
        const WCHAR* errorString = DXGetErrorString(hr) ;
        DXTRACE_ERR_MSGBOX(errorString, hr) ;
    }

    return hr ;
}
复制代码

需要注意的是,在重置Device的过程中(即调用Reset函数时),仍然会发生错误,这时我们简单的输出一个错误框告知用户。由于重置设备后,窗口的大小可能改变,所以我们要调用ResizeD3DScene来调整投影窗口的纵横比,该函数如下

复制代码
// Reset the scene by rebuild the viewing frustum
void ResizeD3DScene(int width, int height)
{
    if (height ==0 ) // Prevent A Divide By Zero By
        height =1; // Making Height Equal One

    // Compute aspect ratio
    float fAspectRatio = width / (FLOAT)height;

    // Setup Projection matrix
    g_Camera.SetProjParams( D3DX_PI/4, fAspectRatio, 1.0f, 1000.0f );

    g_Camera.SetWindow( width, height );
}
复制代码

验证一个3D程序是否正确处理了设备丢失

如果不能正确的处理设备丢失,则D3D程序经常会产生莫名其妙的现象 ,我们可以使用如下方法验证

1 在程序处于渲染状态时(窗口或者全屏态皆可)按下锁屏键(Win+L),然后返回程序,看看渲染内容是否丢失。

2 在程序处于全屏状态时,按下Win+D回到桌面,或者按下Atl+Tab切换到其他程序,然后在再到渲染程序,看看渲染内容是否丢失。

3 还有其他的,大家发挥想象力。。。

Vista及后续系统的情况

前面讨论的情况都是针对XP系统而言,如果你使用的是Window Vista及更高版本,那么情况则有所不同了,Vista使用的是WDDM driver(Windows Device Driver Model),而XP使用的是XPDM (XP Driver Model),前面说了,设备丢失的情况很多,并没有一个完整的列表来描述这些情况,但是在Vista系统上则不然,设备丢失只有两种情况,一是硬件hanging,另一种是driver stopped。

  • 如果是硬件挂起,那么可以通过ResetEx来重置设备,但是纹理内存会丢失。
  • 如果是驱动停止了,那么所有IDirect9Ex 对象必须重新创建以便继续渲染。

在窗口模式下,如果渲染区域被其他窗口遮挡,或者全屏模式下,程序最小化,PresentEx函数都会返回S_D3DPRESENTATIONOCCLUDED,全屏程序在收到WM_ACTIVATEAPP消息时会继续渲染。

在以前版本的DX中,当应用程序经历模式改变时,唯一的恢复办法就是reset device并重新创建所有显存资源及swap chain,但是在Vista上的DirectX,在模式改变后调用reset函数,纹理内存不会丢失,纹理渲染状态信息也不会丢失,这些资源都不必重新创建了。


本文转自zdd博客园博客,原文链接:http://www.cnblogs.com/graphics/archive/2010/08/21/1805548.html,如需转载请自行联系原作者

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
UE5GPU发生崩溃或D3D设备已移除是指在使用UE5引擎进行图形渲染时遇到的问题。崩溃可以是指程序无法正常运行并停止运行,而D3D设备已移除则表示由于某种原因,Direct3D设备与应用程序之间的通信断开。 UE5是一款强大的游戏引擎,用于创建交互性强的游戏或虚拟现实体验。然而,在使用UE5进行图形渲染时,由于各种原因可能会导致崩溃或D3D设备移除的问题。 造成UE5GPU崩溃的原因可能有多种,比如硬件问题、驱动问题、资源限制等。可能的解决方法包括更新最新的显卡驱动程序、降低图形设置、优化资源管理等。 D3D设备移除常见的原因包括显卡过热、显存不足、驱动程序错误等。解决方法可以包括清理显卡散热器、减少资源占用、更新显卡驱动等。 如果遇到UE5GPU崩溃或D3D设备已移除的问题,可以尝试以下步骤来解决: 1. 检查硬件是否正常工作,确保显卡、内存等没有问题。 2. 更新最新的显卡驱动程序,以确保与UE5引擎兼容。 3. 降低图形设置,减少资源占用,以保证D3D设备不会超负荷工作。 4. 检查项目的资源管理,优化资源使用方式,避免资源限制导致的崩溃或D3D设备移除。 5. 清理显卡散热器,并确保显卡工作在正常温度范围内。 6. 如果问题持续存在,可以尝试重启计算机或重新安装UE5引擎,更新或修复可能损坏的文件。 总之,UE5GPU崩溃或D3D设备已移除是比较常见的问题,但通常可以通过检查硬件、更新驱动程序、降低资源使用和优化配置等方法来解决。如果问题持续存在,可以尝试联系UE5官方支持或在相关论坛上咨询其他开发者的意见。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值