shadermodel
シェーダーの世代ごとの違い
DirectX8
ShaderModel 1
VertexShader 1.0~1.1
32bit 浮動少数演算
96 constants
index レジスタあり
12 temp registers
128命令
PixelShader 1.0~1.3
9~12bit程度の固定少数演算。GPU依存
演算範囲は -1.0~+1.0 (GPU依存)
4 テクスチャ命令
8 演算命令
8 constants
2 temp reigisters
swizzle (.xyzw .w .z )
PixelShader 1.4
DirectX9
ShaderModel2.0
VertexShader 2.0
32bit 浮動少数演算
256 constants
12~ temp
1024命令実行
VertexShader 2.0a
nVIDIA 拡張
65536命令実行
temp 16
Dynamic Flow Control
ATI 拡張
PixelShader 2.0
ATI 24bit 浮動少数演算
nVIDIA 16 or 32bit 浮動少数演算
32 constants
12 temp registers
32テクスチャ命令 + 64演算命令 = 96命令slot
8テクスチャ、サンプリング 16
MRT x4
swizzle 制限 (.x .y .z .w .xyzw .yzxw .zxyw .wzyx )
PixelShader 2.0a
nVIDIA 拡張
512命令 slot
1024テクスチャ命令実行
1024演算命令実行
temp 64
16 texture
依存テクスチャ制限なし
動的分岐
自由な Swizzle (制限なし)
MRT x1
PixelShader 2.0b
ShaderModel3.0
VertexShader 3.0
32bit 浮動少数演算
256 constants
32 temp
544命令 slot(NVIDIA)
1024命令 slot(ATI)
65535命令実行
動的分岐
Texture 対応 (nVIDIAのみ)
Geometry Instancing
PixelShader 3.0
DirectX10(Direct3D10) / DirectX10.1(Direct3D10.1)
ShaderModel 4
ShaderModel 4.0 (Vertex/Geometry/Pixel)
4096 constants × 16
32bit 浮動少数演算 + 32bit 整数演算
128 ShaderResources(Texture)
16 samplers
MRT x8
補間レジスタ = 任意の 16個。補間手段を指定可能。整数を渡す場合は補間無し限定。
ShaderModel 4.1 (Vertex/Geometry/Pixel)
4096 constants × 16
32bit 浮動少数演算 + 32bit 整数演算
128 ShaderResources(Texture)
16 samplers
MRT x8
Gather4 sampler, CubeArray sampler 追加
補間レジスタ = 任意の 32個。補間手段を指定可能。整数を渡す場合は補間無し限定。
DirectX11 (Direct3D11) / 11.1 / 11.2
ShaderModel 5
シェーダーステージの増加 (Hull, Domain)
テセレータの追加 (Hull → Tessellator → Domain)
シェーダーから任意のデータを書き込み可能になった (Unordered Access)
シェーダー内のポインタ分岐 (Setup 時に選択) (Dynamic Shader Linkage)
Vertex Pipe, Rasterizer を通らないシェーダー実行 (Compute Shader)
共有メモリへのデータロード
ShaderModel 5.0 (Vertex / Hull / Domain / Geometry / Pixel / Compute )
DirectX12 (Direct3D12)
ShaderModel 5.1 (Vertex / Hull / Domain / Geometry / Pixel / Compute )
Rasterizer Order Views (ROV) 対応。同一パスで同じメモリの読み書きが実行順通りになる。
Steancil Reference Value の出力
UAV で access 可能な型の拡張
Conservative rasterization
ShaderModel 6
ShaderModel 6.0 (Vertex / Hull / Domain / Geometry / Pixel / Compute )
ShaderModel 6.1 (Vertex / Hull / Domain / Geometry / Pixel / Compute )
ShaderModel 6.2 (Vertex / Hull / Domain / Geometry / Pixel / Compute )
補足説明
命令slot と実行命令数
命令slot数
プログラムの最大長、何ステップまでのプログラムを格納できるかを表します。
Loop 命令が追加されるまでは、slot 数 = 最大実行可能な命令数でした。
ShaderModel 1.0~2.0/2.0b までは Texture 命令とカラー演算命令が分かれていました。テクスチャサンプリングが専用ユニットで実行され、時間がかかる処理だったこと。また ShaderModel1 では Color は 8~9bit 整数演算で済むのに対して、Texcoord は 12bit 程度 (4096×4096 dot) 必要で演算精度が異なっていることが理由として考えられます。
実行命令数
静的/動的 loop 命令が登場してから、実行可能命令数という概念が登場しました。
loop命令を使うことで一見無限数の命令実行が可能なように見えますが、実際は上限があるということです。
命令 slot 数よりも実行可能命令数の方が通常は大きいので、GPU 性能を発表する場合にメーカーはこちらの数値を大きく取り上げることがあります。
ところが実際に走らせることが出来る shader のサイズは、slot数によって上限が決まってしまうので、結局宣伝された性能を発揮できることは多くありません。
特に 3.0 までの PixelShader は、constant レジスタの参照に loop index を使うことが出来ないため、constant 参照を行う場合は必ずループ展開されます。テクスチャのサンプリングだけなら loop 可能です。
また loop は実行性能に影響を与えるので、速度を考えると loop 展開した方が有利です。
ペアリングと 0slot 命令
演算命令が .xyz と .w に分かれている場合、異なる演算命令でもペアリングされて 1 slot に融合できることがあります。
当初の Shader Unit が VLIW に近い構造をしており、存在する複数の演算 Unit 分の命令を1命令に格納することが出来たためです。
この場合融合された命令は 0slot 命令となり、実行サイクルも slot 数も消費しません。
通常アセンブラによって自動で最適化されますが、自分で + 記号を使って明示的に融合命令を記述することも出来ました。
また PixelShader 1.x では、各命令ごとに、またはオペランドごとに clamp や 2倍化、4倍化、符号反転、1から減算、0~1.0 を -1.0~1.0 にマッピング(_bx2)、等の付加機能をノーコストで追加できました。
PixelShader 1.0~1.3 がわずか 8slot しかないのに複雑な処理が出来たのは、このような slot も cycle も食わない特殊な機能があったからです。
temp レジスタ
v0/v1, t0~t3 等の入力レジスタも書き換え可能で、実際は temp レジスタ代わりに使えることがあります。そのためspec上の上限よりもプログラミング時の制約は少なくなります。
ShaderModel 2.0 以降は temp レジスタの数がシェーダーの実行速度に対して多大なインパクトを与えるようになったため、HLSL コンパイラなどは上限までレジスタを使うことがありません。
ShaderModel 1.x では演算可能な数値範囲とレジスタのサイズが異なっており、temp レジスタに代入するだけで精度が落ちることがありました。
texture 数
1つのシェーダーにパラメータとして渡せるテクスチャ数と、1つのシェーダーが一度に読み込めるテクスチャ数は異なっています。
例えば PixelShader 2.0 では 8枚のテクスチャを一度に設定できますが、同じテクスチャを uv を変えて何度も読み込めるので最大 16回サンプリングすることが出来ます。
PixelShader 2.0a 以降は、サンプリング回数に制限がなくなりました。1枚のテクスチャを何回も何回も読み出すことが出来ます。
つまり、下記3つの「利用可能テクスチャ数」が存在しています。
一度にShaderに渡せる Texture 数 (APIで渡せる個数)
Shader がサンプリングできる回数 (uvを演算で求めれば何回でもいけることが多い)
Sampler State の数
ShaderModel 1.x では 1~3 は同値でした。
ShaderModel 2~3 では 1/3 と 2 が分離されました。
ShaderModel 4.0 では 1, 2, 3 すべて別の概念として分離されました。
ハードの制約と Direct3D 仕様の制約
shadermodel.txt · 最終更新: 2018/06/20 23:35 by oga