Share via


デバイスの消失

デバイスの消失

Microsoft® Direct3D® デバイスの状態には、処理可能状態と消失状態がある。処理可能状態はデバイスの通常の状態であり、すべてのレンダリングが予測どおりに実行され表示される。フルスクリーン アプリケーションでキーボード フォーカスが消失するなどのイベントが発生してレンダリングできなくなると、デバイスは消失状態になる。消失状態の特性は、表面的には何も現れずにすべてのレンダリング処理が失敗することである。つまり、レンダリング処理は失敗しているのに、レンダリング メソッドは成功コードを返すことがある。このような場合、IDirect3DDevice9::Present によってエラー コード D3DERR_DEVICELOST が返される。

設計では、デバイスが消失するようなすべてのシナリオが想定されているわけではない。一般的な例としては、ユーザーが Alt + Tab キーを押したときなど、つまりシステム ダイアログが初期化されたときにフォーカスが消失する。また、電力管理イベントによって、または他のアプリケーションがフルスクリーン処理を行うときにもデバイスが消失することがある。さらに、IDirect3DDevice9::Reset が失敗すると、デバイスは消失状態となる。

IUnknown から派生するすべてのメソッドは、デバイスが消失した後も動作することが保証されている。デバイス消失後、各機能には通常 3 つのオプションがある。

  • D3DERR_DEVICELOST で失敗する - デバイスが消失したことをアプリケーションが認識し、処理が指定どおりに実行されていないことをアプリケーションが識別する必要があることを示す。
  • 表面には何も現れずに失敗し、S_OK またはその他の戻りコードを返す - 機能がエラーを生成することなく失敗した場合、アプリケーションでは通常 "成功" と "表面には何も現れない失敗" を区別できない。
  • 関数は戻りコードを返す。

デバイス消失への応答

消失したデバイスは、リセット後にリソース (ビデオ メモリ リソースを含む) を再作成する必要がある。デバイスが消失すると、アプリケーションはそのデバイスに対して、処理可能状態に復元できるかどうかを問い合わせる。復元できない場合は、デバイスが復元できるまでアプリケーションは待機する。

復元できる場合、アプリケーションはすべてのビデオ メモリ リソースとスワップ チェーンを破棄して、デバイスの復元に備える。次に、アプリケーションは IDirect3DDevice9::Reset メソッドを呼び出す。Reset は、デバイスが消失状態のときに有効な唯一のメソッドであり、アプリケーションがデバイスを消失状態から処理可能状態に戻すことができる唯一のメソッドである。IDirect3DDevice9::CreateRenderTarget メソッドや IDirect3DDevice9::CreateDepthStencilSurface メソッドで作成されたリソースなど、D3DPOOL_DEFAULT で割り当てられたすべてのリソースをアプリケーションが解放しない限り、IDirect3DDevice9::Reset は失敗する。

ほとんどの場合、Direct3D を頻繁に呼び出してもデバイスが消失しているかどうかに関する情報は返らない。アプリケーションは、消失したデバイスの通知を受け取らなくても、IDirect3DDevice9::DrawPrimitive などのレンダリング メソッドの呼び出しを続行できる。内部的には、これらの処理は、デバイスが処理可能状態にリセットされるまで破棄される。

アプリケーションは、デバイスが消失したときの処理を判定するために IDirect3DDevice9::TestCooperativeLevel メソッドの戻り値を照会する。

ロック処理

内部的には、Direct3D ではデバイスが消失してもロック処理は成功するように機能する。しかし、ロック処理時にはビデオ メモリ リソースのデータが正確かどうかは保証されない。エラー コードが返らないことは保証されている。したがって、アプリケーションの記述にあたっては、ロック処理時のデバイスの消失については考慮しなくてよい。

リソース

リソースはビデオ メモリを消費する。消失したデバイスは、アダプタが所有するビデオ メモリから接続解除されるため、デバイスが消失したときのビデオ メモリの割り当てを保証することはできない。そのため、すべてのリソース作成メソッドは、D3D_OK が返ると成功するが実際にはダミーのシステム メモリのみを割り当てるように実装されている。すべてのビデオ メモリ リソースは、サイズ変更する前にデバイスを破棄する必要があるため、ビデオ メモリの過剰割り当ては発生しない。このようなダミー サーフェイスにより、アプリケーションが IDirect3DDevice9::Present を呼び出してデバイスの消失を検出するまで、ロック処理やコピー処理が正常に機能しているように見える。

ドライバが消失状態から処理可能状態に復元する前に、すべてのビデオ メモリを解放しなければならない。つまり、アプリケーションは IDirect3DDevice9::CreateAdditionalSwapChain によって作成されたすべてのスワップ チェーンや D3DPOOL_DEFAULT メモリ クラスに配置されているすべてのリソースを解放しなければならない。アプリケーションは、D3DPOOL_MANAGED メモリ クラスや D3DPOOL_SYSTEMMEM メモリ クラスに配置されているリソースは解放する必要がない。他の状態データは、処理可能状態への移行によって自動的に破棄される。

アプリケーションの開発にあたっては、デバイスの消失に対して 1 つのコード パスで対応することを推奨する。このコード パスは、スタートアップ時にデバイスの初期化に使用したコード パスと同一ではなくても類似のものにすること。

データの取得

Direct3D では、IDirect3DDevice9::ValidateDevice を使って、ハードウェアによるシングルパス レンダリングに照らしてテクスチャ ステートおよびレンダリング ステートを検証できる。このメソッドは、通常はアプリケーションの初期化時に呼び出され、デバイスが消失している場合は D3DERR_DEVICELOST を返す。

Direct3D によってアプリケーションは、生成された画像 (または以前に描かれた画像) を、ビデオ メモリ リソースから不揮発性のシステム メモリ リソースにコピーできる。このような転送では転送元画像はいつでも失われる可能性があるため、Direct3D が、デバイスが消失したときはコピー処理を失敗させる場合がある。

非同期問い合わせに関しては、IDirect3DQuery9::GetData が S_OK を返さないことをアプリケーションに示すために、FLUSH フラグが指定されている場合は IDirect3DQuery9::GetData は D3DERR_DEVICELOST を返す。

デバイスを消失するとプライマリ サーフェイスは存在しないため、コピー処理である IDirect3DDevice9::GetFrontBufferData は D3DERR_DEVICELOST で失敗する。デバイスが消失するとバック バッファを作成できないため、IDirect3DDevice9::CreateAdditionalSwapChain も D3DERR_DEVICELOST で失敗する。これらのケースは、IDirect3DDevice9::PresentIDirect3DDevice9::TestCooperativeLevelIDirect3DDevice9::Reset メソッド以外で D3DERR_DEVICELOST を使う唯一の例外であることに注意すること。

プログラマブル シェーダ

Microsoft DirectX® 9.0 では、頂点シェーダ 1_1 およびピクセル シェーダ 1_XReset 後に再作成する必要はない。これらは記憶されている。DirectX の以前のバージョンでは、消失したサービスについてはシェーダを再作成する必要があった。