Hello Mali devs,
We are are observing what appear to be tiling artifacts when sampling a depth texture after it has been rendered as part of a water murk effect. The particular sequence of operations is:
1) Render main scene to depth/color texture.
2) Render water murk (sampling depth rendered in main scene) with depth buffer disabled and frame buffer set to colour only.
3) Resture depth/color framebuffer and render rest of the scene.
It appears this is somehow timing related as the artifacting varies based on camera angle/framerate. I've attached a screenshot showing these artifacts taken on a Mali-T628 device.
Has anyone else observed this? Anything in the sequence of operations described above that may be incompatible with TBDR?
Thanks!
Stephane
Hi Sean and Peter,
Thank you both for your answers!
Peter, I was misled to believe it was timing sensitive due to the artifacts depending on the on screen animation.
Sean, interesting observation on x=1024. It does appear that the artifact consistently appears beyond this boundary. If I push the render buffer size to full native resolution of 2560x1600, then the artifact occurs at x=2048 and at double the density (8x8 tiles). At higher resolution the artifacts outside the water become much more apparent and do occur below 2048 (as you pointed out, good eye!). We do indeed perform multiple resolve stages for post processing including pixel based fog, depth of field, glares and distortion passes. The depth of field pass was sampling from and rendering to the same render target which seems to be what was introducing the corruption. Copying the texture to another and using the copy as DOF input has resolved the issue.
Interesting that this issue was limited to the MALI family of GPUs, however it makes sense as this could be tightly related to the internal GL memory management, etc.
Thank you all for your input, much appreciated!
Best,
Hi Stephane,
> The depth of field pass was sampling from and rendering to the same render target which seems to be what was introducing the corruption
I'll need to reread the spec when I get back in the office next week, but from memory reading and writing to the same target in the same FBO pass will result in undefined behavior in OpenGL ES. You seem to have the right solution - use a different target.
Brief reason for the artefacts: as we are tile based you will be reading back part of the image which is rendered from this frame (completed tiles), and part of the image from the previous frame (tiles still pending). I assume your DoF effect samples over the edge of a tile boundary, so "edge pixels" within a tile are loading texture data from neighboring tiles, which are in an undefined state (within a tile you will always get the old data which is why you don't get artifacts within the tile).
What I can't explain is why this appears worse on the right-hand side of the screen - this problem should effect the whole screen - so I still wonder if there is a precision issue lurking somewhere which gives different behavior depending on position. My best guess is that the sample point calculated by the DoF shader shifts slightly further out of the tile the further you get across the screen (bigger exponent needed => fewer mantissa decimal places => more coarse grained steps), whereas samples less than 1024 pixels across in your initial test image only sample within the tile being rendered.
Cheers, Pete
It is very good to hear that you have managed to isolate and fix the problem.
Thanks much gents,
Peter, we initially thought the same thing initially, however, after isolating the DOF shader and reducing it to just a simple blit, the issue persisted. This made it clear that the issue was outside the realm of shader numerical precision. As Sean observed, the artefacts do seem to appear screen wide, however, happened to be more apparent on the water where the color contrast was higher. Again thanks for your help on this. I'm happy to provide a reproducer if you need to further investigate internally.
> I'm happy to provide a reproducer if you need to further investigate internally.
Thanks for the offer, but I think we now know enough to say that we are probably doing what the spec intended. The issue occurs because you reuse the same texture as both input and output to an FBO. The relevant part of the spec which defines this as "undefined" is ...
http://www.khronos.org/registry/gles/specs/3.0/es_spec_3.0.2.pdf
... section ...
4.4.3 Feedback Loops Between Textures and the Framebuffer.
Kind regards, Pete