ostProcessing + Depth of Field Ultra gives bright white stuff in the foreground making the game unplayable
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)
The issue is in the const-to-uniform lowering... which affects all drivers. Basically it has
const uvec4 int foo = ...
which in turn leads that pass to do sad things. Samuel is looking at it now.
Yes, it's a bug in the GLSL compiler.
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.
Created attachment 123334 [details]
frag shader with a huge const array + indirect access
Err, drop the 'k', it's just the number of elements. But you get the idea. :)
OK, so the issue is that it's a different(ish) constant array every time. Code that's like
const foo = 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.
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.
(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.
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?
except the bad perf, everything looks fine :)