* For D3D11 and Vulkan, any views which don't just map to the whole
buffer or image will be highlighted in a colour, and when mousing over
that row a small tooltip will be displayed with the view parameters
that differ.
* Since the Vulkan views are tighter and more strictly specified, we can
always safely use the view format (in the non-mutable case it must
exactly match the underlying resource's format).
* If a swapchain fails to create, we'll just continue and not render
anything. we'll try to recreate a few times and also on resize, in
case the failure is transient.
* Only one major piece of functionality is unimplemented and stubbed out
- WriteToSubresource and ReadFromSubresource in concert with passing
a NULL D3D11_MAPPED_SUBRESOURCE parameter to ID3D11DeviceContext::Map.
* This is a bit convoluted so follow with me here...
* As an optimisation, when not capturing a frame we serialise clears as
clears for resources and mark those resources as clean. This way if a
resource is cleared, then used in the frame, we don't have to worry
about fetching or storing its initial data - we just replay the clear
once while initialising and we're done.
* The alternative here is to mark a resource dirty when it's cleared,
and then we might have to read back and serialise a completely flat
image - rather wasteful.
* The problem is that if the resource is referenced but its view isn't
then the view will be trimmed from the capture and we don't have it
around to actually perform the clear. This only started being a
problem when views were tracked in their own separate records.
* We can't create a circular dependency from view -> resource -> view
as that would create cycles and keep lots of things alive pointlessly.
Instead we add serialisation of the resource & view descriptor so that
we can recreate the view on demand if need be. This adds 32 bytes to
each clear and since clears aren't hugely frequent it's not a big deal
* This can happen when there's divergence in an if/else, or in how many
times a loop executes. We need to make sure threads go back to being
lockstep once the flow converges so derivatives remain valid.