DXGIの理解を深めるため、作りかけのタイマーアプリのコードをベースにテストコードを書いてみようとしつつ、DXGIベストプラクティスガイドを読んでいた。
DXGIはいろいろと手取り足取りアシストしてくれるが、DX9コードからの移行に関しては逆にそれがハマる原因となってしまうようだ。私の場合ある意味「真っ白」なので、そういうレベルの高いハマりは無さそうだけれど。
ベストプラクティスガイドのポイントと思われるところを列挙してみる。
- ウィンドウ・リサイズした場合、DXGIはWM_SIZEメッセージを横取りしてフロントバッファーを変更する。バックバッファはユーザ側でWM_SIZEメッセージを捕まえてリサイズする(IDXGISwapChain::ResizeBuffers)必要がある。
- 全画面モードはIDXGISwapChain::SetFullscreenStateを呼び出す。このメソッドが呼び出されるとやはりWM_SIZEメッセージをDXGIが横取りしてウィンドウサイズを変更する。バックバッファはユーザ側でWM_SIZEメッセージを捕まえてリサイズする必要がある。
- DXGI は全画面表示解像度を既定でデスクトップの解像度に設定する。全画面表示でサイズを変えたい場合は IDXGISwapChain::ResizeTargetを呼び出す。
- IDXGISwapChain::ResizeTargetはIDXGISwapChain::SetFullscreenStateの前に呼び出すほうが良い。逆も可能だがその場合WM_SIZEメッセージが2回発生する。
- 全画面表示モードのときは、デスクトップ ウィンドウ マネージャーが無効になる。
- DXGIでフリップさせるためにはフロントバッファーとバックバッファーを同じサイズ・フォーマットにする必要がある。そうしないとブロック転送となりパフォーマンスが落ちる。
- 全画面表示モードのままで全画面表示の解像度を変更するには、スワップ・チェーン作成時、DXGI_SWAP_CHAIN_DESC構造体のFlagsメンバーにDXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCHを追加する。
- DX9では全画面・ウィンドウのモード切り替え時にウィンドウスタイルを元に戻したりする処理が必要であったが、DXGIでは不要である。
- マルチスレッド・アプリケーションの場合はDXGIに対する処理がデッド・ロックしないように気をつける。できればDXGIに対する処理は1つのスレッドでまとめて行うようにする。