From: notaz Date: Sat, 21 Mar 2026 21:36:55 +0000 (+0200) Subject: gpulib: remove some unreliable heuristics X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b541b5a8e528ad14d80183724efb979e57b78b83;p=pcsx_rearmed.git gpulib: remove some unreliable heuristics Make it another hack option instead. Sucks but I don't have a better solution for now. libretro/pcsx_rearmed#915 --- diff --git a/frontend/libretro.c b/frontend/libretro.c index 22898b56..936bd93d 100644 --- a/frontend/libretro.c +++ b/frontend/libretro.c @@ -2667,6 +2667,18 @@ static void update_variables(bool in_flight) Config.FractionalFramerate = -1; } + var.value = NULL; + var.key = "pcsx_rearmed_alt_flip"; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + if (strcmp(var.value, "early") == 0) + Config.AlternativeFlip = 1; + else if (strcmp(var.value, "late") == 0) + Config.AlternativeFlip = 0; + else // auto + Config.AlternativeFlip = -1; + } + var.value = NULL; var.key = "pcsx_rearmed_screen_centering"; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) diff --git a/frontend/libretro_core_options.h b/frontend/libretro_core_options.h index eb0c3b5a..e049c6f4 100644 --- a/frontend/libretro_core_options.h +++ b/frontend/libretro_core_options.h @@ -446,6 +446,21 @@ struct retro_core_option_v2_definition option_defs_us[] = { }, "auto", }, + { + "pcsx_rearmed_alt_flip", + "Framebuffer readout", + NULL, + "Some games make changes to the framebuffer while it's being sent to the display, which is currently not emulated. However this option allows to choose if the emulator takes the video frame before the emulated PSX active display period ('Early') or after ('Late'). Normally this should be left at 'Auto'.", + NULL, + "video", + { + { "auto", "Auto" }, + { "early", "Early" }, + { "late", "Late" }, + { NULL, NULL }, + }, + "auto", + }, { "pcsx_rearmed_rgb32_output", "RGB32 output", diff --git a/frontend/main.c b/frontend/main.c index 267eb840..ee2de1cf 100644 --- a/frontend/main.c +++ b/frontend/main.c @@ -114,6 +114,7 @@ void emu_set_default_config(void) Config.cycle_multiplier = CYCLE_MULT_DEFAULT; Config.GpuListWalking = -1; Config.FractionalFramerate = -1; + Config.AlternativeFlip = -1; pl_rearmed_cbs.dithering = 1; pl_rearmed_cbs.gpu_neon.allow_interlace = 2; // auto diff --git a/frontend/menu.c b/frontend/menu.c index fd1bebe8..0491908f 100644 --- a/frontend/menu.c +++ b/frontend/menu.c @@ -112,7 +112,7 @@ static int psx_clock; static int memcard1_sel = -1, memcard2_sel = -1; static int cd_buf_count; extern int g_autostateld_opt; -static int menu_iopts[8]; +static int menu_iopts[9]; int g_opts, g_scaler, g_gamma = 100; int scanlines, scanline_level = 20; int soft_scaling, analog_deadzone; // for Caanoo @@ -420,6 +420,7 @@ static const struct { CE_CONFIG_VAL(Cpu), CE_CONFIG_VAL(GpuListWalking), CE_CONFIG_VAL(FractionalFramerate), + CE_CONFIG_VAL(AlternativeFlip), CE_CONFIG_VAL(PreciseExceptions), CE_CONFIG_VAL(TurboCD), CE_CONFIG_VAL(SlowBoot), @@ -1424,7 +1425,7 @@ static menu_entry e_menu_gfx_options[] = mee_range_h ("Gamma adjustment", MA_OPT_GAMMA, g_gamma, 1, 200, h_gamma), mee_onoff ("OpenGL Vsync", MA_OPT_VSYNC, g_opts, OPT_VSYNC), mee_cust_h ("Setup custom scaler", MA_OPT_VARSCALER_C, menu_loop_cscaler, NULL, h_cscaler), - mee_onoff_h ("Force low resolution", 0, pl_rearmed_cbs.scale_hires, 1, h_lowres), + mee_onoff_h ("Force low resolution", 0, menu_iopts[0], 1, h_lowres), mee_end, }; @@ -1432,8 +1433,12 @@ static int menu_loop_gfx_options(int id, int keys) { static int sel = 0; + menu_iopts[0] = pl_rearmed_cbs.scale_hires; + me_loop(e_menu_gfx_options, &sel); + pl_rearmed_cbs.scale_hires = menu_iopts[0]; + return 0; } @@ -1617,7 +1622,7 @@ static menu_entry e_menu_plugin_options[] = #ifdef USE_ASYNC_GPU mee_enum ("GPU multithreading", 0, menu_iopts[1], men_autooo), #endif - mee_enum ("GPU dithering", 0, pl_rearmed_cbs.dithering, men_gpu_dithering), + mee_enum ("GPU dithering", 0, menu_iopts[2], men_gpu_dithering), mee_enum_h ("SPU plugin", 0, spu_plugsel, spu_plugins, h_plugin_spu), #ifndef C64X_DSP mee_onoff_h ("SPU multithreading", MA_OPT_SPU_THREAD, spu_config.iUseThread, 1, h_sputhr), @@ -1635,12 +1640,16 @@ static int menu_loop_plugin_options(int id, int keys) int spu_thread_old = spu_config.iUseThread; menu_iopts[0] = Config.SlowBoot; menu_iopts[1] = pl_rearmed_cbs.thread_rendering + 1; + menu_iopts[2] = pl_rearmed_cbs.dithering; #ifndef C64X_DSP me_enable(e_menu_plugin_options, MA_OPT_SPU_THREAD, pcsxr_sthread_core_count > 1); #endif + me_loop(e_menu_plugin_options, &sel); + Config.SlowBoot = menu_iopts[0]; pl_rearmed_cbs.thread_rendering = menu_iopts[1] - 1; + pl_rearmed_cbs.dithering = menu_iopts[2]; if (spu_config.iUseThread != spu_thread_old) SPU_configure(); @@ -1684,6 +1693,8 @@ static int menu_loop_speed_hacks(int id, int keys) return 0; } +static const char *men_aflip[] = { "Auto", "Late", "Early", NULL }; + static const char h_cfg_cpul[] = "Shows CPU usage in %"; static const char h_cfg_spu[] = "Shows active SPU channels\n" "(green: normal, red: fmod, blue: noise)"; @@ -1707,7 +1718,10 @@ static const char h_cfg_tcd[] = "Greatly reduce CD load times. Breaks some ga static const char h_cfg_psxclk[] = "Over/under-clock the PSX, default is " DEFAULT_PSX_CLOCK_S "\n" "(adjust this if the game is too slow/too fast/hangs)"; -enum { AMO_XA, AMO_CDDA, AMO_IC, AMO_BP, AMO_CPU, AMO_GPUL, AMO_FFPS, AMO_TCD }; +enum { + AMO_XA, AMO_CDDA, AMO_IC, AMO_BP, AMO_CPU, + AMO_GPUL, AMO_FFPS, AMO_TCD, AMO_AFLIP, +}; static menu_entry e_menu_adv_options[] = { @@ -1720,6 +1734,7 @@ static menu_entry e_menu_adv_options[] = mee_onoff_h ("BP exception emulation", 0, menu_iopts[AMO_BP], 1, h_cfg_exc), mee_enum_h ("GPU l-list slow walking",0, menu_iopts[AMO_GPUL], men_autooo, h_cfg_gpul), mee_enum_h ("Fractional framerate", 0, menu_iopts[AMO_FFPS], men_autooo, h_cfg_ffps), + mee_enum ("Framebuffer readout", 0, menu_iopts[AMO_AFLIP], men_aflip), mee_onoff_h ("Turbo CD-ROM ", 0, menu_iopts[AMO_TCD], 1, h_cfg_tcd), #ifdef USE_ASYNC_CDROM mee_range ("CD-ROM read-ahead", 0, cd_buf_count, 0, 1024), @@ -1751,6 +1766,7 @@ static int menu_loop_adv_options(int id, int keys) *opts[i].mopt = *opts[i].opt; menu_iopts[AMO_GPUL] = Config.GpuListWalking + 1; menu_iopts[AMO_FFPS] = Config.FractionalFramerate + 1; + menu_iopts[AMO_AFLIP] = Config.AlternativeFlip + 1; me_loop(e_menu_adv_options, &sel); @@ -1758,6 +1774,7 @@ static int menu_loop_adv_options(int id, int keys) *opts[i].opt = *opts[i].mopt; Config.GpuListWalking = menu_iopts[AMO_GPUL] - 1; Config.FractionalFramerate = menu_iopts[AMO_FFPS] - 1; + Config.AlternativeFlip = menu_iopts[AMO_AFLIP] - 1; cdra_set_buf_count(cd_buf_count); return 0; diff --git a/frontend/plugin.c b/frontend/plugin.c index 20f2e93a..e7ae2097 100644 --- a/frontend/plugin.c +++ b/frontend/plugin.c @@ -167,6 +167,8 @@ void plugin_call_rearmed_cbs(void) pl_rearmed_cbs.screen_centering_type_default = Config.hacks.gpu_centering ? C_INGAME : C_AUTO; + pl_rearmed_cbs.alt_flip = Config.AlternativeFlip > 0 || + (Config.AlternativeFlip < 0 && Config.hacks.alt_flip); rearmed_set_cbs = SysLoadSym(hGPUDriver, "GPUrearmedCallbacks"); if (rearmed_set_cbs != NULL) diff --git a/frontend/plugin_lib.h b/frontend/plugin_lib.h index 1118f20c..4ff3ddf3 100644 --- a/frontend/plugin_lib.h +++ b/frontend/plugin_lib.h @@ -76,9 +76,10 @@ struct rearmed_cbs { unsigned int *gpu_frame_count; unsigned int *gpu_hcnt; unsigned int flip_cnt; // increment manually if not using pl_vout_flip - unsigned int only_16bpp; // platform is 16bpp-only - unsigned int dithering; // 0 off, 1 on, 2 force - unsigned int scale_hires; + unsigned char only_16bpp; // platform is 16bpp-only + unsigned char dithering; // 0 off, 1 on, 2 force + unsigned char scale_hires; + unsigned char alt_flip; int thread_rendering; // -1 auto, 0 off, 1 on struct { int allow_interlace; // 0 off, 1 on, 2 guess diff --git a/libpcsxcore/database.c b/libpcsxcore/database.c index b7285398..2ee4aec1 100644 --- a/libpcsxcore/database.c +++ b/libpcsxcore/database.c @@ -94,6 +94,14 @@ static const char * const f1_hack_db[] = "SCES03404", "SCES03423", "SCES03424", "SCES03524", }; +static const char * const alt_flip_db[] = +{ + /* Darius Gaiden (Japan) */ + "SLPS00574", "SLPM80054", + /* NFS3 */ + "SLUS00620", +}; + #define HACK_ENTRY(var, list) \ { #var, &Config.hacks.var, list, ARRAY_SIZE(list) } @@ -112,6 +120,7 @@ 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), + HACK_ENTRY(alt_flip, alt_flip_db), }; static const struct diff --git a/libpcsxcore/psxcommon.h b/libpcsxcore/psxcommon.h index d181eb27..cd12cfe1 100644 --- a/libpcsxcore/psxcommon.h +++ b/libpcsxcore/psxcommon.h @@ -133,8 +133,9 @@ typedef struct { 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 + s8 GpuListWalking; // -1..1: -1 = auto, 0/1 = off/on + s8 FractionalFramerate; // -1..1, ~49.75 and ~59.81 instead of 50 and 60 + s8 AlternativeFlip; // -1..1 u8 Cpu; // CPU_DYNAREC or CPU_INTERPRETER u8 PsxType; // PSX_TYPE_NTSC or PSX_TYPE_PAL u8 PsxRegion; // PSX_REGION_US, PSX_REGION_JP, PSX_REGION_EU @@ -145,6 +146,7 @@ typedef struct { boolean dualshock_init_analog; boolean fractional_Framerate; boolean f1; + boolean alt_flip; } hacks; } PcsxConfig; diff --git a/plugins/gpulib/gpu.c b/plugins/gpulib/gpu.c index bc1150e1..0e967d6e 100644 --- a/plugins/gpulib/gpu.c +++ b/plugins/gpulib/gpu.c @@ -418,16 +418,6 @@ void GPUwriteStatus(uint32_t data) gpu.frameskip.last_flip_frame = *gpu.state.frame_count; } if (changed) { - if (!gpu.state.vblank && !(gpu.status & PSX_GPU_STATUS_BLANKING) && - !gpu.state.use_alternative_flip) - { - uint32_t fdiff = frame - gpu.state.last_adflip_frame; - gpu.state.last_adflip_frame = frame; - if (fdiff < 9u) { - log_anomaly(&gpu, "active display flip detected\n"); - gpu.state.use_alternative_flip = 1; - } - } if (gpu_async_enabled(&gpu)) gpu_async_notify_screen_change(&gpu); else @@ -1171,7 +1161,6 @@ static void GPUupdateLace(void) void GPUvBlank(int is_vblank, int lcf) { int interlace; - gpu.state.vblank = is_vblank; interlace = gpu.state.allow_interlace && (gpu.status & PSX_GPU_STATUS_INTERLACE) && (gpu.status & PSX_GPU_STATUS_DHEIGHT); @@ -1223,7 +1212,7 @@ void GPUrearmedCallbacks(const struct rearmed_cbs *cbs) gpu.state.enhancement_enable = cbs->gpu_neon.enhancement_enable; gpu.state.enhancement_active = 0; gpu.state.downscale_enable = cbs->scale_hires; - gpu.state.use_alternative_flip = 0; + gpu.state.use_alternative_flip = cbs->alt_flip; gpu.state.screen_centering_type_default = cbs->screen_centering_type_default; if (gpu.state.screen_centering_type != cbs->screen_centering_type || gpu.state.screen_centering_x != cbs->screen_centering_x diff --git a/plugins/gpulib/gpu.h b/plugins/gpulib/gpu.h index 21ce8321..371706ab 100644 --- a/plugins/gpulib/gpu.h +++ b/plugins/gpulib/gpu.h @@ -86,7 +86,6 @@ struct psx_gpu { uint32_t old_interlace:1; uint32_t allow_interlace:2; uint32_t blanked:1; - uint32_t vblank:1; uint32_t use_alternative_flip:1; uint32_t enhancement_enable:1; uint32_t enhancement_active:1; @@ -103,7 +102,6 @@ struct psx_gpu { uint32_t hcnt; } last_list; uint32_t last_vram_read_frame; - uint32_t last_adflip_frame; uint16_t w_out_old, h_out_old, src_y_old; uint32_t status_vo_old; short screen_centering_type;