The ARM Mali GPU driver miscompiles a fragment shader that uses the bitwise not operation on a uvec2 variable. The shader is expected to render a black color, but the Mali GPU renders a white color instead.
uvec2
The source code of the fragment shader is as follows:
#version 300 es
precision highp float;precision highp int;
precision highp float;
precision highp int;
uniform int input1; // input1 = 0
layout(location = 0) out vec4 color;
void main() { uvec2 a = uvec2(input1, 2u) | 1u; // a = (1, 3) uint b = ~a.y; // b = 4294967292 float c = float(b % 2u); // c = 0.0 color = vec4(c, c, c, 1.0); // color = (0.0, 0.0, 0.0, 1.0) a.k.a. black}
void main() {
uvec2 a = uvec2(input1, 2u) | 1u; // a = (1, 3)
uint b = ~a.y; // b = 4294967292
float c = float(b % 2u); // c = 0.0
color = vec4(c, c, c, 1.0); // color = (0.0, 0.0, 0.0, 1.0) a.k.a. black
}
The input uniform is set to 0 during runtime. The variable `a` is set to `(uvec2(0, 2) | 1) = (1, 3)`. The variable `b` is set to `~3 = 4294967292`. The variable `c` is thus `4294967292 % 2 = 0`. The expected color is black `(0.0, 0.0, 0.0, 1.0)`, but the Mali GPU renders the color as white.
I prepared an HTML file that can be simply opened in browser to reproduce this issue. The HTML webpage contains a minimal JS script that executes the fragment shader and outputs the color to the canvas. Also, I prepared a detailed README file describing the environment and steps to reproduce the issue. You can download them all here
Even if we fix the issue in the driver, it will take time for drivers to make their way into devices and even then not all OEMs will take a driver update.
The bug seems to impact vector operations, as a workaround can you try scalarizing these paths - e.g.:
uvec2 a = uvec2(input1, 2u); a.y |= 1u;
Thanks for your checking of this issue! The code snippet that I provided is just a minimal example for demonstration. The problem is that my project have multiple shaders, each containing dozens to hundreds lines of code. Since this issue affects any vector operands, I have to scalarize all of the vector variables into scalars. The refactoring efforts are non-trivial and the code could be less readable.
I understand that it takes time to fix the bug (and thank you for your efforts for debugging and fixing!), I can do the refactoring as a temporary workaround. But as I am developing more shaders, I am looking forward to seeing the fixes in the near future.
Thank you again for your time in investigating this issue.