From c4d8ef43402fb3dc5480ab0d01714fa39c565223 Mon Sep 17 00:00:00 2001 From: Eladash Date: Thu, 11 Jul 2019 08:34:15 +0300 Subject: [PATCH] rsx: Allow to configure vblank rate Removed "HLE protection" hack from sys_rsx_context_attribute --- rpcs3/Emu/Cell/lv2/sys_rsx.cpp | 4 --- rpcs3/Emu/RSX/RSXThread.cpp | 52 ++++++++++++++++++++++++---------- rpcs3/Emu/RSX/RSXThread.h | 4 +-- rpcs3/Emu/System.h | 1 + 4 files changed, 40 insertions(+), 21 deletions(-) diff --git a/rpcs3/Emu/Cell/lv2/sys_rsx.cpp b/rpcs3/Emu/Cell/lv2/sys_rsx.cpp index b218bf6164..3002200909 100644 --- a/rpcs3/Emu/Cell/lv2/sys_rsx.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_rsx.cpp @@ -250,10 +250,6 @@ error_code sys_rsx_context_attribute(s32 context_id, u32 package_id, u64 a3, u64 const auto render = rsx::get_current_renderer(); - //hle protection - if (render->isHLE) - return CELL_OK; - auto m_sysrsx = fxm::get(); if (!m_sysrsx) diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 511f0b7a55..bce2b5ec1c 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -456,37 +456,59 @@ namespace rsx last_flip_time = get_system_time() - 1000000; + vblank_count = 0; + thread_ctrl::spawn("VBlank Thread", [this]() { - const u64 start_time = get_system_time(); + // See sys_timer_usleep for details +#ifdef __linux__ + constexpr u32 host_min_quantum = 50; +#else + constexpr u32 host_min_quantum = 500; +#endif + u64 start_time = get_system_time(); - vblank_count = 0; + const u64 period_time = 1000000 / g_cfg.video.vblank_rate; + const u64 wait_sleep = period_time - u64{period_time >= host_min_quantum} * host_min_quantum; // TODO: exit condition while (!Emu.IsStopped() && !m_rsx_thread_exiting) { - if (get_system_time() - start_time > vblank_count * 1000000 / 60) + if (get_system_time() - start_time >= period_time) { - vblank_count++; - sys_rsx_context_attribute(0x55555555, 0xFED, 1, 0, 0, 0); - if (vblank_handler) + do { - intr_thread->cmd_list - ({ - { ppu_cmd::set_args, 1 }, u64{1}, - { ppu_cmd::lle_call, vblank_handler }, - { ppu_cmd::sleep, 0 } - }); + start_time += period_time; - thread_ctrl::notify(*intr_thread); + if (isHLE) + { + vblank_count++; + + if (vblank_handler) + { + intr_thread->cmd_list + ({ + { ppu_cmd::set_args, 1 }, u64{1}, + { ppu_cmd::lle_call, vblank_handler }, + { ppu_cmd::sleep, 0 } + }); + + thread_ctrl::notify(*intr_thread); + } + } + else + { + sys_rsx_context_attribute(0x55555555, 0xFED, 1, 0, 0, 0); + } } + while (get_system_time() - start_time >= period_time); - std::this_thread::sleep_for(16ms); + thread_ctrl::wait_for(wait_sleep); continue; } while (Emu.IsPaused() && !m_rsx_thread_exiting) - std::this_thread::sleep_for(16ms); + thread_ctrl::wait_for(wait_sleep); thread_ctrl::wait_for(100); // Hack } diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index 536f945285..b164bbe6c8 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include #include @@ -549,7 +549,7 @@ namespace rsx vm::ptr flip_handler = vm::null; vm::ptr user_handler = vm::null; vm::ptr vblank_handler = vm::null; - u64 vblank_count; + atomic_t vblank_count; public: bool invalid_command_interrupt_raised = false; diff --git a/rpcs3/Emu/System.h b/rpcs3/Emu/System.h index 356bf237d8..948c8db03d 100644 --- a/rpcs3/Emu/System.h +++ b/rpcs3/Emu/System.h @@ -477,6 +477,7 @@ struct cfg_root : cfg::node 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}; + cfg::_int<1, 500> vblank_rate{this, "Vblank Rate", 60}; // Changing this from 60 may affect game speed unexpected ways struct node_d3d12 : cfg::node {