GPU: Rasterize software depth on a worker thread

The depth draws were queued and rasterized on the emu thread at each render target change, in
Wipeout about 40 small batches a frame, and around 40% of that thread's time. Now a render target
change hands the batch to a worker thread and carries on. Waiting for it is left to whatever reads
the depth buffers: DrawSync and ListSync, block transfers, framebuffer copies, showing a frame,
savestates and shutdown, and the texture cache when the texture or CLUT it reads overlaps a depth
buffer still being written.

Batches grow as needed instead of being preallocated at full size. A full batch is now handed over
and a new one started, where the draw used to be dropped.

Wipeout headless, output unchanged: 16% less wall time on a Galaxy S8 (8.2 s to 6.9 s for 10
emulated seconds). On an M1, where headless waits on the GPU, the emu thread uses 38% less CPU time.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Henrik RydgårdandClaude Opus 5.5 committed 2026-10-15 16:42:45 +02:00
1 parent da4d6eda8a
commit cd59a16d85
11 files changed
+377 -104

No files matched your search

+5
View File
@@ -652,6 +652,11 @@ void CPU_Shutdown(bool success) {
// Core_LockAgainstShutdown(); it's recursive, so the nested acquire in Memory::Shutdown() is fine.
CoreShutdownLock coreLock = Core_LockAgainstShutdown();
// The GPU outlives memory (GPU_Shutdown comes later), so it must stop writing to it now.
if (gpu) {
gpu->FlushPendingDrawing();
}
UninstallExceptionHandler();
GPURecord::Replay_Unload();