最適なパフォーマンスを得るには、DXGI フリップ モデルを使用します
このトピックでは、最新バージョンの Windows でプレゼンテーション スタックのパフォーマンスと効率を最大化する方法に関する開発者向けガイダンスを提供します。 DXGI フリップ モデル、DirectX 12: Windows 10のプレゼンテーション モード (ビデオ)、およびプレゼンテーションの機能強化がWindows 10: アーリー ルック (ビデオ) が中断された場所を取り上げます。
行動喚起
DXGI_SWAP_EFFECT_DISCARDまたはDXGI_SWAP_EFFECT_SEQUENTIAL ("blt" の現在のモデル) をまだ使用している場合は、停止します。
DXGI_SWAP_EFFECT_FLIP_SEQUENTIALまたはDXGI_SWAP_EFFECT_FLIP_DISCARD (フリップ モデル) に切り替えると、パフォーマンスが向上し、電力使用量が減少し、豊富な機能セットが提供されます。 (これらの値の詳細については、「 DXGI_SWAP_EFFECT列挙 」を参照してください)。
フリップモデルは、従来の「フルスクリーン排他」モードと比較して、ウィンドウモードを実質的に同等以上にするまで行きます。 実際には、フリップ モデルのボーダレス ウィンドウの利点には、より高速なAlt-Tab切り替えと最新のディスプレイ機能との統合が含まれるため、アプリケーションで実際に全画面表示排他モードが必要かどうかを再検討することをお勧めします。
なぜ今あるのか。 2018 年 4 月の更新プログラムより前のバージョンでは、blt モデルが提示されると、ハイブリッド GPU 構成で使用すると目に見える破損が発生する可能性があります。これは、ハイエンド ノート PC でよく見られます ( KB 3158621 を参照)。 2018 年 4 月の更新プログラムでは、このティアリングは、追加の作業を犠牲にして修正されました。 ハイブリッド GPU 全体の高フレームレート (特に 4K などの高解像度) で blt プレゼンテーションを実行している場合、この追加作業は全体的なパフォーマンスに影響を与える可能性があります。 これらのシステムで最高のパフォーマンスを維持するには、blt からフリップ現在のモデルに切り替えます。 さらに、スワップチェーンの解像度を下げることを検討してください。特に、それがユーザー操作の主要なポイントではない場合 (多くの場合、VR プレビュー ウィンドウの場合と同様)。
簡単な履歴
フリップ モデルとは 代替手段は何ですか?
Windows 7 より前では、D3D からコンテンツを表示する唯一の方法は、"blt" するか、ウィンドウまたは画面が所有するサーフェスにコピーすることでした。 D3D9 の FLIPEX スワップ効果から始まり、Windows 8のFLIP_SEQUENTIALスワップ効果を使用して DXGI にアクセスする際に、最小限のコピーでデスクトップ コンポジターと直接共有することで、コンテンツを画面に表示するより効率的な方法を開発しました。 テクノロジの概要については、「 DXGI フリップ モデル 」を参照してください。
この最適化は、WINDOWS デスクトップを駆動するコンポジターである DWM (デスクトップ ウィンドウ マネージャー) のおかげで可能です。
blt モデルを使用する必要がある場合
フリップ モデルで提供されない機能は 1 つあります。コンテンツを生成する複数の異なる API を持ち、すべてのレイヤーが同じ HWND に現在ごとにまとめて配置される機能です。 たとえば、D3D を使用してウィンドウの背景を描画し、 Windows GDI を使用して何かを上に描画するか、2 つの異なるグラフィックス API (または同じ API の 2 つのスワップチェーン) を使用して交互のフレームを生成します。 グラフィックス コンポーネント間の HWND レベルの相互運用が必要ない場合は、blt モデルは必要ありません。
元のフリップ モデル 設計では提供されていない機能の 2 つ目がありますが、現在は使用できます。これは、未変換のフレームレートで表示する機能です。 同期間隔 0 を使用するアプリケーションの場合、 IDXGIFactory5::CheckFeatureSupport API を使用でき、 DXGI_FEATURE_PRESENT_ALLOW_TEARINGのサポートを報告しない限り、モデルを反転するように切り替えることはお勧めしません。 この機能は、最近のバージョンのWindows 10と最新のハードウェアでは、ほぼユビキタスです。
DirectFlip
DirectX 12: プレゼンテーション モードをWindows 10で見た場合は、"Direct Flip" と "Independent Flip" の話が表示されます。これらは、フリップ モデル スワップチェーンを使用するアプリケーションで有効になっている最適化です。 ウィンドウとバッファーの構成に応じて、排他的な全画面表示と同じ方法で、デスクトップの構成を完全にバイパスし、アプリケーション フレームを画面に直接送信することができます。
最近では、これらの最適化は、機能を向上させるために、次の 3 つのシナリオのいずれかに取り組むことができます。
- DirectFlip: スワップチェーン バッファーは画面のサイズと一致し、ウィンドウ クライアント領域は画面をカバーします。 DWM スワップチェーンを使用して画面に表示する代わりに、アプリケーションスワップチェーンが使用されます。
- DirectFlip とパネル フィッター: ウィンドウ クライアント領域が画面を覆い、スワップチェーン バッファーが画面のハードウェアに依存するスケーリング 係数 (0.25 倍から 4 倍など) 内にあります。 GPU スキャンアウト ハードウェアは、バッファーをディスプレイに送信するときにスケーリングするために使用されます。
- マルチプレーン オーバーレイ (MPO) を使用した DirectFlip: スワップチェーン バッファーは、ウィンドウ ディメンションのハードウェアに依存するスケーリング係数内にあります。 DWM は、アプリケーション専用のハードウェア スキャンアウト プレーンを予約でき、スキャンアウトされ、アルファブレンドされた画面のサブ領域に拡張される可能性があります。
ウィンドウ反転モデルを使用すると、アプリケーションはさまざまな DirectFlip シナリオのハードウェア サポートに対してクエリを実行し、 IDXGIOutput6::CheckHardwareCompositionSupport を使用してさまざまな種類の動的スケーリングを実装できます。 注意すべき注意点の 1 つは、パネル フィッターを使用する場合、カーソルがストレッチ副作用を受ける可能性があるということです。これは、 DXGI_HARDWARE_COMPOSITION_SUPPORT_FLAG_CURSOR_STRETCHEDを介して示されます。
スワップチェーンが "DirectFlipped" になると、DWM はスリープ状態になり、アプリケーションの外部で何かが変更されたときにだけウェイクアップできます。 アプリケーション フレームは、全画面表示専用と同じ効率で、画面に直接送信されます。 これは "独立したフリップ" であり、上記のすべてのシナリオに取り組むことができます。 他のデスクトップ コンテンツが一番上にある場合、DWM はシームレスに構成済みモードに戻り、反転する前にアプリケーション上のコンテンツを効率的に "逆作成" するか、MPO を利用して独立した反転モードを維持できます。
PresentMon ツールを確認して、上記のどれが使用されたかを把握してください。
フリップ モデルの新機能は何ですか?
上記の機能強化に加えて、特別なものなしで標準スワップチェーンに適用される機能に加えて、フリップ モデル アプリケーションで使用できるいくつかの機能があります。
-
DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECTを使用して待機時間を短縮する。 独立反転モードの場合、最新バージョンの Windows では最大 1 フレームの待機時間が発生し、構成時に可能な最小限のフォールバックに正常にフォールバックできます。
- 注意: Windows 10 Anniversary Update 以前では、少なくとも 2 フレームの待機時間が発生する問題がありました。 詳細については 、このフォーラムのトピック を参照してください。 これは Fall Creator の更新プログラムで修正されています。
- DXGI_SWAP_EFFECT_FLIP_DISCARD では、直接反転の "逆コンポジション" モードが有効になり、デスクトップを表示する全体的な作業が少なくなります。 DWM は、独自のスワップチェーンに完全コピーを実行する代わりに、アプリケーション バッファーに書き込んで画面に送信できます。
- DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING では、マルチプレーン オーバーレイがサポートされているシステム上のウィンドウでも、待機可能なオブジェクトよりもさらに短い待機時間を実現できます。
- アプリケーションは、スワップチェーンの作成時に設定された DXGI_SCALING プロパティを使用して、ウィンドウのサイズ変更中に発生するコンテンツのスケーリングを制御できます。
- HDR 形式 (R10G10B10A2_UNORMまたはR16G16B16A16_FLOAT) のコンテンツは、SDR デスクトップに構成されていない限り、クランプされません。
- 現在の統計はウィンドウ モードで使用できます。
- UWP (ユニバーサル Windows プラットフォーム) アプリケーション モデルと DX12 との互換性は、フリップ モデルとのみ互換性があるためです。
フリップ モデルを使用するには、何を行う必要がありますか?
フリップ モデルスワップチェーンには、blt スワップチェーンに加えていくつかの追加要件があります。
- バッファー数は少なくとも 2 である必要があります。
- Present 呼び出しの後、バック バッファーを再び使用するには、その前に D3D11 イミディエイト コンテキストに明示的に再バインドする必要があります。
- SetFullscreenState を呼び出した後、アプリケーションは Present の前に ResizeBuffers を呼び出す必要があります。
- MSAA (マルチサンプルアンチエイリアシング) スワップチェーンは、フリップ モデルでは直接サポートされていないため、アプリケーションは Present を発行する前に MSAA 解決を実行する必要があります。
適切なレンダリングとプレゼンテーションの解像度を選択する方法
以前のアプリケーションの従来のパターンは、ユーザーが排他的な全画面表示モードを選択したときに選択できる解像度の一覧をユーザーに提供することです。 最新のディスプレイでコンテンツのスケーリングをシームレスに開始する機能を使用して、出力解像度から独立して、ウィンドウ モードであっても、パフォーマンスのスケーリング用にレンダリング解像度を選択する機能をユーザーに提供することを検討してください。 さらに、アプリケーションでは IDXGIOutput6::CheckHardwareCompositionSupport を利用して、コンテンツを表示する前にコンテンツをスケーリングする必要があるかどうか、またはハードウェアにスケーリングを実行させる必要があるかどうかを判断する必要があります。
現在またはコンポジション操作の一環として、ある GPU から別の GPU にコンテンツを移行する必要がある場合があります。 これは、多くの場合、マルチ GPU ノート PC、または外部 GPU が接続されているシステムで当てはまります。 これらの構成がより一般的になり、高解像度のディスプレイがより一般的になるにつれて、完全な解像度のスワップチェーンを提示するコストが増加します。 スワップチェーンのターゲットがユーザー操作の主要なポイントではない場合は、多くの場合、VR シーンの 2D プレビューをセカンダリ ウィンドウに表示する VR タイトルの場合と同様に、解像度の低いスワップチェーンを使用して、異なる GPU 間で転送する必要がある帯域幅の量を最小限にすることを検討してください。
その他の注意事項
GPU にスワップチェーン バック バッファーへの書き込みを初めて求めるのは、バッファーが使用可能になるのを待って GPU が停止する時間です。 可能な場合は、このポイントをフレームにできるだけ遅らせるようにします。