DirectX12 事始め ルートシグネチャの生成

今回は、ルートシグネチャの生成をしていきます。
ルートシグネチャはシェーダの情報を持っているものと、思ってます。
もちろん他にもいろいろやってくれますが、自分がまだ性能を発揮させてあげれず、
基本の基本しか使えてません。そこも今後勉強していきます。

```c++: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;
};
```

```c++: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(&param, 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;
}
```

これでルートシグネチャの生成は終了です。
一応、テクスチャにも対応させてます。