1.工作组的概念
计算着色器如图所示:可以想象成多个长方体组成的一个大长方体,这些长方体被称为工作组。在计算着色器的shader中会用 如下语句指定小长方体的大小,小长方体即为局部工作组:
layout(local_size_x = 8, local_size_y = 8) in;
通过 glDispatchCompute 和 vkCmdDispatch调用计算着色器时,需要指定x,y,z三个维度的大小,即上面大长方体(全局工作组)的大小。
void vkCmdDispatch(VkCommandBuffer commandBuffer,
uint32_t groupCountX,
uint32_t groupCountY,
uint32_t groupCountZ);
void glDispatchCompute(GLuint num_groups_x,
GLuint num_groups_y,
GLuint num_groups_z);
2.一些内建变量
gl_LocalInvocationID:是赋值着色器运行的硬件单元在工作组中的索引,它是一个uvec3类型的变量,每个元素的取值范围分布从0到之前在着色器中声明的本地工作组大小local_size_x-1、local_size_y-1和local_size_z-1;
gl_WorkGroupSize:表示小长方体的大小,即为(local_size_x,local_size_y, local_size_z );
gl_NumWorkGroups:表示本地工作组的大小,即小长方体的个数
gl_WorkGroupID:表示小长方体在大长方体的的索引值,从0开始
gl_GlobalInvocationID:在全局工作组中,当前运行的硬件着色器所在位置,为一uvec3变量。
gl_LocalInvocationIndex:为gl_GlobalInvocationID的扁平化,即将3位坐标投影到一维上。
gl_GlobalInvocationID = gl_WorkGroupID * gl_WorkGroupSize + gl_LocalInvocationID;
gl_LocalInvocationIndex =
gl_LocalInvocationID.z * gl_WorkGroupSize.x * gl_WorkGroupSize.y +
gl_LocalInvocationID.y * gl_WorkGroupSize.x +
gl_LocalInvocationID.x;
3.计算着色器的输入与输出
计算着色器没有in out属性,所有的输入输出都需要依靠统一变量来实现。在vulkan中需要使用descriptor将输入输出的图片或者缓冲区与shader进行绑定。实际使用中,经常用到gl_GlobalInvocationID,该变量表示图片像素所在位置的索引。