gpu: further timing hacks
authornotaz <notasas@gmail.com>
Fri, 27 Dec 2024 20:04:33 +0000 (22:04 +0200)
committernotaz <notasas@gmail.com>
Sat, 28 Dec 2024 21:10:42 +0000 (23:10 +0200)
libretro/pcsx_rearmed#711
notaz/pcsx_rearmed#348

libpcsxcore/database.c
libpcsxcore/psxcommon.h
libpcsxcore/psxdma.c
plugins/gpulib/gpu.c

index cf2a16a..35d0041 100644 (file)
@@ -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)
index 0a1ef70..9c9bcda 100644 (file)
@@ -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;
index f670dd1..af791c0 100644 (file)
@@ -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))
index ac9b86a..9eb3178 100644 (file)
@@ -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;
 }