rsx: Implement NTSC fixup mode, improve VBLANK accuracy

This commit is contained in:
Eladash 2021-10-28 21:53:34 +03:00 committed by Megamouse
parent 46a54f5474
commit 58040d478a
2 changed files with 29 additions and 3 deletions

View File

@ -641,20 +641,45 @@ namespace rsx
#endif
u64 start_time = get_system_time();
u64 vblank_rate = g_cfg.video.vblank_rate;
u64 vblank_period = 1'000'000 + u64{g_cfg.video.vblank_ntsc.get()} * 1000;
u64 local_vblank_count = 0;
// TODO: exit condition
while (!is_stopped())
{
// Get current time
const u64 current = get_system_time();
const u64 period_time = 1000000 / g_cfg.video.vblank_rate;
const u64 wait_for = period_time - std::min<u64>(current - start_time, period_time);
// Calculate the time at which we need to send a new VBLANK signal
const u64 post_event_time = start_time + (local_vblank_count + 1) * vblank_period / vblank_rate;
// Calculate time remaining to that time (0 if we passed it)
const u64 wait_for = current >= post_event_time ? 0 : post_event_time - current;
// Substract host operating system min sleep quantom to get sleep time
const u64 wait_sleep = wait_for - u64{wait_for >= host_min_quantum} * host_min_quantum;
if (!wait_for)
{
{
start_time += period_time;
local_vblank_count++;
vblank_count++;
if (local_vblank_count == vblank_rate)
{
// Advance start_time to the moment of the current VBLANK
// Which is the last VBLANK event in this period
// This is in order for multiplication by ratio above to use only small numbers
start_time += vblank_period;
local_vblank_count = 0;
// We have a rare chance to update settings without losing precision whenever local_vblank_count is 0
vblank_rate = g_cfg.video.vblank_rate;
vblank_period = 1'000'000 + u64{g_cfg.video.vblank_ntsc.get()} * 1000;
}
if (isHLE)
{
if (vblank_handler)

View File

@ -142,6 +142,7 @@ struct cfg_root : cfg::node
cfg::_int<0, 30000000> driver_recovery_timeout{ this, "Driver Recovery Timeout", 1000000, true };
cfg::_int<0, 16667> driver_wakeup_delay{ this, "Driver Wake-Up Delay", 1, true };
cfg::_int<1, 1800> vblank_rate{ this, "Vblank Rate", 60, true }; // Changing this from 60 may affect game speed in unexpected ways
cfg::_bool vblank_ntsc{ this, "Vblank NTSC Fixup", false, true };
cfg::_bool decr_memory_layout{ this, "DECR memory layout", false}; // Force enable increased allowed main memory range as DECR console
struct node_vk : cfg::node