Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the proper method to use the results of one compute shader in the next compute shader

Suppose I dispatch two compute shaders A and B in metal. I don't want B to run until after A has completed. At the moment I am encoding each shader in their own command buffer and committing like so:

commandBufferA.commit()
commandBufferA.waitUntilCompleted()
commandBufferB.commit()

Is this the proper technique?

like image 200
gloo Avatar asked Sep 19 '25 01:09

gloo


1 Answers

Calling waitUntilCompleted() on a command buffer is useful if you need to use the results of a kernel back on the CPU, but is unnecessary and inefficient if your intent is simply to use the result of a compute command (dispatch) in a subsequent compute command. If there is a data dependency between compute commands, the results written by the former are guaranteed to be visible to the latter, even within a single command buffer. So, you could structure it something like this:

let commandBuffer = commandQueue.makeCommandBuffer()
let commandEncoder = commandBuffer.makeComputeCommandEncoder()

commandEncoder.setComputePipelineState(pipelineStateA)
commandEncoder.setTexture(inputTexture, at: 0)
commandEncoder.setTexture(intermediateTexture, at: 1)
commandEncoder.dispatchThreadgroups(threadgroupCount, 
                                    threadsPerThreadgroup: threadgroupSize)

commandEncoder.setComputePipelineState(pipelineStateB)
commandEncoder.setTexture(intermediateTexture, at: 0)
commandEncoder.setTexture(outputTexture, at: 1)
commandEncoder.dispatchThreadgroups(threadgroupCount, 
                                    threadsPerThreadgroup: threadgroupSize)

commandEncoder.endEncoding()
commandBuffer.commit()

commandBuffer.waitUntilCompleted() // optional; only if you need to read the result on the CPU
like image 84
warrenm Avatar answered Sep 23 '25 05:09

warrenm