During normal operation, a thread waiting on an WaitObject and the
object hold mutual references to each other for the duration of the
wait.
If a process is forcefully terminated (The CTR kernel has a SVC to do
this, TerminateProcess, though no equivalent exists for threads.) its
threads would also be stopped and destroyed, leaving dangling pointers
in the WaitObjects.
The solution is to simply have the Thread remove itself from WaitObjects
when it is stopped. The vector of Threads in WaitObject has also been
changed to hold SharedPtrs, just in case. (Better to have a reference
cycle than a crash.)
This should speed up compile times a bit, as well as enable more liberal
use of forward declarations. (Due to SharedPtr not trying to emit the
destructor anymore.)
Display transfers with the horizontal downscaling flag were calculating
the wrong output size, causing them to write double the amount of data
intended. It is likely that this was perceived as correct due to a
separate bug in calculating source indices which caused the image to be
padded unless the previous bug was present.
This fixes both issues, correcting flickering issues in 3dscraft,
blargSnes and more (caused by the transfer overwriting the back buffer
which followed) as well as potentially fixing other crashes.
Hardware testing determined that the GSP processes shared memory
framebuffer update info even when no memory transfer or filling GX
commands are used. They are now updated on every interrupt, which isn't
confirmed correct but matches hardware behaviour more closely.
This also reverts the hack introduced in #404. It made a few games
behave better, but I believe it's incorrect and also breaks other games.
PDC0 and PDC1 are both VBlank interrupts. PDC0 was being treated as a
HBlank interrupt and fired many more times than it should. They now both
fire together at 60 Hz. This puzzlingly *improves* apparent framerate on
many applications.
A few other interrupts were being fired inside the GSP command
processing instead of on the actual GPU register writes, so they were
moved there, which should cover direct writes tho those registers not
going through the GX command queue.
This enables the /MP compiler flag, which parallelizes builds of by
distributing compilation of individual object files across workes
processes, instead of being limited to per-project parallelism.
Reduces the time for a full compile from 72 s to 45 s on my machine.
Replace all the C-style complicated buffer management with a std::deque.
In addition to making the code easier to understand it also adds support
for non-POD IdTypes.
Also clean the rest of the code to follow our code style.
Replace the loop-based texture address swizzling code by a bit-twiddling
implementation, providing a very small speed up. Also simplify
addressing code.
Use a new buffer management scheme in the clipper that allows using a
bounded minimal amount of buffer space. Even though it copies more data
it is still slightly faster likely due to using less cache.
The triangle clipper was allocating its temporary input, output and work
buffers using a std::vector. Since this is a hot path, it's desirable to
use stack allocation instead.
Unused OutputVertex attributes were being left un-initialized. The
leftover garbage sometimes decoded as floating-point denormalized
values, causing fallbacks to microcode and massive slowdowns in the rest
of the rasterization pipeline even though the results were unused. By
zeroing the structure we ensure these attributes only contain harmless
zeros.
This handle manager more closely mirrors the behaviour of the CTR-OS
one. In addition object ref-counts and support for DuplicateHandle have
been added.
Note that support for DuplicateHandle is still experimental, since parts
of the kernel still use Handles internally, which will likely cause
troubles if two different handles to the same object are used to e.g.
wait on a synchronization primitive.
- Refactor FS::Archive internals to make Archive creation and lifetime
management clearer.
- Remove the "Archive as a File" hack.
- Implement 64-bit Archive handles.
This is a first step at fixing the conceptual insanity that is our
handling of service and IPC calls. For now, interfaces still directly
derived from Session because we don't have the infrastructure to do it
properly. (That is, Processes and scheduling them.)