06-04-2012 05:35 PM
Hello BB NDK dev forums,
We are bringing a relatively large App over from iOS to Blackberry and have notices some relatively severe differences in shader behaviour on the Playbook. These same differences were also observed on some Android devices also running the SGX 540 chipset. Are there known issues or workarounds surrounding this particular chipset? I'd be happy to post example shader code if necessary.
Solved! Go to Solution.
06-05-2012 02:40 AM
To be honest, what you're asking may be beyond the realm of knowledge of many on here. I know it's outside of mine.
What kinds of limitations are you referring to? Could you be more specific? What's creating a stumbling block for you? More specific questions tend to get answered more quickly.
Also, please note that the PlayBook uses a chip from TI that has errata associated with it, such that NEON instructions are disabled by default. While you can certainly use them, you need to incorporate some workaround NOP instructions to ensure that correct values are returned from the CPU/GPU. Heed this warning. Do not do what Gameloft did and just port your code straight over. Or else you'll have 200+ reviews on App World about your app being glitchy, crashing, and not being able to save (that's separate issue).
06-05-2012 02:51 AM
Hi Horizon XP,
Figured out our issue just as your answer came in.
The main issue we were observing was invalid vertex shader output in certain cases. This seems to be due to the fact that when multiplying vertex attributes of lower precision with higher precision uniform or temporary variables, the results seem to get truncated to the lower precision.
attribute lowp vec3 pos;
uniform highp vec4 xform;
mediump xformedPos = pos.x * xform + pos.y * xform + pos.z * xform;
/// this can yield invalid results.
The solution was to increase the precision of the attribute inputs, even though the vertex data didn't require it.
Hope that helps somebody else
06-05-2012 02:56 AM
06-05-2012 01:34 PM
Hi Horizon XP,
This is actually unexpected behaviour and points to a possible bug in either the gl Shader compiler of the SGX 540 driver. According to the GSLS ES spec:
The precision used to internally evaluate an
operation, and the precision qualification subsequently associated with any resulting intermediate values,
must be at least as high as the highest precision qualification of the operands consumed by the operation.
So lowp*mediump, should be evaluated at al least mediump and not lowp as was the case here.
This is similar to the C standard regarding type promotion.
Not a problem working around the issue, but good to know for anyone target ES 2.0 to an SGX 540 device such as the Playbook.
06-05-2012 01:55 PM
06-05-2012 02:09 PM
The SGX 540 definitely seems to be the chipset evaluating it incorrectly. iOS and Android devices running other SGX (tested on 535, 543, 543 MP2 and MP4) chipsets as well as other chipsets (tested on Tegra2 and 3 running GeForce) did not suffer from this issue.
I'll definitely log a bug in the Issue Tracker as soon as I can find it. This workaround is fine but this issue can definitely lead to mysterious bugs.
06-05-2012 02:14 PM
Wow, learn something new every day. I guess it's because on my engineering backgorund, but i would assume that numbers are only as accurate as your least reliable measuremnt. Good to know that such things dont apply in the world of OpenGL.
For my own edification, since im trying to get into OpenGL work myself, is the compiler for shaders implemented in the actual chip hardware, or as software in the driver? Driver-side implementation would likely make sense for the ease of it, but i can see why you might do it in hardware instead for performance reasons.
Could this bug even be fixed?
06-05-2012 02:36 PM
Hi Horizon XP,
This issue can definitely be fixed at either the shader compiler or driver level, similarly to the way a C compiler would generate arithmetically and type correct code when say, multiplying a char by an int and assigning the results to an int (e.g. (char)128*(int)200000 would overflow if arithmetic is done as char). So same applies to both CPU and GPU code.
As for your second question, the compiler for shaders is implemented in software. It receives the source code at runtime and converts it to GPU specific microcode. Now the reason it is done at runtime is because GPUs differ between target platforms and there is no unified microcode model for OpenGL. On other platforms such as consoles, shader compilation is usually done as an offline process and the runtime simply reads and load the precompiled shader microcode.
06-05-2012 02:41 PM