Adding a uniform-dependent if-statement in shader renders a different image
Submitted by Abel Briggs
Assigned to Karol Herbst @karolherbst
Link to original bug (#111006)
Description
Created attachment 144639 Reproduction shader_test files, images and diff
The attached archive contains two shaders, a reference shader and a variant shader, that by construction should render the same image. On the build and PC specified below, however, these shaders render different images. Images of the shaders’ output are also supplied in the archive, as well as the minor diff between the source code of the two shaders.
The difference between the two shaders is that the variant saves the current value of GLF_color, then sets it to a random value. Then, depending on a condition that is always true at runtime, GLF_color is overwritten with its original value.
11a12,13
> uniform vec2 injectionSwitch;
>
20,22c22,23
< float width = 256.0;
< float c_re = 0.8 * (xCoord - width / 2.0) * 4.0 / width - 0.4;
< float c_im = 0.8 * (yCoord - 256.0 / 2.0) * 4.0 / width;
---
> float c_re = 0.8 * (xCoord - 256.0 / 2.0) * 4.0 / 256.0 - 0.4;
> float c_im = 0.8 * (yCoord - 256.0 / 2.0) * 4.0 / 256.0;
32a34,40
> vec4 _GLF_outVarBackup_GLF_color;
> _GLF_outVarBackup_GLF_color = _GLF_color;
> _GLF_color = vec4(2799.7886, 1762.3462, - 8612.3800, - 7.8);
> if(((0.0 < injectionSwitch.y)))
> {
> _GLF_color = _GLF_outVarBackup_GLF_color;
> }
79a88
>
80a90
> uniform vec2 injectionSwitch 0.0 1.0
The value of injectionSwitch is set to (0.0, 1.0), ensuring that the conditional (0.0 < injectionSwitch.y) is always true at runtime. Notably, if you remove injectionSwitch and replace the condition with ‘true’, the variant renders the same image as the reference.
Steps to reproduce:
Obtain and build piglit, the Mesa OpenGL test suite runner: https://gitlab.freedesktop.org/mesa/piglit Download the attached archive. From a terminal, execute the supplied tests with the piglit GLES3 shader runner:
$ bin/shader_runner_gles3 reference.shader_test
$ bin/shader_runner_gles3 variant.shader_test
Expected results:
Both tests should produce an image like reference.png.
Actual results:
The variant produces a different image even though it should run exactly the same as the reference shader. Even though the variant swaps out GLF_color and swaps it back in, the two shaders are semantically equivalent, and there should be no difference in their rendering. Despite this, the variant renders many of the colored pixels in the image as transparent.
Build & PC specs:
CPU: Intel Core i7-5820k
GPU: nVIDIA GTX 970
OS: Ubuntu 19.04
libdrm: git-5db0f769
Mesa: git-d4575c30 (most recent as of this writing)
Xf86-video-nouveau: 1.0.16
Linux kernel version: 5.0.0-16-generic
This bug was found with GraphicsFuzz: https://github.com/google/graphicsfuzz
Attachment 144639, "Reproduction shader_test files, images and diff":
color_fuzz_runtime_if.zip
Version: git