HLSL:在结构内使用数组

发布于 2024-09-15 13:17:41 字数 1358 浏览 1 评论 0原文

我遇到了 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 循环行):

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

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

我的问题是,为什么 DirectX 在使用该结构时尝试展开(不可展开的)for 循环?这是有记录的行为吗?除了将数组放在结构之外是否有任何可用的解决方法?

我使用的是 2010 年 6 月起的着色器模型 4.0、DirectX 10 SDK。

编辑: 为了澄清起见,我添加了工作代码,它仅用普通数组替换了 struct 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];
}

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

I came across a weird behavior of HLSL. I am trying to use an array that is contained within a struct, like this (Pixel Shader code):

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];
}

The code makes no sense logically, it's just a sample. The problem is that when I try to compile this code, I get the following error (line 25 is the for-loop line):

(25,7): error X3511: Forced to unroll
loop, but unrolling failed.

However, when I put the array outside the struct (just declare float a[17] in shMain), everything works as expected.

My question is, why is DirectX trying to unroll the (unrollable) for-loop when using the struct? Is this a documented behavior? Is there any available workaround except for putting the array outside the struct?

I am using shader model 4.0, DirectX 10 SDK from June 2010.

EDIT:
For clarification I am adding the working code, it only replaces usage of the struct Something with plain array:

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];
}

This code compiles and works as expected. It works even if I add [loop] attribute in front of the for-loop which means it is not unrolled (which is a correct behavior).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

記柔刀 2024-09-22 13:17:41

我不确定,但我知道硬件按 2x2 块调度和处理片段(用于计算导数)。这可能是 fxc 尝试展开 for 循环以便着色器程序以锁步模式执行的原因。

您是否还尝试使用 [loop] 属性来生成使用流量控制的代码?

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?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文