Figment.so
Mac hostingWebsite hostingGuidesHow to usePricing

Debug Metal Shaders Remotely on a Rented Mac

If you are chasing a vertex offset mistake or a fragment output that looks wrong, Xcode's GPU Frame Capture and shader debugger are the fastest way to find it. Both tools live in the Xcode GUI on macOS, as described in Apple's Metal debugger documentation. This guide shows how to set them up on a rented M-series Mac reached over screen sharing, so you can step through Metal Shading Language (MSL) without buying Apple hardware.

Direct recommendation: request a Figment M-series Mac from $95/month for Metal shader debugging. The $29 virtual Intel macOS plan runs on Linux/KVM with no GPU acceleration, so there is no Apple GPU for Metal to attach to on that plan. The shader debugger and GPU Timeline view are built against Apple's tile-based GPUs, which in practice means Apple silicon. The physical M-series plan is request-based; the exact chip, RAM, and disk are confirmed in the quote, and current availability is gathered as part of the request. If you also want backups, CI setup, monitoring, and 30 minutes of monthly support bundled around one M-series Mac, the Managed Build Mac is $249/month. Start a request at /mac-hosting/start.

Why Metal Shader Debugging Needs an Apple GPU

GPU Frame Capture records draw calls from a live MTLDevice. The $29 virtual Intel macOS plan is an Intel macOS environment on Linux/KVM with no GPU acceleration or audio, so there is no device for Metal to capture from, and no Apple GPU for the shader debugger to simulate thread execution against. The shader debugger reads MSL source and Apple GPU state; it is not designed for third-party GPUs. Choose an M-series rental when you need to run and debug Metal, and confirm the specific chip in your quote if a particular GPU family matters.

Intel Xcode 26 or earlier can still compile and sign Metal code for other targets, and the virtual Intel macOS plan is useful for building, signing, and running non-GPU parts of your toolchain. Commands run in its own desktop terminal through the browser console, and the CI pieces of your pipeline can reach out from it to your services. For live Metal debugging, step across to an M-series Mac.

Pre-Capture Setup Checklist

Confirm each of these before you hit the capture button. The details come from Apple's guide to capturing a Metal workload in Xcode.

ItemWhere to set itNotes
GPU Frame Capture enabledScheme → Run → Options → GPU Frame Capture: MetalRequired for the capture button to appear
Metal API ValidationScheme → Run → Diagnostics → Metal API Validation: EnabledSurfaces API misuse before you capture
Shader debug infoBuild Settings → MTL_ENABLE_DEBUG_INFO: Yes, with source map (Debug)Needed for line-level shader stepping
Capture scope (programmatic)MTLCaptureDescriptor.captureObject = device or command queueNarrow the capture to one queue when you can
GPU TimelineApple GPU onlyNot available on third-party GPUs

Keep MTL_ENABLE_DEBUG_INFO off for Release builds so symbols do not ship with your binary. If you need to debug an optimised build, archive the matching .metallibsym separately and keep it with your dSYMs. Exact menu wording and build-setting labels move between Xcode versions; verify against the Xcode you have installed, since Intel Macs are limited to Xcode 26 or earlier per Apple's porting guide.

Connecting to a Rented M-Series Mac

Figment M-series Macs are reached through the browser console or a VNC client pointed at the machine's screen-sharing address. Use a VNC client with at least 24-bit colour so the debugger's heatmaps, buffer previews, and attachment thumbnails render correctly.

  1. Open the machine in the Figment dashboard and copy the screen-sharing address.
  2. Connect from your workstation (macOS Screen Sharing, RealVNC Viewer, or Remmina on Linux all work). Set colour depth to at least 24-bit.
  3. On the remote Mac, sign in to Xcode with your Apple ID and open the project.
  4. If the project lives in a remote repository, clone it from the remote Mac's terminal rather than copying a working tree through the viewer.

Network latency shows up as paint delay in the viewer, not as debugger inaccuracy. The captured frame is replayed locally on the Mac, so shader stepping does not depend on VNC round-trip time.

Triggering a Capture

With the scheme configured, run the app on the M-series Mac. The Metal capture button appears in the Xcode debug bar once a Metal command queue is detected. Press it and Xcode records the next frame and opens the GPU Frame Capture view.

To trigger a capture programmatically from a specific frame in your renderer:

#if DEBUG
import Metal

func captureOneFrame(commandQueue: MTLCommandQueue) {
    let manager = MTLCaptureManager.shared()
    let descriptor = MTLCaptureDescriptor()
    descriptor.captureObject = commandQueue
    descriptor.destination = .developerTools

    guard manager.supportsDestination(.developerTools) else { return }
    do {
        try manager.startCapture(with: descriptor)
    } catch {
        NSLog("Metal capture failed: \(error)")
    }
}
#endif

Call MTLCaptureManager.shared().stopCapture() after the frame you want recorded ends. This example is illustrative, not a benchmark; run it against your own renderer to confirm the capture appears in Xcode.

The GPU debugger's left panel shows the render pass tree. Expand a pass to see its draw calls, pipeline states, and the vertex and fragment functions bound to each one. Click the draw call that produces the pixels you are investigating.

  • Attachments shows colour and depth textures before and after the draw. Visually comparing them locates the corrupted region.
  • Bound Resources lists vertex buffers, textures, and uniform buffers along with their values. This is where you spot a wrong stride on an attribute buffer or a transposed matrix.
  • Geometry shows the post-vertex-shader positions. If the error is in the vertex stage, the preview often makes it obvious.

Stepping Through Shader Execution

Click a shader function name in the pipeline state row to open the shader debugger. Xcode shows MSL source with a thread picker at the top.

  1. Pick a thread: a pixel coordinate for fragment shaders or a vertex index for vertex shaders. For a vertex offset bug, choose the index you suspect.
  2. Step line by line through the function. Each line shows the computed value of every variable in that thread.
  3. Click a variable to expand its components. For a float4 position you can read x, y, z, w at the line that wrote them.
  4. Compare threads: open an adjacent known-good thread and watch where the two diverge. This usually points directly at the input that is wrong.

Metal System Trace for Timeline Analysis

For intermittent errors or stalls, open Instruments and choose the Metal System Trace template, then attach to your app process on the remote Mac. Record a few seconds of rendering. The trace shows GPU work duration and gaps, parallel vertex and fragment stage execution on Apple silicon, and per-draw occupancy.

If a vertex pass and the fragment pass that consumes its output show an unexpected gap, it usually points at a missing barrier or fence between a compute write and a vertex read. Select the two encoders in the trace and read the dependency annotation Xcode inserts.

When to Pick Which Figment Plan

  • You need GPU Frame Capture, the shader debugger, or GPU Timeline: M-series Mac from $95/month. Specific chip and RAM confirmed in the quote.
  • You need CI builds, signing, or non-GPU macOS work alongside the debugger: Managed Build Mac at $249/month adds CI setup, backups, monitoring, and 30 minutes of monthly support on one M-series Mac. A two-Mac team with two CI runners and one hour of monthly support is Managed Mac Team at $999/month.
  • You only need Intel macOS for a compatible Xcode 26-or-earlier toolchain or non-GPU tasks: the $29 virtual Intel macOS plan, with the caveat that Metal debugging is not available there.

Start a configuration at /mac-hosting/start, or read the plan summary at /mac-hosting.

Related guides:


Subscribe for Figma design and website publishing guides.


Figment.so

Contact

Twitter

Website pricing

Compute index

About

Privacy

Terms