diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 1430cd834a..ac3b217672 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -2838,7 +2838,7 @@ namespace rsx if (!It->sink) { It->counter_tag = m_statistics_tag_id; - It->due_tsc = m_tsc + m_cycles_delay; + It->due_tsc = get_system_time() + m_cycles_delay; It->sink = sink; It->type = type; @@ -2901,7 +2901,7 @@ namespace rsx } //All slots are occupied, try to pop the earliest entry - m_tsc += max_zcull_cycles_delay; + m_tsc += max_zcull_delay_us; update(ptimer); retries++; @@ -2940,7 +2940,7 @@ namespace rsx if (m_current_task) m_current_task->num_draws++; - m_cycles_delay = max_zcull_cycles_delay; + m_cycles_delay = max_zcull_delay_us; } void ZCULL_control::write(vm::addr_t sink, u32 timestamp, u32 type, u32 value) @@ -3053,20 +3053,30 @@ namespace rsx } //Critical, since its likely a WAIT_FOR_IDLE type has been processed, all results are considered available - m_cycles_delay = min_zcull_cycles_delay; + m_cycles_delay = min_zcull_delay_us; + m_tsc = std::max(m_tsc, get_system_time()); } void ZCULL_control::update(::rsx::thread* ptimer, u32 sync_address) { - m_tsc++; - if (m_pending_writes.empty()) + { return; + } + + const auto& front = m_pending_writes.front(); + if (!front.sink) + { + // No writables in queue, abort + return; + } + + // Update timestamp and proceed with processing only if there is work to be done + m_tsc = std::max(m_tsc, get_system_time()); if (!sync_address) { - const auto& front = m_pending_writes.front(); - if (!front.sink || m_tsc < front.due_tsc) + if (m_tsc < front.due_tsc) { // Avoid spamming backend with report status updates return; diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index 614b63c51e..8fec3c11c6 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -258,9 +258,9 @@ namespace rsx struct ZCULL_control { - // Delay in 'cycles' before a report update operation is forced to retire - const u32 max_zcull_cycles_delay = 128; - const u32 min_zcull_cycles_delay = 16; + // Delay before a report update operation is forced to retire + const u32 max_zcull_delay_us = 500; + const u32 min_zcull_delay_us = 50; // Number of occlusion query slots available. Real hardware actually has far fewer units before choking const u32 occlusion_query_count = 128; @@ -273,7 +273,7 @@ namespace rsx occlusion_query_info* m_current_task = nullptr; u32 m_statistics_tag_id = 0; u64 m_tsc = 0; - u32 m_cycles_delay = max_zcull_cycles_delay; + u32 m_cycles_delay = max_zcull_delay_us; std::vector m_pending_writes; std::unordered_map m_statistics_map;