Synchronizing MTLBuffer in a reader/writer pattern.

I have 2 MTLCommandQueue on 1 device. Each queue involve several passes and they run at different frequencies. One queue ("the writer") runs more slowly and in some stages writes data to a buffer, the other queue ("the renderer") has a pass that renders this data.

It is ok (and expected, due to frequency mismatch) that the renderer will render several frames with the same data in the buffer. What isn't ok is rendering a buffer that is in the process of being written. In psueudocode

Code Block swift
let encoder = writerQueue.makeCommandEncoder()!
encodePass1(encoder)
encodePass2(encoder)
//do some operation to lock the MTLBuffer
encodePassPartiallyWritingToBuffer(encoder)
encodePassCompletingWriteToBuffer(encoder)
//do some operation to unlock the MTLBuffer
encodePass5()
encoder.endEncoding()
commandBuffer.commit()


And then on the render side, similarly

Code Block swift
let encoder = rendererQueue.makeCommandEncoder()!
draw1(encoder)
draw2(encoder)
//do some operation to lock the MTLBuffer
encodePassRenderingBuffer(encoder)
//do some operation to unlock the MTLBuffer
draw4(encoder)
encoder.endEncoding()
commandBuffer.commit()


Using MTLFence to synchronize would require a single command queue, and I think a wait/signal pattern would force these into running at the same frequency with 1 read : 1 write, which isn't what I want.

I could use encodeSignalEvent(event, 1) to indicate we are done writing the buffer, but I'm not sure how to use encodeWaitForEvent(event, ?) to limit execution to either the writer or the reader. There doesn't seem to be "semaphore wait" style operator.

What's the "right" way to synchronize this?
Synchronizing MTLBuffer in a reader/writer pattern.
 
 
Q