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
And then on the render side, similarly
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?
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?