引き続き 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 の場合無条件に両方書き出していたので、
不要なファイルが多数生成されていました。これで、完成した
シェーダーは余計なことをしなくて済むようになります。
あまりきれいな方法じゃないけどちょっと便利になりました。