Can I use semaphores or mutexes in Computer Shaders?

I’ve written a compute shader that generates mesh geometry. Right now its output is a buffer of point data representing triangles. In the current version, each face-vertex just uses the normal of its face which creates a faceted look. I want to be able to calculate smoothed normals for each vertex.

To do this, I need to find the smoothed normal of a vertex, which is the weighted average normal of all the faces that share that vertex. This requires me to uniquely identify each vertex. Luckily I do have a method that gives me an id for each vertex based on where it appears in a grid. However, I then need to map this id to an index. So I need some sort of hash table which allocates a new index when it encounters a new id or returns the already allocated id if it has already been encountered.

Basically, I need a multithread safe function int allocate_index(int hash) that will be fed inputs like
56, 42, 56, 10, 42, 42, 10, 13, 56, 10
and should return
0, 1, 0, 2, 1, 1, 2, 3, 0, 2
over several calls from several different threads. Basically I’m turning a sequence of hash ids into a buffer of indexes.

To do this, I need to lock my hash-to-index function. As far as I can tell, GLSL compute shaders only let you do atomic operations on single lines. I’m also not sure if the barrier() method could be used to create something like a mutex here.

Anyhow, this problem is also very similar to trying to create a compute shader function that calculates an index buffer for a set of unindexed triangles. Fairly straight forward to do on the CPU, but I’m having trouble trying to think of a way to do it in a compute shader.

Technically, you can create a mutex with atomicCompSwap().

In the context of your useage case, however, you are liable to bring the fabulous parallel processing power at your finger tips to its needs, and make it run slower than your CPU.

I suspect you will get far more satisfying results by re-imagining your problem from the ground up.

Yes, using semaphores or mutexes in computer shaders is not a common practice. Shaders are typically designed for parallel execution on GPU cores, where synchronization mechanisms like semaphores or mutexes can lead to performance bottlenecks. Shaders are better suited for data-parallel tasks without explicit synchronization. Instead, synchronization is often achieved through careful design of data dependencies and utilizing GPU-specific features like atomic operations. Applying traditional CPU synchronization mechanisms in shaders may hinder parallelism and compromise the benefits of GPU processing. It’s advisable to explore GPU-friendly synchronization methods tailored to the parallel nature of shader execution.