D3D10/DX10 Effect と CBufferの関係

Effect Interface内情報の続きです。
ID3D10Effect は内部で必要な ConstantBuffer を生成しパラメータを保持
しています。cbuffer 宣言で明示的に ConstantBuffer を指定することが
できますが、実際に生成されているバッファは宣言した cbuffer の数よりも
1つ多いようです。
調べてみると ‘$Globals’ という暗黙の CBuffer が作られており、おそらく
cbuffer 宣言無しに定義した global 変数が $Globals 扱いになるのでしょう。
ID3D10Effect の CBuffer は ID3D10EffectConstantBuffer 経由で取り出せます。

例えば作成済み D3D10Effect の ie1 から、cbuffer LMaterial の IBuffer
(ConstantBuffer) を参照するには次のようになります。

ID3D10Effect* ie1; // input
ID3D10Buffer* ib1= NULL; // output
ID3D10EffectConstantBuffer* cf1= ie1->GetConstantBufferByName( “LMaterial” );
cf1->GetConstantBuffer( &ib1 );

このとき ib1 は Get によって AddRef() されており参照カウンタ値は 2 です。
自前で用意した CBuffer を与えるとどうなるでしょうか。

ID3D10Effect のインスタンスを 2つ用意し、ie1 に ie2 の CBuffer を設定して
みました。

ID3D10Effect* ie1; // input
ID3D10Effect* ie2; // input
ID3D10EffectConstantBuffer* cf1= ie1->GetConstantBufferByName( “LMaterial” );
ID3D10EffectConstantBuffer* cf2= ie2->GetConstantBufferByName( “LMaterial” );
ID3D10Buffer* ib1= NULL;
ID3D10Buffer* ib2= NULL;
cf1->GetConstantBuffer( &ib1 );
cf2->GetConstantBuffer( &ib2 );
cf1->SetConstantBuffer( &1b2 ); // ie1 ← ie2

ここで ib1, ib2 それぞれの参照カウンタを見ると 1 と 3 になっています。
つまり ie1 側の CBuffer は事実上解放されており、ie2 側の CBuffer が
共有されていることが参照カウンタの増加から分かります。

ID3D10Shader を使わずとも ID3D10Effect だけでバッファの共有管理を自前で
行うことができそうです。