The core and the headless tools no longer use mutexes, condition variables,
spinlocks, std::atomic, std::thread or volatile flags. Threads hand off through
libretro-common's retro_atomic and rthreads plus a few small pieces on top of
them in Common/Thread: Thread, MpscQueue, EventCounter, ParkingLot waits and
ReaderGate. Every wait blocks until it's woken; nothing polls on a timer.
State that only one thread touches just loses its lock. The PSP filesystem,
sceIo and the savedata dialog now belong to the emulation thread: async reads
and writes run when they're queued and complete later in emulated time, and
the IO and savedata threads are gone. The friend finder only talks to the
adhoc server and hands what it gets to the emulation thread. GPU init always
runs on the thread that starts the game.
The Vulkan render and compile queues, pipeline and render pass caches, delete
list and SPIR-V cache, the GL render queue, the software renderer's jit caches,
the file loader caches, the web debugger, UPnP, input, savestates, logging and
the GE debugger all hand off through queues and atomics. The IR jit's spinning
profiler thread goes.
A CPU thread with nothing to run now sleeps until work is queued instead of
spinning. Headless with --debugger waits for a client while stopped, and ends
the run once every client that connected has left. Web server shutdown keeps
servicing the CPU queue until the server has finished.
Deflate, zlib and gzip streams go through rinflate and rdeflate, zstd
through rzstd, CHD images through rchd, zip archives through
rzip_archive and PNG through rpng. The bundled libraries, their build
glue and the system-library options are gone; adler32 and uncompress
keep zlib's ABI for the prebuilt FFmpeg archives that still call them.
libretro-common is one CMake library that the core, the headless tool
and the unit tests all link.
The reads take shorter paths on the way. CHD decodes straight from the
loader's reads and a range of blocks at a time, and a file read at any
alignment decodes into place; CSO keeps one inflate stream instead of
one per block; a plain ISO serves a file read with one read of its exact
bytes; a stored zip member is read in place and a deflated one through
restart points rather than a copy of the whole image in memory; zip
members decode into the caller's buffer; sequential reads through the
frontend's VFS skip the seek, which also keeps its buffering.
libretro/test reads one image as ISO, CSO, CHD and zip through the block
devices, boots each, and checks the codecs against Python-made vectors;
a CI job runs it.
Texture pack installs took the destination directory from the archive's
textures.ini, and PKG update installs from the PBOOT's DISC_ID, both
unchecked, so a crafted archive or package could write outside
PSP/TEXTURES or PSP/GAME. Add IsSafePathComponent() to PathUtil and check
both, replacing the WebServer's own upload filename check with it too.
DISC_ID from any PARAM.SFO also names configs, cheats, textures, exdata
and savestates, so ReadSFO now drops one that isn't a safe name and the
game gets a fake ID like homebrew. The same goes for a frame dump's ID.
Combines #22419 and #22420 by Acts1631.
Co-Authored-By: Acts1631 <acts1631kjv@proton.me>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The jump back to the start of the list buffer sets BASE to the buffer's,
but vertex and index addresses already queued for the next draw were made
for the previous one, so they pointed 16 MB away. Tiger Woods (ULUS10420)
read a skinned draw's indices as zeros and lost it.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The software renderer has the real contents of what a replay drew, and a
recorded framebuffer texture can be stale or run over other buffers at its
recorded size. So a copy leaves out the areas the replay's draws could reach
(region and scissor, or the vertex bounds of a 2D draw), instead of skipping
it only when it starts at a drawn buffer:
- Princess Maker 5 textures from the right half of its 1024 wide
framebuffer, and the copy blanked the whole frame.
- Rainbow Six (ULUS10206) copies its 512x512 frame texture, which covers its
display buffer, before each strip it draws into that buffer.
- Burnout keeps a texture beside its frame in columns 480-511, which still
comes through.
- Depth writes count as whole rows in 8-row bands, since the PSP stores
depth swizzled (SOCOM UCUS98649's frame texture copy ran into its depth
buffer's columns 480-511).
Copies also stop at the end of VRAM, and flush the software renderer's
queued draws before writing.
Memsets were also never applied with the software renderer, which leaves
them to the caller.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
With the software renderer, a FRAMEBUF texture snapshot of a framebuffer
this replay already rendered to is skipped: the dump's copy can be stale
(recorded on a hardware backend that never read it back), and it wiped the
frame in a GTA LCS dump (issue 18467's dump now matches the PSP exactly).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Lets a dump replay stopped with --replay-end be compared against the PSP on
an offscreen buffer. The framebuffer commands after the draw limit are
dropped too, so it shows the buffer the last drawn primitive went to.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
--depth-save writes the depth buffer next to the screenshot (u32 width, u32
height, then u16 depths), and --replay-end stops a frame dump replay after
that many primitives. Both match pspautotests' ppdmp-playback, so a dump's
depth can be compared with the PSP's at any point in the frame.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Rename LogType to Log
* Explicitly use the Log:: enum when logging. Allows for autocomplete when editing.
* Mac/ARM64 buildfix
* Do the same with the hle result log macros
* Rename the log names to mixed case while at it.
* iOS buildfix
* Qt buildfix attempt, ARM32 buildfix
If it's less than 256 bytes, we can't mark the entire VRAM area copied.
This still helps frame dumps avoid excessively slow VRAM recopying
situations, but fixes issues like missing trees in #12738.
See #15251, the framedump here reused a VRAM texture for many draws, and
this caused it to recopy the texture over and over again. Use a flag to
skip if possible.