How to disable Metal compiler warnings for SceneKit / ARKit?

The Metal compiler when invoked by SceneKit is generating a lot of spurious warnings in iOS / iPadOS 14 Beta 7 & 8. This seems to be causing a significant degradation in performance for our SceneKit/ARKit-based app.

Is there any way to disable this unnecessary Metal compiler logging? I tried making a MTLCOMPILERFLAGS = -w environment variable, but it didn't seem to have any effect.

Feedback ID FB8618939.

Logging looks like this:
2020-09-09 14:23:33.700122-0700 App[4672:1638397] [Metal Compiler Warning] Warning: Compilation succeeded with: 



programsource:95:26: warning: unused function 'reduceop'

    static inline float4 reduceop(float4 d0, float4 d1)

                         ^

program
source:581:26: warning: unused variable 'scnshadowsamplerordz'

static constexpr sampler scnshadowsamplerordz = sampler(coord::normalized, filter::linear, mipfilter::none, address::clamptoedge, comparefunc::greaterequal);

                         ^

2020-09-09 14:23:33.962519-0700 App[4672:1638397] [Metal Compiler Warning] Warning: Compilation succeeded with: 



program
source:95:26: warning: unused function 'reduceop'

    static inline float4 reduce
op(float4 d0, float4 d1)

                         ^

programsource:581:26: warning: unused variable 'scnshadowsamplerordz'

static constexpr sampler scn
shadowsamplerordz = sampler(coord::normalized, filter::linear, mipfilter::none, address::clamptoedge, comparefunc::greaterequal);

Replies

The shader compile time problem is still happening in the latest iOS 14.3 Beta. I've attached shader compile times using Instruments running our app on an iPad running 14.3 Beta.

It's such a pity that with all of Apple's focus on 3D, AR and GPU performance, especially with the new M1 chip-based Macs, that they haven't resolved such a big performance problem yet. When users get frustrated with our app's UI appearing to hang for seconds at a time, they're unlikely to stick around to appreciate the beautiful billions of triangles-per-second rendering. I sure wish we could come up with a workaround for this.

Start Duration Stage
00:00.067.901 350.18 ms Compile shader
00:00.483.174 382.15 ms Compile shader
00:00.893.477 383.61 ms Compile shader
00:01.342.543 368.81 ms Compile shader
00:01.713.172 355.37 ms Compile shader
00:02.076.597 400.08 ms Compile shader
00:02.521.364 389.56 ms Compile shader
00:02.911.883 352.88 ms Compile shader
00:03.266.651 347.64 ms Compile shader
00:04.025.355 494.98 ms Compile shader
00:04.527.612 392.55 ms Compile shader
00:04.953.428 408.40 ms Compile shader
00:05.362.909 370.68 ms Compile shader
00:05.736.013 368.20 ms Compile shader
Post not yet marked as solved Up vote reply of lenk Down vote reply of lenk
I am also experiencing performance issues with iOS 14.
Is there any bug report / open radar we can follow to receive any update on this?
It appears in iOS 14, there was a change to the Metal compiler to output all errors and warning to a log file. There is not (yet) a way to silence this.

Can one (or many of you) create a request via Feedback Assistant? Please repost the FB number here to help us route this.

Thanks.
An update on this: The logging should be gone with iOS 14.2 Beta 2. However there are still some compile time performance issues to be worked out.
Found FBs in this post below:
FB8891233
and Feedback ID FB8618939
Unfortunately I've verified with Instruments that the performance problem still has not been fixed in iOS 14.3 RC.

The UI hangs are a really bad experience. In our app loading multiple models into a scene, we see hangs like this being logged in the Console app:

Code Block
com.apple.hangtracer Hang detected: 10.03s (always-on hang reporting)
com.apple.hangtracer Hang detected: 1.55s (always-on hang reporting)


So this is understandably frustrating and being investigated.

Note, however, that Metal will cache the fully compiled shaders in a file system cache after each reboot. So subsequent executions of your app should not exhibit these stalls.

Also, so that it doesn't interfere with the UI, you may want to experiment with forcing the shader compilation during your app's initial load time. Perhaps perform some dummy rendering off-screen (I unfortunately am not knowledgeable about how you'd do this with SceneKit)..

Graphics and Games Engineer : Thank you for your response.

The Metal cache is helpful, but for some reason it is either too small or fails much of the time. During my investigations, for some scenes, the "compile time" is indeed a couple of milliseconds, so it must be hitting the cache. But I cannot figure out a pattern or how to get the cache to work all the time. Is there some way to adjust the size? I see what looks like the cache in Library/Caches/app-id/com.apple.metal/functions.list, functions.data, libraries.list, libraries.data, so I see it written when a scene is loaded and shaders are compiled. Is there doc on how it works? I'm also not sure what you mean by "...after each reboot."

At least for our app, SceneKit scenes ARE the app UI, so there really isn't a way to show something else while the shaders compile. I'd be happy if there was some way to just get the shader compilation off the frame refresh (CADisplayLink) so it wouldn't hang the entire app UI. If you have some suggestions on how to achieve that, it'd be super appreciated.
Hello,

I am having significant issues on iOS 14 as well – to the point where the whole Scene and overlaying UI freeze up completely.
I've tested the same exact build on two iPhone 7, one running iOS 13.6 and the other 14.2.
The iOS 13 device had pretty good performance in general but more importantly never caused the complete app to freeze.

Here a side by side comparison: streamable.com/wx2at9 (please paste manually as the forum does not allow me to post the full URL).

The scene is actually quite simple and is displaying only a couple elements at a time (mostly downloaded USDZs or planes with a SpriteKit texture applied).

It almost seems like the GPU chokes up at some point and the only option then is to force quit the app.

Please note that I'm initially adding all objects to the scene and then call SCNView's prepare method https://developer.apple.com/documentation/scenekit/scnscenerenderer/1523375-prepare which should afaik precompile the shaders (and it worked in the past).

The freezes also occurred on more modern devices e.g an iPhone XS and 11.

Since a while I've noticed even on my 2020 iPad Pro that it drops frames when displaying certain nodes (with PBR shaders) for the first time – even after preparing the scene.
Radar and sample project: FB8244426

We have the same issue within our main app as well as the App Clip version and it's quite frustrating as we now can't promote them as planned and first have to figure out a workaround for this issue or wait for a solution.

I really like SceneKit and it's features though I am aware that the focus now lies on RealityKit. But until it is ready for primetime – for us once custom shaders, particle systems, transparent textures and a couple more things are supported – it would be great to get this fixed.
arthurfromberlin: Sounds like you're encountering similar problems. You can see it via Instruments / SceneKit by just running a sample app made using the standard Game template in Xcode.

BTW: I have tried (and even shipped) many different attempts to use both the synchronous and background versions of the SCNView.prepare method. I have had many problems with both of them. The background version crashes (at least since iOS 13) if the view is removed from the UIWindow (e.g., user changes views). I've debugged this and it's lacking a check for a null window but so far have not been able to convince Apple to fix it (FB7716713 May 27, 2020). Trying to use the synchronous version on a non-main DispatchQueue also crashes randomly and, at least for our app, actually makes it slower when it doesn't crash (FB5418811 Feb 11, 2019). Both of them seem to still cause the the shaders to be compiled during the CADisplayLink frame refresh, so they hang the whole app UI anyway. I've removed all uses of prepare from our app, at least until the bugs are fixed.

I agree with your assessment of RealityKit also: not a replacement for the functionality of SceneKit yet with a few too many missing features.
Post not yet marked as solved Up vote reply of lenk Down vote reply of lenk
lenk,

By  "...after each reboot" I meant that the shader cache is cleared after each reboot of the device. Your shaders will also be cleared if you reinstall the app (after rebuilding, for instance).

The cache itself is quite large (255 MB on iOS devices), so it's unlikely that your shaders are getting ejected due to it filling up. You can only reduce the cache size from the default size by setting the MTL_SHADER_CACHE_SIZE env var (size in bytes). Since you can only reduce the size, this is really only useful for testing your uncached compilation time by setting it to 0.
Hello,
I've read through the posts in this thread and at last found out why a simple ARKit scene was freezing on the initial node rendering. I had the same problems mentioned by lenk while trying to use the SCNView.prepare methods.

Is there a workaround for this?

Thank you!
I tested the last iOS Beta (14.4 beta 2) and the problem is still present.

Adding nodes to the SceneView scene still hangs the app UI even when calling prepare. Sometimes, it also causes ARKit to lose the tracking. More importantly, the app freezes completely from time to time and cannot be recovered unless the app is killed. The user experience is terrible.

Any help or workaround is very welcome. At the moment, the only solution I see would be to move our app to Unity...
Has there been any updates on this, or has anyone managed to find a work around? It still appears to be affecting out ARKit app.
I still have not found a workaround and the performance is still terrible in today's iOS 14.5 Beta 3 and macOS 11.3 Beta 3 builds.