Return video thread creation errors through CoreThreadInitialize and unwind
the core-thread resources initialized before the failure.
Unlikely to occur, and if thread creation fails we have bigger problems,
but whatever.
Run fatal reconfiguration handling through the active video execution context
so video-owned teardown and thread assertions execute on the correct thread.
Pass the core-thread fullscreen state through the queued resize callback so
video-thread recovery does not read mutable core-owned state.
Assert fullscreen entry points stay on the core thread.
Run the non-trivial reconfigure command destructor after direct single-threaded
execution to release copied settings resources before FIFO storage is reused.
Assert that command allocation, submission, and synchronization run on the
core thread. Marshal exclusive-fullscreen loss to the core thread instead
of enqueueing recursively from the video thread.
Write the four per-frame capture values through one helper so the capture
position, IRQ target, and IRQ eligibility are loaded once. Preserve the
original channel order and continue checking for an IRQ immediately after
each corresponding RAM store.
This turns four scattered coefficient loads and four scalar multiplies into two
contiguous 64-bit loads and one vector signed multiply-add with a horizontal
reduction.
The coefficient and sample bounds keep every intermediate within signed 32-bit
range, so reassociation is exact.
Gets us another ~2.5% when SPU-bound.
- Walk the voice array directly and consume the noise, pitch modulation, and
reverb masks one bit at a time.
- Pass the previous voice volume into SampleVoice explicitly, preserving pitch
modulation ordering while avoiding repeated indexed lookups and the per-voice
address multiplication generated for the 148-byte Voice structure.
~2% speedup in SPU-bound scenarios.
I previously had this in PageFaultHandler::ExceptionHandler(),
but it was causing random strange crashes in XTAJIT (Windows
ARM64 x86 emulation layer). Seems like some threads were being
created and triggering exceptions before the TLS storage was
initialized. Very strange. Anyway, best to just avoid that
completely, since apparently you can't guarantee that the TLS
will be initialized at the point a VEH runs.