godot icon indicating copy to clipboard operation
godot copied to clipboard

Metal GPU profiling/frametime does not work

Open julcst opened this issue 9 months ago • 1 comments
trafficstars

Tested versions

  • Reproducible in 4.4.beta4, 4.4.beta3, 4.4.beta2

System information

Godot v4.4.beta4 - macOS Sequoia (15.3.0) - Multi-window, 1 monitor - Metal (Mobile) - integrated Apple M1 (Apple7) - Apple M1 (8 threads)

Issue description

For every 3D project using the Metal backend on macOS the reported frametime is always 0.0. Vulkan backend reports valid frametime of around 4ms.

Tested with this script:

extends Label

func _process(_delta: float) -> void:
	var viewport := get_viewport().get_viewport_rid()
	var cpu := RenderingServer.viewport_get_measured_render_time_cpu(viewport)
	var gpu := RenderingServer.viewport_get_measured_render_time_gpu(viewport)
	text = "FPS: %f\nCPU: %f\nGPU: %f" % [Performance.get_monitor(Performance.TIME_FPS), cpu, gpu]

The reported fps is valid but RenderingServer.viewport_get_measured_render_time_cpu and RenderingServer.viewport_get_measured_render_time_gpu both return 0.0.

Visual Profiler looks like this: Image

View Frame Time option shows this: Image

Steps to reproduce

Every 3D project on macOS has this issue for me when using Metal backend.

Minimal reproduction project (MRP)

Example project with a simple FPS label and sphere mesh: Archive.zip

julcst avatar Feb 17 '25 20:02 julcst

  • Related to https://github.com/godotengine/godot/pull/99301.

This is mentioned in the description of https://github.com/godotengine/godot/pull/88199 as a known limitation:

  • The Visual Profiler and GPU frame times are not supported, as Godot's timestamp-based timing mechanism is not compatible with TBDR GPUs like Apple's M-series and mobile GPUs. Apple GPUs can reorder render passes based on input and output dependencies.

However, it should be mentioned in the class reference and optimization manual. We can also make RenderingServer.viewport_set_measure_render_time_gpu(true) print a warning when using Metal.

Calinou avatar Feb 18 '25 01:02 Calinou

Apologies for putting this here, but I can't seem to find anywhere in the docs that even mention this issue.

Since the Visual Profiler doesn't show GPU on Apple GPU, is there an alternate way to profile my game and figure out what's taking the GPU so long? I tried Instruments, but I'm not finding much useful there other than a confirmation that I'm running at around 20ms per frame (50fps).

jamonholmgren avatar Mar 15 '25 06:03 jamonholmgren

The only option is to use the Metal Frame debugger in XCode. It has a really excellent profiler built in that will give you detailed information on what the GPU is spending time on

clayjohn avatar Mar 15 '25 06:03 clayjohn

This also happens on 4.4.1 stable with a 2D project

lucasmaffazioli avatar Aug 26 '25 20:08 lucasmaffazioli

This is mentioned in the description of https://github.com/godotengine/godot/pull/88199 as a known limitation:

The Visual Profiler and GPU frame times are not supported, as Godot's timestamp-based timing mechanism is not compatible with TBDR GPUs like Apple's M-series and mobile GPUs. Apple GPUs can reorder render passes based on input and output dependencies. However, it should be mentioned in the class reference and optimization manual. We can also make RenderingServer.viewport_set_measure_render_time_gpu(true) print a warning when using Metal.

Having just stumbled on this myself, it is not an actual technical limitation of Metal itself @Calinou. There are ways to measure timing on Metal. First there is the is the basic Metal command buffer completion handler:

[commandBuffer addCompletedHandler:^(id<MTLCommandBuffer> commandBuffer) {
    CFTimeInterval start = commandBuffer.GPUStartTime;
    CFTimeInterval end = commandBuffer.GPUEndTime;
    CFTimeInterval gpuRuntimeDuration = end - start;
    ...
}];

Then it also has full detailed frame capture support via MTLCaptureManager.

iamvoidcoder avatar Oct 21 '25 10:10 iamvoidcoder