Flush Metal rendering when program is paused in LLDB?

I watched a WWDC talk on LLDB, and they showed a nice trick of calling CATransaction.flush() from the debugger, to push changes to a UIView to the screen, even when the program was paused. Is there is a similar thing we can do with Metal?

I'm using MTKView, but I can change to a lower level if that's required. The MTKView is paused, so I'm using setNeedsDisplay. As usual, I implement the draw delegate method to encode and commit a command buffer.

If I do this from LLDB:

metalView.setNeedsDisplay()
CATransaction.flush()

I can see that causes my draw function to run, but nothing shows up on screen.

Is there something else we can do to flush those metal commands to the GPU and see them on screen while stepping through the program with the debugger?

Answered by in 695029022

Hi rnikander,

Metal's command submission model is fundamentally different from how CoreAnimation schedules its work. This makes it a bit tricker to achieve something similar to the effect you are describing.

The closest approach we can recommend is:

  1. Commit your command buffer containing the work to visualize.
  2. Insert a waitUntilCompleted after the commit call.
  3. Insert a breakpoint after waitUntilCompleted.

This will effectively have the effect of sending the work to the GPU and waiting for all of it to be completed. At this point, the result of your GPU work would likely be visible.

Note, however, because the presentation model is asynchronous, there is a chance that when the debugger stops the process, that the contents are still not reflected on the drawable. If this is your case, you can try adding a call to sleep() with a small value right after the waitUntilCompleted call, just to ensure that the drawable's presentation process has completed as well.

Once you have finished debugging, we recommend removing this scaffolding to help prevent GPU bubbles.

Accepted Answer

Hi rnikander,

Metal's command submission model is fundamentally different from how CoreAnimation schedules its work. This makes it a bit tricker to achieve something similar to the effect you are describing.

The closest approach we can recommend is:

  1. Commit your command buffer containing the work to visualize.
  2. Insert a waitUntilCompleted after the commit call.
  3. Insert a breakpoint after waitUntilCompleted.

This will effectively have the effect of sending the work to the GPU and waiting for all of it to be completed. At this point, the result of your GPU work would likely be visible.

Note, however, because the presentation model is asynchronous, there is a chance that when the debugger stops the process, that the contents are still not reflected on the drawable. If this is your case, you can try adding a call to sleep() with a small value right after the waitUntilCompleted call, just to ensure that the drawable's presentation process has completed as well.

Once you have finished debugging, we recommend removing this scaffolding to help prevent GPU bubbles.

Flush Metal rendering when program is paused in LLDB?
 
 
Q