From d52bb78d2cd854bdcf85ba1b364be457bf053f57 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sat, 21 May 2022 13:05:35 +0300 Subject: [PATCH] rsx: Trivial non-blocking display synchronization --- rpcs3/Emu/Cell/lv2/sys_rsx.cpp | 3 +-- rpcs3/Emu/RSX/RSXThread.cpp | 26 +++++++++++++++++++++++++- rpcs3/Emu/RSX/RSXThread.h | 3 +++ rpcs3/Emu/RSX/rsx_methods.cpp | 11 ++++++++--- 4 files changed, 37 insertions(+), 6 deletions(-) diff --git a/rpcs3/Emu/Cell/lv2/sys_rsx.cpp b/rpcs3/Emu/Cell/lv2/sys_rsx.cpp index a1f31c5cd4..bed548073c 100644 --- a/rpcs3/Emu/Cell/lv2/sys_rsx.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_rsx.cpp @@ -498,9 +498,8 @@ error_code sys_rsx_context_attribute(u32 context_id, u32 package_id, u64 a3, u64 driverInfo.head[a3].lastQueuedBufferId = static_cast(a4); driverInfo.head[a3].flipFlags |= 0x40000000 | (1 << a4); - render->send_event(0, SYS_RSX_EVENT_QUEUE_BASE << a3, 0); - render->on_frame_end(static_cast(a4)); + render->send_event(0, SYS_RSX_EVENT_QUEUE_BASE << a3, 0); } break; diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index a263c2bd53..85def5c8e3 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -3099,6 +3099,18 @@ namespace rsx Emu.Pause(); } + if (false && wait_for_flip_sema) // Breaks framepacing + { + const auto& value = vm::_ref(device_addr + 0x30).val; + while (value != flip_sema_wait_val && !test_stopped()) + { + _mm_pause(); + } + + wait_for_flip_sema = false; + m_eng_interrupt_mask |= rsx::display_interrupt; + } + if (zcull_ctrl->has_pending()) { // NOTE: This is a workaround for buggy games. @@ -3195,7 +3207,7 @@ namespace rsx case frame_limit_type::_50: limit = 50.; break; case frame_limit_type::_60: limit = 60.; break; case frame_limit_type::_30: limit = 30.; break; - case frame_limit_type::_auto: limit = 0.; break; // Handled in RSX semaphore_acquire + case frame_limit_type::_auto: limit = 0.; break; default: break; } @@ -3231,6 +3243,18 @@ namespace rsx } } } + else if (wait_for_flip_sema) + { + const auto& value = vm::_ref(device_addr + 0x30).val; + if (value != flip_sema_wait_val) + { + // Not yet signaled, handle it later + async_flip_requested |= flip_request::emu_requested; + return; + } + + wait_for_flip_sema = false; + } int_flip_index++; diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index 046a837b29..faa7cb56b2 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -650,6 +650,9 @@ namespace rsx atomic_t vblank_count{0}; bool capture_current_frame = false; + bool wait_for_flip_sema = false; + u32 flip_sema_wait_val = 0; + public: atomic_t sync_point_request = false; bool in_begin_end = false; diff --git a/rpcs3/Emu/RSX/rsx_methods.cpp b/rpcs3/Emu/RSX/rsx_methods.cpp index 90c0423763..86b0e8b916 100644 --- a/rpcs3/Emu/RSX/rsx_methods.cpp +++ b/rpcs3/Emu/RSX/rsx_methods.cpp @@ -104,8 +104,13 @@ namespace rsx rsx->flush_fifo(); } - if (addr == rsx->device_addr + 0x30 && g_cfg.video.frame_limit == frame_limit_type::none) + if (addr == rsx->device_addr + 0x30) { + if (g_cfg.video.frame_limit == frame_limit_type::_auto) + { + rsx->flip_sema_wait_val = arg; + rsx->wait_for_flip_sema = (sema != arg); + } return; } @@ -1733,7 +1738,7 @@ namespace rsx template struct driver_flip { - static void impl(thread* /*rsx*/, u32 /*reg*/, u32 arg) + static void impl(thread* rsx, u32 /*reg*/, u32 arg) { sys_rsx_context_attribute(0x55555555, 0x102, index, arg, 0, 0); } @@ -1742,7 +1747,7 @@ namespace rsx template struct queue_flip { - static void impl(thread* /*rsx*/, u32 /*reg*/, u32 arg) + static void impl(thread* rsx, u32 /*reg*/, u32 arg) { sys_rsx_context_attribute(0x55555555, 0x103, index, arg, 0, 0); }