vk: Fix query reset when renderpass is active

- Performs delayed query reset on-demand
This commit is contained in:
kd-11 2020-06-04 21:45:49 +03:00 committed by kd-11
parent 334d0bbc86
commit 69c2150fbd
2 changed files with 27 additions and 16 deletions

View file

@ -989,14 +989,14 @@ void VKGSRender::end()
if (m_current_command_buffer->flags & vk::command_buffer::cb_load_occluson_task)
{
u32 occlusion_id = m_occlusion_query_pool.find_free_slot();
u32 occlusion_id = m_occlusion_query_pool.find_free_slot(*m_current_command_buffer);
if (occlusion_id == UINT32_MAX)
{
// Force flush
rsx_log.error("[Performance Warning] Out of free occlusion slots. Forcing hard sync.");
ZCULL_control::sync(this);
occlusion_id = m_occlusion_query_pool.find_free_slot();
occlusion_id = m_occlusion_query_pool.find_free_slot(*m_current_command_buffer);
if (occlusion_id == UINT32_MAX)
{
//rsx_log.error("Occlusion pool overflow");

View file

@ -156,6 +156,9 @@ namespace vk
void release_global_submit_lock();
void queue_submit(VkQueue queue, const VkSubmitInfo* info, fence* pfence, VkBool32 flush = VK_FALSE);
bool is_renderpass_open(VkCommandBuffer cmd);
void end_renderpass(VkCommandBuffer cmd);
template<class T>
T* get_compute_task();
void reset_compute_tasks();
@ -3211,12 +3214,7 @@ public:
void begin_query(vk::command_buffer &cmd, u32 index)
{
if (query_slot_status[index].active)
{
//Synchronization must be done externally
vkCmdResetQueryPool(cmd, query_pool, index, 1);
query_slot_status[index] = {};
}
verify(HERE), query_slot_status[index].active == false;
vkCmdBeginQuery(cmd, query_pool, index, 0);//VK_QUERY_CONTROL_PRECISE_BIT);
query_slot_status[index].active = true;
@ -3250,13 +3248,11 @@ public:
vkCmdCopyQueryPoolResults(cmd, query_pool, index, 1, dst, dst_offset, 4, VK_QUERY_RESULT_WAIT_BIT);
}
void reset_query(vk::command_buffer &cmd, u32 index)
void reset_query(vk::command_buffer &/*cmd*/, u32 index)
{
if (query_slot_status[index].active)
{
vkCmdResetQueryPool(cmd, query_pool, index, 1);
query_slot_status[index] = {};
// Actual reset is handled later on demand
available_slots.push_back(index);
}
}
@ -3277,17 +3273,32 @@ public:
}
}
u32 find_free_slot()
u32 find_free_slot(vk::command_buffer& cmd)
{
if (available_slots.empty())
{
return ~0u;
}
u32 result = available_slots.front();
available_slots.pop_front();
const u32 result = available_slots.front();
if (query_slot_status[result].active)
{
// Trigger reset if round robin allocation has gone back to the first item
if (vk::is_renderpass_open(cmd))
{
vk::end_renderpass(cmd);
}
verify(HERE), !query_slot_status[result].active;
// At this point, the first available slot is not reset which means they're all active
for (auto It = available_slots.cbegin(); It != available_slots.cend(); ++It)
{
const auto index = *It;
vkCmdResetQueryPool(cmd, query_pool, index, 1);
query_slot_status[index] = {};
}
}
available_slots.pop_front();
return result;
}
};