これまで RADEON は PixelShader の slot 数にわりと小さ目の上限があって、
シェーダーが巨大化すると全部入りきらなくなったり、multi pass に
分けなければならなかったりと結構対応に困ることがありました。
例えば ShaderModel2.0 は 1.0 に比べると飛躍的な拡張が行われましたが、
ps2.0 の命令数は演算で 64slot、texture 命令込みで 96slot
しかありません。
ps1.0 の 8命令+4命令 (1.4 で 8+6) に比べるとかなり大きいものの、
従来1命令で演算できた _bx2 が無くなっていて、ps1.0 よりも余分に
命令数を消費することがあります。
swizzle も VertexShader ほど自由度がなく、出力レジスタが固定で
最後に代入や alpha 合成が入ったりして意外に制限になったりします。
Xbox1 だと ps1 だけど xmma/xdd 等の複合命令があって 1slot に 2演算
畳み込めたり、ファイナルコンバイナでも演算を追加できたり、
alpha に別演算を入れることで実質 2~3倍程度の演算ができたことを
考えると、これが思ったほど余裕がありません。
per pixel lighting やら Shadow Mapping とかやりだすと
あっという間に 64+32 slot 使い切ってしまいます。
shader には loop 命令があるので、本当は命令 slot の上限とは関係なく
もっと長い shader 命令を走らせることが可能です。
ところが ps2.0~ps3.0 の場合 constan register のアクセスに index
参照使うことができないので、異なる constant register を変数参照する
場合は全部ループ展開されてしまいます。
この 96命令の ps2.0 は、RADEON で 9700→X800 とかなり長く続いたため、
ほとんど制限の無い GeForce6~7 と比べて少々厄介でした。
GeForce6 は ShaderModel2.x に見切りをつけて、RADEON よりも 1世代先に
ShaderModel3.0 に移行してしまいます。
・RADEON 9700 (sm2) – GeForceFX5800 (sm2x)
・RADEON X800 (sm2) – GeForce6800 (sm3)
・RADEON X1800 (sm3) – GeForce7800 (sm3)
・RADEON HD2900 (sm4) – GeForce8800 (sm4)
ps3.0 になると上限は最小 512命令に拡張されます。
GeForce6800~ はほぼ上限無しの 512より長い shader を走らせることが
可能でした。
RADEON X1800 でやっと ShaderModel3.0 対応になりますが、PixelShader は
512 命令が上限です。96命令に比べると大幅に増えたものの、GeForce6~
とかでべらぼうに長い shader に慣れてしまうと、これが 512命令の上限にも
あっさり引っかかってしまいます。
特に Shadow 関連のシェーダーは、たとえ事前演算でも PCF で巨大に
なりがちです。
さらに視線交差を求めるレリーフマップ等の機能をまじめにシーン内の
一般のシェーダーに組み込むと、あっという間に slot を埋め尽くします。
先日登場した RADEON HD 2900XT は、GeForce8800 同様待望の
ShaderModel4.0 対応です。
さらに制限も減っており、機能も大幅に拡張されています。
まだ ShaderModel3.0 用シェーダーしか試していませんが、GeForce 向けに
作った 512 命令を超える巨大な Shader もすんなり動作しました。
不思議なことに NVIDIA ShadowMap もそのままで動作しています。
1世代ずれなかったおかげか、まだまだ ShaderModel4.0 を使い切った
shader も特に無いせいかもしれませんが、、、
とりあえず GeForce6~ のように制限なく ShaderModel3.0 が走る
RADEON が登場したわけです。
なんだか同じ土俵に来たな、という感じがします。
ShaderModel4.0 側の機能は実はまださっぱり試していません。
これからです。
PixelShader でも index 付きループにたたみこめるし、
必要なら広大な buffer を任意にアクセスできるし、
メモリアクセスに sampler を使わなくてもいいし、
ShaderModel4.0 では速度以外の制限がほとんどなくなった気がします。