Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Shader.CreateGPUProgram takes a long time on first startup (iOS)

Discussion in 'iOS and tvOS' started by Johannski, Feb 13, 2018.

  1. Johannski

    Johannski

    Joined:
    Jan 25, 2014
    Posts:
    823
    We're having this problem of very long loading times on the very first startup of our game (or when restarting the phone, but not when killing the app and reopening it or when reinstalling it).

    A check with the profiler shows that Shader.CreateGPUProgram is the problem:
    Fresh install: 6053ms
    Reinstall: 253ms
    Shader.CreateGPUProgram.png
    Can I control when this happens? We disabled loading shader variants and the shaders used at that stage (first scene) are very few.
    We do use quite a lot of shaders. I guess reducing the amount of shaders would help. I'm wondering however:
    - Are shaders included in the Resource folder also affected for Shader.CreateGPUProgram
    - Will shaders with shader variants create a smaller overhead than the shaders as separate files
    - What actually happens at Shader.CreateGPUProgram? And why does it take so much more time at the first run? Is this a bug, or does it make sense?

    btw. running Unity 5.6.4p4 and XCode 9.3 if that is important.
     
    Petr777 likes this.
  2. Johannski

    Johannski

    Joined:
    Jan 25, 2014
    Posts:
    823
    Quick update: Shader.CreateGPUProgram compiles the shaders for the specific gpu. This happens whenever an app is freshly installes or the phone is restarted. Here is a simple test I made to show the impact:

    This is only for creating the shaders. Warming up the shaders takes about the same amount of time. Interestingly enough this seems to behave rather similar as Shader.CreateGPUProgram. It is normally only necessary at fresh install or when the phone is restarted.
    Can someone explain to me why shaders won't need warmup when I kill the app and restart it? Is the shader actually still on the GPU? And is there a faster way to flush the GPU buffer other than restarting the phone?

    TLDR: When implementing shaders, don't only look at performance but also loading times, they have a huge impact on the first start of your app.
     
    Last edited: Feb 23, 2018
    Petr777 likes this.
  3. KristoferBoman

    KristoferBoman

    Joined:
    Feb 16, 2016
    Posts:
    61
    Hi,

    Did you ever solve this problem. We have it in our game as well. Our "Fresh Install" time for an iPhone 7 is around 20 seconds and "Reopening" time is 2 seconds.

    We have been blaiming the Resource folder up until i saw this post. We will try to fix this as well and i'll post back if we come to any conclusion on how to get rid of the problem.

    If someone from Unity could comment on this that would be even better.

    Thanks,
    Kristofer
     
  4. Johannski

    Johannski

    Joined:
    Jan 25, 2014
    Posts:
    823
    Well, as pointed out in the second post: The shaders get compiled on the device, that's taking a S***load of time. Additionally the shaders also need to be warmed up, this is also mostly only necessary for fresh installs.
    So in the end, try reducing the amount of shaders (and shader variants) you are using. A unity team member commented on it in this thread: https://forum.unity.com/threads/profiling-shader-creategpuprogram.249362/
     
  5. Nokola

    Nokola

    Joined:
    Jul 25, 2015
    Posts:
    5
    I have the same issue with Unity 2017.4.0 and blank project. 7-12 seconds startup on iOS. 1-2 seconds on Android. Just opened a bug in the issue tracker but haven't heard from Unity yet.
     
  6. trovius

    trovius

    Joined:
    Feb 4, 2017
    Posts:
    1
    Was this ever resolved? I am encountering the same issue on Oculus Go. The profiler shows Shader.CreateGPUProgram running even when I have preloaded a shader variant collection with single pass VR rendering.
     
  7. DenisK_WRG

    DenisK_WRG

    Joined:
    Oct 16, 2018
    Posts:
    14
    And is it possible is that cause crash on first launch because of lack of memory for example?
     
  8. Johannski

    Johannski

    Joined:
    Jan 25, 2014
    Posts:
    823
    I had a meeting at Unite Berlin with an evangelist. Apparently ShaderVariantCollection.WarmUp does not always do what it should do on different platforms (apparently not even iOS). So maybe try showing the different shaders to a camera that renders into a render texture.

    I would doubt that, did you check the profiler / logcat / Xcode log / whatever you're on.
     
    chrismarch likes this.
  9. AGulev-k

    AGulev-k

    Joined:
    Jan 16, 2020
    Posts:
    8
    Hi, did you find the answer to your question? (I have the same issue and would like to know how it works inside)
     
  10. Johannski

    Johannski

    Joined:
    Jan 25, 2014
    Posts:
    823
    Hi,

    Nope I still have no clue why that is the case, if you find it out, let me know :)
     
  11. Skjalg

    Skjalg

    Joined:
    May 25, 2009
    Posts:
    211
    Last edited: Sep 23, 2020
  12. Johannski

    Johannski

    Joined:
    Jan 25, 2014
    Posts:
    823
    No, in my case, it was a simple Unity 5.6 project with the good old builtin renderpipeline, no fancy packages involved. I just wrote quite a few shaders for the game, that's why I hit the bottleneck.
    My learning from here is clearly is to not only look on performance of shaders, but also on number of shaders to compile as little shaders as necessary.

    For example, I built multiple shaders for stencil operations, until I learnt, that you can dynamically set, how a material reads or writes to the stencil and what id they are using. This lead me to build this repo: https://github.com/supyrb/ConfigurableShaders

    I guess the VFX problem still has the same root cause: Compiling (too many) shaders. It is odd however, that the shader copile happens for you, even if you don't use the FX graph. Did your shaders maybe somehow land in the always include assets or always include shaders lists? If that is not the case, I guess Unity does some magic under the hood to make sure those shaders are prewarmed at the start of the application...
     
  13. Skjalg

    Skjalg

    Joined:
    May 25, 2009
    Posts:
    211
    Yeah my best bet is that unity is doing this under the hood :/
     
  14. PandaArcade

    PandaArcade

    Joined:
    Jan 2, 2017
    Posts:
    128
    I'm pretty sure this is the cause of our long initial load times. On first startup, our splash screen is visible for 10+ seconds, subsequent startups are under 4 seconds. We have a Preloaded Shaders list with ~700 variants o_O
     
    Last edited: Dec 8, 2020
  15. Johannski

    Johannski

    Joined:
    Jan 25, 2014
    Posts:
    823
    Yes, that is most likely the reason for your long startup time. Try to minimize the shaders or its variants or merge shaders. Any maybe don't load the shaders at startup, but in a supersmall first scene, so you can show a progressbar or some kind of progress to its users. https://forum.unity.com/threads/app-startup-time-optimizations.504220/
     
    PandaArcade likes this.
  16. EmmaEwert

    EmmaEwert

    Joined:
    Mar 13, 2014
    Posts:
    30
    I was having similar issues with WebGL, where CreateGPUProgram was exceptionally untimely (in the middle of gameplay when some my shaders are introduced).

    Just chiming in to say that showing my two heavy shaders to my render texture camera first allowed me to control when those shaders were being compiled.