From 397f72d9df69b4480160c8e08f252db89b5bc9ef Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Sat, 19 Apr 2025 15:27:02 +0200 Subject: [PATCH] lightrec: Detect and speed up GPU status polling If the GPUSTATUS_POLLING_THRESHOLD macro is set to a value > 0, the Lightrec glue code will attempt to detect polling of the GPU status register, with a polling interval in PSX cycles up to the threshold configured. This is still quite experimental, hence the reason why it's disabled by default. However, this gives a huge speed boost (35% and above) when running on Dreamcast, tested with a threshold value of 350, on games that don't use the PSX CPU much and spend a lot of time waiting for VSYNC. Signed-off-by: Paul Cercueil --- libpcsxcore/lightrec/plugin.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/libpcsxcore/lightrec/plugin.c b/libpcsxcore/lightrec/plugin.c index f05012d7..3e112654 100644 --- a/libpcsxcore/lightrec/plugin.c +++ b/libpcsxcore/lightrec/plugin.c @@ -61,6 +61,10 @@ # endif #endif +#ifndef GPUSTATUS_POLLING_THRESHOLD +# define GPUSTATUS_POLLING_THRESHOLD 0 +#endif + psxRegisters psxRegs; Rcnt rcnts[4]; @@ -234,12 +238,30 @@ static u16 hw_read_half(struct lightrec_state *state, static u32 hw_read_word(struct lightrec_state *state, u32 op, void *host, u32 mem) { - u32 val; + static u32 old_cycle, oldold_cycle, old_gpusr; + u32 val, diff; lightrec_tansition_to_pcsx(state); val = psxHwRead32(mem); + if (GPUSTATUS_POLLING_THRESHOLD > 0 && mem == 0x1f801814) { + diff = psxRegs.cycle - old_cycle; + + if (diff > 0 + && diff < GPUSTATUS_POLLING_THRESHOLD + && diff == old_cycle - oldold_cycle) { + while (psxRegs.next_interupt > psxRegs.cycle && val == old_gpusr) { + psxRegs.cycle += diff; + val = psxHwRead32(mem); + } + } + + oldold_cycle = old_cycle; + old_cycle = psxRegs.cycle; + old_gpusr = val; + } + lightrec_tansition_from_pcsx(state); return val; -- 2.39.5