次の定数バッファーを宣言する HLSL で記述されたピクセル シェーダーがあります。
cbuffer RenderParametersData : register(b2)
{
float4 LineColor[16];
};
シェーダー関数の 1 つで、インデックス「色」に基づいて出力色を検索します (これは実際には色ではなく、インデックスを LineColors の配列に配置するのに便利な場所です)。
output.Color = Colors[input.Color.b * 255];
これにより、アセンブリ コードの命令スロット数が大幅に増加します。他のすべてを一定に保ちますが、代わりに定数配列ルックアップを実行します - output.Color = LineColor[0];
- 算術演算の数は 10 から 37 になります。追加演算のほとんどすべては次のようになります。
cmp r2, -r1.x, c0, r0.w
cmp r2, -r1.y, c1, r2
cmp r2, -r1.z, c2, r2
cmp r1, -r1.w, c3, r2
c は 15 に増加し、LineColor の要素数と一致します。LineColor のサイズを 8 要素に変更すると、コードは 2 番目のケースとほぼ同じになりましたが、c は 7 だけになり、配列内の要素数と一致しました。定数検索に戻ると、操作の数は 10 に減少しました。
そのため、動的な定数バッファー配列のルックアップにはかなりの追加コストがかかるようです。配列の要素ごとに 1 つの比較命令が追加され、さらにオーバーヘッドがいくらかかかります。この配列ルックアップのコストの高さに本当に驚いています。配列サイズがすぐに 1 桁増加することを考えると、64 演算命令の制限を超えることになります。
これは予想される動作ですか?私はここで何か間違ったことをしていますか、それとも動的配列インデックスの必要な結果ですか?
ありがとう!
編集:追加の詳細を追加するために、私が求めている効果は、頂点シェーダーとテクスチャ座標からのデータに基づいていくつかのクワッドに色を付けることです。頂点シェーダーで作業を行いますが、テクスチャ座標の補間を最初に行う必要があります。
EDIT2:これを解決しました。ターゲットが ps_4_0_level_9_1 であることを FXC に指定していたため、シェーダー モデル 2.0 と 4.0 の両方のアセンブリが生成されました。要素ごとの追加の比較の問題は、モデル 2.0 アセンブリ コードでのみ発生することがわかりました。コンパイラ ターゲットを PS_4_0 に切り替えると、モデル 4.0 コードのみが取得され、レベル 9_1 に制約されていないため、問題なく動作しています。