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
Created attachment 133501 [details] Scene from the beginning on windows
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.
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: glDispatchCompute(13,7,1): This invokes the misbehaving compute shader. glDispatchCompute(1,1,1): 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.
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.)
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: void GLAPIENTRY _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: void GLAPIENTRY _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).
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.
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.