From 5315eb546fb845867b302a02fbc4a61cf4a2924b Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sat, 14 May 2022 18:41:33 +0300 Subject: [PATCH] rsx: Stop spamming ZCULL update method - This has a negative impact when ZCULL is active due to spamming __rdtsc - While the method is fast, it is not free and some checks are done before the instruction can be emitted Let's use the saved time to actually get something useful done --- rpcs3/Emu/RSX/RSXThread.cpp | 18 ++++++++++++++---- rpcs3/Emu/RSX/RSXThread.h | 5 +++++ rpcs3/Emu/RSX/RSXZCULL.cpp | 17 ++++++++++++++++- rpcs3/Emu/RSX/VK/VKGSRender.cpp | 4 ++++ 4 files changed, 39 insertions(+), 5 deletions(-) diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 3b2606b902..0aeef5487b 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -763,11 +763,18 @@ namespace rsx sync_point_request.release(false); } - // Execute backend-local tasks first - do_local_task(performance_counters.state); + // Update sub-units every 64 cycles. The local handler is invoked for other functions externally on-demand anyway. + // This avoids expensive calls to check timestamps which involves reading some values from TLS storage on windows. + // If something is going on in the backend that requires an update, set the interrupt bit explicitly. + if ((m_cycles_counter++ & 63) == 0 || + m_graphics_state & (rsx::pipeline_state::backend_interrupt_bits)) + { + // Execute backend-local tasks first + do_local_task(performance_counters.state); - // Update sub-units - zcull_ctrl->update(this); + // Update other sub-units + zcull_ctrl->update(this); + } // Execute FIFO queue run_FIFO(); @@ -2952,6 +2959,8 @@ namespace rsx m_invalidated_memory_range = unmap_range; } + + m_graphics_state |= rsx::pipeline_state::backend_interrupt; } } @@ -3143,6 +3152,7 @@ namespace rsx async_flip_buffer = buffer; async_flip_requested |= flip_request::emu_requested; + m_graphics_state |= rsx::pipeline_state::backend_interrupt; } } diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index bfd2c7c961..3c0016acc2 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -132,11 +132,15 @@ namespace rsx push_buffer_arrays_dirty = 0x20000, // Push buffers have data written to them (immediate mode vertex buffers) + backend_interrupt = 0x80000000, // Backend interrupt, must serve immediately + fragment_program_dirty = fragment_program_ucode_dirty | fragment_program_state_dirty, vertex_program_dirty = vertex_program_ucode_dirty | vertex_program_state_dirty, invalidate_pipeline_bits = fragment_program_dirty | vertex_program_dirty, invalidate_zclip_bits = vertex_state_dirty | zclip_config_state_dirty, memory_barrier_bits = framebuffer_reads_dirty, + backend_interrupt_bits = memory_barrier_bits | backend_interrupt, + all_dirty = ~0u }; @@ -424,6 +428,7 @@ namespace rsx { u64 timestamp_ctrl = 0; u64 timestamp_subvalue = 0; + u64 m_cycles_counter = 0; display_flip_info_t m_queued_flip{}; diff --git a/rpcs3/Emu/RSX/RSXZCULL.cpp b/rpcs3/Emu/RSX/RSXZCULL.cpp index f32f5c0946..0621b17697 100644 --- a/rpcs3/Emu/RSX/RSXZCULL.cpp +++ b/rpcs3/Emu/RSX/RSXZCULL.cpp @@ -14,7 +14,22 @@ namespace rsx } ZCULL_control::~ZCULL_control() - {} + { + std::scoped_lock lock(m_pages_mutex); + + for (auto& block : m_locked_pages) + { + for (auto& p : block) + { + if (p.second.prot != utils::protection::rw) + { + utils::memory_protect(vm::base(p.first), 4096, utils::protection::rw); + } + } + + block.clear(); + } + } void ZCULL_control::set_active(class ::rsx::thread* ptimer, bool state, bool flush_queue) { diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index 3155ea3e86..c552666384 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -804,6 +804,7 @@ bool VKGSRender::on_access_violation(u32 address, bool is_writing) g_fxo->get().set_mem_fault_flag(); m_queue_status |= flush_queue_state::deadlock; + m_graphics_state |= rsx::pipeline_state::backend_interrupt; // Wait for deadlock to clear while (m_queue_status & flush_queue_state::deadlock) @@ -1646,6 +1647,9 @@ void VKGSRender::sync_hint(rsx::FIFO_hint hint, void* args) void VKGSRender::do_local_task(rsx::FIFO_state state) { + // Clear interrupt bit if set + m_graphics_state &= ~rsx::pipeline_state::backend_interrupt; + if (m_queue_status & flush_queue_state::deadlock) { // Clear offloader deadlock