【问题标题】:Understanding the "sampler array index must be a literal expression" error in ComputeShaders了解 ComputeShaders 中的“采样器数组索引必须是文字表达式”错误
【发布时间】:2014-04-24 20:37:19
【问题描述】:

假设我有一个计算着色器,它使用组的 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-&gt;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 不支持这种索引,因为我看不到任何分歧或其他问题,至少在这种情况下是这样?

【问题讨论】:

    标签: hlsl directx-11 compute-shader directcompute


    【解决方案1】:

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

    当你有:

    Texture2DArray<float4> gTextureArray[2];
    

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

    上面这行和做的一样:

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

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

    如果您有一个带有 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 组件是切片索引,所以在这种情况下这是完全可能的。

    【讨论】:

    • 是的。你是对的。以我建议的方式使用纹理数组似乎只是语法糖。在这篇文章gamedev.net/topic/… 中给出了额外的说明
    • @catflier,如何将 c# 中的 Texture2d 与 hlsl 中的 Texture2DArray 结合起来?我缺少一个链接。在 hlsl 中使用 switch 来避免上述异常,sux
    • @JeroenvanLangen 这在创建时很容易构建纹理数组,但答案取决于您使用的 c# 包装器(slimdx 或 sharpdx),也可以从 gpu 生成的资源中使用 draw调用、计算通行证或复制资源区域。也许一个问题会更容易(也有助于人们将这些答案隐藏在 cmets 中)。
    猜你喜欢
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 2012-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-11
    • 1970-01-01
    相关资源
    最近更新 更多