Compute shaders require a work group count when being dispatched. This has to be supplied in 3 dimensions. The same goes for the work group size specified in the compute shader itself.
Function to dispatch a compute shader in OpenGl: glDispatchCompute
.
Question:
There are computations that are inherently 2 or 3 dimensional. And there are computations that are inherently 1 dimensional. Someone is going to be inconvenienced. Either the multidimensional users will have to take a 1D index and turn it into 2/3D indices, or the single dimensional users may have to take a 2/3D index and compact it to 1D.
Of course, note the difference between "will" and "may". Single dimension users only need to recognize the Y or Z dimensions if the limitations of the implementation on the X dimension of the dispatch command is too small to run enough invocations. Given that all implementations must provide at least 65535 work groups for each dimension, that covers a lot of ground.
So while the multidimensional nature of compute operations may inconvenience single-dimension work, there's plenty of single-dimension work that doesn't get inconvenienced. So "may" is preferable to "will".
how do the 3 dimensions result in an actual number?
Assuming you need to use the Y and Z corrdinates in your single-dimensional compute operation at all (and you rarely do), there are numerous ways to do it. They only vary with regard to the order of the different dimensions. The following way uses the gl_LocalInvocationIndex
ordering.
If you need to get an index for a particular work group, that's easy enough:
uint WorkGroupIndex = dot(gl_WorkGroupID, uvec3(1, gl_NumWorkGroups.x, gl_NumWorkGroups.x * gl_NumWorkGroups.y));
If you need to get an index for each invocation within the entire dispatch call, take WorkGroupIndex
above and do this:
uint UniqueIndex = (WorkGroupIndex * gl_WorkGroupSize.x * gl_WorkGroupSize.y * gl_WorkGroupSize.z) + gl_LocalInvocationIndex;