From ec768afbd969b63f22ca6f4923899a94741347ac Mon Sep 17 00:00:00 2001 From: kd-11 Date: Fri, 30 Nov 2018 14:39:15 +0300 Subject: [PATCH] rsx: Flip workarounds for applications that flip via syscall - Do not assume flip marks end-of-frame if executed via syscall - Also disables skip_frame for these applications as there is no frame boundary - NOTE: QUEUE_HEAD cannot be relied on as it is seemingly possible to flip the same head and not need to queue it --- rpcs3/Emu/RSX/RSXFIFO.cpp | 7 ++++ rpcs3/Emu/RSX/RSXFIFO.h | 1 + rpcs3/Emu/RSX/RSXThread.cpp | 65 ++++++++++++++++++++++--------------- 3 files changed, 47 insertions(+), 26 deletions(-) diff --git a/rpcs3/Emu/RSX/RSXFIFO.cpp b/rpcs3/Emu/RSX/RSXFIFO.cpp index 321d8cfd5e..ea2f069756 100644 --- a/rpcs3/Emu/RSX/RSXFIFO.cpp +++ b/rpcs3/Emu/RSX/RSXFIFO.cpp @@ -201,6 +201,13 @@ namespace rsx } } + void flattening_helper::force_disable() + { + enabled = false; + num_collapsed = 0; + fifo_hint = optimization_hint::load_unoptimizable; + } + void flattening_helper::evaluate_performance(u32 total_draw_count) { if (!enabled) diff --git a/rpcs3/Emu/RSX/RSXFIFO.h b/rpcs3/Emu/RSX/RSXFIFO.h index 379a92dd1a..700a012b29 100644 --- a/rpcs3/Emu/RSX/RSXFIFO.h +++ b/rpcs3/Emu/RSX/RSXFIFO.h @@ -82,6 +82,7 @@ namespace rsx u32 get_primitive() const { return deferred_primitive; } bool is_enabled() const { return enabled; } + void force_disable(); void evaluate_performance(u32 total_draw_count); inline flatten_op test(register_pair& command); }; diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index fcd86cf43c..28d1a152c5 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -2246,13 +2246,46 @@ namespace rsx void thread::flip(int buffer) { - async_flip_requested.clear(); - - if (!g_cfg.video.disable_FIFO_reordering) + if (!(async_flip_requested & flip_request::any)) { - // Try to enable FIFO optimizations - // Only rarely useful for some games like RE4 - m_flattener.evaluate_performance(m_draw_calls); + // Flip is processed through inline FLIP command in the commandstream + // This is critical as it is a reliable end-of-frame marker + + if (!g_cfg.video.disable_FIFO_reordering) + { + // Try to enable FIFO optimizations + // Only rarely useful for some games like RE4 + m_flattener.evaluate_performance(m_draw_calls); + } + + // Reset zcull ctrl + zcull_ctrl->set_active(this, false); + zcull_ctrl->clear(this); + + if (zcull_ctrl->has_pending()) + { + LOG_TRACE(RSX, "Dangling reports found, discarding..."); + zcull_ctrl->sync(this); + } + + if (g_cfg.video.frame_skip_enabled) + { + m_skip_frame_ctr++; + + if (m_skip_frame_ctr == g_cfg.video.consequtive_frames_to_draw) + m_skip_frame_ctr = -g_cfg.video.consequtive_frames_to_skip; + + skip_frame = (m_skip_frame_ctr < 0); + } + } + else + { + if (async_flip_requested & flip_request::emu_requested) + { + m_flattener.force_disable(); + } + + async_flip_requested.clear(); } if (!skip_frame) @@ -2261,26 +2294,6 @@ namespace rsx m_draw_calls = 0; } - if (g_cfg.video.frame_skip_enabled) - { - m_skip_frame_ctr++; - - if (m_skip_frame_ctr == g_cfg.video.consequtive_frames_to_draw) - m_skip_frame_ctr = -g_cfg.video.consequtive_frames_to_skip; - - skip_frame = (m_skip_frame_ctr < 0); - } - - //Reset zcull ctrl - zcull_ctrl->set_active(this, false); - zcull_ctrl->clear(this); - - if (zcull_ctrl->has_pending()) - { - LOG_TRACE(RSX, "Dangling reports found, discarding..."); - zcull_ctrl->sync(this); - } - performance_counters.sampled_frames++; }