1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-26 04:32:35 +01:00

rsx: Conditional render sync optimization

- ZCULL queue was updated to one-per-cb but the conditional render sync hint was not updated.
- Do not unconditionally flush the queue unless the upcoming ref is contained in the active CB.
- This avoids spamming queue flush, which frees up resources and improves performance
This commit is contained in:
kd-11 2019-07-30 15:22:53 +03:00 committed by kd-11
parent d689a6e47b
commit f0bd0b5a7c
5 changed files with 32 additions and 7 deletions

View File

@ -3095,5 +3095,16 @@ namespace rsx
update(ptimer, sync_address);
}
}
occlusion_query_info* ZCULL_control::find_query(vm::addr_t sink_address)
{
for (auto &writer : m_pending_writes)
{
if (writer.sink == sink_address)
return writer.query;
}
return nullptr;
}
}
}

View File

@ -397,6 +397,9 @@ namespace rsx
// Check for pending writes
bool has_pending() const { return !m_pending_writes.empty(); }
// Search for query synchronized at address
occlusion_query_info* find_query(vm::addr_t sink_address);
// Backend methods (optional, will return everything as always visible by default)
virtual void begin_occlusion_query(occlusion_query_info* /*query*/) {}
virtual void end_occlusion_query(occlusion_query_info* /*query*/) {}
@ -614,7 +617,7 @@ namespace rsx
// sync
void sync();
void read_barrier(u32 memory_address, u32 memory_range);
virtual void sync_hint(FIFO_hint /*hint*/) {}
virtual void sync_hint(FIFO_hint /*hint*/, u32 /*arg*/) {}
gsl::span<const gsl::byte> get_raw_index_array(const draw_clause& draw_indexed_clause) const;
gsl::span<const gsl::byte> get_raw_vertex_buffer(const rsx::data_array_format_info&, u32 base_offset, const draw_clause& draw_array_clause) const;

View File

@ -2157,15 +2157,26 @@ void VKGSRender::flush_command_queue(bool hard_sync)
open_command_buffer();
}
void VKGSRender::sync_hint(rsx::FIFO_hint hint)
void VKGSRender::sync_hint(rsx::FIFO_hint hint, u32 arg)
{
// Occlusion test result evaluation is coming up, avoid a hard sync
if (hint == rsx::FIFO_hint::hint_conditional_render_eval)
{
if (m_current_command_buffer->flags & vk::command_buffer::cb_has_occlusion_task)
// Occlusion queries not enabled, do nothing
if (!(m_current_command_buffer->flags & vk::command_buffer::cb_has_occlusion_task))
return;
// If a flush request is already enqueued, do nothing
if (m_flush_requests.pending())
return;
// Check if the required report is synced to this CB
if (auto occlusion_info = zcull_ctrl->find_query(vm::cast(arg)))
{
// Occlusion test result evaluation is coming up, avoid a hard sync
if (!m_flush_requests.pending())
auto& data = m_occlusion_map[occlusion_info->driver_handle];
if (data.command_buffer_to_wait == m_current_command_buffer && !data.indices.empty())
{
// Confirmed hard sync coming up, post a sync request
m_flush_requests.post(false);
m_flush_requests.remove_one();
}

View File

@ -463,7 +463,7 @@ public:
void set_scissor(bool clip_viewport);
void bind_viewport();
void sync_hint(rsx::FIFO_hint hint) override;
void sync_hint(rsx::FIFO_hint hint, u32 arg) override;
void begin_occlusion_query(rsx::reports::occlusion_query_info* query) override;
void end_occlusion_query(rsx::reports::occlusion_query_info* query) override;

View File

@ -581,7 +581,7 @@ namespace rsx
}
// Defer conditional render evaluation
rsx->sync_hint(FIFO_hint::hint_conditional_render_eval);
rsx->sync_hint(FIFO_hint::hint_conditional_render_eval, address_ptr);
rsx->conditional_render_test_address = address_ptr;
rsx->conditional_render_test_failed = false;
}