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 swiftlet encoder = writerQueue.makeCommandEncoder()!encodePass1(encoder)encodePass2(encoder)//do some operation to lock the MTLBufferencodePassPartiallyWritingToBuffer(encoder)encodePassCompletingWriteToBuffer(encoder)//do some operation to unlock the MTLBufferencodePass5()encoder.endEncoding()commandBuffer.commit()
And then on the render side, similarly
Code Block swiftlet encoder = rendererQueue.makeCommandEncoder()!draw1(encoder)draw2(encoder)//do some operation to lock the MTLBufferencodePassRenderingBuffer(encoder)//do some operation to unlock the MTLBufferdraw4(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?