次の方法で共有


GPU ベースの検証と Direct3D 12 デバッグ レイヤー

このトピックでは、Direct3D 12 デバッグ レイヤーを最大限に活用する方法について説明します。 GPU ベースの検証 (GBV) を使用すると、CPU での API 呼び出し中に不可能な GPU タイムラインでの検証シナリオが可能になります。 GBV は、Windows 10 Anniversary Update 用グラフィックス ツールから入手できます。

GPU ベースの検証の目的

GPU ベースの検証は、次のエラーを特定するのに役立ちます。

  • シェーダーでの初期化されていない記述子または互換性のない記述子の使用。
  • シェーダーで削除されたリソースを参照する記述子の使用。
  • 昇格されたリソースの状態とリソースの状態の減衰の検証。
  • シェーダー内の記述子ヒープの末尾を超えたインデックス作成。
  • シェーダーは、互換性のない状態のリソースにアクセスします。
  • シェーダーでの初期化されていないサンプラーまたは互換性のないサンプラーの使用。

GBV は、シェーダーに直接検証が追加された修正プログラムが適用されたシェーダーを作成することによって機能します。 パッチが適用されたシェーダーは、シェーダーの実行中にアクセスされたルート引数とリソースを検査し、ログ バッファーにエラーを報告します。 GBV では、追加の操作とディスパッチ呼び出しがアプリケーション コマンド リストに挿入され、GPU タイムライン上のコマンド リストによって課されるリソース状態の変更を検証して追跡します。

GBV にはシェーダーを実行する機能が必要であるため、COPY コマンド リストは COMPUTE コマンド リストによってエミュレートされます。 これにより、最終的な結果を変更する必要はありませんが、ハードウェアによるコピーの実行方法が変わる可能性があります。 アプリケーションでは引き続き、これらは COPY コマンド リストであると認識され、デバッグ レイヤーはそれらを検証します。

GPU ベースの検証を有効にする

DIRECT3D 12 デバッグ レイヤーを強制的に適用し、さらに GPU ベースの検証 (コントロール パネルの新しいタブ) を強制的に実行することで、DIRECTX コントロール パネル (DXCPL) の使用を強制できます。 有効にすると、Direct3D 12 デバイスがリリースされるまで GBV は有効なままになります。 または、Direct3D 12 デバイスを作成する前に、プログラムで GBV を有効にすることもできます。

void EnableShaderBasedValidation()
{
    CComPtr<ID3D12Debug> spDebugController0;
    CComPtr<ID3D12Debug1> spDebugController1;
    VERIFY(D3D12GetDebugInterface(IID_PPV_ARGS(&spDebugController0)));
    VERIFY(spDebugController0->QueryInterface(IID_PPV_ARGS(&spDebugController1)));
    spDebugController1->SetEnableGPUBasedValidation(true);
}

一般に、ほとんどの場合、デバッグ レイヤーを有効にしてコードを実行する必要があります。 ただし、GBV では処理速度が大幅に低下する可能性があります。 開発者は、より小さいデータ セット (たとえば、エンジンデモや PSO とリソースが少ない小さなゲーム レベル) で GBV を有効にするか、早期アプリケーションの起動中にパフォーマンスの問題を減らすことを検討できます。 コンテンツが大きい場合は、夜間テスト パスで 1 台または 2 台のテスト マシンで GBV をオンにすることを検討してください。

デバッグ出力

GBV は、ExecuteCommandLists の呼び出し GPU での実行が完了した後にデバッグ出力を生成します。 これは GPU タイムライン上であるため、デバッグ出力は他の CPU タイムライン検証と非同期になる可能性があります。 アプリケーション開発者は、デバッグ出力を同期するために、独自の wait-after-execute を挿入することができます。

GBV 出力は、シェーダー内でエラーが発生した場所と、関連オブジェクトの現在の描画/ディスパッチ数と ID (コマンド リスト、キュー、PSO など) を識別します。

デバッグ メッセージの例

次のエラー メッセージは、"Main Color Buffer" という名前のリソースがシェーダー リソースとしてシェーダーでアクセスされたが、シェーダーが GPU で実行されたときに順序付けされていないアクセス状態にあったことを示しています。 シェーダー ソース内の場所、コマンド リストの名前、描画カウント (描画インデックス)、関連する D3D インターフェイス オブジェクトの名前などの追加情報も提供されます。

D3D12 ERROR: Incompatible resource state: Resource: 0x0000016F61A6EA80:'Main Color Buffer', 
Subresource Index: [0], 
Descriptor heap index: [0], 
Binding Type In Descriptor: SRV, 
Resource State: D3D12_RESOURCE_STATE_UNORDERED_ACCESS(0x8), 
Shader Stage: PIXEL, 
Root Parameter Index: [0], 
Draw Index: [0], 
Shader Code: E:\FileShare\MiniEngine_GitHub_160128\MiniEngine_GitHub\Core\Shaders\SharpeningUpsamplePS.hlsl(37,2-59), 
Asm Instruction Range: [0x138-0x16b], 
Asm Operand Index: [3], 
Command List: 0x0000016F6F75F740:'CommandList', SRV/UAV/CBV Descriptor Heap: 0x0000016F6F76F280:'Unnamed ID3D12DescriptorHeap Object', 
Sampler Descriptor Heap: <not set>, 
Pipeline State: 0x0000016F572C89F0:'Unnamed ID3D12PipelineState Object',  
[ EXECUTION ERROR #942: GPU_BASED_VALIDATION_INCOMPATIBLE_RESOURCE_STATE]

デバッグ レイヤー API

デバッグ レイヤーを有効にするには、EnableDebugLayer呼び出します。

GPU ベースの検証を有効にするには、SetEnableGPUBasedValidation呼び出し、次のインターフェイスのメソッドを参照します。

次の列挙体と構造体を参照してください。