All calling code assumes that the rasterizer will be in a valid state,
which is a totally fine assumption. The only way the rasterizer wouldn't
be is if initialization is done incorrectly or fails, which is checked
against in System::Init().
We move the initialization of the renderer to the core class, while
keeping the creation of it and any other specifics in video_core. This
way we can ensure that the renderer is initialized and doesn't give
unfettered access to the renderer. This also makes dependencies on types
more explicit.
For example, the GPU class doesn't need to depend on the
existence of a renderer, it only needs to care about whether or not it
has a rasterizer, but since it was accessing the global variable, it was
also making the renderer a part of its dependency chain. By adjusting
the interface, we can get rid of this dependency.
This makes the formatting expectations more obvious (e.g. any zero padding specified
is padding that's entirely dedicated to the value being printed, not any pretty-printing
that also gets tacked on).
Not all physical regions need to be mapped into the address space of every process, for example, system modules do not have a VRAM mapping.
This fixes a crash when loading applets and system modules.
This is slightly more ergonomic to use, correctly handles virtual
regions which are disjoint in physical addressing space, and checks only
regions which can be cached by the rasterizer.
Unmapping pages tries to flush any cached GPU surfaces touching that
region. When a cached page is invalidated, GetPointerFromVMA() is used
to restore the original pagetable pointer. However, since that VMA has
already been deleted, this hits an UNREACHABLE case in that function.
Now when this happens, just set the page type to Unmapped and continue,
which arrives at the correct end result.