日別アーカイブ: 2007年7月6日

D3D10/DX10 シェーダーと64bit浮動少数

GPU も G9x (GeForce8xの次世代) では float64 にも対応するのでは
ないか、との話です。
GPUサーバーの時代を開くNVIDIAの「Tesla」
もともと ShaderModel1.0 の PixelShader は 9~12bit 整数演算で、
D3D10 の表記でいえば SNORM に相当します。固定少数値
-1.0~+1.0 にMapされていたわけです。
VertexShader は 32bit float でした。

ShaderModel2.0 になって ATI(AMD) RADEON は 9700 シリーズで 24bit float を
導入し、これが X800 系まで続きます。
ShaderModel2.0 で出遅れた nVIDIA の方は GeForceFX で 32bit float を
先行実現しましたが、実際は 16bit half float とのハイブリッドで、
half を積極的に使わないとパフォーマンスに影響が生じるものでした。

ShaderModel3.0 になると GeForce6800~ も RADEON X1800~ も、頂点
同様の 32bit 浮動少数精度を実現します。

ここまで来てようやく PixelShader の演算精度が VertexShader に肩を
並べることができたわけで、D3D10 ShaderModel4.0 世代のユニファイド
シェーダーへ向けて準備が整ったといえます。

ちなみに ATI(AMD) は X1800 より前にも、Xbox360 向け GPU にて
先行して 32bit 浮動少数精度の PixelShader、ユニファイドシェーダー、
ストリームアウトプットなどの機能を実現していました。

さて ShaderModel4.0 で IEEE754 単精度に対応したら次は倍精度 64bit
というわけです。この流れは実は DirectX SDK の D3D10 のマニュアルを
じっくり見ているとわかります。

なにせ HLSL のリファレンスを開くと、一番最初が変数型の説明で、
その最初のページに dobule 型がしっかりと記載されています。
はじめて ShaderModel4.0 のマニュアルを読み進めていたときに、
もう倍精度も対応しているのかと驚きました。
でも試したら使えませんでした。

ID3D10EffectType や ID3D10ShaderReflectionType 等が使っている
D3D10_SHADER_VARIABLE_TYPE を見ても、32bit INT と 32bit FLOAT
しかありません。本当に 64bit float に対応するなら D3D の core
を含めてまた大幅な更新が必要となりそうです。

ちなみに cbuffer 等で double 宣言を使ったどうなるか。
実はコンパイルはきちんと通ります。でも Reflection を取ってみると
ただの 32bit の float になっていました。
ShaderModel4.0 においては half も float 扱いとなるようです。