カスタム ビジュアライザーを使用すると、主に次の 2 つのことが可能になります。
パイプライン ビュー テクスチャ ビューアーを拡張して、パイプラインの任意のステージにバインドされた任意のリソースを読み取り、ビューアーに表示される 2D テクスチャを出力できるカスタム コンピュート シェーダーを実行します。
パイプライン ビュー バッファー ビューアーを拡張して、パイプラインの任意のステージにバインドされた任意のリソースを読み取り、メッシュ ビューアーに表示されるインデックス バッファーと頂点バッファーの両方を出力できるカスタム コンピューティング シェーダーを実行します。
PIX 拡張機能の設定
Extensibility Paths 設定を使用して、ビジュアライザー (*.hlsl
ファイル) を検索する PIX の任意の数のフォルダーを指定できます。
ビジュアライザー シェーダーで、主要な HLSL ビジュアライザー ファイルの横に存在しないファイルの #include
を使用する場合は、Extensibility Include Search Paths 設定でそれらの検索パスを指定できます。
カスタム テクスチャ ビジュアライザー
設定でビジュアライザー シェーダーへのパスを構成したと仮定すると、ビジュアライザーが [視覚化] パネルに一覧表示されます。
視覚化パネル
[視覚化] パネルの一覧からカスタム ビジュアライザーを選択すると、[カスタム視覚化] セクションが表示されます。 そこから、ビジュアライザー出力の既定のテクスチャ形式を上書きすることを選択できます。 既定では、選択した出力形式は、現在選択されているテクスチャのパイプライン ビューと互換性があります。 ここでも、シェーダー コンパイルの警告/エラーが表示されます。
カスタム テクスチャ ビジュアライザーの作成
ビジュアライザーは、選択されたイベント (描画、ディスパッチ、ディスパッチ メッシュなど) に対して実行されるコンピューティング シェーダーであり、その出力は現在選択されているテクスチャ/レンダリング ターゲットの代わりにテクスチャ ビューアーに表示されます。 PIX によって正常に認識されるようにするには、エントリ ポイントに main という名前を付ける必要があります。
コンピューティング シェーダーのスレッド グループ サイズは、任意のコンピューティング シェーダーと同じように、属性 ([numthreads(8, 8, 1)]
など) として指定することで選択できます。 PIX はコンピューティング シェーダーを呼び出し、ピクセルごとに 1 つのスレッドを実行できるようにします。
たとえば、テクスチャのサイズが 512 x 512 ピクセルで、コンピューティング シェーダがスレッドグループサイズ (8, 8, 1)
を使用する場合、PIX エンジンによって内部的に実行される呼び出しは Dispatch(64, 64, 1)
になります。 テクスチャ サイズがスレッド グループ サイズの倍数でない場合は、すべてのテクスチャをカバーするためにピクセルよりも多くのスレッドが呼び出されます。
コンピューティング シェーダーによって生成された出力テクスチャには、HLSL API を介して出力される最大の座標 (PixExt_StorePixel_Float(uint2 offset, float4 pixel)
など) が反映されます。
シェーダ コードが PIX エンジンでコンパイルされると、使用されるルート署名は、選択したイベントでバインドされたものの修正バージョンになります。 つまり、そのイベントで利用可能なすべてのリソースに加え、PIX HLSL API を通じて IA ステージと OM ステージにバインドされたすべてのリソースにアクセスできます。
シェーダー ([視覚化] パネルの > テキスト ボックスの [カスタム視覚化] セクションにエラーがある場合は、ファイルを編集してエラーを修正し、テクスチャ ビューアーの更新ボタンを使用してビジュアライザーを再構築し、再実行するだけです。
例
ビジュアライザー シェーダーの基本的な例を次に示します。
Texture2D<float4> SelectedTexture : PixExt_SelectedResourceRegister;
// For the custom PSO to successfully build, the root signature
// of the selected event must have a valid binding for t0.
Texture2D<float4> SRV0 : register(t0);
[numthreads(8, 8, 1)]
void main(PixExt_ComputeInput input)
{
uint2 selSize, srvSize;
SelectedTexture.GetDimensions(selSize.x, selSize.y);
SRV0.GetDimensions(srvSize.x, srvSize.y);
float2 uvs = input.dispatchThreadId.xy / (float2)selSize;
int2 srvCoords = (int2)(srvSize * uvs);
float4 selectedValue = SelectedTexture.Load(int3(input.dispatchThreadId.xy, 0));
float4 srv0Value = SRV0.Load(int3(srvCoords, 0));
float4 finalValue = selectedValue * srv0Value.yzxw;
PixExt_StorePixel_Float(input.dispatchThreadId.xy, finalValue);
}
上記の例では、PIX HLSL API 特殊レジスタ SelectedTexture
を使用して、現在選択されているテクスチャのパイプライン ビューを指すように PixExt_SelectedResourceRegister
を宣言します。 また、t0 で SRV0 を宣言します。これは、作業対象の GPU キャプチャのルート署名に存在することが分かっています。 拡張機能は、ユース ケースの指示に従って、常に汎用的または具体的なものにすることができます。 最後に、ピクセル位置と値を引数として受け取る PixExt_StorePixel_Float
関数を使用してテクスチャ ビューアーに出力します。
API の詳細については、HLSL API のセクションを参照してください。
カスタム バッファー ビジュアライザー
設定にビジュアライザー シェーダーへの設定パスがあると仮定すると、ビジュアライザーが [カスタム視覚化] パネルに一覧表示され、次のバッファー ビューアー ツール バー アイコンを使用して開くことができます。{}
カスタム視覚化パネル
このパネルから、利用可能なカスタム ビジュアライザーを選択し、シェーダー コンパイラからの警告/エラー メッセージを確認できます。
カスタム バッファー ビジュアライザーの作成
ビジュアライザーは、選択されたイベントに対して実行されるコンピューティング シェーダーであり、その出力は、現在選択されているバッファー データを表示するバッファー ビューアーの代わりにメッシュ ビューアーに表示されます。 PIX に正しく認識されるためには、エントリ ポイントの名前を main にする必要があります。
任意のコンピューティング シェーダーと同様に、コンピューティング シェーダーのスレッド グループ サイズを選択するには、それを属性 ([numthreads(32, 1, 1)]
など) として指定します。 PIX はコンピューティング シェーダーを呼び出し、バファー要素ごとに 1 つのスレッドを実行できるようにします。
たとえば、100 個の要素のバッファーがあり、コンピューティング シェーダーがスレッド グループ サイズ (32, 1, 1)
を使用する場合、PIX エンジンによって内部的に実行される呼び出しは Dispatch(4, 1, 1)
になります。 バッファー サイズがスレッド グループ サイズの倍数でない場合は、すべてのバッファー要素をカバーするために、バッファー要素よりも多くのスレッドが呼び出されます。
コンピューティング シェーダーに割り当てられた出力インデックスと頂点バッファーは、出力するすべてのデータに合わせて動的に拡大します。 必要な量のデータを出力できます。 インデックスは 32 ビットで、頂点は float4 位置にのみ使用できます。
シェーダ コードが PIX エンジンでコンパイルされると、使用されるルート署名は、選択したイベントでバインドされたものの修正バージョンになります。 つまり、そのイベントで利用可能なすべてのリソースに加え、PIX HLSL API を通じて IA ステージと OM ステージにバインドされたすべてのリソースにアクセスできます。
シェーダー ([視覚化] パネルの >[DXC 出力] テキスト ボックスの [カスタム視覚化] セクションにエラーがある場合は、ファイルを編集してエラーを修正し、メッシュ ビューアーの更新ボタンを押してビジュアライザーを再構築し、再実行するだけです。
例
ビジュアライザー シェーダーの基本的な例を次に示します
struct Vertex
{
float3 position;
float2 uv;
};
StructuredBuffer<Vertex> Vertices : PixExt_VertexBufferRegister0;
[numthreads(32, 1, 1)]
void main(PixExt_ComputeInput input)
{
const uint vertexCount = PixExt_GetVertexCountPerInstance();
if (input.dispatchThreadId.x < vertexCount)
{
const uint vertexStart = PixExt_GetStartVertexLocation();
uint vertexOffset = input.dispatchThreadId.x + vertexStart;
Vertex vertex = Vertices[vertexOffset];
float4 newPosition = float4(vertex.position, 1.f);
PixExt_StoreIndex(input.dispatchThreadId.x, input.dispatchThreadId.x);
PixExt_StoreVertex(input.dispatchThreadId.x, newPosition);
}
}
上記の例では、PIX HLSL API 特殊レジスタ Vertices
を使用して、現在バインドされている頂点バッファー 0 を指す PixExt_VertexBufferRegister0
を宣言する頂点にアクセスします。 次に、バッファー オフセットを受け取り、それぞれインデックス値と頂点値を引数として受け取る PixExt_StoreIndex
関数と PixExt_StoreVertex
関数を使用して、メッシュ ビューアーに出力します。
API の詳細については、HLSL API のセクションを参照してください。
バッファーをテクスチャとして視覚化する
テクスチャに出力するバッファーとカスタム ビジュアライザーを選択することもできます。 その場合、通常のバッファー ビューアーの代わりにテクスチャ ビューアーが表示され、結果が表示されます。
ユーザー定数
すべてのビジュアライザー呼び出しに対して UI から値を設定できる定数を追加できます。 これらは、すべてのカスタム ビジュアライザー型でサポートされています。
HLSL の例
PixExt_Declare_UserConstants_Start
PixExt_UserConstant_Int(int_constant_name);
PixExt_UserConstant_Uint(uint_constant_name);
PixExt_UserConstant_Float(float_constant_name);
PixExt_Declare_UserConstants_End
ビジュアライザーでは、単一のユーザー定数ブロック (PixExt_Declare_UserConstants_Start
/ PixExt_Declare_UserConstants_End
ペア) を使用できます。 int
、uint
、float
の3種類の定数をいくつでも追加できます。 宣言された各エントリについて、視覚化パネルに新しいエントリが表示され、目的の値が入力されます。 0
は、すべての定数の既定値です。
PIX HLSL API
PIX はシェーダーをコンパイルするときに内部実装コードを挿入し、すべてのリソースにアクセスできるようにして、データをビューアーに出力するための標準的な手段を提供します。 実装は常に変更される可能性がありますが、次の文書化された API は PIX バージョン間で安定しています。
リソース アクセス
API は、本質的にアクセスできないさまざまなパイプライン ステージのリソースにアクセスするために使用できる特別なレジスタのセットを定義します。
選択したリソース
PixExt_SelectedResourceRegister
: パイプライン ビューで現在選択されているリソースへのアクセス権を付与します。
レンダー ターゲット
PixExt_RenderTargetRegister0
PixExt_RenderTargetRegister1
PixExt_RenderTargetRegister2
PixExt_RenderTargetRegister3
PixExt_RenderTargetRegister4
PixExt_RenderTargetRegister5
PixExt_RenderTargetRegister6
PixExt_RenderTargetRegister7
深さ/ステンシル
PixExt_DepthRegister
PixExt_StencilRegister
入力アセンブリ ステージ リソース
PixExt_IndexBufferRegister
PixExt_VertexBufferRegister0
PixExt_VertexBufferRegister1
PixExt_VertexBufferRegister2
PixExt_VertexBufferRegister3
PixExt_VertexBufferRegister4
PixExt_VertexBufferRegister5
PixExt_VertexBufferRegister6
PixExt_VertexBufferRegister7
PixExt_VertexBufferRegister8
PixExt_VertexBufferRegister9
PixExt_VertexBufferRegister10
PixExt_VertexBufferRegister11
PixExt_VertexBufferRegister12
PixExt_VertexBufferRegister13
PixExt_VertexBufferRegister14
PixExt_VertexBufferRegister15
PixExt_VertexBufferRegister16
PixExt_VertexBufferRegister17
PixExt_VertexBufferRegister18
PixExt_VertexBufferRegister19
PixExt_VertexBufferRegister20
PixExt_VertexBufferRegister21
PixExt_VertexBufferRegister22
PixExt_VertexBufferRegister23
PixExt_VertexBufferRegister24
PixExt_VertexBufferRegister25
PixExt_VertexBufferRegister26
PixExt_VertexBufferRegister27
PixExt_VertexBufferRegister28
PixExt_VertexBufferRegister29
PixExt_VertexBufferRegister30
PixExt_VertexBufferRegister31
可変レート シェーディング
PixExt_ShadingRateImageRegister
シェーダー入力
PixExt_ComputeInput
構造体は、メイン シェーダー関数への入力として使用できます。 これはヘルパーであり、必須ではありません。
struct PixExt_ComputeInput
{
uint3 dispatchThreadId : SV_DispatchThreadID;
uint3 groupId : SV_GroupID;
uint3 groupThreadId : SV_GroupThreadID;
uint groupIndex : SV_GroupIndex;
};
選択したテクスチャ情報
// Returns the currently selected sample.
uint PixExt_GetSelectedSample();
// Returns the currently selected mip.
uint PixExt_GetSelectedMip();
// Returns the currently selected slice.
uint PixExt_GetSelectedSlice();
選択したイベント引数
// For a DrawIndexedInstanced event,
// returns the IndexCountPerInstance.
uint PixExt_GetIndexCountPerInstance();
// For a DrawIndexedInstanced event,
// returns the StartIndexLocation
uint PixExt_GetStartIndexLocation();
// For a DrawInstanced event,
// returns the VertexCountPerInstance.
uint PixExt_GetVertexCountPerInstance();
// For a DrawInstanced event,
// returns the StartVertexLocation.
uint PixExt_GetStartVertexLocation();
// For a DrawInstanced or DrawIndexedInstanced event,
// returns the InstanceCount.
uint PixExt_GetInstanceCount();
// For a DrawInstanced or DrawIndexedInstanced event,
// returns the StartInstanceLocation.
uint PixExt_GetStartInstanceLocation();
// For a Dispatch or DispatchMesh event,
// returns the ThreadGroupCountX.
uint PixExt_GetThreadGroupCountX();
// For a Dispatch or DispatchMesh event,
// returns the ThreadGroupCountY.
uint PixExt_GetThreadGroupCountY();
// For a Dispatch or DispatchMesh event,
// returns the ThreadGroupCountZ.
uint PixExt_GetThreadGroupCountZ();
可変レート シェーディング
// Returns the screen-space VRS image pixel tile size.
uint PixExt_GetShadingRateImageTileSize();
リソース名によるバインド
PixExt_BindByName
特殊レジスタを使用して、名前によってリソースに明示的にバインドできます。
カスタム ビジュアライザー リソース宣言で使用すると、選択したイベント内でバインドする同じ名前のリソースを検索するように PIX に指示されます。 たとえば、カスタム ビジュアライザーで次のコードを使用すると、選択したイベント シェーダーで見つかった g_texture
という名前のリソースへのバインドが発生します。
Texture2D<float4> g_texture : PixExt_BindByName;
シェーダー出力
次の関数を使用して、ビューアーにデータを出力します。
テクスチャ
// Stores the given INT pixel data for texture viewer display.
//
// offset: Pixel position to write to.
// pixel: Pixel data to write.
void PixExt_StorePixel_Int(uint2 offset, int4 pixel);
// Stores the given UINT pixel data for texture viewer display.
//
// offset: Pixel position to write to.
// pixel: Pixel data to write.
void PixExt_StorePixel_Uint(uint2 offset, uint4 pixel);
// Stores the given FLOAT pixel data for texture viewer display.
//
// offset: Pixel position to write to.
// pixel: Pixel data to write.
void PixExt_StorePixel_Float(uint2 offset, float4 pixel);
メッシュ型
// Stores the given index for mesh viewer display.
//
// offset: Offset into the index buffer to write to.
// index: Index to write.
void PixExt_StoreIndex(uint offset, uint index);
// Stores the given vertex position for mesh viewer display.
//
// offset: Offset into the vertex buffer to write to.
// vertex: Vertex position to write.
void PixExt_StoreVertex(uint offset, float4 vertex);
要件
カスタム ビジュアライザー シェーダーは、Shader Model 6.6 (cs_6_6) と HLSL バージョン 2021 を使用してコンパイルされます。 今後のリリースでは、さらに新しいシェーダー モデルをサポートし、HLSL 2021 の制限を緩和する予定です。