1.系统会为每个线程组都分配一个ID,这个ID称为线程组ID ( group ID),其系统值的语义为 SV_GroupID。如果Gx x Gy x Gz:为所分派线程组的个数,则组ID的范围为(0, 0, 0)至(Gx-1,Gy-1,Gz-1)。
2.在线程组中,每个线程都被指定了一个组内的唯一 ID。若线程组的规模为X x Y x Z,则组内线程ID ( group thread ID )的范围实为(0, 0, 0)到(X-1, Y-1, Z-1)。组内线程ID系统值的语义为 SV_GroupThreadID。
3.调用一次Dispatch函数便会分派一个线程组网格。调度线程ID ( dispatch thread ID,分派线程ID )是Dispatch调用为线程所生成的唯一标识(相对于所有的线程而言)。换句话说,组内线程ID是线程相对于所在线程组的唯一标识(局部),而调度线程ID则是Dispatch调用为线程指定的相对于所有线程组中全部线程的唯一识别信息(全局)。今设线程组的规模为 ThreadGroupSize = (X,Y,Z),那么我们便可以根据线程组ID与组内线程ID,通过以下方法推算出调度线程ID:
dispatchThreadID.xyz = groupID.xyz * ThreadGroupSize.xyz +groupThreadlD.xyz;
调度线程ID的系统值语义为SV_DispatchThreadIDo如果分派了一个大小为3x2的线程组, 且其中每个线程组的规模为10x10,则共分发了 600个线程,而且所调度线程的ID范围为(0, 0, 0) 至(29, 19,0)。
4.通过Direct3D的系统值SV_GroupIndex便可以指定组内线程ID的线性索引,它的换算方法为:
grouplndex = groupThreadID.z*ThreadGroupSize.x*ThreadGroupSize.y +groupThreadID.y*ThreadGroupSize.x + groupThreadID.x;
至于坐标的索引顺序,其第一个坐标指出的是线程在X方向上的位置(或称“列”),第二 个坐标则是线程在y方向上的位置(或称“行”)。这个顺序与普通矩阵的记法刚好相反, 即表示矩阵中第 i 行、第 j 列的那一个元素。
为什么需要给出这些线程ID值呢?这是因为计算着色器通常会以若干数据结构作为输入,再将计 算结果输出到另一些数据结构之中。而我们就可以利用这些线程ID值来对这些数据结构进行索引:
Texture2D glnputA;
Texture2D glnputB;
RWTexture2D<float4> gOutput;
[numthreads(16, 16, 1)]
void CS(int3 dispatchThreadID : SV_DispatchThreadID)
(
//通过调度线程工D来索引输入与输出的纹理
gOutput[dispatchThreadID.xy] =glnputA[dispatchThreadID.xy] +glnputB[dispatchThreadID.xy];
)
利用SV_GroupThreadID系统值即可极为便利地对线程的本地存储器进行索引。