たまに触らなくなると,すぐに忘れるので思い出せるようにメモしておきます。
前提として
// コンピュートシェーダ側. [numthreads(dimX, dimY, dimZ)] void main(...) { ... }
// cpp側 pCmdList->Dispatch(A, B, C);
としておく。
グループが A * B * C 出来上がる
例えば,Dispatch(3, 2, 1)とした場合は, 3 * 2 * 1 = 6個のグループになる。
(0, 0, 0), (1, 0, 0), (2, 0, 0)
(1, 1, 0), (1, 1, 0), (2, 1, 0)
という感じ。
上記のuint3型6つのものがSV_GroupIDとなる。
コンピュートシェーダでは,これらのグループごとにスレッドが生成される。
つまり,dimX * dimY * dimZ のグループスレッドができあがある。
例えば,[numthreads(2, 2, 1)]とした場合は,
(0, 0, 0), (1, 0, 0)
(0, 1, 0), (1, 1, 0)
と4つのグループスレッドが出来上がある。
上記のuint3型4つのものがSV_GroupThreadIDとなる。
一番細かい単位は,実行するスレッド。つまりディスパッチされたスレッドで
グループIDとグループスレッドIDから決まるので24個のディスパッチスレッドIDが生成される。
例えば,
a : [0, A)
b : [0, B)
c : [0, C)
の半開区間を用いて、SV_GroupIDを(a, b, c)として表し,
x : [0, dimX)
y : [0, dimY)
z : [0, dimZ)
の半開区間を用いて,SV_GroupThreadIDを(x, y, z)として表したとする。
このとき,SV_DispatchThreadIDはuint3型であり、そのIDは
(a, b, c) * (dimX, dimY, dimZ) + (x, y, z) で表される。
グループ番号は,SV_GroupThreadIDとnumthredsから算出され
SV_GroupIndex = x + (A) * y + (A * B) * z;
で求まる。
例えば,
[numthreads(2, 2, 1)]とした場合は0~3までの4グループ
[numthreads(10, 8, 3)]とした場合は0~239までの240グループ
となる。
Microsoftのドキュメントに図が載っているので,以上を踏まえて読むと分かるはず。
https://docs.microsoft.com/ja-jp/windows/win32/direct3dhlsl/sv-dispatchthreadid