PIX


~ PIX for Windows ~






■はじめに

すっかり紹介を忘れていた、強力なデバッギングツールの PIX(Performance Investigator for DirectX) for Windows です。 これを知っているのと知らないのでは、開発効率に天と地との差があります。

"for Windows" とあるように、"Not for windows" もあります。 と、いうか、そもそも PIX は、Xbox 用のツールとして開発されたらしいです。
いやぁ、規格が決まっている Xbox から、色々な環境が混在する Windows なんて無理もいいとこです。
大助かりです。
ぜひ、OpenGL 用とか、他の環境にも…

■起動法

今回は、簡単で楽しい、フレームキャプチャ機能で遊びます。
この機能は、あるフレームのコマンドを全て記録しておいて、 オフライン実行や、はてはピクセル単位のデバッグまでしてくれます。

PIX を使うには、メニューの DirectX の「DirectX Utiliies」の項目から、「PIX for Windows」を選択して実行します。
立ち上がると、次のような画面になります。
ここに、デバッグしたいプログラムをドラッグ&ドロップしてみると、「Program path」のところにプログラムが登録されます。
あとは、「A single-frame capture of Direct3D whenever F12 is pressed」を選択したら、「Start Experiment」です。

すると、いつものプログラムが、左上に変なのが付いて実行されると思います。
これが、プログラムが PIX の奴隷になった証拠です。 後は、F12 を押してみると、ちょっと(だいぶ?)止まって、再び動き出すと思います。 そしたらプログラムを終わりましょう。

終わると、PIX の画面がばばばって動いて、色々なウィンドウが開くと思います。
これが、スナップとかされないのでしょぼいと思うのですが、それはここではおいといて、 左下の「Run1: Events」のウィンドウの「frame ###(あなたがF12を押したフレーム)」の「+」を押して開いてみましょう。

狭いので、下にあるウィンドウをそれぞれ上に引き伸ばしました。
ごちゃごちゃ書いてありますが、これがそのフレームであなたが呼び出した Direct3D のコマンドです。
ためしに、IDirect3DDevice::SetRenderTarget の2つめの引数の16進数をクリックしてみてください(SetRenderTargetをつかってないときは、右側のウィンドウの「Render」のタブをクリック)。
その時点での、クリックしたバッファに記録された画像が右側に表示されます。

そのまま、下のコマンドを選択すると、その時点で記録されたバッファの内容が画面に表示されます。
これで、画面が壊れたときに、どの時点でおかしくなったかが追えると思います。

で、上の画面は、なんかチェック模様が入っていますが、これは、アルファ値に0が設定されていて透けた画面です。 標準の表示は、アルファ成分を不透明度とした表示がされるので、うざいときは、画像の上の「Channel(s)」を「RGB」にすると、抜きが無くなって良い感じになります。

他にも、深度バッファのアドレスをクリックして「Depth」にすると深度値が確認できます(その右のスライドバーで見え方が調整できますです)。

■頂点デバッグ

で、さらに詳細にデバッグしましょう。
モデルの描画がされないときがあると思いますが、その時頂点処理が悪いかどうかは、PIX でばっちりわかります。
正常に表示されないメッシュの「DrawSubset」のコマンド等を選択して、右側のタブの「Mesh」を押してください。
すると、そのメッシュにおける「頂点処理前の状態」、「頂点処理後の状態」、「画面での見栄え」の図が表示されるとともに、その頂点データ(ディフォルトでは入力されたデータ)が列挙されます。
これを見ることによって、入力されたデータが悪いのか、頂点処理が悪いのか、それとも画面からはみ出しているだけなのかがわかります。

さらに、真ん中のタブを「PostVS」にすると、頂点処理後のデータの値が列挙されます。
運が良いと、頂点番号をクリックすることによって、デバッグが可能ですが、まだ機能的に不十分で完全にはデバッグできないようです。もう少し待ちましょう。

■ピクセルデバッグ

頂点が正しく出ていることがわかれば、次はピクセルの情報です。
右側の絵が出ているウィンドウで、よさげな場所で右クリックして「Debug This Pixel」を選択してください。

すると、カーソルのあったピクセルが、何時のコマンドで、何色に変更されたのかが列挙されます。 ここで、確認したいコマンドのところで「Debug pixel shader」を選択すると、シェーダのデバッグ画面に移ります。

この画面で、適当にブレークポイントを指定して実行したりすると、その行で止まってそのときのレジスタの値などが確認できます。
HLSL でないのが少々残念ですが、短いシェーダならなんとなく感じがつかめると思います。

■タグ付け

で、以上で基本は終わりですが、ここで覚えとくとよい機能を紹介しておきます。
PIX の左下のコマンド一覧は、名前をつけてまとめることができます。
たとえば、下の画面では、普通に画面を更新した「Render Scene」と、その後のメニューや画面情報を表示した「Debug Status」の名前をつけました。

この名前付けは、下のように、「D3DPERF_BeginEvent」と「D3DPERF_EndEvent」ではさんでDirect3D の命令を実行することによって実現できます。
色も指定してますが、どこに出てるんでしょうかねぇ???

main.cpp
void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
    D3DPERF_BeginEvent(D3DCOLOR_RGBA(0xff, 0,0,0), L"Render Scene");
    
    // 普通に描画
    
    D3DPERF_EndEvent();
    
    D3DPERF_BeginEvent(D3DCOLOR_RGBA(0,0,0,0), L"Debug Status");
    
    // メニューやデバッグ情報の表示
    
    D3DPERF_EndEvent();
}

これで確認するときに範囲が絞れるので、デバッグが容易になります。
上のウィンドウの「Timeline」もそれぞれの名前で記されるので、どの処理にどの程度かかっているのかを確認することが可能です。

■最後に

PIX は、NVPerfKIT と連携することによって、さらに強力なツールになるのですが、 まぁ、今回は入門編ということでこんなとこで。
まだまだ発展途上なツールだと思いますが、これだけでも OpenGL を捨てて DirectX 派になる強力な動機になると思います。





もどる

imagire@gmail.com