LoginSignup
2
3

More than 5 years have passed since last update.

D3D12でHLSL内にRootSignatureを定義してフェッチしてみる

Last updated at Posted at 2018-07-27

概要

HLSL内にルートシグネチャを定義してCpp側からフェッチしてみるだけ。半分備忘録。

RootSignatureの定義

shader.hlsl
//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の定義の上部にある部分です。

shader.hlsl
#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"\
                                            ")"\

上記のコードの部分と

shader.hlsl
[RootSignature(RS)]

この部分です。

これは#defineでルートシグネチャを定義して、[RootSignature(RootSignature名)]でシェーダーにバインドしています。こうすることでシェーダーバイナリからRootSignatureがフェッチ可能になります。

CBVやSRV等をシェーダに投げるときのインデックス(RootParamaterIndex)はRootFlagsとStaticSamplerを除いて定義した順番になるので注意が必要です。
例えば上記のRootSignatureだと、CBV(b0)がインデックス0番、SRV(t0)がインデックス1番、といった感じになります。

CPP側からフェッチ

fetch.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を定義する

上記の記事はとても参考になりました。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3