引き続き HLSL/Effect のコンパイル周りの話です。
core API 側の Shader Compiler で #include に対応するには
ID3D10Include の準備が必要です。
これはもともと Direct3D9 の D3DX にあったもので、
機能も使い方もいっしょのようです。
ただ、D3DX10 の Shader Compiler API を使う分には内部で
勝手に include 処理をやってくれますし、下記エントリで書いた
ように D3DX 側 API を使った方が良いので、普通に使う分には
あまり気にする必要は無いかもしれません。
>・Direct3D 10 Shader4.0 APIによってコンパイラが違う
一応試してみました。
class fxInclude : public ID3D10Include { public: fxInclude() { } ~fxInclude() { } virtual HRESULT __stdcall Open( D3D10_INCLUDE_TYPE inctype, LPCSTR filename, LPCVOID parentdata, LPCVOID* ppdata, UINT* pbyte ) { UINT bsize= __FileSize( filename ); void* ptr= __Alloc( bsize ); if( ptr ){ if( __Load( ptr, filename, bsize ) ){ *ppdata= ptr; *pbyte= bsize; return S_OK; } __Free( ptr ); } return E_FAIL; } virtual HRESULT __stdcall Close( LPCVOID ppdata ) { __Free( const_cast( ppdata ) ); return S_OK; } };
使っているところ。
ID3D10Blob* blobEffect= NULL; ID3D10Blob* blobError= NULL; fxInclude incFunc; D3D10CompileEffectFromMemory( memory, size, fxname, cpp_defines,// def &incFunc, // inc 0, // HLSLflag 0, // FXflag &blobEffect, &blobError );
#include の度にファイル名を持って callback されるので、
必要なメモリ領域を作ってあげるだけです。
不要になったら Close() を呼び出してくれます。
ID3D10Include を自前で用意する目的として考えられるのは、
include path 検索への対応でしょうか。
もしくは File にこだわらず、特定の include キーワードに
反応して別のコマンドを挿入したり pragma のように動作を
変えることも出来そうです。
自分で Effect のテキストを読み進める処理が不要なので、
意外に使えるかもしれません。
というわけで
#include “output_disassemble”
#include “output_preprocess”
と記述したシェーダーは、デバッグテスト用に disassemble や
preprocess 結果をファイルに書き出すようにしてみました。
テスト&デバッグ中は毎回出力して欲しいけど、完成した
シェーダーの場合は余計なファイルを作られても困ります。
今までは debug build の場合無条件に両方書き出していたので、
不要なファイルが多数生成されていました。これで、完成した
シェーダーは余計なことをしなくて済むようになります。
あまりきれいな方法じゃないけどちょっと便利になりました。