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ループ行です)。

(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]します。つまり、展開されません(これは正しい動作です)。

4

1 に答える 1

1

よくわかりませんが、ハードウェアのスケジュールとプロセスのフラグメントを2x2のブロックで処理します(導関数の計算用)。fxcこれは、シェーダープログラムがロックステップモードで実行されるようにforループを展開しようとする理由である可能性があります。

また[loop]、フロー制御を使用するコードを生成するために属性を使用しようとしましたか?

于 2010-08-25T09:19:55.763 に答える