丢失的设备 (Direct3D 9)

Direct3D 设备可以处于运行状态或丢失状态。 运行状态是设备的正常状态(设备正在运行),并能如预期般呈现所有内容。 当出现全屏应用程序失去键盘焦点而导致无法呈现内容等事件时,设备会转换到丢失状态。 丢失状态的特征在于所有呈现操作都没有任何提示就失败,这意味着即使呈现操作失败,呈现方法也可能返回成功代码。 在这种情况下,错误代码D3DERR_DEVICELOST由 IDirect3DDevice9::P resent 返回。

根据设计,未指定可导致设备丢失的所有场景。 一些典型的示例包括丢失焦点,例如当用户按下 ALT+TAB 时或当系统对话框进行初始化时。 设备也可能由于电源管理事件或另一个应用程序采取全屏操作而丢失。 此外, IDirect3DDevice9::Reset 的任何故障都会使设备进入丢失状态。

IUnknown 派生的所有方法都可以保证在设备丢失后正常工作。 设备丢失后,每个函数一般有以下三个选项:

  • 失败并D3DERR_DEVICELOST - 这意味着应用程序需要识别设备已丢失,以便应用程序确定某些事情未按预期发生。
  • 无提示失败、返回S_OK或任何其他返回代码 - 如果函数以无提示方式失败,应用程序通常无法区分“成功”和“无提示失败”的结果。
  • 函数返回返回代码。
Direct3D 9 和 Direct3D 9Ex 之间的差异:
Direct3D 9 设备返回D3DERR_DEVICELOST。 从 IDirect3DDevice9::P resent 返回后,仿真行为将不再运行,所有将来的调用都将失败,直到设备成功重置。
Direct3D 9Ex 设备永远不会返回D3DERR_DEVICELOST,但可以返回新的状态消息, () 查看 设备行为更改

 

响应丢失的设备

丢失的设备必须在重置后重新创建资源(包括视频存储器资源)。 如果设备丢失,应用程序会查询设备以了解其能否恢复到运行状态。 如果不能,应用程序将等待,直到设备可以恢复。

如果设备可以恢复,则应用程序通过销毁所有视频存储器资源和任何交换链来准备设备。 然后,应用程序调用 IDirect3DDevice9::Reset 方法。 重置是在设备丢失时唯一有效的方法,也是应用程序将设备从丢失状态更改为运行状态的唯一方法。 除非应用程序释放D3DPOOL_DEFAULT中分配的所有资源,包括 IDirect3DDevice9::CreateRenderTargetIDirect3DDevice9::CreateDepthStencilSurface 方法创建的资源,否则重置将失败。

在大多数情况下,Direct3D 的高频调用不返回有关设备是否已丢失的任何信息。 应用程序可以继续调用呈现方法,例如 IDirect3DDevice9::D rawPrimitive,而不会收到丢失设备的通知。 内部会放弃这些操作,直到设备被重置为运行状态。

应用程序可以通过查询 IDirect3DDevice9::TestCooperativeLevel 方法的返回值来确定遇到丢失设备时要执行的操作。

锁定操作

在内部,Direct3D 会执行充足的工作,以确保锁定操作将在设备丢失后成功。 但是,不保证视频存储器资源的数据在锁定操作期间准确无误。 保证不返回任何错误代码。 这使得在锁定操作期间可以向应用程序执行写入操作,而不理会设备是否丢失。

资源

资源可能会使用视频存储器。 丢失的设备会与适配器拥有的视频存储器断开连接,因而在设备丢失时不能保证视频存储器的分配。 因此,所有资源创建方法都通过返回D3D_OK来实现,但实际上只分配虚拟系统内存。 由于所有视频存储器资源都必须在设备调整大小之前销毁,所以不会出现过度分配视频存储器的问题。 这些虚拟表面允许锁定和复制操作正常运行,直到应用程序调用 IDirect3DDevice9::P resent 并发现设备已丢失。

必须先释放所有视频存储器,然后设备才能从丢失状态重置为运行状态。 这意味着应用程序应释放使用 IDirect3DDevice9::CreateAdditionalSwapChain 创建的任何交换链以及放置在 D3DPOOL_DEFAULT 内存类中的任何资源。 应用程序无需释放D3DPOOL_MANAGED或D3DPOOL_SYSTEMMEM内存类中的资源。 通过转换到运行状态,其他的状态数据会被自动销毁。

我们建议你开发通过单一代码路径响应设备丢失的应用程序。 此代码路径可能类似于(或等同于)在启动时初始化设备的代码路径。

检索的数据

Direct3D 允许应用程序使用 IDirect3DDevice9::ValidateDevice 根据硬件的单通道呈现来验证纹理和呈现状态。 此方法通常在应用程序初始化期间调用,如果设备丢失,将返回D3DERR_DEVICELOST。

Direct3D 还允许应用程序将生成的或先前写入的图像从视频存储器资源复制到非易失性系统内存资源。 由于此类传输的源图像可能在任何时间丢失,Direct3D 允许此类复制操作在设备丢失时失败。

关于异步查询,如果指定了 FLUSH 标志, IDirect3DQuery9::GetData 将返回D3DERR_DEVICELOST,以便向应用程序指示 IDirect3DQuery9::GetData 永远不会返回S_OK。

复制操作 IDirect3DDevice9::GetFrontBufferData 可能会失败并出现D3DERR_DEVICELOST,因为设备丢失时没有主表面。 IDirect3DDevice9::CreateAdditionalSwapChain 也可能因D3DERR_DEVICELOST而失败,因为设备丢失时无法创建后台缓冲区。 请注意,这些情况是 IDirect3DDevice9::P resent、IDirect3DDevice9::TestCooperativeLevelIDirect3DDevice9::Reset 方法之外的唯一D3DERR_DEVICELOST实例。

可编程着色器

在 Direct3D 9 中,重置后无需重新创建顶点着色器和像素着色器。 他们会被记住的。 在早期版本的 DirectX 中,丢失的设备需要重新创建着色器。

Direct3D 设备