理解"采样器数组索引必须是文字表达式" ComputeShaders中的错误

时间:2014-04-24 20:37:19

标签: hlsl directx-11 compute-shader directcompute

假设我有一个计算着色器,它使用像这样的组的Id从Texture2DArray中检索数据:

Texture2DArray<float4> gTextureArray[2];
[numthreads(32, 1, 1)]
void Kernel(uint3 GroupID : SV_GroupID, uint3 GroupThreadID : SV_GroupThreadID)
{
    float3 tmp = gTextureArray[GroupID.x].Load(int4(GroupThreadID.x,GroupThreadID.x,0,0)).rgb;

    ....
}

让我说我像这样deviceContext->Dispatch(2, 0, 0);

启动它

因此,2组,每组32个线程从Texture2DArray读取像素值。 GroupID.x = 0中的所有线程将从gTextureArray [0]读取值,GroupID.y = 0中的所有线程将从gTextureArray [1]读取值。事实证明我无法编译那个简单的代码,而是得到了这个编译错误error X3512: sampler array index must be a literal expression

现在,我知道我可以这样做:

Texture2DArray<float4> gTextureArray[2];
[numthreads(32, 1, 1)]
void Kernel(uint3 GroupID : SV_GroupID, uint3 GroupThreadID : SV_GroupThreadID)
{
    float3 tmp = float3(0,0,0);
    if(GroupID.x == 0)
        tmp = gTextureArray[0].Load(int4(GroupThreadID.x,GroupThreadID.x,0,0)).rgb;
    else if(GroupID.x == 1)
        tmp = gTextureArray[1].Load(int4(GroupThreadID.x,GroupThreadID.x,0,0)).rgb;

    ....
}

或者在我有很多小组的情况下使用开关,这样看起来不那么糟糕(它仍然存在)

注意没有扭曲分歧,因为每个组中的所有线程都将进入一个分支或另一个分支。我的问题是,我在这里遗漏了什么吗?为什么HLSL不支持这种索引,因为我看不出任何分歧或其他问题,至少在这种情况下?

1 个答案:

答案 0 :(得分:1)

我不确定您是否正确绑定了您的管道,但让我们评估这两种情况。

当你有:

Texture2DArray<float4> gTextureArray[2];

技术上绑定2个纹理数组(一个在插槽0中,一个在插槽1中),因此运行时无法动态切换着色器资源插槽。

以上一行与执行相同:

Texture2DArray<float4> gTextureArray0;
Texture2DArray<float4> gTextureArray1;

在两种情况下,您都可以有效地绑定两种不同的资源,因此无法动态切换。

如果您有一个包含2个切片的纹理数组,则可以通过以下方式更改代码:

Texture2DArray<float4> gTextureArray;

[numthreads(32, 1, 1)]
void Kernel(uint3 GroupID : SV_GroupID, uint3 GroupThreadID : SV_GroupThreadID)
{
    float3 tmp = gTextureArray.Load(int4(GroupThreadID.x,GroupThreadID.x,GroupID.x,0)).rgb;

}

Z分量是切片索引,因此在这种情况下,完全可能。