Bug 95190 - Tomb Raider with PostProcessing enable and Depth of Field set to Ultra has white stuff in the foreground
Summary: Tomb Raider with PostProcessing enable and Depth of Field set to Ultra has wh...
Status: RESOLVED FIXED
Alias: None
Product: Mesa
Classification: Unclassified
Component: glsl-compiler (show other bugs)
Version: git
Hardware: Other All
: medium major
Assignee: Ian Romanick
QA Contact: mesa-dev
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-04-28 16:02 UTC by Karol Herbst
Modified: 2016-08-23 19:37 UTC (History)
3 users (show)

See Also:
i915 platform:
i915 features:


Attachments
Tomb Raider ultimate settings on radeonsi (r9 290x) just after applying graphics settings (menu still open) (155.74 KB, image/png)
2016-04-28 21:50 UTC, Luzipher
Details
frag shader with a huge const array + indirect access (145.62 KB, text/plain)
2016-04-28 22:18 UTC, Samuel Pitoiset
Details

Description Karol Herbst 2016-04-28 16:02:28 UTC
ostProcessing + Depth of Field Ultra gives bright white stuff in the foreground making the game unplayable

Trace: https://drive.google.com/open?id=0B78S7GSrzebIaExsb1FNSUNPTDA
Comment 1 Luzipher 2016-04-28 21:50:30 UTC
Created attachment 123330 [details]
Tomb Raider ultimate settings on radeonsi (r9 290x) just after applying graphics settings (menu still open)

This also affects radeonsi, see attached image. Just after setting graphics to ultimate it all turns white. "MESA_GL_VERSION_OVERRIDE=4.3 MESA_GLSL_VERSION_OVERRIDE=430" has no effect. Switching "Depth of Field" to normal helps (Post Processing still switched on).

Mesa and LLVM version: current git (28.04.2016)
GPU: R9 290x
Kernel Driver: radeon (not amdgpu)
Comment 2 Ilia Mirkin 2016-04-28 21:54:49 UTC
The issue is in the const-to-uniform lowering... which affects all drivers. Basically it has

const uvec4 int foo[200] = ...

foo[indirect]
foo[indirect]
foo[indirect]

which in turn leads that pass to do sad things. Samuel is looking at it now.
Comment 3 Samuel Pitoiset 2016-04-28 21:56:22 UTC
Yes, it's a bug in the GLSL compiler.
Comment 4 Samuel Pitoiset 2016-04-28 22:17:40 UTC
So, the issue is that the count_uniforms_size pass which is used to calculate the storage requirements for a set of uniform has a bug for constant arrays.

The problem is that the pass aggregates the size of a constant array each time it finds a reference in the shader source.

For example, in the attached shader, the lowering pass returns 95484k of uniforms but it should be 1308k (327*4) (+ some other things). The 95484 is computed as follow: 327 * 4 * 73 (number of occurences of icb in the shader).

I had a look at the code, and I think that the correct solution should be to do this lowering pass only once for constant arrays (this will require to somehow remember which one has been lowered though).

Ken, can you look into this?
Thanks in advance.
Comment 5 Samuel Pitoiset 2016-04-28 22:18:46 UTC
Created attachment 123334 [details]
frag shader with a huge const array + indirect access
Comment 6 Samuel Pitoiset 2016-04-28 22:28:03 UTC
Err, drop the 'k', it's just the number of elements. But you get the idea. :)
Comment 7 Ilia Mirkin 2016-04-29 03:11:23 UTC
OK, so the issue is that it's a different(ish) constant array every time. Code that's like

const foo[] = bar

foo[]
foo[]
foo[]

becomes

bar[]
bar[]
bar[]

And so in essence we have 3 arrays, each of which is becoming its own uniform. I tried adding a hash table on ir_constant*, but that was useless, since they're different ir_constant* pointers each time. This is going to be a bit tricky... I guess we could hash the actual data. Probably other solutions I'm neglecting, too.
Comment 8 Timothy Arceri 2016-04-29 05:40:18 UTC
I noticed and attempted to fix this a couple of weeks ago as it was giving me problems with my shader cache work. In the end I dropped it in the too hard basket and did this work around for my issue: https://github.com/tarceri/Mesa_arrays_of_arrays/commit/1cd0191635ad3a0d775077493b4ee28875280fa0

The problem as Ilia points out is that a new unidentifiable ir_constant array is propagated to each reference of the const array, this means we end up with a new uniform array of the entire array each time we access a single element.

My thinking at the time was that we need to convert the 'const foo[]' to 'uniform foo[]' before other optimisations passes such as constant propagation start messing with it.
Comment 9 Ilia Mirkin 2016-04-29 05:58:27 UTC
(In reply to Timothy Arceri from comment #8)
> My thinking at the time was that we need to convert the 'const foo[]' to
> 'uniform foo[]' before other optimisations passes such as constant
> propagation start messing with it.

We need to be careful to only do that for indirect accesses though - otherwise we'll end up sticking things into uniforms that could have been const-propagated.
Comment 10 Samuel Pitoiset 2016-08-23 17:19:48 UTC
This has been recently fixed by Kenneth. At least, I can't reproduce that fog issue on gm107 (I did force GL4.3 because that game requires a 4.2 context though).

Karol, can you confirm and close the ticket, please?
Comment 11 Karol Herbst 2016-08-23 19:37:12 UTC
except the bad perf, everything looks fine :)


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.