2009年05月16日

DirectXのスキャンライン取得機能の信憑性を確認してみた

DirectXでは現在モニタに出力している走査線の位置を取得する機能があるのですが、最近のビデオカードに備わっているスケーリング機能を使った際にどのような動作をするのか気になったので調べてみました。

スケーリング機能とは、アスペクト比固定拡大などをビデオカードに行わせる機能で、液晶パネルのネイティブ解像度よりも低い解像度に設定した場合でも、モニタへの信号は常にネイティブ解像度で出力し、周りに黒枠を挿入したりして調整する機能です。

この機能を使っている場合は、例えばSXGA(1280*1024)のモニタで画面モードを1024*768に設定しても、DVIケーブルを流れるのはSXGAの信号になります。このとき、DirectXの返す走査線位置の情報は1024*768の位置なのか、それとも1280*1024の位置なのかを調べてみました。

結論は、スケーリング機能を使用していても、設定した解像度(この場合は1024*768)の走査線位置が返ってきました。(報告される走査線位置の最大値を確認)

次に、このスケーリング機能が、どのように実装されているのかが気になりました。

思いつく実装方法は次の大雑把に分けて次の2通りです。

  • フレームバッファからDVIに信号を出力する回路がなんやかんやといい感じに処理してくれる
  • 出力用のフレームバッファを暗黙的に作成しVBlank中にコピーする

前者はDVIトランスミッタがある程度プログラマブルでないと実現できませんから、私の予想では後者でした。後者ならば、VSync割り込みさえあればドライバレベルで実装できますから。

もし後者の場合、DVIトランスミッタは出力用のバッファを走査しているはずなので、DirectXの報告する走査線位置はデタラメか、描画用バッファの解像度に合わせて変換した換算値ということになります。

確認方法は、走査線位置に応じた色でフレームバッファを塗りつぶすという方法で行いました。

具体的な処理内容は次の通りです。

  1. 現在の走査線位置(高さ)を取得する
  2. 走査線位置をそのままカラーコードとしてフレームバッファ全体を塗りつぶす
  3. 1〜2の処理を休み無くひたすら繰り返す。

このプログラムが動いている間、フレームバッファは単色で塗りつぶされ続けます。もし、仮説の出力用バッファにコピーする方法の場合、モニタに表示されるのは単色の画面になるはずです。逆にDVIトランスミッタがスケーリングをしていれば、走査線に応じたグラデーションが表示されます。

結果は次のようになりました。

monitor

カラーコードの下位8bitが青成分なので、256ライン周期の青のグラデーションが表れました。VBlank中は白で塗りつぶす処理も入れたので、走査開始直後の部分は白くなっています。

これで私の仮説の、出力用のフレームバッファにコピーしてる説は違うことが分かりました。出力用フレームバッファに1ラインずつコピーしてるという可能性も0ではありませんが、そんな面倒な実装はしていないでしょう。

ちなみに、この検証はGeForce 9600GT、GeForce 7600GS、Intel GMA950で行いました。Radeon系はあまり新しい物を持っていないので未確認です。

ノートPCでは以前から使われていた機能なので、トランスミッタの機能として実装されているんでしょうね。

塗りつぶし処理に伴う多少の遅延はありますが、走査線位置とカラーコードの対応もだいたい合っているので、DirectXの返す走査線位置はスケーリング機能を使用していても信用できるようです。

タグ:DirectX
2009年05月16日 【プログラミング】 | コメント(0) |

この記事へのトラックバックURL


この記事へのトラックバック

昨日の記事で使った走査線位置を調べるプログラムで、以前から疑問に思っていたクローンモードでの同期について確認できることに気が付きました。 LCD Delay Checkerでは、クローンモードで2つ..
この記事へのコメント

コメントを書く
お名前: [必須入力]

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。