Improve SmackDown 2 runtime stability, audio, and Vulkan performance - #16
Improve SmackDown 2 runtime stability, audio, and Vulkan performance#16shaneomac1337 wants to merge 7 commits into
Conversation
- psx_cyc.h / psx_cycles.c: _BitScanForward/_BitScanReverse shims for __builtin_ctz/__builtin_clz under _MSC_VER - full_function_emitter.cpp / main_psx.cpp: emit a portable .CRT$XCU init-pointer instead of GCC-only __attribute__((constructor)) in generated dispatch/game code - main.cpp: declare cross-language globals extern "C" so MSVC links them against their C definitions (no-op for GCC/Clang) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Two deterministic boot hangs (WWF SmackDown! 2, SLUS-01234): 1. overlay_loader_dispatch()/is_candidate()/call_native() ran during early BIOS kernel init (0xBFC0DB10 memcard polling loop) before overlay_loader_init() built the range-index structures, walking uninitialized lists until a PC=0 trap (froze at cycle 208195 every boot). Guard all three entry points on s_active. 2. Code at 0x800D1F28 (boot-text populated by bulk host transfer that bypassed the RAM write-marking hooks) was neither compiled, dirty, nor overlay -> unknown-dispatch fail at frame 1340. Add a fallback: an address above overlay_region_floor whose word decodes as valid MIPS is marked executable and handed to the dirty-RAM interpreter. Validated 5/5 reproducible boots, 2000+ frame sustained runs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Replace nearest-sample voice pitch resampling with the PS1 hardware 4-tap Gaussian (No$ table, new spu_gauss.h; formula (g[0xFF-i]*s[-3] + g[0x1FF-i]*s[-2] + g[0x100+i]*s[-1] + g[i]*s[0])>>15 with i=(phase>>4)&0xFF). Nearest-sample put a flat aliasing shelf at ~-31 dB across 8-22 kHz (measured); Gaussian drops it 18 dB and restores natural spectral decay. Adds prev[3] cross-block history. - Beetle-model reverb engine on the SPU mix. - Gate the float-shadow substitution off while any voice has a reverb send (the shadow models only the dry mix). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The PS1 GPU does not render a polygon or line when the distance between any two vertices exceeds 1023 horizontally or 511 vertically (No$ docs; Beetle/DuckStation enforce it per rendered triangle). Games rely on the cull during zoom transitions and close camera cuts: their 11-bit-wrapped vertices span the whole coordinate space and, without the reject, get rasterized as giant flat-color triangles covering the frame (SmackDown 2 rendered its menu star wipe and in-match crowd cuts as a full black cover in both the software and GL backends). Applied per-triangle in all polygon execs (quads reject each half independently; textured variants still latch the texpage word first, matching hardware), plus lines and both polyline continuations. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Fixes found chasing block corruption on AMD RDNA3 (RX 7900 XT) that the NVIDIA driver this backend was developed on tolerates: - flush_cpu_upload: keep every packed rect's VkBufferImageCopy bufferOffset 4-byte aligned (an odd w*h rect misaligned every following rect's R16 offset to 2 mod 4) - begin_geo_pass + wide passes: color-aspect self-barrier mirroring the existing stencil self-barrier (img_to emits no barrier when the layout is unchanged, and the render pass declares no EXTERNAL dependency, so back-to-back passes had no memory dependency on the color attachment) - submit_present: wait the acquire semaphore at TRANSFER (all swapchain writes here are transfer ops); waiting at COLOR_ATTACHMENT_OUTPUT left them unordered against presentation-engine release Still NOT fixed on AMD: black block confetti on BIOS/FMV screens. VRAM-state dumps prove the hr image content is bit-perfect at present time, so remaining corruption is in the present chain. Env-gated diagnostics (tagged [DEBUG-vk01]) included for the ongoing hunt: PSX_VK_VERIFY / PSX_VK_DUMP / PSX_VK_ONEPASS / PSX_VK_EAGER_UPLOAD / PSX_VK_NO_MERGE. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Hello!. I have pulled the MSVC generated-initializer fix into #1 and the overlay pre-initialization guardinto #23 The broader executable discovery, GPU/SPU changes, Vulkan work, and shaders are not yet pulled in. I need to give those more of my time before I can merge them out. But thank you for the work so far! Eager to find time to dig into the rest |
|
Tested the extracted Vulkan changes from this PR in Tomba 2 on an RTX 3080 Ti. It booted through SCEA and the Whoopee Camp FMV into gameplay, but it does not feel merge-ready yet:
Keeping the Vulkan work parked for further isolation. |
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>
|
Hello! Wanted to follow up on this draft. The SPU reverb implementation closely seems to model Beetle/Medafen's, which are GPLv2. Want to make sure before I include anything that I understand attribute. Similar question for the CRT shader. Suggest it's inspired by CRT-Royale. I'm not sure what that is, and would like to understand its licensing as well before taking it into consideration. Take care! |
Adapt only the fail-closed overlay lifecycle checks from mstan/psxrecomp#16 commit e6809ccf7d778a4c2f32d9e27c0ec31a44cbd2ba. Add a focused structural regression test and record the excluded dirty-interpreter and game/runtime work. Co-authored-by: Martin Penkava <mpenkava1337@gmail.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
|
A follow up on this PR. PR #104 introduced a clean room psx-spx/nocash register instead. One thing that was not addressed in that was the hardware's 22.05->44.1 kHz reverb reconstruction filter. Given Beetle's GPL licensing, I wasn't able to borrow it from there and would need to derive a clean room implementation. The functionality is isolated and a future PR that modifies it is always welcome; assuming it follows proper licensing. |
…inational Closes the four gaps named in issue mstan#103 and lands the separable, verified parts of PR mstan#102. See docs/internal/SPU_FIDELITY_103.md for the per-piece disposition and the oracle-verification queue. SPU DSP (issue mstan#103), clean-room from hardware documentation: - Reverb: the documented 22050 Hz engine — vLIN/vRIN input, same-side and crossed different-side IIR reflections, 4-tap comb early echo, both all-pass filters, vLOUT/vROUT output, and the work-area address advance. Gated on SPUCNT bit 7 for WRITES only; reads, IRQ checks, address advance and output always run, as on hardware. Addressing is confined to [mBASE, 0x80000). Per-voice sends from EON, CD send from SPUCNT bits 0+2. - Noise: 16-bit LFSR with the documented parity feedback, clocked at the SPUCNT bits 8-13 rate; NON voices substitute it for their ADPCM sample. - Volume sweeps: all 24 voice L/R plus main L/R. Bit 15 selects sweep vs direct; sweep is a live envelope on the same rate machinery as ADSR, and a guest read of a sweeping register returns the live level. - Capture buffers: CD L/R and voice 1/3 output written to SPU RAM, so a game that parks the IRQ address there still gets its interrupt. - SPU IRQ (I_STAT bit 9): checked at every SPU RAM access class — FIFO, DMA both directions, ADPCM block fetch, capture writes, reverb work-area accesses — gated on SPUCNT bit 6, mirrored in SPUSTAT bit 6, acked by clearing SPUCNT bit 6. The CD-only fast path in spu_render was removed rather than extended: the SPU now has per-frame work that must run in every path, and an FMV (XA audio with zero active voices) is exactly the CD-with-reverb case. This is a clean-room implementation from the psx-spx/nocash register map and documented algorithm. Beetle's source was deliberately not consulted: it is GPL-2.0-or-later and this project is PolyForm Noncommercial. PR mstan#16 was parked for exactly that reason and PR mstan#13's reverb was separately wrong (it gated on bit 15 of dAPF1, an address offset, instead of SPUCNT bit 7). The one place this knowingly deviates from hardware is the 22.05 -> 44.1 kHz reconstruction filter, which the documentation does not specify; it is isolated in a single function and flagged for oracle comparison. CAUSE.IP2 (from PR mstan#102): IP2 is combinational on R3000A — it mirrors the interrupt line and falls the instant the guest acks I_STAT or masks the source. It was being OR'd in at delivery and never cleared, in TWO places (the compiled path and psx_interpreter.c, the latter missed by PR mstan#102), leaving a phantom pending interrupt that can spin a kernel dispatcher looping on CAUSE.IP & SR.IM. psx_irq_refresh_cause_ip2() is now the sole writer of bit 10, refreshed at raise, I_STAT ack, I_MASK write, HLE context restore and power-on. Verified against the Beetle oracle's irq.cpp/cpu.cpp rather than asserted, and covered by test_cause_ip2_combinational. Mid-dispatch audio pump (from PR mstan#102), with a fix: routed through a gate that mirrors sdl_audio_update's mute/sink decision. Pumping unconditionally from the VBlank edge, as submitted, would have pushed real audio during every turbo-load hard mute and defeated the freeze-in-place mute model. SPU RAM DMA readback (from PR mstan#102): DMA4 in the SPU->RAM direction wrote literal zeros; SPU RAM is readable memory and titles carry state through it across an Exec boundary. Also fixes an unrelated build race found on the way: tools/embed_spirv.py wrote its intermediate SPIR-V to <source>.spv, so the two runtime targets that embed the same shaders raced on one path and one deleted the file the other was reading. Co-Authored-By: Alexandros Mandravillis <Alexbeav@live.com> Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>



What changed
Why
SmackDown 2 previously encountered boot freezes, missing reverb, and Vulkan frame-time spikes caused by repeated command submissions, staging allocations, and competing presentation pacing.
Impact
The game boots reliably, retains higher-quality PSX audio, and renders through Vulkan at a much steadier cadence while preserving configurable screen simulation.
Validation
SmackDown2Recomp.exesuccessfully with Vulkan enabledThe generic BIOS-only framework link still reports the existing unresolved
psx_game_address_in_textsymbol; the game target itself builds successfully.