From 78c8d2142c67405833cd3b449fde154dac1633c6 Mon Sep 17 00:00:00 2001 From: notaz Date: Fri, 27 Dec 2024 22:04:33 +0200 Subject: [PATCH] gpu: further timing hacks libretro/pcsx_rearmed#711 notaz/pcsx_rearmed#348 --- libpcsxcore/database.c | 41 ++++++++++++++++++++++++++++++++++------- libpcsxcore/psxcommon.h | 2 +- libpcsxcore/psxdma.c | 11 ++++++----- plugins/gpulib/gpu.c | 6 +++--- 4 files changed, 44 insertions(+), 16 deletions(-) diff --git a/libpcsxcore/database.c b/libpcsxcore/database.c index cf2a16aa..35d00414 100644 --- a/libpcsxcore/database.c +++ b/libpcsxcore/database.c @@ -32,6 +32,8 @@ static const char * const gpu_slow_llist_db[] = "SLES01712", "SLPS01525", "SLPS91138", "SLPM87102", "SLUS00823", /* Crash Bash */ "SCES02834", "SCUS94570", "SCUS94616", "SCUS94654", + /* F1 2000 - aborting/resuming dma in menus */ + "SLUS01120", "SLES02722", "SLES02723", "SLES02724", "SLPS02758", "SLPM80564", /* Final Fantasy IV */ "SCES03840", "SLPM86028", "SLUS01360", /* Point Blank - calibration cursor */ @@ -54,12 +56,6 @@ static const char * const gpu_centering_hack_db[] = "SLPM86009", }; -static const char * const dualshock_timing1024_hack_db[] = -{ - /* Judge Dredd - could also be poor cdrom+mdec+dma timing */ - "SLUS00630", "SLES00755", -}; - static const char * const dualshock_init_analog_hack_db[] = { /* Formula 1 Championship Edition */ @@ -109,7 +105,6 @@ hack_db[] = HACK_ENTRY(cdr_read_timing, cdr_read_hack_db), HACK_ENTRY(gpu_slow_list_walking, gpu_slow_llist_db), HACK_ENTRY(gpu_centering, gpu_centering_hack_db), - HACK_ENTRY(gpu_timing1024, dualshock_timing1024_hack_db), HACK_ENTRY(dualshock_init_analog, dualshock_init_analog_hack_db), HACK_ENTRY(fractional_Framerate, fractional_Framerate_hack_db), HACK_ENTRY(f1, f1_hack_db), @@ -157,6 +152,22 @@ cycle_multiplier_overrides[] = { 200, { "SLUS01519", "SCPS45260", "SLPS01463" } }, }; +static const struct +{ + int cycles; + const char * const id[4]; +} +gpu_timing_hack_db[] = +{ + /* Judge Dredd - poor cdrom+mdec+dma+gpu timing */ + { 1024, { "SLUS00630", "SLES00755" } }, + /* F1 2000 - flooding the GPU in menus */ + { 300*1024, { "SLUS01120", "SLES02722", "SLES02723", "SLES02724" } }, + { 300*1024, { "SLPS02758", "SLPM80564" } }, + /* Soul Blade - same as above */ + { 512*1024, { "SLUS00240", "SCES00577" } }, +}; + static const char * const lightrec_hack_db[] = { /* Tomb Raider (Rev 2) - boot menu clears over itself */ @@ -223,6 +234,22 @@ void Apply_Hacks_Cdrom(void) } } + Config.gpu_timing_override = 0; + for (i = 0; i < ARRAY_SIZE(gpu_timing_hack_db); i++) + { + const char * const * const ids = gpu_timing_hack_db[i].id; + for (j = 0; j < ARRAY_SIZE(gpu_timing_hack_db[i].id); j++) + if (ids[j] && strcmp(ids[j], CdromId) == 0) + break; + if (j < ARRAY_SIZE(gpu_timing_hack_db[i].id)) + { + Config.gpu_timing_override = gpu_timing_hack_db[i].cycles; + SysPrintf("using gpu_timing_override: %d\n", + Config.gpu_timing_override); + break; + } + } + if (drc_is_lightrec()) { lightrec_hacks = 0; if (Config.hacks.f1) diff --git a/libpcsxcore/psxcommon.h b/libpcsxcore/psxcommon.h index 0a1ef707..9c9bcda5 100644 --- a/libpcsxcore/psxcommon.h +++ b/libpcsxcore/psxcommon.h @@ -145,6 +145,7 @@ typedef struct { boolean TurboCD; int cycle_multiplier; // 100 for 1.0 int cycle_multiplier_override; + int gpu_timing_override; s8 GpuListWalking; s8 FractionalFramerate; // ~49.75 and ~59.81 instead of 50 and 60 u8 Cpu; // CPU_DYNAREC or CPU_INTERPRETER @@ -154,7 +155,6 @@ typedef struct { boolean gpu_slow_list_walking; boolean gpu_centering; boolean dualshock_init_analog; - boolean gpu_timing1024; boolean fractional_Framerate; boolean f1; } hacks; diff --git a/libpcsxcore/psxdma.c b/libpcsxcore/psxdma.c index f670dd15..af791c0e 100644 --- a/libpcsxcore/psxdma.c +++ b/libpcsxcore/psxdma.c @@ -192,10 +192,11 @@ void psxDma2(u32 madr, u32 bcr, u32 chcr) { // GPU case 0x01000401: // dma chain PSXDMA_LOG("*** DMA 2 - GPU dma chain *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); // when not emulating walking progress, end immediately + // (some games abort the dma and read madr so break out of that logic) madr_next = 0xffffff; do_walking = Config.GpuListWalking; - if (do_walking < 0 || Config.hacks.gpu_timing1024) + if (do_walking < 0) do_walking = Config.hacks.gpu_slow_list_walking; madr_next_p = do_walking ? &madr_next : NULL; @@ -204,9 +205,9 @@ void psxDma2(u32 madr, u32 bcr, u32 chcr) { // GPU HW_DMA2_MADR = SWAPu32(madr_next); - // a hack for Judge Dredd which is annoyingly sensitive to timing - if (Config.hacks.gpu_timing1024) - cycles_sum = 1024; + // timing hack with some lame heuristics + if (Config.gpu_timing_override && (do_walking || cycles_sum > 64)) + cycles_sum = Config.gpu_timing_override; psxRegs.gpuIdleAfter = psxRegs.cycle + cycles_sum + cycles_last_cmd; set_event(PSXINT_GPUDMA, cycles_sum); @@ -238,7 +239,7 @@ void gpuInterrupt() { psxRegs.gpuIdleAfter = psxRegs.cycle + cycles_sum + cycles_last_cmd; set_event(PSXINT_GPUDMA, cycles_sum); //printf("%u dma2cn: %6ld,%4d %08x\n", psxRegs.cycle, cycles_sum, - // cycles_last_cmd, HW_DMA2_MADR); + // cycles_last_cmd, HW_DMA2_MADR); return; } if (HW_DMA2_CHCR & SWAP32(0x01000000)) diff --git a/plugins/gpulib/gpu.c b/plugins/gpulib/gpu.c index ac9b86a3..9eb31787 100644 --- a/plugins/gpulib/gpu.c +++ b/plugins/gpulib/gpu.c @@ -831,10 +831,8 @@ long GPUdmaChain(uint32_t *rambase, uint32_t start_addr, } } - if (progress_addr) { - *progress_addr = addr; + if (progress_addr && (cpu_cycles_last + cpu_cycles_sum > 512)) break; - } if (addr == ld_addr) { log_anomaly(&gpu, "GPUdmaChain: loop @ %08x, cnt=%u\n", addr, count); break; @@ -851,6 +849,8 @@ long GPUdmaChain(uint32_t *rambase, uint32_t start_addr, gpu.state.last_list.cycles = cpu_cycles_sum + cpu_cycles_last; gpu.state.last_list.addr = start_addr; + if (progress_addr) + *progress_addr = addr; *cycles_last_cmd = cpu_cycles_last; return cpu_cycles_sum; }