- if (b->shader->options->lower_cs_local_id_from_index) {
- /* We lower gl_LocalInvocationID from gl_LocalInvocationIndex based
- * on this formula:
- *
- * gl_LocalInvocationID.x =
- * gl_LocalInvocationIndex % gl_WorkGroupSize.x;
- * gl_LocalInvocationID.y =
- * (gl_LocalInvocationIndex / gl_WorkGroupSize.x) %
- * gl_WorkGroupSize.y;
- * gl_LocalInvocationID.z =
- * (gl_LocalInvocationIndex /
- * (gl_WorkGroupSize.x * gl_WorkGroupSize.y)) %
- * gl_WorkGroupSize.z;
- *
- * However, the final % gl_WorkGroupSize.z does nothing unless we
- * accidentally end up with a gl_LocalInvocationIndex that is too
- * large so it can safely be omitted.
- */
- nir_ssa_def *local_index = nir_load_local_invocation_index(b);
- nir_ssa_def *local_size = build_local_group_size(b);
-
- nir_ssa_def *id_x, *id_y, *id_z;
- id_x = nir_umod(b, local_index,
- nir_channel(b, local_size, 0));
- id_y = nir_umod(b, nir_udiv(b, local_index,
- nir_channel(b, local_size, 0)),
- nir_channel(b, local_size, 1));
- id_z = nir_udiv(b, local_index,
- nir_imul(b, nir_channel(b, local_size, 0),
- nir_channel(b, local_size, 1)));
- return nir_vec3(b, id_x, id_y, id_z);
- } else {
- return nir_load_local_invocation_id(b);
- }
+ nir_ssa_def *group_size = nir_load_local_group_size(b);
+ nir_ssa_def *num_work_groups = nir_load_num_work_groups(b);
+ return nir_imul(b, nir_u2u(b, group_size, bit_size),
+ nir_u2u(b, num_work_groups, bit_size));