mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 19:45:20 +00:00
vk: Improve zcull synchronization
- Use zcull sync hints more aggressively
This commit is contained in:
parent
fe3c290d03
commit
3e0f9dff4d
1 changed files with 67 additions and 43 deletions
|
@ -2172,7 +2172,9 @@ void VKGSRender::flush_command_queue(bool hard_sync)
|
|||
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)
|
||||
switch (hint)
|
||||
{
|
||||
case rsx::FIFO_hint::hint_conditional_render_eval:
|
||||
{
|
||||
// Occlusion queries not enabled, do nothing
|
||||
if (!(m_current_command_buffer->flags & vk::command_buffer::cb_has_occlusion_task))
|
||||
|
@ -2193,6 +2195,31 @@ void VKGSRender::sync_hint(rsx::FIFO_hint hint, u64 arg)
|
|||
m_flush_requests.remove_one();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case rsx::FIFO_hint::hint_zcull_sync:
|
||||
{
|
||||
if (!(m_current_command_buffer->flags & vk::command_buffer::cb_has_occlusion_task))
|
||||
return;
|
||||
|
||||
auto occlusion_info = reinterpret_cast<rsx::reports::occlusion_query_info*>(arg);
|
||||
auto& data = m_occlusion_map[occlusion_info->driver_handle];
|
||||
|
||||
if (data.command_buffer_to_wait == m_current_command_buffer && !data.indices.empty())
|
||||
{
|
||||
std::lock_guard lock(m_flush_queue_mutex);
|
||||
flush_command_queue();
|
||||
|
||||
if (m_flush_requests.pending())
|
||||
{
|
||||
// Clear without wait
|
||||
m_flush_requests.clear_pending_flag();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2804,33 +2831,37 @@ void VKGSRender::close_and_submit_command_buffer(VkFence fence, VkSemaphore wait
|
|||
// Wait before sync block below
|
||||
rsx::g_dma_manager.sync();
|
||||
|
||||
if (m_attrib_ring_info.dirty() ||
|
||||
m_fragment_env_ring_info.dirty() ||
|
||||
m_vertex_env_ring_info.dirty() ||
|
||||
m_fragment_texture_params_ring_info.dirty() ||
|
||||
m_vertex_layout_ring_info.dirty() ||
|
||||
m_fragment_constants_ring_info.dirty() ||
|
||||
m_index_buffer_ring_info.dirty() ||
|
||||
m_transform_constants_ring_info.dirty() ||
|
||||
m_texture_upload_buffer_ring_info.dirty())
|
||||
// TODO: Better check for shadowed memory
|
||||
if (m_attrib_ring_info.shadow)
|
||||
{
|
||||
std::lock_guard lock(m_secondary_cb_guard);
|
||||
m_secondary_command_buffer.begin();
|
||||
if (m_attrib_ring_info.dirty() ||
|
||||
m_fragment_env_ring_info.dirty() ||
|
||||
m_vertex_env_ring_info.dirty() ||
|
||||
m_fragment_texture_params_ring_info.dirty() ||
|
||||
m_vertex_layout_ring_info.dirty() ||
|
||||
m_fragment_constants_ring_info.dirty() ||
|
||||
m_index_buffer_ring_info.dirty() ||
|
||||
m_transform_constants_ring_info.dirty() ||
|
||||
m_texture_upload_buffer_ring_info.dirty())
|
||||
{
|
||||
std::lock_guard lock(m_secondary_cb_guard);
|
||||
m_secondary_command_buffer.begin();
|
||||
|
||||
m_attrib_ring_info.sync(m_secondary_command_buffer);
|
||||
m_fragment_env_ring_info.sync(m_secondary_command_buffer);
|
||||
m_vertex_env_ring_info.sync(m_secondary_command_buffer);
|
||||
m_fragment_texture_params_ring_info.sync(m_secondary_command_buffer);
|
||||
m_vertex_layout_ring_info.sync(m_secondary_command_buffer);
|
||||
m_fragment_constants_ring_info.sync(m_secondary_command_buffer);
|
||||
m_index_buffer_ring_info.sync(m_secondary_command_buffer);
|
||||
m_transform_constants_ring_info.sync(m_secondary_command_buffer);
|
||||
m_texture_upload_buffer_ring_info.sync(m_secondary_command_buffer);
|
||||
m_attrib_ring_info.sync(m_secondary_command_buffer);
|
||||
m_fragment_env_ring_info.sync(m_secondary_command_buffer);
|
||||
m_vertex_env_ring_info.sync(m_secondary_command_buffer);
|
||||
m_fragment_texture_params_ring_info.sync(m_secondary_command_buffer);
|
||||
m_vertex_layout_ring_info.sync(m_secondary_command_buffer);
|
||||
m_fragment_constants_ring_info.sync(m_secondary_command_buffer);
|
||||
m_index_buffer_ring_info.sync(m_secondary_command_buffer);
|
||||
m_transform_constants_ring_info.sync(m_secondary_command_buffer);
|
||||
m_texture_upload_buffer_ring_info.sync(m_secondary_command_buffer);
|
||||
|
||||
m_secondary_command_buffer.end();
|
||||
m_secondary_command_buffer.end();
|
||||
|
||||
m_secondary_command_buffer.submit(m_swapchain->get_graphics_queue(),
|
||||
VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||
m_secondary_command_buffer.submit(m_swapchain->get_graphics_queue(),
|
||||
VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
// End any active renderpasses; the caller should handle reopening
|
||||
|
@ -3617,19 +3648,6 @@ bool VKGSRender::check_occlusion_query_status(rsx::reports::occlusion_query_info
|
|||
return true;
|
||||
|
||||
if (data.command_buffer_to_wait == m_current_command_buffer)
|
||||
{
|
||||
if (!m_flush_requests.pending())
|
||||
{
|
||||
//Likely to be read at some point in the near future, submit now to avoid stalling later
|
||||
m_flush_requests.post(false);
|
||||
m_flush_requests.remove_one();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (data.command_buffer_to_wait->pending)
|
||||
//Don't bother poking the state, a flush later will likely do it for free
|
||||
return false;
|
||||
|
||||
u32 oldest = data.indices.front();
|
||||
|
@ -3649,21 +3667,27 @@ void VKGSRender::get_occlusion_query_result(rsx::reports::occlusion_query_info*
|
|||
std::lock_guard lock(m_flush_queue_mutex);
|
||||
flush_command_queue();
|
||||
|
||||
//Clear any deferred flush requests from previous call to get_query_status()
|
||||
if (m_flush_requests.pending())
|
||||
{
|
||||
m_flush_requests.clear_pending_flag();
|
||||
m_flush_requests.consumer_wait();
|
||||
}
|
||||
}
|
||||
|
||||
if (data.command_buffer_to_wait->pending)
|
||||
data.command_buffer_to_wait->wait(GENERAL_WAIT_TIMEOUT);
|
||||
// Fast wait. Avoids heavyweight routines
|
||||
while (!data.command_buffer_to_wait->poke())
|
||||
{
|
||||
_mm_pause();
|
||||
|
||||
//Gather data
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Gather data
|
||||
for (const auto occlusion_id : data.indices)
|
||||
{
|
||||
//We only need one hit
|
||||
// We only need one hit
|
||||
if (auto value = m_occlusion_query_pool.get_query_result(occlusion_id))
|
||||
{
|
||||
query->result = 1;
|
||||
|
|
Loading…
Add table
Reference in a new issue