#概要
HLSL内にルートシグネチャを定義してCpp側からフェッチしてみるだけ。半分備忘録。
#RootSignatureの定義
//RootSignatureの定義
#define RS "RootFlags(ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT),"\
"CBV(b0),"\
"SRV(t0),"\
"DescriptorTable(CBV(b1,numDescriptors = 1,space = 0),visibility = SHADER_VISIBILITY_ALL),"\
"DescriptorTable(SRV(t1,numDescriptors = 1,space = 0),visibility = SHADER_VISIBILITY_PIXEL),"\
"StaticSampler(s0 ,"\
"filter = FILTER_MIN_MAG_MIP_LINEAR,"\
"addressU = TEXTURE_ADDRESS_WRAP,"\
"addressV = TEXTURE_ADDRESS_WRAP,"\
"addressW = TEXTURE_ADDRESS_WRAP,"\
"mipLodBias = 0.0f,"\
"maxAnisotropy = 16,"\
"comparisonFunc = COMPARISON_NEVER,"\
"borderColor = STATIC_BORDER_COLOR_TRANSPARENT_BLACK,"\
"minLOD = 0.0f,"\
"maxLOD = 3.402823466e+38f,"\
"space = 0,"\
"visibility = SHADER_VISIBILITY_ALL"\
")"\
//RootSignatureの定義ここまで
//ConstantBuffer (b0)
cbuffer Color : register(b0)
{
float4 color
}
//ConstantBuffer (b1)
cbuffer Color : register(b0)
{
float4 color
}
//Texture(t0)
Texture2D<float4> : register(t0);
//Texture(t1)
Texture2D<float4> SphereTex : register(t1);
//Static Sampler (s0)
SamplerState Sampler : register(s0);
//VertexShader
//ここでシェーダーに使用するRootSignatureをバインド
[RootSignature(RS)]
float4 VSMain(float3 pos : POSITION) : SV_POSITION
{
return float4 (pos.xyz ,1.0f);
}
//PixelShader
float4 PSMain(float4 pos : SV_POSITION) : SV_Target
{
return pos
}
このシェーダで注目してほしいのはHLSL内で一番上にあるRootSignatureの定義部分とVertexShaderの定義の上部にある部分です。
#define RS "RootFlags(ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT),"\
"CBV(b0),"\
"SRV(t0),"\
"DescriptorTable(CBV(b1,numDescriptors = 1,space = 0),visibility = SHADER_VISIBILITY_ALL),"\
"DescriptorTable(SRV(t1,numDescriptors = 1,space = 0),visibility = SHADER_VISIBILITY_PIXEL),"\
"StaticSampler(s0 ,"\
"filter = FILTER_MIN_MAG_MIP_LINEAR,"\
"addressU = TEXTURE_ADDRESS_WRAP,"\
"addressV = TEXTURE_ADDRESS_WRAP,"\
"addressW = TEXTURE_ADDRESS_WRAP,"\
"mipLodBias = 0.0f,"\
"maxAnisotropy = 16,"\
"comparisonFunc = COMPARISON_NEVER,"\
"borderColor = STATIC_BORDER_COLOR_TRANSPARENT_BLACK,"\
"minLOD = 0.0f,"\
"maxLOD = 3.402823466e+38f,"\
"space = 0,"\
"visibility = SHADER_VISIBILITY_ALL"\
")"\
上記のコードの部分と
[RootSignature(RS)]
この部分です。
これは*#define*でルートシグネチャを定義して、[RootSignature(RootSignature名)]でシェーダーにバインドしています。こうすることでシェーダーバイナリからRootSignatureがフェッチ可能になります。
CBVやSRV等をシェーダに投げるときのインデックス(RootParamaterIndex)はRootFlagsとStaticSamplerを除いて定義した順番になるので注意が必要です。
例えば上記のRootSignatureだと、CBV(b0)がインデックス0番、SRV(t0)がインデックス1番、といった感じになります。
#CPP側からフェッチ
Microsoft::WRL::ComPtr<ID3DBlob> vertexShader; //すでにコンパイル済みの頂点シェーダー
Microsoft::WRL::ComPtr<ID3DBlob> signature; //シェーダーバイナリからフェッチしたRootSignatureの情報
Microsoft::WRL::ComPtr<ID3D12RootSignature> rootSignature; //RootSignature本体
Microsoft::WRL::ComPtr<ID3D12Device> d3d12Device; //作成済みのデバイス
//シェーダーバイナリからRootSignatureの部分をフェッチ
auto hr = D3DGetBlobPart(vertexShader->GetBufferPointer(), vertexShader->GetBufferSize(), D3D_BLOB_ROOT_SIGNATURE, 0, &signature);
if (FAILED(hr))
{
return hr;
}
//RootSignatureの作成
hr = d3d12Device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&rootSignature));
if (FAILED(hr)) {
return hr;
};
こんな感じです。
#参考資料
Specifying Root Signatures in HLSL
[DX12] HLSLにRoot Signatureを定義する
上記の記事はとても参考になりました。