読者です 読者をやめる 読者になる 読者になる

Where Is The Clock?

DirectX

masafumi さんのところに紹介されていた NVIDIA GPU Programming Guide をぱらぱらと読んでみました.

NVIDIA GPU Programming Guideの日本語版のリリース』
http://www.shader.jp/xoops/html/modules/wordpress/index.php?p=13

82 ページ目,『遅延を少なくとも2フレームに抑える』は,ゲームの反応速度を気にするゲーマーの人にとっても面白い内容かもしれません.

DirectXではドライバで最大3フレームまでバッファリングが可能です。フレームのバッファリングは、CPU と GPU が互いに独立して動作し、最大の性能を発揮できるようにするためには望ましいことです。一方、バッファリングされるフレームが増えると、それだけコマンドの発行からその結果を画面で見るまでの時間が長くかかります。人間は30msという短い遅延時間まで感知できることから(テストシナリオによるが)、この遅延は一般に望ましくありません。

ガイドではさらに,コマンドキューイングによる遅延を減らす方法ための強引な (良くない) 方法として以下のような方法も紹介されています.

そのため、一部のゲームでは、バッファリングするフレーム数を人為的に抑えています。たとえば、バックバッファをロックして、強制的にCPUとGPUのハードウェア同期をさせています。バックバッファをロックするとまずCPUをストールさせ、すべてのバッファを空にし、それから GPU をストールさせます。ロック終了時に、すべてのシステムがアイドル状態になり、バッファリングされたフレームの数がゼロになります。

このようなやり方でシステムをストールさせると、一方で性能に重大な影響を及ぼすことになるので、特に、複数GPU構成では、避けるべきです。

この方法に比べれば比較的ましとされているのが,デバイス完了クエリを利用する方法です.同ガイドでも軽く触れられていますが,具体的な方法については以下に詳しいです.

『How to (and How NOT to) Reduce Lag』
http://developer.nvidia.com/object/devnews016.html#1

(追記) 『How to (and How NOT to) Reduce Lag』で紹介されている IDirect3DQuery9 のサンプルコードですが,以下のように修正して使ってください.EVENT タイプのクエリは bool 型ではなく BOOL 型を引数にとります.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/programmingguide/advancedtopics/queries.asp

BOOL data;
while (pQuery->GetData(&data, sizeof(data), D3DGETDATA_FLUSH) == S_FALSE);

bool data;
while (pQuery->GetData(&data, sizeof(data), D3DGETDATA_FLUSH) == S_FALSE);