IDXGISwapChain
COM公式ドキュメント
IDXGISwapChain インターフェイスは、レンダリングされたデータを出力(アウトプット)へ表示(プレゼント)する前に格納するための 1 つ以上のサーフェスを実装します。
解説(Remarks)
スワップチェーンは、 IDXGIFactory2::CreateSwapChainForHwnd、IDXGIFactory2::CreateSwapChainForCoreWindow、または IDXGIFactory2::CreateSwapChainForComposition を呼び出すことで作成できます。D3D11CreateDeviceAndSwapChain を呼び出す際にもスワップチェーンを作成できますが、その場合は IDXGISwapChain インターフェイスが提供するスワップチェーン機能のサブセットにのみアクセスできます。
メソッド 10
vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。
レンダリングされたイメージをユーザーに表示(プレゼント)します。
| SyncInterval | DWORD | in | フレームの表示(プレゼント)を垂直ブランキングとどのように同期させるかを指定する整数です。 ビットブロック転送(bitblt)モデル(DXGI_SWAP_EFFECT_DISCARD または DXGI_SWAP_EFFECT_SEQUENTIAL)の場合、値は次のとおりです。
更新領域が複数の出力(アウトプット)(それぞれ IDXGIOutput で表される)にまたがる場合、Present は対象ウィンドウのクライアント領域の最大の部分矩形を含む出力に対して同期を行います。 |
| Flags | DXGI_PRESENT | in | スワップチェーンの表示(プレゼント)オプションを格納する整数値です。これらのオプションは DXGI_PRESENT 定数で定義されます。 |
戻り値
型: HRESULT
返される可能性のある値には次のものがあります。S_OK、DXGI_ERROR_DEVICE_RESET または DXGI_ERROR_DEVICE_REMOVED(DXGI_ERROR を参照)、DXGI_STATUS_OCCLUDED(DXGI_STATUS を参照)、または D3DDDIERR_DEVICEREMOVED。
解説(Remarks)
Direct3D 11.1 以降では、IDXGISwapChain1::Present1 の使用を検討してください。これを使用すると、スワップチェーンの表示(プレゼント)でダーティ矩形とスクロール矩形を利用でき、メモリ帯域幅の消費が減り、その結果としてシステムの消費電力も抑えられます。スワップチェーンの表示におけるダーティ矩形とスクロール矩形の使用について詳しくは、スワップチェーンの表示におけるダーティ矩形とスクロール矩形の使用 を参照してください。
全画面アプリケーションでスワップチェーンのバッファーをフリップする際に最高のパフォーマンスを得る方法については、全画面アプリケーションのパフォーマンスに関するヒント を参照してください。
Present を呼び出すと、レンダースレッドがメッセージポンプスレッドを待機する可能性があるため、複数のスレッドを使用するアプリケーションでこのメソッドを呼び出す際は注意してください。詳しくは、マルチスレッドに関する考慮事項 を参照してください。
|
Direct3D 9 と Direct3D 10 の違い:
Flags パラメーターに DXGI_PRESENT_TEST を指定することは、Direct3D 9 の IDirect3DDevice9::TestCooperativeLevel に相当します。 |
DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL または DXGI_SWAP_EFFECT_DISCARD の値を設定して作成したフリップ表示モデルのスワップチェーンでは、表示(プレゼント)が成功すると、バックバッファー 0(通常は OMSetRenderTargets で設定される)がグラフィックスパイプラインからバインド解除されます。ただし、Flags パラメーターに DXGI_PRESENT_DO_NOT_SEQUENCE フラグを渡した場合を除きます。
コンテンツを画面に表示(プレゼント)する際にデータ値がどのように変化するかについては、色空間に応じたデータ変換 を参照してください。
フリップ表示モデルのキュー
次のように、sync-interval 値を持つフレームが、Present を呼び出す前に古いもの(A)から新しいもの(E)の順にキューに入っているとします。A: 3、B: 0、C: 0、D: 1、E: 0
Present を呼び出すと、ランタイムはフレーム A を垂直ブランキング 1 回分の間だけ表示します。フレーム B の sync interval が 0 であるため、ランタイムはフレーム A を早期に終了させます。 次にランタイムはフレーム D を垂直ブランキング 1 回分の間表示し、その後、新しい表示(プレゼント)を送信するまでフレーム E を表示します。ランタイムはフレーム B と C を破棄します。
可変リフレッシュレートディスプレイ
可変リフレッシュレートディスプレイでは、テアリングが有効になっていることが要件となります。この機能が利用可能かどうかを判断するには CheckFeatureSupport メソッドを使用できます。また、必要なフラグの設定については、DXGI_PRESENT_ALLOW_TEARING と DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING の説明、および 可変リフレッシュレートディスプレイ を参照してください。スワップチェーンのバックバッファーの 1 つにアクセスします。
| Buffer | DWORD | in | 0 から始まるバッファーインデックスです。 スワップチェーンのスワップ効果が DXGI_SWAP_EFFECT_DISCARD の場合、このメソッドは最初のバッファーにのみアクセスできます。この場合はインデックスに 0 を設定してください。 スワップチェーンのスワップ効果が DXGI_SWAP_EFFECT_SEQUENTIAL の場合、スワップチェーンのインデックス 0 のバッファーのみが読み取りと書き込みの対象になります。インデックスが 0 より大きいスワップチェーンのバッファーは読み取り専用です。そのため、そのようなバッファーに対して IDXGIResource::GetUsage メソッドを呼び出すと、DXGI_USAGE_READ_ONLY フラグが設定されています。 スワップチェーンのスワップ効果が DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL の場合、インデックスとバッファーの対応関係は一貫しています。IDXGISwapChain::Present が呼び出されるたびにスワップチェーンのインデックス 0 のバッファーを取得しても、結果は同じです。現在のバックバッファーを取得するには、正しいフレームインデックスを使用してください。 |
| riid | GUID* | in | バッファーを操作するために使用するインターフェイスの型です。 |
| ppSurface | void** | out | バックバッファーインターフェイスへのポインターです。 |
戻り値
型: HRESULT
次の DXGI_ERROR のいずれかを返します。
表示状態をウィンドウモードまたは全画面に設定します。
| Fullscreen | BOOL | in | 表示状態をウィンドウモードにするか全画面にするかを指定するブール値です。全画面の場合は TRUE、ウィンドウモードの場合は FALSE を指定します。 |
| pTarget | IDXGIOutput* | inoptional | 表示状態を全画面に設定するために Fullscreen パラメーターに TRUE を渡す場合、このパラメーターには、スワップチェーンを含む出力(アウトプット)ターゲットの IDXGIOutput インターフェイスへのポインターを任意で設定できます。このパラメーターに NULL を設定すると、DXGI はスワップチェーンのデバイスと出力ウィンドウの配置に基づいて出力を選択します。Fullscreen に FALSE を渡す場合は、このパラメーターに NULL を設定する必要があります。 |
戻り値
型: HRESULT
このメソッドは次のいずれかの値を返します。
- S_OK — 処理が成功し、スワップチェーンが要求された状態になった場合。
- DXGI_ERROR_NOT_CURRENTLY_AVAILABLE — 処理が失敗した場合。このエラーが返された場合でも、アプリケーションはウィンドウモードで実行を続け、後で全画面モードへの切り替えを試みることができます。ウィンドウモードのスワップチェーンが全画面モードに切り替えられない理由はさまざまです。以下にいくつかの例を示します。
- アプリケーションがターミナルサーバー経由で実行されている。
- 出力ウィンドウが隠されている。
- 出力ウィンドウがキーボードフォーカスを持っていない。
- 別のアプリケーションが既に全画面モードになっている。
- DXGI_STATUS_MODE_CHANGE_IN_PROGRESS — この API が呼び出された時点で全画面/ウィンドウモードの遷移が発生している場合に返されます。
- その他のエラーコード — メモリ不足やその他の予期しない障害が発生した場合。これらのコードは、回復不能な重大なエラーとして扱われることがあります。
解説(Remarks)
DXGI は、エンドユーザーやシステムの要求に応じて、スワップチェーンの表示状態を変更することがあります。
ウィンドウモードのスワップチェーンを作成し、エンドユーザーが SetFullscreenState を通じてスワップチェーンを全画面に変更できるようにすることをお勧めします。つまり、スワップチェーンを強制的に全画面にするために DXGI_SWAP_CHAIN_DESC の Windowed メンバーを FALSE に設定しないでください。ただし、スワップチェーンを全画面として作成する場合は、サポートされている表示モードの一覧もエンドユーザーに提示してください。サポートされていない表示モードで作成されたスワップチェーンは、ディスプレイが真っ暗になり、エンドユーザーが何も見えなくなる原因となることがあるためです。また、エンドユーザーが表示モードを変更できるようにする場合は、タイムアウト確認画面などのフォールバック機構を用意することをお勧めします。
Windows ストアアプリに関する注意事項
Windows ストアアプリが SetFullscreenState を呼び出して表示状態を全画面に設定しようとすると、SetFullscreenState は DXGI_ERROR_NOT_CURRENTLY_AVAILABLE で失敗します。IDXGIFactory2::CreateSwapChainForComposition で作成したスワップチェーンに対して SetFullscreenState を呼び出すことはできません。
フリップ表示モデルでは、表示状態を全画面に遷移させた後、IDXGISwapChain1::Present1 の呼び出しが成功することを保証するために、ResizeBuffers を呼び出す必要があります。
全画面モードに関連付けられた状態を取得します。
| pFullscreen | BOOL* | outoptional | 次のいずれかの値を持つブール値へのポインターです。
|
| ppTarget | IDXGIOutput** | outoptional | モードが全画面の場合は出力(アウトプット)ターゲット(IDXGIOutput を参照)へのポインター、それ以外の場合は NULL です。 |
戻り値
型: HRESULT
次の DXGI_ERROR のいずれかを返します。
解説(Remarks)
スワップチェーンが全画面モードの場合、ターゲット出力(アウトプット)へのポインターが返され、その参照カウントがインクリメントされます。
スワップチェーンの説明を取得します。
| pDesc | DXGI_SWAP_CHAIN_DESC* | out | スワップチェーンの説明(DXGI_SWAP_CHAIN_DESC を参照)へのポインターです。 |
戻り値
型: HRESULT
次の DXGI_ERROR のいずれかを返します。
スワップチェーンのバックバッファーのサイズ、フォーマット、バッファー数を変更します。アプリケーションのウィンドウがリサイズされたときに呼び出す必要があります。
| BufferCount | DWORD | in | スワップチェーン内のバッファー数(すべてのバックバッファーとフロントバッファーを含む)です。 この数は、スワップチェーンを作成したときのバッファー数と異なっていてもかまいません。 この数は DXGI_MAX_SWAP_CHAIN_BUFFERS を超えることはできません。 スワップチェーンの既存のバッファー数を維持するには、この数を 0 に設定します。 フリップ表示モデルでは、バッファー数を 2 未満にすることはできません。 |
| Width | DWORD | in | バックバッファーの新しい幅です。 0 を指定すると、DXGI は対象ウィンドウのクライアント領域の幅を使用します。 コンポジションサーフェス用のスワップチェーンを作成するために IDXGIFactory2::CreateSwapChainForComposition メソッドを呼び出した場合、幅を 0 に指定することはできません。 |
| Height | DWORD | in | バックバッファーの新しい高さです。 0 を指定すると、DXGI は対象ウィンドウのクライアント領域の高さを使用します。 コンポジションサーフェス用のスワップチェーンを作成するために IDXGIFactory2::CreateSwapChainForComposition メソッドを呼び出した場合、高さを 0 に指定することはできません。 |
| NewFormat | DXGI_FORMAT | in | バックバッファーの新しいフォーマットを表す DXGI_FORMAT 型の値です。 バックバッファーの既存のフォーマットを維持するには、この値を DXGI_FORMAT_UNKNOWN に設定します。 フリップ表示モデルは、ビットブロック転送(bitblt)モデルよりも制限された範囲のフォーマットをサポートします。 |
| SwapChainFlags | DWORD | in | ビット単位の OR 演算で組み合わせた DXGI_SWAP_CHAIN_FLAG 型の値の組み合わせです。 結果として得られる値は、スワップチェーンの動作に関するオプションを指定します。 |
戻り値
型: HRESULT
成功した場合は S_OK を返し、それ以外の場合はエラーコードを返します。 エラーコードの一覧については、DXGI_ERROR を参照してください。
解説(Remarks)
スワップチェーンのバックバッファーに対する未解放の参照をすべて解放しない限り、スワップチェーンをリサイズすることはできません。 ResizeBuffers を成功させるには、バックバッファーに対する直接参照と間接参照をすべて解放する必要があります。
直接参照は、アプリケーションがリソースに対して AddRef を呼び出した後にアプリケーションが保持します。
間接参照は、リソースへのビュー、リソースのビューのデバイスコンテキストへのバインド、そのリソースを使用したコマンドリスト、そのリソースへのビューを使用したコマンドリスト、そのリソースを使用した別のコマンドリストを実行したコマンドリストなどが保持します。
ResizeBuffers を呼び出す前に、リソース、リソースへのビュー、およびリソースまたはビューを使用するコマンドリストに対するすべての参照を、アプリケーションが(適切な回数の Release 呼び出しによって)解放していることを確認し、リソースとビューのいずれもデバイスコンテキストにバインドされたままになっていないことを確認してください。 すべての参照が解放されていることを保証するために、ID3D11DeviceContext::ClearState を使用できます。 ビューが遅延コンテキストにバインドされている場合は、部分的に構築されたコマンドリストも破棄する必要があります(ID3D11DeviceContext::ClearState、続いて ID3D11DeviceContext::FinishCommandList、続いてコマンドリストに対する Release を呼び出します)。 ResizeBuffers を呼び出した後は、IDXGISwapChain::GetBuffer を介してインターフェイスを再取得できます。
DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE で作成したスワップチェーンの場合は、ResizeBuffers を呼び出す前に、未解放の GDI デバイスコンテキスト(DC)が開いたままになっていないことを保証するために、スワップチェーンのバックバッファーサーフェスに対して IDXGISurface1::ReleaseDC も呼び出してください。
クライアントウィンドウがリサイズされたとき(つまり、アプリケーションが WM_SIZE メッセージを受け取ったとき)に ResizeBuffers を呼び出すことをお勧めします。
Windows 8 と Windows 7 における IDXGISwapChain::ResizeBuffers の唯一の違いは、DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL または DXGI_SWAP_EFFECT_FLIP_DISCARD の値を設定して作成したフリップ表示モデルのスワップチェーンに関するものです。 Windows 8 では、全画面モードとウィンドウモードの間の遷移を実現するために ResizeBuffers を呼び出す必要があります。 そうしないと、次に IDXGISwapChain::Present メソッドを呼び出したときに失敗します。
出力(アウトプット)ターゲットをリサイズします。
| pNewTargetParameters | DXGI_MODE_DESC* | in | モードを記述する DXGI_MODE_DESC 構造体へのポインターです。この構造体は、ターゲットの新しい幅、高さ、フォーマット、リフレッシュレートを指定します。 フォーマットが DXGI_FORMAT_UNKNOWN の場合、ResizeTarget は既存のフォーマットを使用します。このメソッドはスレッドセーフではないため、DXGI_FORMAT_UNKNOWN の使用は、スワップチェーンが全画面モードの場合にのみ推奨します。 |
戻り値
型: HRESULT
成功または失敗を示すコードを返します。この API が呼び出された時点で全画面/ウィンドウモードの遷移が発生している場合は、DXGI_STATUS_MODE_CHANGE_IN_PROGRESS が返されます。その他の DXGI エラーコードについては、DXGI_ERROR を参照してください。
解説(Remarks)
ResizeTarget は、スワップチェーンがウィンドウモードの場合は対象ウィンドウをリサイズし、スワップチェーンが全画面モードの場合は対象の出力(アウトプット)の表示モードを変更します。したがって、アプリケーションは、スワップチェーンの表示モードを意識することなく、SetWindowPos などの Microsoft Win32API ではなく ResizeTarget を呼び出して対象ウィンドウをリサイズできます。
Windows ストアアプリが ResizeTarget を呼び出すと、DXGI_ERROR_NOT_CURRENTLY_AVAILABLE で失敗します。
IDXGIFactory2::CreateSwapChainForComposition で作成したスワップチェーンに対して ResizeTarget を呼び出すことはできません。
バックバッファーを変更できるのは ResizeBuffers だけであるため、アプリケーションは ResizeTarget を呼び出した後も IDXGISwapChain::ResizeBuffers を呼び出す必要があります。ただし、ResizeBuffers を呼び出すウィンドウリサイズ処理を実装しているアプリケーションであれば、そのウィンドウリサイズ処理がアプリケーションの必要とする処理を行うため、ResizeTarget を呼び出した後に明示的に ResizeBuffers を呼び出す必要はありません。
対象ウィンドウのクライアント領域の大部分を含む出力(アウトプット)(ディスプレイモニター)を取得します。
| ppOutput | IDXGIOutput** | out | 出力(アウトプット)インターフェイス(IDXGIOutput を参照)へのポインターです。 |
戻り値
型: HRESULT
次の DXGI_ERROR のいずれかを返します。
解説(Remarks)
メソッドが成功すると、出力(アウトプット)インターフェイスが設定され、その参照カウントがインクリメントされます。使用が終わったら、メモリリークを防ぐために必ずインターフェイスを解放してください。
この出力は、スワップチェーンのデバイスが作成されたアダプターにも所有されています。
IDXGIFactory2::CreateSwapChainForComposition で作成したスワップチェーンに対して GetContainingOutput を呼び出すことはできません。
そのようなスワップチェーンに対応する出力を特定するには、IDXGIFactory::EnumAdapters を呼び出し、続いて IDXGIAdapter::EnumOutputs を呼び出して、利用可能なすべての出力を列挙してください。その後、DXGI_OUTPUT_DESC1::DesktopCoordinates または DXGI_OUTPUT_DESC::DesktopCoordinates で報告される各出力のデスクトップ座標と、CoreWindow::Bounds の境界を交差させてください。
直前のレンダーフレームに関するパフォーマンス統計を取得します。
| pStats | DXGI_FRAME_STATISTICS* | out | フレーム統計を格納する DXGI_FRAME_STATISTICS 構造体へのポインターです。 |
戻り値
型: HRESULT
DXGI_ERROR 値のいずれかを返します。
解説(Remarks)
ビットブロック転送(bitblt)表示モデルを使用し、かつウィンドウモードで描画するスワップチェーンに対しては、GetFrameStatistics を使用できません。
GetFrameStatistics を使用できるのは、フリップ表示モデルを使用するか、全画面モードで描画するスワップチェーンに限られます。スワップチェーンがフリップ表示モデルを使用することを指定するには、DXGI_SWAP_CHAIN_DESC1 構造体の SwapEffect メンバーに DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL の値を設定します。
複数モニターの多くのシナリオや、他の全画面アプリケーションが実行されているシナリオでは、統計は信頼できません。
Hardware Flip Queue をサポートするシステムでは、フレーム統計が更新される前に DwmFlush を呼び出す必要がある場合があります。
IDXGISwapChain::Present または IDXGISwapChain1::Present1 が呼び出された回数を取得します。
| pLastPresentCount | DWORD* | out | 呼び出し回数を受け取る変数へのポインターです。 |
戻り値
型: HRESULT
DXGI_ERROR 値のいずれかを返します。
解説(Remarks)
フレームの表示(プレゼント)統計については、DXGI_FRAME_STATISTICS を参照してください。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
HSP用 COM定義
#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"。
#define global IID_IDXGISwapChain "{310D36A0-D2E7-4C0A-AA04-6A9D23B8886A}" #usecom global IDXGISwapChain IID_IDXGISwapChain "{}" #comfunc global IDXGISwapChain_Present 8 int,int #comfunc global IDXGISwapChain_GetBuffer 9 int,var,sptr #comfunc global IDXGISwapChain_SetFullscreenState 10 int,sptr #comfunc global IDXGISwapChain_GetFullscreenState 11 var,sptr #comfunc global IDXGISwapChain_GetDesc 12 var #comfunc global IDXGISwapChain_ResizeBuffers 13 int,int,int,int,int #comfunc global IDXGISwapChain_ResizeTarget 14 var #comfunc global IDXGISwapChain_GetContainingOutput 15 sptr #comfunc global IDXGISwapChain_GetFrameStatistics 16 var #comfunc global IDXGISwapChain_GetLastPresentCount 17 var ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数は var(変数直渡し)。varptr 方式にも切替可。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。#define global IID_IDXGISwapChain "{310D36A0-D2E7-4C0A-AA04-6A9D23B8886A}" #usecom global IDXGISwapChain IID_IDXGISwapChain "{}" #comfunc global IDXGISwapChain_Present 8 int,int #comfunc global IDXGISwapChain_GetBuffer 9 int,sptr,sptr #comfunc global IDXGISwapChain_SetFullscreenState 10 int,sptr #comfunc global IDXGISwapChain_GetFullscreenState 11 sptr,sptr #comfunc global IDXGISwapChain_GetDesc 12 sptr #comfunc global IDXGISwapChain_ResizeBuffers 13 int,int,int,int,int #comfunc global IDXGISwapChain_ResizeTarget 14 sptr #comfunc global IDXGISwapChain_GetContainingOutput 15 sptr #comfunc global IDXGISwapChain_GetFrameStatistics 16 sptr #comfunc global IDXGISwapChain_GetLastPresentCount 17 sptr ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。