DirectCompute着色器数据输入/输出

时间:2015-09-16 16:15:10

标签: c++ directx hlsl directcompute

我正在学习DirectCompute,而且我遇到了StructuredBufferes。事情是我了解到为着色器提供数据我需要使用View-SRV或UAV,这取决于我想要实现的目标。但是Microsoft站点的代码示例没有解释,C ++代码中定义的视图如何与着色器代码中定义的特定Buffer相对应。但是,有一个我不太懂的hlsl关键字 - register()。在样本中有三个bufferes:

    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 方法而变得容易多了。 提前谢谢。

1 个答案:

答案 0 :(得分:2)

着色器中声明的寄存器绑定对应于绑定数组参数中的索引。例如,如果您拨打CSSetShaderResources(7 /*StartSlot*/, 3 /*NumViews*/, viewArray);,则会将viewArray[0]绑定到register(t7),将viewArray[1]绑定到register(t8),将viewArray[2]绑定到register(t9) }。请注意,如果viewArray的其中一个元素为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];
}