Windowモードの遅延について検証


※上記の広告は60日以上更新のないWIKIに表示されています。更新することで広告が下部へ移動します。

DirectXに興味があったので勉強しようとしたところ、
フレーム遅延が云々という話を聞いたので勉強ついでにちょっと検証。

自分のPC環境はWindows8.1なんですが、DWMが切れないからフレーム遅延が必ず発生するとか。
まずはwindowsモードにおいてDirectXのパラメータ設定の変更が反映されるのか?という点を検証。

比較方法は下記ページを参考に240fpsで撮影。
入力に対する遅延 の検証ではなく、普段のアプリとの遅延比較するだけ。
7→8でDWMの仕様自体は変わってないと思うのである程度の検証にはなると思う。


ちょっと調べてみたところ、
描画に関係してそうなのは以下のパラメータ
  • 生成するスワップチェーンのBufferCount
 バッファリングのフレーム数のこと。この数だけ溜め込む。と思う。
  • Presentの引数SyncInterval
 いわゆる垂直同期。0なら垂直同期を無視して描画。
 1以上なら垂直同期信号を指定回数分待つ。
  • Presetnの引数PresentFlags
 フレームバッファの使い方を指定。とりあえずはNONE。
  • DXGIのMaxFrameLatency
 最大フレーム遅延数。デフォルトで3。いろんなところで紹介されているやつ。



簡単なプログラムの作成
  • 今何フレーム目を描画しているのかがわかる必要がある
  数字を表示しようと思ったら思ったより面倒そうなので後回し。
  こちらの方のブログを参考にして、
  三角形を60フレーム分位置をずらして描画することで今何フレーム目を描画しているかを区別する
  下の例だと、26フレーム目ぐらいかな?(縦6マス×横10マスで左下が0フレーム目。1マス上で1フレーム目。)

  • 二つのアプリでフレーム描画タイミングの同期が必要
  PCのTickCountを基準として描画することで実現可能
  1000msec単位で16msecごとに割ることで現在60フレーム中何フレーム目を描画すべきかを判断できる。

試験環境

  • Windows 8.1


1.垂直同期有り、無しの比較


下記が設定。
BufferCount SyncInterval Flag MaxFrameLatency
1 0 NONE 3
1 1 NONE 3

結論:垂直同期なしだと画像9フレーム分(60Hzで約2.5フレームの遅延)早く描画される。
   普通のアプリが3フレーム遅延してるとすると、
   DirectXのプログラム次第で普通に遅延解消できるような…

測定フレーム紹介:左が垂直同期無し、右が垂直同期有り
二つとも同じexeで引数でパラメータを設定。
どちらも同じタイミングで描画しているのにずれている。
1フレーム目
2フレーム目(ここで左が次のフレームに到達)
3フレーム目
4フレーム目
5フレーム目
6フレーム目
7フレーム目
8フレーム目
9フレーム目
10フレーム目(ここで右が2フレーム目と同じ位置に追いついた)


2.MaxFrameRatency


下記が設定。
垂直同期無し
BufferCount SyncInterval Flag MaxFrameLatency
1 0 NONE 3
1 0 NONE 1
垂直同期無し+最大フレーム遅延を極端に
BufferCount SyncInterval Flag MaxFrameLatency
1 0 NONE 3
1 0 NONE 15
垂直同期有り+最大フレーム遅延を極端に
BufferCount SyncInterval Flag MaxFrameLatency
1 1 NONE 3
1 1 NONE 15

結論:垂直同期ON/OFFのどちらもMaxFrameLatencyによる描画タイミングは変わらない。
   Windowモードだとこのパラメータは影響しない?