为什么在引用 RWStructuredBuffer 时此 HLSL 像素着色器无法编译?
Why won't this HLSL Pixel Shader compile when RWStructuredBuffer is referenced?
我正在使用 DirectX 12,尝试使用无人机进行渲染。这是我的像素着色器代码:
struct PSInput
{
float4 position : SV_POSITION;
float4 color : COLOR;
};
struct FragmentDataStruct
{
float4 color;
float depth;
};
struct FragmentAndLinkStruct
{
FragmentDataStruct fragmentData;
uint nextFragment;
};
RWStructuredBuffer <FragmentAndLinkStruct> FLBuffer : register(u0);
RWByteAddressBuffer StartOffsetBuffer : register(u1);
float4 PSMain(PSInput input) : SV_TARGET
{
input.color.x = float(FLBuffer[0].nextFragment);
return input.color;
}
使用D3DCompileFromFile
函数编译失败
当我替换这一行时:
input.color.x = float(FLBuffer[0].nextFragment);
像这样:
FragmentAndLinkStruct otherThing;
otherThing.nextFragment = 1;
input.color.x = float(otherThing.nextFragment);
没有提到 RWStructuredBuffer
,然后它就可以正常编译并正确呈现。
我认为绑定数据没有任何问题(VS Graphics Debugger 显示两个 UAV 正确绑定)。不过,我认为这不会影响着色器的编译。
任何时候我引用 FLBuffer
或 StartOffsetBuffer
,它都不会编译。
什么会导致这个问题?
在弄清楚如何读取编译器给出的错误后,我解决了这个问题。这里的问题是渲染目标输出使用 u0
着色器寄存器。
为了找到这个,我通过使用下面的代码将其转换为 char*
数组,从 D3DCompileFromFile
中读出本机给出的错误作为 ID3DBlob*
,其中 error
是一个 ID3DBlob*
:
const char* error2 = static_cast<const char*>(error->GetBufferPointer());
我在最后一行后立即设置了一个断点,并简单地从 VS 中的本地选项卡中读取了错误消息:
error X4509: UAV registers live in the same name space as outputs, so they
must be bound to at least u1, manual bind to slot u0 failed
错误消息非常简洁明了。很有帮助。
更新后的代码:
struct PSInput
{
float4 position : SV_POSITION;
float4 color : COLOR;
};
struct FragmentDataStruct
{
float4 color;
float depth;
};
struct FragmentAndLinkStruct
{
FragmentDataStruct fragmentData;
uint nextFragment;
};
RWStructuredBuffer <FragmentAndLinkStruct> FLBuffer : register(u1);
RWByteAddressBuffer StartOffsetBuffer : register(u2);
float4 PSMain(PSInput input) : SV_TARGET
{
uint pixelCount = FLBuffer.IncrementCounter();
input.color.x = float(pixelCount);
return input.color;
}
请注意,编译器甚至不会查看对 return
输出没有贡献的代码。我通过向 PSMain
函数添加一些代码来测试它,该函数与 FLBuffer
交互而不影响返回的 input.color
。查看反汇编,所有多余的代码都被删除了,没有编译。
另外,因为我在工作时没有引用 FLBuffer
,所以它没有在输出着色器寄存器和我绑定的 u0
着色器寄存器之间建立任何连接,所以没有出现问题.
然后我必须假设它在完整性检查代码之前删除了多余的代码,这在寻找效率时很有意义。一旦它进行了健全性检查,它就会继续编译。
希望这对以后学习 DirectX 或 HLSL 的人有所帮助。
我正在使用 DirectX 12,尝试使用无人机进行渲染。这是我的像素着色器代码:
struct PSInput
{
float4 position : SV_POSITION;
float4 color : COLOR;
};
struct FragmentDataStruct
{
float4 color;
float depth;
};
struct FragmentAndLinkStruct
{
FragmentDataStruct fragmentData;
uint nextFragment;
};
RWStructuredBuffer <FragmentAndLinkStruct> FLBuffer : register(u0);
RWByteAddressBuffer StartOffsetBuffer : register(u1);
float4 PSMain(PSInput input) : SV_TARGET
{
input.color.x = float(FLBuffer[0].nextFragment);
return input.color;
}
使用D3DCompileFromFile
函数编译失败
当我替换这一行时:
input.color.x = float(FLBuffer[0].nextFragment);
像这样:
FragmentAndLinkStruct otherThing;
otherThing.nextFragment = 1;
input.color.x = float(otherThing.nextFragment);
没有提到 RWStructuredBuffer
,然后它就可以正常编译并正确呈现。
我认为绑定数据没有任何问题(VS Graphics Debugger 显示两个 UAV 正确绑定)。不过,我认为这不会影响着色器的编译。
任何时候我引用 FLBuffer
或 StartOffsetBuffer
,它都不会编译。
什么会导致这个问题?
在弄清楚如何读取编译器给出的错误后,我解决了这个问题。这里的问题是渲染目标输出使用 u0
着色器寄存器。
为了找到这个,我通过使用下面的代码将其转换为 char*
数组,从 D3DCompileFromFile
中读出本机给出的错误作为 ID3DBlob*
,其中 error
是一个 ID3DBlob*
:
const char* error2 = static_cast<const char*>(error->GetBufferPointer());
我在最后一行后立即设置了一个断点,并简单地从 VS 中的本地选项卡中读取了错误消息:
error X4509: UAV registers live in the same name space as outputs, so they
must be bound to at least u1, manual bind to slot u0 failed
错误消息非常简洁明了。很有帮助。
更新后的代码:
struct PSInput
{
float4 position : SV_POSITION;
float4 color : COLOR;
};
struct FragmentDataStruct
{
float4 color;
float depth;
};
struct FragmentAndLinkStruct
{
FragmentDataStruct fragmentData;
uint nextFragment;
};
RWStructuredBuffer <FragmentAndLinkStruct> FLBuffer : register(u1);
RWByteAddressBuffer StartOffsetBuffer : register(u2);
float4 PSMain(PSInput input) : SV_TARGET
{
uint pixelCount = FLBuffer.IncrementCounter();
input.color.x = float(pixelCount);
return input.color;
}
请注意,编译器甚至不会查看对 return
输出没有贡献的代码。我通过向 PSMain
函数添加一些代码来测试它,该函数与 FLBuffer
交互而不影响返回的 input.color
。查看反汇编,所有多余的代码都被删除了,没有编译。
另外,因为我在工作时没有引用 FLBuffer
,所以它没有在输出着色器寄存器和我绑定的 u0
着色器寄存器之间建立任何连接,所以没有出现问题.
然后我必须假设它在完整性检查代码之前删除了多余的代码,这在寻找效率时很有意义。一旦它进行了健全性检查,它就会继续编译。
希望这对以后学习 DirectX 或 HLSL 的人有所帮助。