[DirectX12] Compute Shader の Thread とシステム値
Compute Shader で起動するスレッド数は、コマンドバッファに記録する Dispatch() の引数と、シェーダー内に記述する numthreads の Thread Group 数によって決まる。Dispatch() の引数は、アプリ実行時に動的に変更することが可能だが、numthreads への指定はシェーダーコンパイル時に決まるため、こちらは固定の数になる。
Compute Shader で起動したスレッドは、後述するシステムセマンティックの ID によって、シェーダー内で一意の ID を取得することが出来る。その ID によって処理やデータを分岐して処理する。
Dispatch
実行する Thread Group の数を X, Y, Z で指定する。例えば 1,1,1 で Dispatch した場合は、1つの Thread Group が起動する。
numthreads
コンピュートシェーダーが Dispatch された(起動した)ときの、一つの Thread Group 内で起動するスレッド数を numthreads で指定する。シェーダーコンパイル時に値が決まるため、動的な変更はできない。
System Value
Compute Shader で取得できるシステムセマンティックは4つある。
uint3 gid | SV_GroupID |
uint3 dtid | SV_DispatchThreadID |
uint3 gtid | SV_GroupThreadID |
uint gi | SV_GroupIndex |
SV_GroupID (uint3)
スレッドが、どこの Thread Group で起動しているかを取得できる。Dispatch に指定した値によって変化する。
例えば、Dispatch(2,1,1) を呼び出すと、2*1*1 = 2 Thread Group が起動して、SV_GroupID の値としては(0,0,0)と(1,0,0)という値がスレッド内で得られる。
SV_GroupThreadID (uint3)
スレッドが、Thread Group 内のどの Thread かを表す。numthread に指定した値によって変化する。
例えば、numthreads(3,2,1) が指定された場合は 3*2*1 = 6 Thread 起動する。SV_GroupThreadID としては (0-2, 0-1, 0) 範囲の値が取得できる。
SV_DispatchThreadID (uint3)
Dispatch と numthread の組み合わせによって変化する。
SV_GroupIndex (uint)
起動例 1
Distach(4, 4, 4) / numthread[1,1,1]
SV_GroupID には (0,0,0)~(3,3,3) の値が来る。
SV_GroupID から、一意な Index を取得したい場合は、下記で変換できる。
// index = (gid.z * dispatch_y * dispatch_x) + (gid.y * dispatch_x) + gid.z
uint index = (gid.z * 4 * 4) + (gid.y * 4) + gid.z;
index は 0~63 までの値になる。