今回は、ルートシグネチャの生成をしていきます。
ルートシグネチャはシェーダの情報を持っているものと、思ってます。
もちろん他にもいろいろやってくれますが、自分がまだ性能を発揮させてあげれず、
基本の基本しか使えてません。そこも今後勉強していきます。
Root.h
# include "Obj.h"
class Device;
class Root :
public Obj
{
public:
// コンストラクタ
Root(Device* dev);
// デストラクタ
~Root();
// 頂点シェーダのコンパイル
HRESULT ComVertex(LPCWSTR fileName, LPCSTR func, LPCSTR target = "vs_5_0");
// ピクセルシェーダのコンパイル
HRESULT ComPixel(LPCWSTR fileName, LPCSTR func, LPCSTR target = "ps_5_0");
// メッセージの取得
ID3DBlob* GetMsg(void) const {
return signature;
}
// エラーメッセージの取得
ID3DBlob* GetError(void) const {
return error;
}
// 頂点シェーダの取得
ID3DBlob* GetVertex(void) const {
return vertex;
}
// ピクセルシェーダの取得
ID3DBlob* GetPixel(void) const {
return pixel;
}
// ルートシグネチャの取得
ID3D12RootSignature* Get(void) const {
return root;
}
private:
// シリアライズ
HRESULT Serialize(void);
// ルートシグネチャの生成
HRESULT CreateRoot(void);
// デバイス
Device* dev;
// メッセージ
ID3DBlob * signature;
// エラーメッセージ
ID3DBlob* error;
// 頂点シェーダ
ID3DBlob* vertex;
// ピクセルシェーダ
ID3DBlob* pixel;
// ルートシグネチャ
ID3D12RootSignature * root;
};
Root.cpp
# include <d3dcompiler.h>
# include "Root.h"
# include "Device.h"
# pragma comment (lib, "d3dcompiler.lib")
// コンストラクタ
Root::Root(Device* dev) :
dev(dev), signature(nullptr), error(nullptr), vertex(nullptr), pixel(nullptr), root(nullptr)
{
Serialize();
CreateRoot();
}
// デストラクタ
Root::~Root()
{
Release(root);
Release(pixel);
Release(vertex);
Release(error);
Release(signature);
delete dev;
}
// 頂点シェーダのコンパイル
HRESULT Root::ComVertex(LPCWSTR fileName, LPCSTR func, LPCSTR target)
{
result = D3DCompileFromFile(fileName, nullptr, nullptr, func, target, D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION, 0, &vertex, &error);
return result;
}
// ピクセルシェーダのコンパイル
HRESULT Root::ComPixel(LPCWSTR fileName, LPCSTR func, LPCSTR target)
{
result = D3DCompileFromFile(fileName, nullptr, nullptr, func, target, D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION, 0, &pixel, &error);
return result;
}
// シリアライズ
HRESULT Root::Serialize(void)
{
//ディスクリプタレンジの設定.
D3D12_DESCRIPTOR_RANGE range[2];
SecureZeroMemory(&range, sizeof(range));
//ルートパラメータの設定.
D3D12_ROOT_PARAMETER param[2];
SecureZeroMemory(¶m, sizeof(param));
//定数バッファ用
range[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_CBV;
range[0].NumDescriptors = 1;
range[0].BaseShaderRegister = 0;
range[0].RegisterSpace = 0;
range[0].OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
param[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
param[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX;
param[0].DescriptorTable.NumDescriptorRanges = 1;
param[0].DescriptorTable.pDescriptorRanges = &range[0];
//テクスチャ用
range[1].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
range[1].NumDescriptors = 1;
range[1].BaseShaderRegister = 0;
range[1].RegisterSpace = 0;
range[1].OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
param[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
param[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
param[1].DescriptorTable.NumDescriptorRanges = 1;
param[1].DescriptorTable.pDescriptorRanges = &range[1];
//静的サンプラーの設定
D3D12_STATIC_SAMPLER_DESC sampler = {};
sampler.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
sampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
sampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
sampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
sampler.MipLODBias = 0;
sampler.MaxAnisotropy = 0;
sampler.ComparisonFunc = D3D12_COMPARISON_FUNC_NEVER;
sampler.BorderColor = D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK;
sampler.MinLOD = 0.0f;
sampler.MaxLOD = D3D12_FLOAT32_MAX;
sampler.ShaderRegister = 0;
sampler.RegisterSpace = 0;
sampler.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
//ルートシグネチャ設定用構造体の設定
D3D12_ROOT_SIGNATURE_DESC desc = {};
desc.NumParameters = _countof(param);
desc.pParameters = param;
desc.NumStaticSamplers = 1;
desc.pStaticSamplers = &sampler;
desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;
// シリアライズ
result = D3D12SerializeRootSignature(&desc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error);
return result;
}
// ルートシグネチャの生成
HRESULT Root::CreateRoot(void)
{
result = dev->Get()->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&root));
return result;
}
これでルートシグネチャの生成は終了です。
一応、テクスチャにも対応させてます。