I've got myself somewhat confused regards required memory barriers in a compute shader where invocations within the same dispatch access a list stored in a SSBO.
I have the SSBO declared coherent and I protected the list with an atomic exchanged based spinlock (taking care to lock only in the lead thread for a warp).
If I do the following in order in the shader:
1) Acquire lock
2) Modify list items and list item count
3) Release lock
Where do I need a memory barrier? I think at best I only need a memoryBarrierBuffer() between (2) & (3)?
The atomic operation in (3) I believe does not guarantee that the changes made in (2) have occurred from the point of other invocations within the dispatch right? So by placing the memoryBarrierBuffer() between (2) & (3) it should ensure that the other invocations within the same dispatch see the buffers changes correctly after they acquire the lock?
Also if I call memoryBarrierBuffer() only in the lead warp thread I assume that's not good?
So what I should really have is maybe(?) something like:
if(leadWarpThread) AcquireLock();
ModifyBufferListItemsAndCount();
memoryBarrierBuffer();
if(leadWarpThread) ReleaseLock();