Where Is The Clock? (2)

前回の NVIDIA の資料にはキューイングされるフレーム数として「3回」という数字が出てきました.これは D3DPRESENT_PARAMETERS 構造体 の BackBufferCount に指定可能な数の最大値 3 と一致しています.ではこのキューイングフレーム数は BackBufferCount に指定した値に拘束されるかというと,そうでも無いのかもしれません.実のところ私もよく分かっていなかったりします.別の参考資料として,BBX にポストされた Masa さんの投稿があります.

RE レンダリング終了の検出
http://bbx.hp.infoseek.co.jp/cgi-bin/bbx.cgi?log=38&vew=143

少し補足しておくと,3D デバイス作成時のさまざまなフラグには,保険の契約書に書かれた小さな但し書きのように巧妙に,しかし時として大きな行動権をドライバにもたらすものが含まれています.例えば D3DSWAPEFFECT_DISCARD フラグを受け取ったデバイスは,Present 後のサーフェイスが格納するデータが,Present 以前と同一あることの保証義務から解放されます.この規制緩和により,ドライバはスワップチェーンに ring buffer ではなく任意の queue を使うことが可能になります.

D3DSWAPEFFECT_FLIP を使うスワップ チェーンと同様に、D3DSWAPEFFECT_DISCARD を使うスワップ チェーンは複数のバック バッファを含むことがあり、どのバック バッファにも IDirect3DDevice9::GetBackBuffer または IDirect3DSwapChain9::GetBackBuffer を使ってアクセスできます。このスワップ チェーンはキューと考えるのが最も妥当であり、このキューの中では、次の Present 処理によって表示されるバック バッファのインデックスが常に 0 となり、表示が完了したバッファはこのキューから破棄されます。

このようなセマンティクスの微修正が,ドライバに「3回のキューイング」を可能にする一因となっていることは想像に難くありません.
DirectX Graphics の世界には,一見セマンティクスを保っているように見えて,巧妙に追加された条文が大きく実態を変えてしまったものが潜んでいます.確かに「バックバッファ」や「フリップ」といった旧来の用語が残っていますが,それらは本当に「かつて,そうであったもの」でしょうか?

ディスプレイ アダプタ ドライバによって行われる "フリッピング処理" と、D3DSWAPEFFECT_FLIP を使って作成されたスワップ チェーンに適用される "Present" 処理には明らかな違いがあることに注意することが大切です。

一般に "フリップ" という用語は、ディスプレイ アダプタがその出力信号を生成するために使うビデオ メモリのアドレス範囲を変更する処理のことであり、これによって隠れていたバック バッファの内容が表示されます。Microsoft DirectX 9.0 の場合、この用語はより一般的に使われ、D3DSWAPEFFECT_FLIP スワップ効果で作成されたスワップ チェーンにおけるバック バッファのプレゼンテーションのことを表します。

スワップ チェーンがフルスクリーンの場合、"Present" のような処理はほとんどフリップ処理によって実装される一方、スワップ チェーンがウィンドウの際は、必ずコピー処理によって実装されます。さらに、ディスプレイ アダプタ ドライバは、D3DSWAPEFFECT_DISCARD と D3DSWAPEFFECT_COPY に基づくフルスクリーン スワップ チェーンに対して Present 処理を実装するためにフリッピングを使う場合があります。

市販の入門書よりも DirectX のヘルプの方が好ましい点として,このような用語の override についてある程度の解説を行っていることが挙げられます.個人的な意見としては,DirectX の入門書が「ダブルバッファ」や「フリップ」といった用語の導入を,従来のハードウェア的な解説のみで済ませてしまうことには疑問があります.もっともそれは PC に関係する他の分野にも同じことが言えるでしょうけど.CPU,メモリ,OS,ファイルシステムなど,日々進化する実装について行くのは大変です.実際私自身,これらの仕組みについてかなり抽象化した性質しか知らないと言う他ありません.きっと多くの部分で,昔どこかで読んだ単純なモデルを今でも信じているところがあると思います.
少し見渡せば,違和感はいくつもあるはずです.
例えば WindowsXP は,DirectX Graphics ウィンドウモードでのプレゼンテーションをデスクトップに対応するフレームバッファに直接 BitBlt するような実装にしてしまっていいのでしょうか? もしそうなら DirectX Graphics を利用するウィンドウの上に,別の半透明ウィンドウを配置したときどうなるでしょう?
一部の環境では「ダブルバッファ」と「フリップ」によるティアリング防止が有効かもしれません.しかしさて,今売られているビデオカードはその描画内容で,本当にレイテンシ 16ms 以内に最大スループットが達成できるでしょうか?
もはや推理すらもかなわない状況でも,世界には推理ばかりが増えていきます.
惨劇を暴け.