diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 5f84da86aa..fd4d993533 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -2843,6 +2843,7 @@ namespace rsx m_current_task->sync_timestamp = 0; m_current_task->active = true; m_current_task->owned = false; + m_current_task->hint = false; return; } @@ -2866,6 +2867,7 @@ namespace rsx m_current_task->sync_timestamp = 0; m_current_task->active = true; m_current_task->owned = false; + m_current_task->hint = false; return; } @@ -3050,6 +3052,17 @@ namespace rsx { if (m_tsc < front.due_tsc) { + if (front.query && !front.query->hint && (front.due_tsc - m_tsc) <= m_backend_warn_threshold) + { + if (front.type == CELL_GCM_ZPASS_PIXEL_CNT || front.type == CELL_GCM_ZCULL_STATS3) + { + // Imminent read + ptimer->sync_hint(FIFO_hint::hint_zcull_sync, reinterpret_cast(front.query)); + } + + front.query->hint = true; + } + // Avoid spamming backend with report status updates return; } @@ -3120,6 +3133,13 @@ namespace rsx } else { + if (!query->hint && (writer.due_tsc - m_tsc) <= m_backend_warn_threshold) + { + // Imminent read + ptimer->sync_hint(FIFO_hint::hint_zcull_sync, reinterpret_cast(query)); + query->hint = true; + } + //Too early; abort break; } @@ -3176,18 +3196,21 @@ namespace rsx const auto memory_end = memory_address + memory_range; u32 sync_address = 0; + occlusion_query_info* query; for (auto It = m_pending_writes.crbegin(); It != m_pending_writes.crend(); ++It) { if (It->sink >= memory_address && It->sink < memory_end) { sync_address = It->sink; + query = It->query; break; } } if (sync_address) { + ptimer->sync_hint(FIFO_hint::hint_zcull_sync, reinterpret_cast(query)); update(ptimer, sync_address); } } diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index a83e7983c4..a69753f820 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -97,7 +97,8 @@ namespace rsx enum FIFO_hint : u8 { - hint_conditional_render_eval = 1 + hint_conditional_render_eval = 1, + hint_zcull_sync = 2 }; u32 get_vertex_type_size_on_host(vertex_base_type type, u32 size); @@ -330,6 +331,7 @@ namespace rsx u32 driver_handle; u32 result; u32 num_draws; + bool hint; bool pending; bool active; bool owned; @@ -366,6 +368,7 @@ namespace rsx u32 m_statistics_tag_id = 0; u64 m_tsc = 0; u32 m_cycles_delay = max_zcull_delay_us; + u32 m_backend_warn_threshold = max_zcull_delay_us / 2; std::vector m_pending_writes; std::unordered_map m_statistics_map; @@ -688,7 +691,7 @@ namespace rsx // sync void sync(); void read_barrier(u32 memory_address, u32 memory_range); - virtual void sync_hint(FIFO_hint /*hint*/, u32 /*arg*/) {} + virtual void sync_hint(FIFO_hint /*hint*/, u64 /*arg*/) {} gsl::span get_raw_index_array(const draw_clause& draw_indexed_clause) const; gsl::span get_raw_vertex_buffer(const rsx::data_array_format_info&, u32 base_offset, const draw_clause& draw_array_clause) const; diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index b93478b88c..1385c57d8c 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -2169,7 +2169,7 @@ void VKGSRender::flush_command_queue(bool hard_sync) open_command_buffer(); } -void VKGSRender::sync_hint(rsx::FIFO_hint hint, u32 arg) +void VKGSRender::sync_hint(rsx::FIFO_hint hint, u64 arg) { // Occlusion test result evaluation is coming up, avoid a hard sync if (hint == rsx::FIFO_hint::hint_conditional_render_eval) diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.h b/rpcs3/Emu/RSX/VK/VKGSRender.h index 383b582823..9e726db7db 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.h +++ b/rpcs3/Emu/RSX/VK/VKGSRender.h @@ -467,7 +467,7 @@ public: void set_scissor(bool clip_viewport); void bind_viewport(); - void sync_hint(rsx::FIFO_hint hint, u32 arg) override; + void sync_hint(rsx::FIFO_hint hint, u64 arg) override; void begin_occlusion_query(rsx::reports::occlusion_query_info* query) override; void end_occlusion_query(rsx::reports::occlusion_query_info* query) override;