overlay: unify cache read/write location + fix missing ws_cull symbol in DLLs

Two framework bugs that made overlay variants run interpreted forever (the
"agonizing lag" in overlay-heavy areas like Tomba's dwarf village):

1. Cache read/write divergence. The loader reads <exe>/cache and the runtime
   writes captures to <exe>/overlay_captures.json, but the gcc autocompile path
   used the game.toml command verbatim, whose hard-coded --out-dir/--captures
   pointed elsewhere (build-stable/build-modern). So compiled shards landed where
   the loader never looked and captures were read stale -> the variant never went
   native. Fix: the runtime now injects PSX_OVERLAY_CACHE_DIR / PSX_OVERLAY_CAPTURES
   (the canonical loader paths) into every autocompile spawn; compile_overlays.py
   honors them over any CLI flag (--captures now optional). One source of truth for
   the cache location, uniform across all games, dev or prod. gcc/tcc stay separated
   by the existing <compiler> namespace.

2. Overlay DLL preamble missing psx_ws_cull_sltiu. auto_screen_x emits this helper
   at every width-cull site into EVERY build's C (identity at 4:3), and the main EXE
   links it from gpu.c, but the overlay DLL preamble never defined it -> any overlay
   variant with cull sites failed to link -> no shard -> interpreter. Fix: provide
   the self-contained helper (depends only on the already-forwarded psx_ws_x_margin)
   in the DLL preamble.

Proven on Tomba dwarf village: dispatch_native 29/s -> 11454/s (was ~97% interp,
now ~97% native).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Matthew Stanley
2026-06-25 18:57:57 -07:00
parent 1915b5c1bf
commit e7f7fb6cf0
4 changed files with 78 additions and 4 deletions
+12 -2
View File
@@ -2039,11 +2039,21 @@ int main(int argc, char** argv) {
ac_cmd = &gc.runtime.overlay_autocompile_cmd;
}
if (ac_cmd) {
/* Pin the compile's WRITE cache + READ captures to the SAME
* canonical locations the loader uses (cache_dir = <exe>/cache,
* <exe>/overlay_captures.json — set above). The framework owns
* the cache location; no game.toml --out-dir/--captures can make
* the write drift from the read. Single source of truth, all
* games, dev or prod. */
std::string captures_path =
(exe_dir / "overlay_captures.json").string();
autocompile_set_cache_paths(cache_dir.c_str(),
captures_path.c_str());
autocompile_configure(ac_cmd->c_str(),
gc.project_root.string().c_str());
std::fprintf(stdout,
"psxrecomp: overlay autocompile enabled (%s)\n",
overlay_backend_name(eff));
"psxrecomp: overlay autocompile enabled (%s); cache=%s\n",
overlay_backend_name(eff), cache_dir.c_str());
}
code_provider_init(cfg_backend, gcc_avail);
/* Now that the backend is resolved, apply the sljit live policy: