Single_Bell1225
@Single_Bell1225

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

レジスタ指定によるエラー

解決したいこと

現在DirectX12でコンスタントバッファ、テクスチャ、ストラクチャバッファをhlslに指定しようとしています。テクスチャをt0,ストラクチャバッファをt1に指定しているときは成功し、適切に描画されました。

しかし、二つのレジスタを逆にしてみるとエラーとなります。hlslでもC++側でも適切にしているにも関わらずです。

内部でどう動いているのか、エラーの原因、エラーを直す方法をご教授いただければ幸いです。

発生している問題・エラー

D3D12SerializeRootSignatureでE_INVALIDARG One or more arguments are invalid.となる。

該当するソースコード

struct PerInstance
{
	float4x4 World;
	float tick;

	float val0;
	float val1;
	float val2;
};
cbuffer Util : register(b0)
{
	float4x4 View		: packoffset(c0);
	float4x4 Projection : packoffset(c4);
	float Time : packoffset(c8);
};
SamplerState colsmp : register(s0);


StructuredBuffer<PerInstance> Data	: register(t0);
Texture2D	 colmap : register(t1);

該当するソースコード

 enum
 {
     CB = 0,
     SB,
     TEX,
     
     AMMOUNT
 };

 D3D12_ROOT_PARAMETER r_param[AMMOUNT] = {};
 {
     r_param[CB].ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
     r_param[CB].Descriptor.RegisterSpace = 0;
     r_param[CB].Descriptor.ShaderRegister = 0;
     r_param[CB].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
 }

 D3D12_DESCRIPTOR_RANGE range_SB = {};
 {
     range_SB.BaseShaderRegister = 0;
     range_SB.NumDescriptors = CBCOUNT;
     range_SB.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
     range_SB.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
     range_SB.RegisterSpace = 0;
 }

 r_param[SB];
 {
     r_param[SB].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
     r_param[SB].DescriptorTable.NumDescriptorRanges = 1;
     r_param[SB].DescriptorTable.pDescriptorRanges = &range_SB;
     r_param[SB].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
 }

 D3D12_DESCRIPTOR_RANGE range_Tex = {};
 {
     range_Tex.BaseShaderRegister = 1;
     range_Tex.NumDescriptors = 1;
     range_Tex.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
     range_Tex.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
     range_Tex.RegisterSpace = 0;
 }

 r_param[TEX];
 {
     r_param[TEX].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
     r_param[TEX].DescriptorTable.NumDescriptorRanges = 1;
     r_param[TEX].DescriptorTable.pDescriptorRanges = &range_Tex;
     r_param[TEX].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
 }

 D3D12_STATIC_SAMPLER_DESC sampler = {};
 {
     sampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_MIRROR;
     sampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_MIRROR;
     sampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_MIRROR;
     sampler.BorderColor = D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK;
     sampler.ComparisonFunc = D3D12_COMPARISON_FUNC_NEVER;
     sampler.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
     sampler.MaxAnisotropy = 1;
     sampler.MaxLOD = D3D12_FLOAT32_MAX;
     sampler.MinLOD = D3D12_FLOAT32_MAX * -1;
     sampler.MipLODBias = D3D12_DEFAULT_MIP_LOD_BIAS;
     sampler.RegisterSpace = 0;
     sampler.ShaderRegister = 0;
     sampler.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
 }

 //--------++++++++++++++++++++++
 D3D12_ROOT_SIGNATURE_DESC r_s_desc = {};
 {
     auto flag = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;
     flag |= D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS;
     flag |= D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS;
     flag |= D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS;

     r_s_desc.pParameters = r_param;
     r_s_desc.pStaticSamplers = &sampler;
     r_s_desc.Flags = flag;
     r_s_desc.NumParameters = AMMOUNT;
     r_s_desc.NumStaticSamplers = 1;
 }

 ID3DBlob* S_blob;
 ID3DBlob* E_blob;

 res = D3D12SerializeRootSignature
 (
     &r_s_desc,
     D3D_ROOT_SIGNATURE_VERSION_1_0,
     &S_blob,
     &E_blob
 );
 if (FAILED(res))     return 0;

自分で試したこと

順番を入れ替えただけでエラーとなるので、テクスチャとストラクチャバッファには順番がある?と思い調べましたがそのような情報は特になし。

であれば、OffsetInDescriptorsFromTableStartあたりが怪しいのでしょうが如何せんよくわからず今回質問させていただきました。

初めて質問するので、何か作法や必要な情報など知識にないため、もしそちらもご教授いただければ幸いです。

0

1Answer

StructuredBuffer Data : register(t0);
Texture2D colmap : register(t1);

想定ですが、PerInstanceの全メンバーのビット幅がt0のビット幅に収まらず、t1にまで及んでいるのではないでしょうか?
とりあえず、Texture2D colmap : register(t20);ぐらいまで十分に離せば動くのではないでしょうか。

テクスチャをt0,ストラクチャバッファをt1の場合は、t2以降を使う変数が存在しないので、動作するものと思います。

0Like

Comments

  1. ご返信ありがとうございます。
    ストラクチャバッファの数*サイズ分である、t512を指定したところ正常に動作し、問題なく使えました。
    レジスタはセマンティクスのような存在だと思っていたため、nakさんのご返信がなければ完全に詰まっていました。
    本当にありがとうございました。

Your answer might help someone💌