次の方法で共有


チュートリアル: デバイス状態によるオブジェクトの不足

このチュートリアルでは、Visual Studio のグラフィックス診断を使用して、デバイスの状態の構成が正しくないために表示されないオブジェクトを調べる方法を示します。

このチュートリアルでは、次の方法を示します。

  • グラフィックス イベント一覧を使用して、問題を引き起こしている可能性がある箇所を特定します。

  • [グラフィックス パイプライン ステージ] ウィンドウを使用して、DrawIndexed Direct3D API 呼び出しの影響を確認します。

  • [グラフィックス ピクセル履歴] ウィンドウを使用して、問題の箇所をより具体的に特定します。

  • デバイスの状態に潜在的な問題または構成の間違いがないかどうかを調べます。

シナリオ

3-D アプリでオブジェクトが想定どおりの場所に表示されない理由の 1 つに、グラフィックス デバイスの構成の誤りがあります。構成が正しくないと、オブジェクトがレンダリングから除外されます。たとえば、ワインディング順序が原因で三角形が誤ってカリングされる場合や、深度テストの関数が原因でオブジェクトのすべてのピクセルが拒否される場合などがあります。

このチュートリアルのシナリオでは、3-D アプリ開発の第 1 マイルストーンまで到達し、初めてアプリをテストする準備が整っています。 しかし、アプリを実行すると、画面にはユーザー インターフェイスしか表示されません。 そこで、アプリのデバッグを実行できるように、グラフィックス診断を使用してグラフィックス ログ ファイルに問題をキャプチャします。 問題は、アプリケーションでは次のように見えます。

問題修正前のアプリ

グラフィックスの問題をグラフィックス ログにキャプチャする方法については、「グラフィックス情報のキャプチャ」を参照してください。

調査

グラフィックス診断ツールを使用すると、グラフィックス ログ ファイルを読み込んで、テスト中にキャプチャされたフレームを検査することができます。

グラフィックス ログのフレームを調査するには

  1. Visual Studio で、モデルの欠落を表すフレームを含むグラフィックス ログを読み込みます。 新しいグラフィックス診断タブが Visual Studio に表示されます。 このタブの上部に、選択されたフレームのレンダー ターゲットが出力されます。 下部の [フレーム一覧] には、キャプチャされた各フレームがサムネイル イメージとして表示されます。

  2. [フレーム一覧] で、モデルが表示されていないことを示すフレームを選択します。 レンダー ターゲットが更新され、選択したフレームが反映されます。 このシナリオでは、グラフィックス ログのタブは次のように表示されます。

    .vsglog タブ framebuffer プレビューとフレーム リスト

問題を示しているフレームを選択したら、[グラフィックス イベント一覧] を使用してそのフレームを診断できます。 [グラフィックス イベント一覧] には、アクティブなフレームをレンダリングするために行われたすべての Direct3D API 呼び出し (たとえば、デバイスの状態の設定、バッファーの作成および更新、フレームに表示されるオブジェクトの描画を行う各 API 呼び出しなど) が含まれます。 アプリが想定どおりに動作しているときは、さまざまな種類の呼び出し (描画、ディスパッチ、コピー、クリアなどの呼び出し) が関与します。(必ずではありませんが) 多くの場合、対応する変更がレンダー ターゲットで発生するからです。 描画呼び出しは、それぞれがアプリでレンダリングされたジオメトリを表すので特に重要です (ディスパッチ呼び出しでもジオメトリをレンダリングできます)。

描画呼び出しが行われていることを確認するには

  1. [グラフィックス イベント一覧] ウィンドウを開きます。 グラフィックス診断ツール バーで、[イベント一覧] を選択します。

  2. [グラフィックス イベント一覧] で描画呼び出しを調べます。 この操作を簡単に行うには、[グラフィックス イベント一覧] ウィンドウの右上隅にある [検索] ボックスに「Draw」と入力します。 これによって一覧がフィルター処理され、タイトルに "Draw" を含むイベントのみが一覧に表示されます。 このシナリオでは、いくつかの描画呼び出しが行われています。

    キャプチャされたイベントを示すグラフィックス イベント リスト

描画呼び出しが行われていることを確認したら、表示されないジオメトリに対応する描画呼び出しを調べます。 (このケースでは) 表示されないジオメトリがレンダー ターゲットに描画されていないことがわかっているため、[グラフィックス パイプライン ステージ] ウィンドウを使用して、表示されないジオメトリにどの描画呼び出しが対応しているかを判断できます。 [グラフィックス パイプライン ステージ] ウィンドウには、各描画呼び出しに対して送信されたジオメトリが、レンダー ターゲットに与える影響には関係なく表示されます。 描画呼び出し間を移動すると、選択されている呼び出しに関連付けられたジオメトリを表示するようにパイプライン ステージが更新され、その呼び出しが完了した後のレンダー ターゲットの状態を表示するようにレンダー ターゲットの出力が更新されます。

表示されないジオメトリの描画呼び出しを見つけるには

  1. [グラフィックス パイプライン ステージ] ウィンドウを開きます。 グラフィックス診断ツール バーで、[パイプライン ステージ] を選択します。

  2. 表示されないモデルを [グラフィックス パイプライン ステージ] ウィンドウで探しながら、描画呼び出し間を移動します。 [入力アセンブラー] ステージには、生のモデル データが表示されます。 [頂点シェーダー] ステージには、変換されたモデル データが表示されます。 [ピクセル シェーダー] ステージには、ピクセル シェーダーの出力が表示されます。 [出力マージャー] ステージには、この描画呼び出しと前の描画呼び出しをマージしたレンダー ターゲットが表示されます。

  3. 表示されないモデルに対応する描画呼び出しが見つかったら移動を停止します。 このシナリオでは、ジオメトリがレンダリングされたのに、レンダー ターゲットに表示されなかったことが [グラフィックス パイプライン ステージ] ウィンドウからわかります。

    不足しているオブジェクトを示すパイプライン ビューアー

表示されないジオメトリがアプリでレンダリングされたことを確認したら、対応する描画呼び出しを見つけて、表示されないジオメトリを表示するべきレンダー ターゲット出力の部分を選択し、ピクセルが除外された理由を [グラフィックス ピクセル履歴] ウィンドウをで調べます。 ピクセル履歴には、特定のピクセルに影響を与えた可能性があるすべての描画呼び出しの一覧が含まれます。 [グラフィックス ピクセル履歴] ウィンドウ内の各描画呼び出しは、[グラフィックス イベント一覧] ウィンドウにも表示される番号で識別されます。 これは、表示されないジオメトリをピクセルが表示する必要があることを確認し、ピクセルが除外された理由を判断するのに役立ちます。

ピクセルが除外された理由を判断するには

  1. [グラフィックス ピクセル履歴] ウィンドウを開きます。 [グラフィックス診断] ツール バーで、[ピクセル履歴] を選択します。

  2. [ピクセル シェーダー] 縮小表示に基づいて、表示されないジオメトリの一部を含んだピクセルをフレーム バッファー出力内で選択します。 このシナリオでは、ピクセル シェーダーの出力がレンダー ターゲットの大部分をカバーしているため、ピクセルを選択すると [グラフィックス ピクセル履歴] ウィンドウが次のようになります。

    関連する描画呼び出しを示すピクセル履歴ウィンドウ

  3. 選択されたレンダー ターゲットのピクセルに、ジオメトリの一部が含まれていることを確認します。そのためには、([グラフィックス イベント一覧] ウィンドウ内の) 調べている描画呼び出しの番号が、[グラフィックス ピクセル履歴] ウィンドウ内のいずれかの描画呼び出しの番号と一致しているかどうかを調べます。 調べている描画呼び出しが [グラフィックス ピクセル履歴] ウィンドウ内のどの呼び出しとも一致しない場合は、一致が見つかるまで上記の手順 (手順 1. を除く) を繰り返します。 このシナリオでは、一致する描画呼び出しは次のようになります。

    フラグメント情報を示すピクセル履歴ウィンドウ

  4. 一致する描画呼び出しが見つかったら、[グラフィックス ピクセル履歴] ウィンドウでそれを展開し、ピクセルが除外されていることを確認します。 [グラフィックス ピクセル履歴] ウィンドウ内の各描画呼び出しは、対応するオブジェクトのジオメトリの結果としてそのピクセルと交差した、1 つ以上のジオメトリ プリミティブ (点、線、または三角形) に対応しています。 そのような各交差は、ピクセルの最終的な色に関与している可能性があります。 深度テストに失敗したために除外されたプリミティブは、右下がりの矢印の上に Z の字を重ねたアイコンで表されます。

  5. 除外されたプリミティブを展開して、除外の原因となった状態をさらに詳しく調べます。 [出力マージャー] グループの [結果] の上にポインターを移動します。 プリミティブが除外された理由を示すツールヒントが表示されます。 このシナリオでは、プリミティブが深度テストに失敗したことが理由で除外されたため、ピクセルの最終的な色に関与していないことがわかりました。

プリミティブの深度テストの失敗が理由でジオメトリが表示されないことを確認したら、この問題がデバイス状態の構成の誤りと関係している可能性を疑います。 デバイスの状態およびその他の Direct3D オブジェクト データは、[グラフィックス オブジェクト テーブル] で調べることができます。

デバイスの状態を確認するには

  1. [グラフィックス オブジェクト テーブル] ウィンドウを開きます。 グラフィックス診断ツール バーで、[オブジェクト テーブル] を選択します。

  2. [グラフィックス オブジェクト テーブル]D3D10 Device オブジェクトを探し、D3D10 Device オブジェクトを開きます。 新しい [d3d10 device] タブが Visual Studio で開きます。 この操作を簡単に行うには、[種類] を使用して [グラフィックス オブジェクト テーブル] を並べ替えます。

    グラフィックス オブジェクト テーブルと関連するデバイス状態

  3. [d3d10 device] タブに表示されているデバイスの状態に潜在的な問題がないかどうかを調べます。 プリミティブが深度テストに失敗したことが原因でジオメトリが表示されないので、深度テストに影響するデバイスの状態 (深度ステンシルなど) を重点的にチェックします。 このシナリオでは、([出力マージャーの状態] の下にある) [深度ステンシルの説明][深度関数] メンバーに D3D10_COMPARISON_GREATER という見慣れない値が含まれています。

    深度ステンシル情報を示す D3D10 デバイス ウィンドウ

深度関数の構成の誤りが原因でレンダリングの問題が発生した可能性があることを確認したら、この情報とコードの知識を使用して深度関数の設定が誤っている箇所を特定し、問題を修正します。 コードに精通していない場合は、デバッグ時に収集した手掛かりを使用して問題を探すこともできます。たとえば、このシナリオの [深度ステンシルの説明] に基づいて、"深度" や "GREATER" などの語をコードで探すことができます。 コードを修正したら、それを再度ビルドし、再度アプリケーションを実行してレンダリングの問題が解決されたことを確認します。

問題修正後のアプリ