OK, I had a good go at this today and got lots of things figured out - please ignore my above questions unless it looks like I've got something wildly wrong.
I am however stuck at locking a section of critical code inside a shader (the lock below is a 'per pixel' lock, and my app is drawing 100 square overlapping sprites. To start with, I've been trying to implement a simple depth buffer with a storage buffer).
I started out with a classic lazy spinlock, eg:
while !atomicCompareExchange(lock, 0, 1).exchanged { }
...critical stuff here...
atomicStore(lock, 0);
Found a few variations on this, my favourite being I think:
while atomicExchange(lock, 1) == 1 { }
However, this approach would just crash the graphics card, usually quite politely with a 'lost device' error - so I added a retry counter to prevent starvation, eg:
var retries = 10;
while !atomicCompareExchange(lock, 0, 1).exchanged {
if retries == 0 { return FAILURE }
retries -= 1;
}
This worked better, although no matter how high I set retries I couldn't get it to work perfectly. Even with a million retries, there were still noticeable errors, and it was running VERY slowly!
So I tried something 'ticket' based, eg:
let ticket = atomicAdd(ticket, 1);
while atomicLoad(turn) != ticket { }
...critical stuff here...
atomicAdd(turn, 1);
I thought I had it that time, but this just locks up too!
It seems like the 'unlock' in all cases is somehow occasionally 'getting lost', ie: other shader instances can't see the unlocked value perhaps similar to non-atomic c++ vars? Either that or the 'busy loops' when locking are somehow crashing?
Any help, as always, would be greatly appreciated!
Bye,
Mark