LoginSignup
2
2

More than 5 years have passed since last update.

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

Posted at

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

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(&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;
}

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

2
2
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
2