I've encountered another problem,
To reproduce the issue:
open the APK https://www.dropbox.com/s/yza47wllwfwvhaq/Application2.7z?dl=0
hold 2 fingers on the screen - camera will start auto rotating and you will see weird glowy outlines around the character
if you then hold 3 fingers, then the problem goes away.
From my understanding the problem is as follows:
-I use depth buffer as depth texture
-I clear the depth buffer
-I render the character model, writing to the depth buffer
-I disable depth buffer writes, so I can process it in read only mode, and read depth values from the depth buffer texture
-I render the blue sky model, in which I use the shader with depth buffer texture reads, however the values from the depth texture are not up-to-date but seem like they come from the previous frame
In all stages of above I don't change render targets / attachments / fbo, so from my understanding how the mali chip works, is that the depth buffer is stored in fast memory on the chip, but when I switch to read-only mode for depth buffer and want to read from the depth texture in the shader, then the driver does not detect properly that depth texture needs to be updated from the on-chip memory?
And to prove that problem, when you hold 3 fingers, then before sky is drawn, then I temporarly set a null (0) color render target and null (0) depth buffer, after that I restore the original color RT and depth buffer, so because of that switch, the driver flushes the depth contents to the texture, and it starts to work OK.
Esenthel said: then the driver does not detect properly that depth texture needs to be updated from the on-chip memory?
It sounds like its the same issue as you had on your other post.
You cannot safely make texture samples from an attachment which is currently attached as a framebuffer attachment; it's "implementation defined" behavior in the specification. It won't throw an error, but you've got no guarantees about what any vendor's implementation will do.
For Mali the "implementation defined behavior" will only give stable results if the attachment has been read-only for the entire render pass; anything else will give unpredictable results. Switching to read-only part way though a pass is not effective - as you are finding the tile-state is not written back to memory until the end of a render pass. What other vendors will do may be completely different, so you're definitely not writing portable code at this point.
Hope that clears it up,
Cheers, Pete
Thank you for your reply Pete.
Is there any way to force the Depth Buffer to be flushed from FBO to the Texture Memory in an efficient way?
Currently I'm using the workaround:
// disable depth attachment glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT , GL_RENDERBUFFER, 0); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
// restore depth attachment glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT , GL_TEXTURE_2D, id, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, id, 0);
And this works, however performance is affected a bit more than expected.
Driver could potentially make 2 memory copy operations in this situation - #1 copy from FBO to texture when disabling depth attachment, #2 copy back from texture to FBO when restoring depth attachment.
However I really only need to perform 1 memory copy, the #1.
Thanks,
Greg
If they are available on your platform - they are not available on Mali-4xx or some of the early Mali-T6xx series products - we have some extensions which let a fragment fetch the current framebuffer values (color, and depth/stencil) at it's coordinate, so you can read directly from tile memory.
https://www.khronos.org/registry/OpenGL/extensions/ARM/ARM_shader_framebuffer_fetch.txt
https://www.khronos.org/registry/OpenGL/extensions/ARM/ARM_shader_framebuffer_fetch_depth_stencil.txt
For good performance similar rules apply - don't interleave draw calls which modify depth with draw calls which read from the depth buffer - it will cause dependencies between pixels which can drop efficiency. Start modifying depth, and once you've built your depth value, then switch all draws thereafter to depth masked and using the extension.
Esenthel said:Driver could potentially make 2 memory copy operations in this situation - #1 copy from FBO to texture when disabling depth attachment, #2 copy back from texture to FBO when restoring depth attachment.
This is definitely what's happening - the contents of *all* attachments are being dumped back to memory and then restored as a second render pass. Inserting a glFlush() call would have the same effect.
If you know that the prepass is depth-only, then it can be worth setting up a dedicated FBO with only the depth attachment to minimize what gets bounced via main memory if you've not tried that already.
HTH, Pete