1
votes

I'm using a storage buffer to store a per pixel linked list from a fragment shader with fragment shader interlock. Everything works fine within a single draw call but I'm having trouble synchronizing the storage buffer between consecutive draw calls.

My understanding is that you can perform a pipeline barrier within a render pass for the fragment shader stage but only if it concerns an image bound to the framebuffer.

Do I have to call vkCmdEndRenderPass then vkCmdPipelineBarrier then vkCmdBeginRenderPass between each draw call or is there a better solution ?

1
When you do this synchronization, are you trying to ensure that all commands from prior draw calls have executed before any interlocked FS invocations from later draw calls have happened? - Nicol Bolas
Yes, that's the idea. I guess that the fact that I'm also writing to a color attachment already ensures synchronisation between color writes to the same pixel for two consecutive draw calls, but I don't know if that means that the fragment shader waits for the color write to complete before it begins execution or if the fragment shader is allowed to run and then blocks until the previous color write is done. If it's the latter then I guess I still need to ensure that all work is complete before starting the second draw call - Martin

1 Answers

0
votes

Synchronization in this case is expected to be done through the interlock operation itself. If your interlock doesn't respect primitive ordering, then you're not supposed to care about the primitive order, so no synchronization should be necessary. If your interlock does care about primitive ordering, then primitive ordering will be imposed by the interlock, so no other synchronization is necessary.

Primitive order defines that primitives generated by one draw call are ordered before all primitives from a later draw call. So if you're doing primitive order interlocking, then by definition critical sections from primitives in one rendering command will be ordered after those from a prior one.

So there's no need for barriers; what you want is primitive ordering.

Now, if you have one group of commands that only need critical sections and don't care about order, but a later group that themselves only need critical sections but need to come after the first, that is a contradiction. The second group does care about ordering, so they should use primitive ordering, not unordered.

Note that in order to make previous writes visible, you need the coherent qualifier. Ordering only guarantees ordering.