1

我正在学习 DirectCompute,但我坚持使用 StructuredBufferes。事情是我了解到,要向着色器提供数据,我需要使用视图 - SRV 或 UAV,具体取决于我想要实现的目标。但是来自微软网站的代码示例并没有解释,在 C++ 代码中定义的视图如何与在着色器代码中定义的特定 Buffer 相对应。但是,有一个 hlsl 关键字我不太明白 - register()。在示例中有三个缓冲区:

    StructuredBuffer<BuffType> Buff0 : register(t0);
    StructuredBuffer<BuffType> Buff1 : register(t1);
    RWStructuredBuffer<BuffType> BuffOut : register(u0);

在 C++ 代码中,作者只需设置 ComputeShader、1 个 UAV、2 个 SRV,然后调用 Context.Dispatch(,,)(假设他们之前已准备好所有缓冲区和视图)。所以问题是 - 我如何理解特定的 SRV(其中有两个)为特定的 StructuredBuffer 提供数据?它是否由寄存器编号控制(例如首先填充寄存器(t0),寄存器(t1)-第二)。如果是,如果我想先向第二个缓冲区提供数据,然后填充第一个缓冲区怎么办?我觉得自己错过了一些非常重要的东西,但是在之前的教程中,由于 EffectVariales 和.GetVariableBy方法,我使用的一切都变得容易多了。提前致谢。

4

1 回答 1

2

着色器中声明的寄存器绑定对应于绑定数组参数中的索引。例如,如果你调用CSSetShaderResources(7 /*StartSlot*/, 3 /*NumViews*/, viewArray);,这将绑定viewArray[0]register(t7)viewArray[1]toregister(t8)viewArray[2]to register(t9)viewArray请注意,如果is的元素之一NULL,这将有效地取消绑定相应的寄存器槽。

请注意,在 HLSL 中,省略显式register绑定将自动分配从 0 开始的寄存器。在常见情况下,StartSlot将是0,因此您只需要确保视图的viewArray顺序与着色器中的声明顺序相匹配。尽管如此,最好的做法是显式分配注册表并确保它们与您的绑定数组匹配,因为如果 HLSL 编译器确定您不需要声明的视图之一,它将消除它并且不会在隐式中跳过它的插槽任务。例如:

StructuredBuffer<float> foo; // register(t0)
StructuredBuffer<float> bar; // eliminated!
StructuredBuffer<float> baz; // register(t1) // skipped over bar!
RWStructuredBuffer<float> biz; // register(u0)
void main()
{
    float x = foo[0];
    if(x < 0) x = 0;
    else if(x >= 0) x = 1;
    else x = bar[0]; // branch never hit, compiler optimizes out the only use of bar!
    biz[0] = x + baz[0];
}
于 2015-10-09T19:41:36.727 回答