Commit Graph
32 Commits
Author SHA1 Message Date
libretroadmin f1208a7a5a Make threading lock-free
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.
2026-10-09 04:56:16 +02:00
libretroadmin 9f13f0f051 Remove sleeps and timed polling from the emulation and render paths
The core no longer sleeps to pace itself: the frontend runs retro_run at
its own rate, so the frame throttle, the idle-vblank delay and the real
clock sync event (and its core option) are gone, and a stepping CPU hands
straight back instead of waiting 2 ms. Waits that polled now park on a
lock-free eventcount through Common/Thread/ParkingLot and are woken by
whoever changes the state: a paused GL emu thread, which also queues a
marker behind its last frame so pausing runs the render queue up to it
instead of polling; async I/O results; the software renderer when its
queue is full; Vulkan pipeline compiles; and debugger requests once
stepping ends. Boot joins the loader thread, cache shutdown joins its
read-ahead thread, and the slow-I/O simulation is removed.

The path browser, the HTTP and WebSocket servers, the Windows console and
the game info cache are left out of the core build. libretro/test gains
lrgltest, which drives the GL backend on a surfaceless EGL context through
every path that pauses or stops the emu thread; run.sh and the image
checks CI job run it on llvmpipe.
2026-10-08 17:58:42 +02:00
libretroadmin 320e4554c4 libretro: fix software renderer OOB read, oversized buffer, extra copy
SOFT_BMP_SIZE was a byte count used as the element count of a u16
array, keeping ~1 MB resident per context, and SwapBuffers memcpy'd a
full frame out of the vector ConvertFramebufferForLibretro returns empty
for unsupported formats, a heap OOB read. The intermediate buffer and
its per-frame memcpy are gone: the converted vector goes to video_cb
directly, with the 16:9 crop done by pointer offset. Before a GPU exists,
or when conversion fails, a frame dupe is sent instead of stale data.
2026-10-08 09:18:49 +02:00
libretroadmin 0b656e2303 libretro: fix OOB, UAF, data races and control flow in core glue
System_AudioPushSamples converts straight into the output buffer: the
block loop never advanced the source pointer and copied numSamples*2
int16s out of a 2048-sample stack buffer, a stack OOB read for any push
over 1024 frames. Realloc failure drops samples instead of crashing and
log_cb is NULL-checked. retro_serialize refuses to write a state larger
than the frontend's buffer, retro_get_memory_data/size return nothing
until PSP memory is mapped, deferred unserialize no longer leaks the
previous buffer, and the cheat entry points stop leaking a CWCheatEngine
per call.

The emu thread acknowledges a pause with a CAS so it cannot clobber a
concurrent quit request. EmuThreadStop stops and joins from any live
state, so unloading while paused no longer leaves a thread running over
freed state. EmuThreadPause pumps queued frames until the thread parks,
via a new non-blocking GLRenderManager::HasQueuedThreadWork() check,
instead of draining one frame, which deadlocked when the thread was
blocked on a readback sync in the next frame. retro_run resumes a paused
thread and pauses it before check_variables() rewrites g_Config,
retro_reset stops it before PSP_Shutdown(), and the sleep_ms(4) after
resume is gone.
2026-10-08 09:18:45 +02:00
AlemarandClaude Opus 4.8 821c5b4534 libretro: restore emu-thread pause handshake to fix serialize deadlock
c42a3f070a removed PAUSE_REQUESTED, which turned the acknowledge-wait in
EmuThreadPause() into dead code: emuThreadState is set to PAUSED on the line
above the `while (emuThreadState != PAUSED)` poll, so pause returns without the
emu thread parked at a frame boundary. retro_serialize / retro_unserialize then
race the GL ThreadFrame handshake and can deadlock the emu thread under periodic
save-states.

Restore the minimal handshake: EmuThreadPause() requests the pause, the emu
thread transitions PAUSE_REQUESTED -> PAUSED at its own frame boundary, and
retro_run treats the request window as paused. START_REQUESTED stays removed and
the new shutdown path is untouched.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-25 03:08:31 -06:00
Henrik Rydgård 893ac3e3db Frametests: add framedump rendering test runner and PNG screenshot support
- Add frametests.py: walks a dump tree, renders each dump per config variant
  through PPSSPPHeadless, generates reference images when missing and compares
  MSE when present, and writes a self-contained HTML report. The JSON config
  (which lives with the test set, not in the repo) points at the data tree
  and defines variants as suffix -> CLI args, e.g. 'soft': '--graphics=software'.
- Headless: --screenshot-save saves PNG when the path ends in .png; new
  --screenshot-diff always writes a visual comparison when comparing;
  screenshot comparison failures (mismatch or unloadable reference) now fail
  the test instead of passing silently.
- Read back framebuffers top-down, flipping only for BMP output/input
  (fixes upside-down PNG references). Sync libretro copy accordingly.
- Document the system in docs/frametest.md; add AGENTS.md reference.
2026-08-09 13:41:39 +02:00
Henrik Rydgård c42a3f070a Implement the new shutdown path for libretro too 2026-08-04 17:45:03 +02:00
Henrik Rydgård 3eb056ad86 Move Common/GraphicsContext.h to Common/GPU/GraphicsContext.h 2026-07-26 13:58:17 +02:00
Henrik Rydgård 7f218acc53 Change the GraphicsContext interface to be more consistent 2026-07-26 10:22:00 +02:00
Henrik Rydgård a317890c08 Remove the GPUDebugInterface class
Just a pointless extra layer in the class hiearchy, making it
unnecessarily hard to modify the interface.

Might as well hit GPUCommon directly.
2026-06-02 11:15:08 +02:00
celerizer 72bd0fa4d3 add null-checks on software render path 2026-04-07 11:05:50 -05:00
刘皓 a018cfc017 Update libretro-common and remove redundant libretro header files 2025-12-30 23:06:58 -05:00
Henrik Rydgård 6cfea96e58 Remove D3D9 support, to make future changes easier 2025-06-10 15:07:16 +02:00
sonninnos 49b9319570 libretro: Revised software rendering option 2024-06-04 14:25:46 +03:00
sonninnos 957c4c7d74 libretro: Add CropTo16x9 core option 2024-06-03 21:48:12 +03:00
sonninnos c8b7ae817d libretro: Add video renderer core option 2024-06-03 21:48:12 +03:00
Henrik Rydgård ff6e118fff Get rid of a lot of ifdefs around presentation mode. Instead, set things dynamically. 2023-08-14 11:02:29 +02:00
Henrik Rydgård dc4de340b3 Some debug overlays don't make sense when not in-game, disable them. Minor feedback fixes. 2023-08-13 21:54:24 +02:00
Henrik Rydgård 1ea11c233c Remove "SwapBuffers" from the GraphicsContext interface.
Buildfixes

More buildfix

headless buildfix

One more buildfix
2023-08-11 01:57:02 +02:00
Stuart Kenny da4652aa2a Do not skip SwapBuffer() when skipDrawReason set.
Fixes nothing being rendered with high frameskip ratios.
2021-09-06 20:00:50 +01:00
Unknown W. Brackets 3c9ab13672 GPU: Remove NULL GPU.
We can use the software GPU without a backend now, and this is in every
way superior and will result in better tests/headless behavior.
2021-01-02 09:36:13 -08:00
Henrik Rydgård 81bddf268a Merge pull request #13598 from tbocek/master
Fix issue in #12145
2020-11-27 23:04:36 +01:00
Henrik Rydgård 0e3a84b4a8 Move most GPU things to Common.
It works after the move, on Windows and Android at least.

Deletes the D3DX9 shader compiler loader, which was not used.
2020-10-04 23:39:02 +02:00
tbocek b009ec8f52 No need to call video_cb if there is no image 2020-05-31 11:32:24 +02:00
tbocek 1f49141c30 Setting the width and height to 0 made the frameskip unusable on lakka/libretro with a XU4 with a MALI GPU T628. The result was that bad flickering happened when in frameskip mode. Once it reached 60fps, no flickering, below that flickering. This change fixes the flickering and calls video_cb with the correct height and width. 2020-04-04 11:59:27 +02:00
Unknown W. Brackets 5871ab0538 UI: Stop caching the draw context in coreParam.
This is possibly getting outdated in some paths of graphics reinit, and
then causing crashes.  Let's just always get it from the graphicsContext.
2019-09-28 21:58:15 -07:00
aliaspider 4202ae58bd Libretro: style nits. 2018-03-26 17:37:34 +01:00
aliaspider 5a9ce3bc19 Libretro: set cache_context to true, fixes GL and D3D11 context reset. 2018-03-26 17:21:11 +01:00
aliaspider 808bf8e681 Libretro: add experimental D3D11 support. 2018-03-25 23:07:02 +01:00
aliaspider 4113ba74f2 libretro: msvc build fix. 2018-03-24 22:47:12 +01:00
aliaspider d1711c5aa4 nits. 2018-03-24 13:39:05 +01:00
aliaspider c4f7790618 Libretro port. 2018-03-24 12:44:53 +01:00