紛失したデバイス (Direct3D 9)
Direct3D デバイスは、操作状態または失われた状態にすることができます。 操作状態は、デバイスが実行され、すべてのレンダリングが想定どおりに表示されるデバイスの通常の状態です。 デバイスは、全画面表示アプリケーションでのキーボード フォーカスの損失など、イベントによってレンダリングが不可能になったときに、失われた状態に遷移します。 失われた状態は、すべてのレンダリング操作のサイレント エラーによって特徴付けられます。つまり、レンダリング操作が失敗しても、レンダリング メソッドは成功コードを返すことができます。 この状況では、エラー コード D3DERR_DEVICELOSTは、IDirect3DDevice9::P resentによって返されます。
設計上、デバイスが失われる可能性があるシナリオの完全なセットは指定されていません。 一般的な例としては、ユーザーが Alt キーを押しながら Tab キーを押したときやシステム ダイアログが初期化されたときなど、フォーカスが失われることがあります。 また、電源管理イベントが原因でデバイスが失われたり、別のアプリケーションで全画面表示が想定されたりする場合もあります。 さらに、IDirect3DDevice9::Reset によってデバイスが失われた状態になります。
IUnknownから派生するすべてのメソッドは、デバイスが失われた後に動作することが保証されます。 デバイスの損失後、各関数には通常、次の 3 つのオプションがあります。
- D3DERR_DEVICELOSTで失敗する - これは、アプリケーションがデバイスが失われたことを認識する必要があることを意味します。これにより、アプリケーションは何かが予期したとおりに発生していないことを識別します。
- サイレント 失敗、S_OKまたはその他のリターン コードを返す - 関数がサイレントで失敗した場合、アプリケーションは通常、"成功" と "サイレント エラー" の結果を区別できません。
- この関数は戻りコードを返します。
Direct3D 9 と Direct3D 9Ex の違い: Direct3D 9 デバイスは、D3DERR_DEVICELOSTを返します。 IDirect3DDevice9::P存在から返されると、エミュレーション動作は動作しなくなり、デバイスが正常にリセットされるまで、以降のすべての呼び出しは失敗します。 Direct3D 9Ex デバイスはD3DERR_DEVICELOSTを返しませんが、新しいステータス メッセージを返すことができます (デバイスの動作の変更を参照)。 |
紛失したデバイスへの応答
紛失したデバイスは、リセット後にリソース (ビデオ メモリ リソースを含む) を再作成する必要があります。 デバイスが失われた場合、アプリケーションはデバイスに対してクエリを実行して、操作状態に復元できるかどうかを確認します。 そうでない場合、アプリケーションはデバイスを復元できるようになるまで待機します。
デバイスを復元できる場合、アプリケーションはすべてのビデオ メモリ リソースとスワップ チェーンを破棄してデバイスを準備します。 次に、アプリケーションは IDirect3DDevice9::Reset メソッドを呼び出します。 リセットは、デバイスが失われたときに影響を与える唯一の方法であり、アプリケーションがデバイスを紛失状態から操作状態に変更できる唯一の方法です。 IDirect3DDevice9::CreateRenderTarget および IDirect3DDevice9::CreateDepthStencilSurface メソッドによって作成されたものを含む、D3DPOOL_DEFAULTに割り当てられているすべてのリソースをアプリケーションが解放しない限り、リセットは失敗します。
ほとんどの場合、Direct3D の高頻度呼び出しでは、デバイスが失われたかどうかに関する情報は返されません。 アプリケーションは、紛失したデバイスの通知を受け取ることなく、IDirect3DDevice9::D rawPrimitiveなどのレンダリング メソッドを引き続き呼び出すことができます。 内部的には、これらの操作は、デバイスが操作状態にリセットされるまで破棄されます。
アプリケーションは、IDirect3DDevice9::TestCooperativeLevel メソッドの戻り値に対してクエリを実行することで、紛失したデバイスが検出された場合の処理を決定できます。
ロック操作
内部的には、Direct3D は、デバイスが失われた後にロック操作が成功するように十分な作業を行います。 ただし、ロック操作中にビデオ メモリ リソースのデータが正確になることは保証されません。 エラー コードが返されていないことが保証されます。 これにより、ロック操作中にデバイスが失われることを気にせずにアプリケーションを書き込むことが可能になります。
リソース
リソースはビデオ メモリを使用できます。 紛失したデバイスはアダプターが所有するビデオ メモリから切断されるため、デバイスが失われたときにビデオ メモリの割り当てを保証することはできません。 その結果、すべてのリソース作成メソッドは、D3D_OKを返すことによって成功するように実装されますが、実際にはダミー システム メモリのみを割り当てます。 デバイスのサイズを変更する前にビデオ メモリ リソースを破棄する必要があるため、ビデオ メモリを過剰に割り当てる問題はありません。 これらのダミー サーフェスを使用すると、アプリケーションが IDirect3DDevice9::P存在する呼び出し、デバイスが失われたことを検出するまで、ロック操作とコピー操作が正常に機能するように見えます。
デバイスを紛失状態から操作状態にリセットするには、すべてのビデオ メモリを解放する必要があります。 つまり、アプリケーションは、IDirect3DDevice9::CreateAdditionalSwapChain と、D3DPOOL_DEFAULT メモリ クラスに配置されたすべてのリソースで作成されたスワップ チェーンを解放する必要があります。 アプリケーションは、D3DPOOL_MANAGEDまたはD3DPOOL_SYSTEMMEMメモリ クラスのリソースを解放する必要はありません。 その他の状態データは、運用状態への移行によって自動的に破棄されます。
デバイスの損失に対応するために、1 つのコード パスを持つアプリケーションを開発することをお勧めします。 このコード パスは、起動時にデバイスを初期化するために取得したコード パスと同じでない場合に似ている可能性があります。
取得されたデータ
Direct3D を使用すると、IDirect3DDevice9::ValidateDeviceを使用して、ハードウェアによるシングル パス レンダリングに対してテクスチャとレンダリングの状態を検証できます。 このメソッドは、通常、アプリケーションの初期化中に呼び出され、デバイスが失われた場合にD3DERR_DEVICELOSTを返します。
Direct3D では、生成されたイメージまたは以前に書き込まれたイメージをビデオ メモリ リソースから不揮発性システム メモリ リソースにコピーすることもできます。 このような転送のソース イメージはいつでも失われる可能性があるため、Direct3D では、デバイスが失われたときにこのようなコピー操作が失敗する可能性があります。
非同期クエリに関しては、IDirect3DQuery9::GetData は、IDirect3DQuery9::GetData がS_OKを返さないことをアプリケーションに示すために、FLUSH フラグが指定されている場合にD3DERR_DEVICELOSTを返します。
IDirect3DDevice9::GetFrontBufferDataコピー操作は、デバイスが失われたときにプライマリ サーフェスがないため、D3DERR_DEVICELOSTで失敗する可能性があります。 IDirect3DDevice9::CreateAdditionalSwapChain は、デバイスが失われたときにバック バッファーを作成できないため、D3DERR_DEVICELOSTで失敗する可能性もあります。 これらのケースは、IDirect3DDevice9::P resent、IDirect3DDevice9::TestCooperativeLevel、および IDirect3DDevice9::Reset メソッドの外部にあるD3DERR_DEVICELOSTの唯一のインスタンスであることに注意してください。
プログラミング可能なシェーダー
Direct3D 9 では、頂点シェーダーとピクセル シェーダーをリセット後に再作成する必要はありません。 これらは記憶されます。 以前のバージョンの DirectX では、紛失したデバイスでシェーダーを再作成する必要があります。
関連トピック
-
Direct3D デバイス の