日別アーカイブ: 2007年9月29日

Direct3D 10 HLSL のプリプロセッサ機能の限界

DX10/D3D10 では Effect(fx)/HLSL のプリプロセッサが拡張されている
ことを下記のエントリで書きました。
Direct3D 10 HLSL の関数型マクロ定義

その後もう少しだけ調べてみましたが、残念ながらまだ C/C++ と
完全互換というわけにはいかないようです。
もしかしたら BOOST_PP でも動くんじゃないか、と思って試したら
甘かったです。

●引数無しの関数型マクロが定義できない

#define NAME_A() 0x40f

上記のような引数無しの関数型マクロ名がエラーになります。
ダミーでも NAME_A(_r) のように何か引数を与えないとだめでした。

●意味のない # 行が無視されない

例えば単独で出てくる行頭の ‘#’ のみの行がエラーになります。

●#if 等で bit 演算できない

#if BITFLAG & 4

こんな形の bit 判定はエラーになります。| や ^ 等もだめ。
一般的な四則演算や論理演算はもちろん大丈夫です。

Effect(fx)/HLSL 単体でここまで凝った使い方をすることはあまり
無いかもしれません。
ただ、定数シンボルなどを共通化するために C++ ソースとヘッダを
共有する可能性はあるので、この辺の互換性には注意しておきたい
ところです。

内蔵 Preprocessor は動的コンパイルでは必要になります。
でも、もし完全に事前コンパイルしてもいいのならば、普通に C++ の
プリプロセッサを通した方が良いかもしれません。
従来 DirectX8(vsa/psa)~DirectX9 の時はいろいろ機能的に
物足りなかったので、例えば下記のような感じで Makefile を
作っていました。

# Makefile
# nmake 用

PROFILE	= fx_4_0
FXINCLUDE = -I.

.fx.fxo:
	cl /E $< $(FXINCLUDE) > $*.tmp
	fxc /T$(PROFILE) /Fo$@ $*.tmp

.SUFFIXES:	.fx .fxo

sysdef.fx というファイルが存在する状態で sysdef.fxo を作りたければ
コマンドラインから

nmake sysdef.fxo

とキータイプするだけです。Makefile はカレントに必要です。
nmake.exe や cl.exe、fxc.exe 等にパスを通しておく必要があります。

VisualStudio は Common~\IDE と VC\bin の2箇所にパスが通って
いれば OK です。例えば 32bit(x86) + VS2005 でパスを通しておく
フォルダは下記の通り。

%DXSDK_DIR%Utilities\Bin\x86
C:\Program Files\Microsoft Visual Studio 8\Common7\IDE
C:\Program Files\Microsoft Visual Studio 8\VC\bin

VisualStudio にこだわる必要は無く、gcc など他の C/C++
プリプロセッサやコマンドでも全く同じように使えます。
Makefile の書式は make コマンドによって若干異なります。
ちょっと混用して gmake + cl だとこんな感じでしょうか。

# gmake の場合
PROFILE	= fx_4_0
FXINCLUDE = -I.

%.fxo: %.fx
	cl /E $< $(FXINCLUDE) > $*.tmp
	fxc /T$(PROFILE) /Fo$@ $*.tmp