How to render to texture, to save as image?

Hi,


I'd like to save the result of Metal rendering as an image file. I just tried something, and it worked, but I probably got lucky.

In response to a tap on a 'save image' button:


1. In the next call to MTKView delegate's `draw(in:)`, I keep a reference to the MTLTexture from my MTKView's `currentRenderPassDescriptor.colorAttachments[0].texture`

2. `commandBuffer.addCompletionHandler { _ in finishSave() }

3. In `finishSave()` I convert the MTLTexture from step 1 to a CIImage -> CGImage -> PNG file.


Should I be creating a second color attachment texture instead, and writing to that second texture in my fragment shader? Possible problems with above... maybe that texture is in the process of being overwritten when I try to save it? Or maybe it's not always readable by CPU?


thanks,

Rob

Yes. You're probably getting lucky 🙂. If you perform this in the completionHandler you could be reading back the contents of the drawabl;e texture after another frame has begun rendering to it (so you could get some of that frame's renderings)


You can call MTLCommandBuffer.waitUntilCompleted and then perform the readback and save. This has the side affect of forcing a CPU-GPU Sync Point.

You can also encpde blit from the drawable to a texture which you will read from (instead of reading directly from the drawal.e You can avoid unecessary sync points by double or triple buffering the textures you read from, perform the read in a completion handler and signal a your frame pacing semapore after that read. This solution is generally only necessary if you want to save a series of animating frames.

How to render to texture, to save as image?
 
 
Q