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:ループの展開を強制しましたが、展開に失敗しました。
ただし、配列を構造体の外に置くと(で宣言するだけfloat a[17]
でshMain
)、すべてが期待どおりに機能します。
私の質問は、構造体を使用しているときに、DirectXが(展開可能な)forループを展開しようとするのはなぜですか?これは文書化された動作ですか?配列を構造体の外に置くことを除いて、利用可能な回避策はありますか?
2010年6月からシェーダーモデル4.0、DirectX10SDKを使用しています。
編集: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]
します。つまり、展開されません(これは正しい動作です)。