3

我遇到了一个奇怪的 HLSL 行为。我正在尝试使用包含在结构中的数组,如下所示(像素着色器代码):

struct VSOUT {
    float4 projected : SV_POSITION;
    float3 pos: POSITION;
    float3 normal : NORMAL;
};


struct Something  {
    float a[17];
};


float4 shMain (VSOUT input) : SV_Target {
    Something s;

    for (int i = 0; i < (int)(input.pos.x * 800); ++i)
        s.a[(int)input.pos.x] = input.pos.x;

    return col * s.a[(int)input.pos.x];
}

该代码在逻辑上没有意义,它只是一个示例。问题是当我尝试编译这段代码时,我得到以下错误(第 25 行是 for-loop 行):

(25,7):错误 X3511:强制展开循环,但展开失败。

但是,当我将数组放在结构之外(只需float a[17]在 中声明shMain),一切都按预期工作。

我的问题是,为什么 DirectX 在使用结构时试图展开(不可滚动的)for 循环?这是记录在案的行为吗?除了将数组放在结构之外,还有其他可用的解决方法吗?

我从 2010 年 6 月开始使用着色器模型 4.0、DirectX 10 SDK。

编辑: 为澄清起见,我正在添加工作代码,它仅用Something普通数组替换结构的使用:

struct VSOUT {
    float4 projected : SV_POSITION;
    float3 pos: POSITION;
    float3 normal : NORMAL;
};


float4 shMain (VSOUT input) : SV_Target {
    float a[17];  // Direct declaration of the array

    for (int i = 0; i < (int)(input.pos.x * 800); ++i)
        a[(int)input.pos.x] = input.pos.x;

    return col * a[(int)input.pos.x];
}

此代码按预期编译和工作。即使我[loop]在 for 循环前面添加属性,它也可以工作,这意味着它没有展开(这是正确的行为)。

4

1 回答 1

1

I'm not sure but what I know is that the hardware schedule and process fragments by block of 2x2 (for computing derivatives). This could be a reason that fxc try to unroll the for loop so that the shader program is executed in lockstep mode.

Also did you try to use [loop] attribute for generating code that uses flow control?

于 2010-08-25T09:19:55.763 回答