Hi everyone,
I have been digging into an issue we've seen in one of our apps that only occurs on the Galaxy S8 and the Galaxy S8+.
I'm posting here because I've narrowed it down to a small shader that breaks in mysterious ways that I can't explain and hoping someone would either be able to point out what I'm doing wrong or this can turn into a bug report.
Originally the breaking shader was a 2 pass gaussian blur with a 10x10 kernel. I have simplified it greatly while maintaining the problem. It now just blurs 3 pixels together.
I have an app (I attached the small Android project to reproduce, you need Android Studio and a fairly recent Android SDK) which blurs a picture of an Android using a shader in the Y dimension and draws it. It uses 1 very simple shader:
This shader runs properly (I get a slightly blurred android) on every device I have tried except the Galaxy S8 and the Galaxy S8+.
uniform highp sampler2D inImage; uniform highp float inSigma; varying highp vec4 varPosition; #define PI 3.1415926535 #define STEPSIZE vec2(0.0, 1.0 / 50.0) void main() { highp vec4 texCoords = varPosition; texCoords.t *= -1.0; texCoords += 0.5; highp vec4 g; g.x = 1.0/ (sqrt(2.0 * PI) * inSigma); g.y = exp(-0.5 / (inSigma * inSigma)); g.z = g.y * g.y; g.q = 1.0; highp vec4 center = texture2D(inImage, texCoords.st); highp vec4 sum = g.x * center; highp float norm = g.x; g.xy *= g.yz; highp vec4 sam1 = texture2D(inImage, texCoords.st + STEPSIZE); highp vec4 sam2 = texture2D(inImage, texCoords.st - STEPSIZE); sum += g.x * sam1; sum += g.x * sam2; norm += 2.0 * g.x; highp vec3 result = (sum/norm).rgb; gl_FragColor = vec4(result, 1.0); }
However, if I change "highp vec4 g;" to "mediump vec4 g;", it works on the S8 as well. Furthermore, if I change the uniform "inSigma" to be a #define instead so it is constant, it also runs properly. So I think I'm getting some weird shader compiler behavior because it doesn't seem to be related to the code logic or the values. Please let me know if there's any more information I can provide.
Am I no following the spec in some way or is this a bug in the shader compiler or something else?
Project:
0211.GLES20_ShaderIssue.zip
Thanks!
-Alex
Hi Alex,
Thanks for the bug report, I've raised this with the driver team and will let you know if we have any suggested workarounds.
Cheers,
Pete
Thanks Peter. I really appreciate it!
Our driver team have confirmed that this is a bug which impacts our Bifrost architecture "r3p0" driver release; it is fixed in our newer releases (the latest release from us is r6p0). Unfortunately we have no control over when device manufacturers push an over-the-air a driver update for their phones, so can't tell you when the Galaxy S8 will be getting an update.
In terms of workarounds you can try, the issue is caused by a bug in an optimisation pass which aims to remove sub-expressions which are common to all vertices or fragments; i.e. shader computations which are dependent only on uniforms. For example, in your code you have a lot of computation which is dependent only on the value of inSigma which is a uniform, and so every fragment will compute the same value.
If you move this computation to the CPU (e.g. upload the value of "g" as a uniform rather than the value of "inSigma") then you should avoid the issue. Note that moving this type of uniform-based computation to the application CPU logic is generally recommended application best practice for best performance anyway - why logically compute the same value thousands or millions of times when you can compute it just once.
Regards, Pete
Hi Peter,
We are developing a video player that renders to a GL_TEXTURE_EXTERNAL_OES texture. I seems that the colour of the video is slightly wrong on our Galaxy S8 test device. (in fact the colour of this video seems wrong in any built in or 3rd party video player apps on this device) On every other device in our possession the colour seems fine. Could this be related to this bug? My guess would be, that maybe the internal YUV -> RGB conversion would be guilty. If that's the case, could there be any workaround? (right now I'm trying to write our own conversion, but I'm afraid that wouldn't be ideal considering all the possible YUV output formats http://bigflake.com/mediacodec/ - see "Q5")
Here is the video:
Here is the first frame exported in photoshop:
And here is screenshot from the built in video player from the device:
If you look carefully, you can see, that colour of the grass is a little off.
Thanks,
Peter
This looks like a different issue - can you raise this as a new discussion please, so that search keeps topics coherent.Thanks, Pete
Sure thing, here it is: https://community.arm.com/graphics/f/discussions/9322/video-rendered-with-slightly-wrong-colours-on-galaxy-s8
Thanks, for the quick feedback!