SGX 543 driver is compiling shaders inside a glDrawElements call

After noticing a bunch of small freezes in my iOS app (on any device and iOS version), I went to Instruments and got the following stack trace (sorry, no text version):



https://dl.dropboxusercontent.com/u/10365187/stack_trace.png



It turns out that, when rendering with some (if not all) shaders for the first time, the driver performs some internal shader compilation inside the glDrawElements call. I found this thread which seems to be about the same issue, only 3 years ago. In the answer from Joe, he mentions that creating different instances of the shader program with different opengl states might fix it, but this is a very generic answer.



Can I have a more comprehensive answer to this? I tried different combinations of blending functions and it doesn’t seem to help at all, and I’m pretty sure I don’t use multiple texture formats. My shaders are already being compiled beforehand to avoid this things, and I really don’t want to do any dirty hacks to get this fixed.



Thanks.

Hi Thiagosg,



Blending functions are the states that I would have suggested to target with this sort of stuff, but it’s possible that what you’re seeing is just delayed shader compilation which can be solved with something known as “pre-warming” them.



Some drivers (including Apple’s - which are different from ours) will delay shader compilation until they are first used. You can solve this by making a draw call as soon as a program is linked. To make this as quick as possible, if you draw a single triangle to the framebuffer in an offscreen location (i.e. outside of the clipspace) then the GPU will do almost no work, and the driver will fully compile your shader long before you plan to use it.



Hope that helps?



Regards,

Tobias

Hi Tobias…



Following your advice above, we pre-warm our shader programs right after linking them. This is done, as you describe, using a minimal dummy mesh, which we render to a minimal off-screen framebuffer (4x4 pixels with color buffer only). It seems to work fine when performed on a single GL context.



However, much of our model loading is performed on a background thread, which can result in the loading, compiling, linking and pre-warming of any new shader programs required by the models. The background and foreground threads use separate GL contexts connected with a sharegroup under iOS.



We’ve noticed that we are still encountering a delay in the main rendering thread the first time a shader program is used there. It’s almost as if the effect of pre-warming on the background GL context is not recognized in the foreground GL context.



Is that expected behaviour? Does pre-warming need to be performed on each GL context separately? Or should we expect that a shader program that is pre-warmed in a background GL context will be treated as such by the foreground GL context?



Thanks…



…Bill

Hi Bill,



Unfortunately I’ve never drilled down into Apple’s drivers enough to give you any useful advice here I’m afraid, I’d suggest you contact Apple directly for their advice on this. I would have assumed that this would work, but if what you’re seeing doesn’t support that - maybe not? If you do find out please let us know though!



Sorry I can’t be of more help!

Tobias