`bios_hle` (default on) is the player-facing "skip the BIOS and go
straight to the game" flag, and it did nothing under the bundled
OpenBIOS: choosing OpenBIOS sat the player in the boot animation while
the identical build on retail SCPH-1001 went straight to the game.
Root cause was ordering, not policy. The tier has two axes with
different per-image requirements:
* boot-skip needs only `shell_entry_phys`, works under pure LLE
(nothing is synthesized — the shell call just returns
immediately), so any image exporting it can skip
* kernel-call needs `deliver_event_ret`, the kernel's own
DeliverEvent `$ra`, or a delivered callback returns to
the wrong PC
main.cpp correctly refused the call axis on an image without
`deliver_event_ret` by assigning `bios_hle = false` — and then derived
`boot_skip` from that already-mutated flag. OpenBIOS omits
`deliver_event_ret` (B0 semantics unvalidated) but DOES export
`shell_entry_phys`, so an available skip was cancelled by an unrelated
refusal, and one flag meant two things depending on a BIOS detail no
player can see.
Both axes are now decided by one pure, dependency-free function,
`psx_bios_hle_plan()` (runtime/src/bios_hle_plan.c): the boot decision
reads the REQUESTED `bios_hle`, each axis is gated on only the anchor it
needs, and refusals are reported at startup instead of downgrading
silently. `psx_bios_hle_configure()` clamps `boot_skip` to
`shell_entry_phys != 0` as a backstop so the banner and `hle_dump`
cannot overstate what can fire. The main.cpp local is renamed
`bios_hle_requested` and is no longer written back from the plan — the
`session_reboot` path re-enters that block, so folding a refusal into
the request would have made a netplay rematch differ from first launch.
Also in this pass:
* A BIOS profile's `[runtime]` block was parsed into
`BiosConfig::runtime` and read by NOTHING, and bios/OpenBIOS.toml
carried an inert `bios_hle = false` there that read as the reason HLE
was off on OpenBIOS. It was not. `load_bios_config` now REJECTS
`[runtime]` in a BIOS profile: a profile states facts about an image,
never preferences.
* `psx_icache_fastpath_test` had been unbuildable ("redefinition of
`psx_advance_cycles`" — the test's counting stub vs the header's
`static inline`), which blocked every runtime test registered after
it. It now builds with `PSX_OVERLAY_DLL_BUILD=1`, the seam
psx_cycles.h already provides for a TU supplying its own advance.
Tests: new `bios_hle_plan_test` pins the matrix, including a 64-case
sweep asserting the boot decision is independent of
`deliver_event_ret` and the call decision independent of
`shell_entry_phys`. Runtime ctest 15/15, recompiler ctest 30/30.
Validated on Ape Escape (SCUS-94423) built against this framework with
both backends linked, headless, all four cases:
OpenBIOS default bios_boot=skip to game; route=2 fire at vec 0x30000
ra=0xBFC06EA8 (the continuation OpenBIOS.toml
documents); in-game on screen
retail default bios_boot=skip to game; route=2 at vec 0x30000
ra=0xBFC0702C; in-game on screen; differs only in
bios_backend=HLE (LLE fallback)
PSX_BIOS_HLE=0 bios_boot=real intro; ring empty (no hook)
KEEP_INTRO=1 bios_boot=real intro; ring empty
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Cycle the renderer selector through Software, OpenGL, and Vulkan while retaining OpenGL-only option gating.
Co-authored-by: Martin Penkava <mpenkava1337@gmail.com>
Record queue-wait, acquire, and present durations plus presentation timestamps in the existing vk_perf ring.
Co-authored-by: Martin Penkava <mpenkava1337@gmail.com>
Let the frontend remain the sole frame pacer by requesting MAILBOX for tear-free delivery, with FIFO retained as the required fallback.
Co-authored-by: Martin Penkava <mpenkava1337@gmail.com>
Keep a shared work command buffer open across logical GPU operations and submit it at the existing synchronization boundary.
Co-authored-by: Martin Penkava <mpenkava1337@gmail.com>
Add same-layout color attachment barriers before geometry and wide-surface render passes so prior writes are visible to LOAD and blend operations.
Co-authored-by: Martin Penkava <mpenkava1337@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Include the transfer stage in the swapchain acquire wait mask because the present command buffer clears and blits the acquired image with transfer operations.
Co-authored-by: Martin Penkava <mpenkava1337@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Pad each packed R16 upload region to an even texel count so subsequent VkBufferImageCopy offsets retain the required four-byte alignment.
Co-authored-by: Martin Penkava <mpenkava1337@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Port the reusable Gaussian interpolation slice from PR #16 while keeping its reverb engine on a separate branch.
Co-authored-by: Martin Penkava <mpenkava1337@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Apply the PS1 1023x511 size rule to every polygon triangle, line, and polyline continuation before widescreen transforms while preserving textured-command state latching.
Co-authored-by: Martin Penkava <mpenkava1337@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Admit post-EXE RAM to the dirty interpreter only after a real control transfer and an existing MIPS decodability check. Keep the already-merged overlay initialization guard out of this focused change.
Co-authored-by: Martin Penkava <mpenkava1337@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>