Bug 111006 - Adding a uniform-dependent if-statement in shader renders a different image
Summary: Adding a uniform-dependent if-statement in shader renders a different image
Status: RESOLVED MOVED
Alias: None
Product: Mesa
Classification: Unclassified
Component: Drivers/DRI/nouveau (show other bugs)
Version: git
Hardware: x86-64 (AMD64) Linux (All)
: medium normal
Assignee: Karol Herbst
QA Contact: Nouveau Project
URL: https://trello.com/c/ESKBoRGN/215-cod...
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-06-26 16:39 UTC by Abel Briggs
Modified: 2019-09-18 20:48 UTC (History)
0 users

See Also:
i915 platform:
i915 features:


Attachments
Reproduction shader_test files, images and diff (41.57 KB, application/zip)
2019-06-26 16:39 UTC, Abel Briggs
Details

Description Abel Briggs 2019-06-26 16:39:09 UTC
Created attachment 144639 [details]
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-5db0f7692d1fdf05f9f6c0c02ffa5a5f4379c1f3
Mesa: git-d4575c3071 (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
Comment 1 Michel Dänzer 2019-06-27 07:30:19 UTC
Can't reproduce with radeonsi or llvmpipe/softpipe => seems to be a nouveau issue.
Comment 2 Paul 2019-06-27 09:29:15 UTC
Hi Abel.

Could you provide your configure command, please?
Comment 3 Karol Herbst 2019-06-27 13:43:15 UTC
this is caused by a "call/return stack" overflow. We know of another shader causing this issue in a game, so it's something we probably want to fix.
Comment 4 Abel Briggs 2019-06-27 14:46:00 UTC
If you're referring to the Meson(In reply to Paul from comment #2)
> Hi Abel.
> 
> Could you provide your configure command, please?

If you mean the Meson configure command, the only things I changed from the default is that I enabled ASAN with -Db_sanitize=address and I set the prefix to be a different location(along with the libdrm I compiled) so I wouldn't mess up my normal graphics stack. I compiled with gcc 8.3.0.

I'm not sure of any other configure commands you may mean, so please let me know if this isn't what you're looking for.
Comment 5 GitLab Migration User 2019-09-18 20:48:11 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/mesa/mesa/issues/1183.


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.