本サイトでは、アフィリエイト広告およびGoogleアドセンスを利用しています。

DirectX11 でマルチフルスクリーン

Windwos 10 になってから、 DirectX11 の挙動で妙な点を発見しました。
以前 Windows 8.0 で OpenGL をマルチディスプレイで使った際にも変な動きがありました。それについての詳細情報は以前の日記を参照してください。OpenGL での問題の動きは Windows10 1703 でも発生していないようです。
今回の問題は、 SetFullscreenState が失敗して、各ディスプレイでフルスクリーンに遷移できないというものです。

現挙動の確認

昔ながらのコードが悪いのかと思い、 IDXGIFactory2 を使用して、 CreateSwapChainForHwnd でスワップチェインを作成するようにしてみました。
また、 DXGI_SWAP_CHAIN_FULLSCREEN_DESC にも各ディスプレイから取得した情報で値をセットするようにし、 Windowed メンバを TRUE にした状態で、フルスクリーンのスワップチェインを作成するようにしました。もちろん、各画面に応じて別のウィンドウとなるため、ウィンドウ (HWND) は2つ作成しています。

これでアプリケーションを実行すると、一瞬フルスクリーンモードになるのですが、すぐに解除されてしまいウィンドウモードでの実行となってしまいました。 NVIDIA, Intel ともに同じ動きをしているので、 Microsoft Windows 側の仕様変更が疑われます。

GetFullscreenState で状態を確認して、フルスクリーンモードに再度遷移する、と実装を修正して実行を試みました。結果はある程度はフルスクリーンモード状態になって、その後解除され、再びフルスクリーンモードに遷移して・・・と繰り返す動きでした。

情報収集

この件について何か情報があるかなと色々と検索してみたところ、同じようにマルチディスプレイの環境で失敗する事例はそれなりに報告があるようです。DirectX9 ですら、マルチディスプレイのフルスクリーンモードに失敗しているとのことでしたが、どこかの Windows10 の更新にて対応されているようです。これについては手元でも試してみましたが、確かにマルチディスプレイそれぞれでフルスクリーンモードとすることが出来ました。

検索していて見つけた情報で気になる点がありました。
“DXGI 1.4 Improvements” の項目にて、 以下のような記載がありました。

SetFullscreenState no longer exclusively owns the display,
so user-initiated operating system elements can seamlessly appear in front of application output.Volume settings is an example of this.

一応項目のカテゴリが DirectX12 の話ではあるのですが、気になる内容です。

リンク: DXGI 1.4 Improvements

まとめ

安定してフルスクリーンとすることは諦めて、ウィンドウを最前面の全画面にして擬似的なフルスクリーンモードとするのが1つの解法のようです。Windows 8 以降では、 DXGI の flip model が使用可能となっており、コピーが発生しない分パフォーマンスが良いとされているようです。
リンク: DXGI flip model

フルスクリーンモードを使いたい理由の1つは、やはり画面を flip で更新して余計なコピーが発生しない分高速に動くことを期待していたと思います。そのため、 DXGI Flip model が同じような動きをしてくれるのであれば、これを使うので解決するのかもと思います。

追記

マルチフルスクリーンのネタが3回構成になりました。以下の記事に続いています。

DirectX
すらりんをフォローする
すらりん日記
タイトルとURLをコピーしました