Take the following scenario:
- Application binds and clears FBO1
- Application binds FBO2 and renders to it
- Application binds FBO1 again and renders to it
Steps 2 and 3 each require a render pass for rendering. The clear in step 1 can potentially be done
through loadOp
of the render pass for step 3, assuming step 2 doesn't use the attachments of FBO1.
This optimization is achieved in ANGLE by deferring clears.
When a clear is issued, one of the following happens:
- If a render pass is already open, the framebuffer is cleared inline (using
vkCmdClearAttachments
) - If the clear is not to the whole attachment (i.e. is scissored, or masked), a draw call is used to perform the clear.
- Otherwise the clear is deferred.
Deferring a clear is done by staging a Clear
update in the vk::ImageHelper
corresponding to the
attachment being cleared.
There are two possibilities at this point:
- The
vk::ImageHelper
is used in any way other than as a framebuffer attachment (for example it's sampled from), or - It's used as a framebuffer attachment and rendering is done.
In scenario 1, the staged updates in the vk::ImageHelper
are flushed. That includes the Clear
updates which will be done with an out-of-render-pass vkCmdClear*Image
call.
In scenario 2, FramebufferVk::syncState
is responsible for extracting the staged Clear
updates,
assuming there are no subsequent updates to that subresource of the image, and keep them as
deferred clears. The FramebufferVk
call that immediately follows must handle these clears one
way or another. In most cases, this implies starting a new render pass and using loadOp
s to
perform the clear before the actual operation in that function is performed. This also implies that
the front-end must always follow a syncState
call with a call to the backend (and for example
cannot decide to no-op the call in between). That way, the backend has a chance to flush any
deferred clears.
If the subsequent call itself is a clear operation, there are further optimizations possible. In particular, the previously deferred clears are overridden by and/or re-deferred along with the new clears.