I recently implemented a water simulation in Metal using a ping pong buffer and compute shaders. It is working well but I was just wondering what the cost of swapping the textures several times a frame would be and whether this could be improved by using the Blit Command Encoder?
Here is a sample of the code:
let computeEncoder = commandBuffer.makeComputeCommandEncoder()!
computeEncoder.setComputePipelineState(pipelineState)
computeEncoder.setTexture(textureA, index: 0)
computeEncoder.setTexture(textureB, index: 1)
var width = pipelineState.threadExecutionWidth
var height = pipelineState.maxTotalThreadsPerThreadgroup / width
let threadsPerThreadGroup = MTLSizeMake(width, height, 1)
width = Int(textureA.width)
height = Int(textureA.height)
let threadsPerGrid = MTLSizeMake(width, height, 1)
computeEncoder.dispatchThreads(threadsPerGrid, threadsPerThreadgroup: threadsPerThreadGroup)
computeEncoder.endEncoding()
swap(&textureA, &textureB)
This method works nicely:
I haven't done any tests to see if this improves performance although I assume it does. Will post results once I have!