diff --git a/rpcs3/Emu/RSX/rsx_methods.cpp b/rpcs3/Emu/RSX/rsx_methods.cpp index 092cab8295..4ed1d265ea 100644 --- a/rpcs3/Emu/RSX/rsx_methods.cpp +++ b/rpcs3/Emu/RSX/rsx_methods.cpp @@ -65,7 +65,7 @@ namespace rsx const u32 addr = get_address(method_registers.semaphore_offset_406e(), method_registers.semaphore_context_dma_406e()); if (vm::ps3::read32(addr) == arg) return; - const u64 start = get_system_time(); + u64 start = get_system_time(); while (vm::ps3::read32(addr) != arg) { // todo: LLE: why does this one keep hanging? is it vsh system semaphore? whats actually pushing this to the command buffer?! @@ -75,14 +75,35 @@ namespace rsx if (Emu.IsStopped()) break; - if ((get_system_time() - start) > 1000000) + const auto tdr = (s64)g_cfg.video.driver_recovery_timeout; + if (tdr == 0) { - //If longer than 1s force exit - LOG_ERROR(RSX, "nv406e::semaphore_acquire has timed out. semaphore_address=0x%X", addr); - break; + //No timeout + std::this_thread::yield(); + continue; } - std::this_thread::yield(); + if (Emu.IsPaused()) + { + while (Emu.IsPaused()) + { + std::this_thread::yield(); + } + + //Reset + start = get_system_time(); + } + else + { + if ((get_system_time() - start) > tdr) + { + //If longer than driver timeout force exit + LOG_ERROR(RSX, "nv406e::semaphore_acquire has timed out. semaphore_address=0x%X", addr); + break; + } + + std::this_thread::yield(); + } } } diff --git a/rpcs3/Emu/System.h b/rpcs3/Emu/System.h index 28ec7d9ca4..62c42ae05d 100644 --- a/rpcs3/Emu/System.h +++ b/rpcs3/Emu/System.h @@ -342,6 +342,7 @@ struct cfg_root : cfg::node cfg::_int<50, 800> resolution_scale_percent{this, "Resolution Scale", 100}; cfg::_int<0, 16> anisotropic_level_override{this, "Anisotropic Filter Override", 0}; cfg::_int<1, 1024> min_scalable_dimension{this, "Minimum Scalable Dimension", 16}; + cfg::_int<0, 30000000> driver_recovery_timeout{this, "Driver Recovery Timeout", 1000000}; struct node_d3d12 : cfg::node {