Bug 102218 - Nier:Automata (through wine) - Bloom too bright
Summary: Nier:Automata (through wine) - Bloom too bright
Alias: None
Product: Mesa
Classification: Unclassified
Component: Mesa core (show other bugs)
Version: git
Hardware: Other All
: medium normal
Assignee: mesa-dev
QA Contact: mesa-dev
Depends on:
Reported: 2017-08-14 17:02 UTC by Fabian Maurer
Modified: 2017-11-27 11:05 UTC (History)
3 users (show)

See Also:
i915 platform:
i915 features:

Scene from the beginning on linux (53.25 KB, image/png)
2017-08-14 17:02 UTC, Fabian Maurer
Scene from the beginning on windows (208.43 KB, image/png)
2017-08-14 17:03 UTC, Fabian Maurer
Edited compute shader (1.91 KB, text/plain)
2017-08-14 21:22 UTC, Philip Rebohle

Description Fabian Maurer 2017-08-14 17:02:55 UTC
Created attachment 133500 [details]
Scene from the beginning on linux

Tested this issue with running a game called "NieR:Automata" in wine2.14-staging with CSMT enabled.
It renders fine overall, but the bloom is way too bright, see the attached screenshots.
It seems to work fine with the proprietary NVIDIA driver though, as seen in the wine appdb entry for the game.

Uploaded an OpenGL trace here: http://www.mediafire.com/file/n3n1jn4cndizb5k/nier-opengl.7z (732MB compressed, 5.1GB unpacked)

Also see the linked wine bug for more info and an edited shader that fixed the issue.

LIBGL_ALWAYS_SOFTWARE doesn't work at all.

System the bug was tested on:
- Arch Linux 64bit
- Linux 4.12.7, AMDGPU driver
- Mesa 17.3.0-devel (git-b420680ede)/ Mesa 17.1
- Radeon R9 285
Comment 1 Fabian Maurer 2017-08-14 17:03:13 UTC
Created attachment 133501 [details]
Scene from the beginning on windows
Comment 2 Philip Rebohle 2017-08-14 21:22:01 UTC
Created attachment 133511 [details]
Edited compute shader

As mentioned, an edited compute shader fixes the rendering. I attached another version of the shader which includes a #define to switch between a code path that uses shared memory and one that doesn't.

Unless I'm missing something, both versions should produce identical results. The code that uses shared memory shows the exact same rendering issues as the original shader generated by Wine, which works in a similar fashion. The Wine shader however is lacking explicit memory barriers.
Comment 3 Philip Rebohle 2017-08-16 19:38:33 UTC
I've tried to create a sample program that reproduces the issue, but so far, the shader that breaks the game actually works correctly in an isolated environment.

Anyway, in the apitrace, the following sequence of dispatch/draw calls is involved:

This invokes the misbehaving compute shader.

Processes the output of that compute shader, computes the actual average brightness of the image and mixes it with the average brightness of the previous frame.

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4):
Uses the output of the previous compute shader to render the (more or less) final image.

My system specs:
- Arch Linux 64-bit
- AMD RX 480
- Linux 4.12.6
- Mesa 17.1.6 (tested with mesa-git as well, same issue)
- LLVM 4.0.1

I haven't succeeded in building mesa-git against LLVM 5.0rc2.
Comment 4 David Chalmers 2017-11-20 12:15:50 UTC
Affects me also.

It might be relevant, but the behaviour of the Radeon 7850 differs from the 7790/R9270X/RX460/RX580 in this game on the systems I can test depending on what driver is loaded.

7850 w/ radeon module - crash upon attempting to enter the game.

The other cards using Radeon (7790, R9 270X) act as described by the others in this thread.

Using the AMDGPU driver module, the 7850 plays the game and shows less distortion on the edge of objects.

At first I thought that meant that the amdgpu module was somehow improved over the radeon module for this game, but the RX460/RX580 actually show MORE distortion on my systems.

I'm using Debian Buster (with another kernel installed to get amdgpu on southern islands hardware).
(The behaviour of the radeon-based cards on my system is unchanged with the vanilla debian kernel.)
Comment 5 Matias N. Goldberg 2017-11-20 16:15:19 UTC
I'm just passing by:

I'm 90% sure this is just a missing barrier before/after compute (which would indicate a Wine bug).

If you're able to modify wine's source code, try inserting
glMemoryBarrier( GL_ALL_BARRIER_BITS ); before and after the glDispatch calls.
Alternatively, you could modify Mesa's source code so a barrier is performed at the beginning and end of each glDispatch call.

I faced a similar situation in my own programs, where the compute shader would be launched before rendering; and this happened because I needed to unbind the FBO before launching the compute shader, otherwise Mesa will put them asynchronously, running in parallel. As a result the compute shader will read mostly flickering garbage as input.
A workaround is to use a barrier with all bits, which in radeonsi has a similar effect as unbinding the FBO.

Most GL drivers (actually all GL drivers I've seen except Mesa) just play safe by serializing everything, which would explain why it works fine on NVIDIA.

Just go to src/mesa/main/compute.c
and modify:
_mesa_DispatchCompute(GLuint num_groups_x,
                      GLuint num_groups_y,
                      GLuint num_groups_z)
   dispatch_compute(num_groups_x, num_groups_y, num_groups_z, false);

so that it reads:
_mesa_DispatchCompute(GLuint num_groups_x,
                      GLuint num_groups_y,
                      GLuint num_groups_z)
   _mesa_MemoryBarrier( 0xFFFFFFFF );
   dispatch_compute(num_groups_x, num_groups_y, num_groups_z, false);
   _mesa_MemoryBarrier( 0xFFFFFFFF );

If that fixes the problem, then this is very likely a Wine bug (wine needs to unbind the target as an FBO before using it as input for the compute shader).
Comment 6 Philip Rebohle 2017-11-20 17:01:18 UTC
Thanks for the detailed answer, this does indeed work.

It is exactly as you described, while wine actually does insert barriers *after* glDispatchCompute, it reads from the same resource that is currently bound for rendering. Reporting this back to wine.
Comment 7 Nicolai Hähnle 2017-11-27 11:05:40 UTC
Seems to be a game or Wine bug judging by previous comments.

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.