ConstantBuffer は D3D8~9 同様 32bit×4 が Element の基本サイズに
なります。ただし D3D10 は float, int の混在が可能です。
マニュアルには Packing Rule として、変数がどのように Constant Buffer
へ格納されるか説明が載っています。
配列変数の場合は、インデックス参照を行うとアドレッシングの影響を強く
受けてしまうので大胆なパッキングができません。
例えば次のように宣言して、A を変数インデックスで動的に参照する場合、
cbuffer _Array {
uint A[256];
};
cb[] の参照は必ず Element 単位となるため 128bit のアライメント整合
が発生します。よって上記の cbuffer は
256 × 4 × 4 = 4096byte になります。(厳密には 4096-12=4084byte)
さらに次のように宣言すると
cbuffer _Array {
uint A[256];
float B[256];
};
本当は A を .x に、B を .y にでもパックしてしまえばデータ構造的には
要素をまとめることができるはずですが、
この場合もリニアに 512 × 4 × 4 = 8192byte とられてしまいます。
(厳密には 8192-12 = 8180byte)
struct _pack {
uint a;
float b;
};
cbuffer _Array {
_pack A[256];
};
上のように自分で構造体にまとめると半分の 4096 (4096-8=4088) byte です。
ld 命令が 4要素単位となる tbuffer (Buffer) でも全く同じでした。
この「32bit×4」の制限を回避するには、Sampler を使って 1D Texture
としてアクセスする方法が考えられます。