mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-29 22:20:48 +00:00
vk: Add support for spec-compliant query scopes
This commit is contained in:
parent
afc10ea112
commit
883529eaf3
@ -797,6 +797,16 @@ void VKGSRender::emit_geometry(u32 sub_index)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Before starting a query, we need to match RP scope (VK_1_0 rules).
|
||||||
|
// We always want our queries to start outside a renderpass whenever possible.
|
||||||
|
// We ignore this for performance reasons whenever possible of course and only do this for sensitive drivers.
|
||||||
|
if (vk::use_strict_query_scopes() &&
|
||||||
|
vk::is_renderpass_open(*m_current_command_buffer))
|
||||||
|
{
|
||||||
|
vk::end_renderpass(*m_current_command_buffer);
|
||||||
|
emergency_query_cleanup(m_current_command_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
// Begin query
|
// Begin query
|
||||||
m_occlusion_query_manager->begin_query(*m_current_command_buffer, occlusion_id);
|
m_occlusion_query_manager->begin_query(*m_current_command_buffer, occlusion_id);
|
||||||
|
|
||||||
|
@ -2877,6 +2877,14 @@ void VKGSRender::end_occlusion_query(rsx::reports::occlusion_query_info* query)
|
|||||||
// NOTE: flushing the queue is very expensive, do not flush just because query stopped
|
// NOTE: flushing the queue is very expensive, do not flush just because query stopped
|
||||||
if (m_current_command_buffer->flags & vk::command_buffer::cb_has_open_query)
|
if (m_current_command_buffer->flags & vk::command_buffer::cb_has_open_query)
|
||||||
{
|
{
|
||||||
|
// VK_1_0 rules dictate that query must match subpass behavior on begin/end query.
|
||||||
|
// This is slow, so only do this for drivers that care.
|
||||||
|
if (vk::use_strict_query_scopes() &&
|
||||||
|
vk::is_renderpass_open(*m_current_command_buffer))
|
||||||
|
{
|
||||||
|
vk::end_renderpass(*m_current_command_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
// End query
|
// End query
|
||||||
auto open_query = m_occlusion_map[m_active_query_info->driver_handle].indices.back();
|
auto open_query = m_occlusion_map[m_active_query_info->driver_handle].indices.back();
|
||||||
m_occlusion_query_manager->end_query(*m_current_command_buffer, open_query);
|
m_occlusion_query_manager->end_query(*m_current_command_buffer, open_query);
|
||||||
|
@ -31,6 +31,8 @@ namespace vk
|
|||||||
bool g_drv_sanitize_fp_values = false;
|
bool g_drv_sanitize_fp_values = false;
|
||||||
bool g_drv_disable_fence_reset = false;
|
bool g_drv_disable_fence_reset = false;
|
||||||
bool g_drv_emulate_cond_render = false;
|
bool g_drv_emulate_cond_render = false;
|
||||||
|
bool g_drv_strict_query_scopes = false;
|
||||||
|
bool g_drv_force_reuse_query_pools = false;
|
||||||
|
|
||||||
u64 g_num_processed_frames = 0;
|
u64 g_num_processed_frames = 0;
|
||||||
u64 g_num_total_frames = 0;
|
u64 g_num_total_frames = 0;
|
||||||
@ -231,6 +233,16 @@ namespace vk
|
|||||||
return g_drv_emulate_cond_render;
|
return g_drv_emulate_cond_render;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool use_strict_query_scopes()
|
||||||
|
{
|
||||||
|
return g_drv_strict_query_scopes;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool force_reuse_query_pools()
|
||||||
|
{
|
||||||
|
return g_drv_force_reuse_query_pools;
|
||||||
|
}
|
||||||
|
|
||||||
void raise_status_interrupt(runtime_state status)
|
void raise_status_interrupt(runtime_state status)
|
||||||
{
|
{
|
||||||
g_runtime_state |= status;
|
g_runtime_state |= status;
|
||||||
|
@ -62,6 +62,8 @@ namespace vk
|
|||||||
bool sanitize_fp_values();
|
bool sanitize_fp_values();
|
||||||
bool fence_reset_disabled();
|
bool fence_reset_disabled();
|
||||||
bool emulate_conditional_rendering();
|
bool emulate_conditional_rendering();
|
||||||
|
bool use_strict_query_scopes();
|
||||||
|
bool force_reuse_query_pools();
|
||||||
VkFlags get_heap_compatible_buffer_types();
|
VkFlags get_heap_compatible_buffer_types();
|
||||||
|
|
||||||
// Sync helpers around vkQueueSubmit
|
// Sync helpers around vkQueueSubmit
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
#include "VKHelpers.h"
|
||||||
#include "VKQueryPool.h"
|
#include "VKQueryPool.h"
|
||||||
#include "VKRenderPass.h"
|
#include "VKRenderPass.h"
|
||||||
#include "VKResourceManager.h"
|
#include "VKResourceManager.h"
|
||||||
@ -74,13 +75,20 @@ namespace vk
|
|||||||
{
|
{
|
||||||
ensure(!m_current_query_pool);
|
ensure(!m_current_query_pool);
|
||||||
|
|
||||||
const u32 count = ::size32(query_slot_status);
|
if (m_query_pool_cache.size() > 0)
|
||||||
m_current_query_pool = std::make_unique<query_pool>(*owner, query_type, count);
|
{
|
||||||
|
m_current_query_pool = std::move(m_query_pool_cache.front());
|
||||||
|
m_query_pool_cache.pop_front();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const u32 count = ::size32(query_slot_status);
|
||||||
|
m_current_query_pool = std::make_unique<query_pool>(*owner, query_type, count);
|
||||||
|
}
|
||||||
|
|
||||||
// From spec: "After query pool creation, each query must be reset before it is used."
|
// From spec: "After query pool creation, each query must be reset before it is used."
|
||||||
vkCmdResetQueryPool(cmd, *m_current_query_pool.get(), 0, count);
|
vkCmdResetQueryPool(cmd, *m_current_query_pool.get(), 0, m_current_query_pool->size());
|
||||||
|
m_pool_lifetime_counter = m_current_query_pool->size();
|
||||||
m_pool_lifetime_counter = count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void query_pool_manager::reallocate_pool(vk::command_buffer& cmd)
|
void query_pool_manager::reallocate_pool(vk::command_buffer& cmd)
|
||||||
@ -89,7 +97,8 @@ namespace vk
|
|||||||
{
|
{
|
||||||
if (!m_current_query_pool->has_refs())
|
if (!m_current_query_pool->has_refs())
|
||||||
{
|
{
|
||||||
vk::get_resource_manager()->dispose(m_current_query_pool);
|
auto ref = std::make_unique<query_pool_ref>(this, m_current_query_pool);
|
||||||
|
vk::get_resource_manager()->dispose(ref);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -112,7 +121,8 @@ namespace vk
|
|||||||
{
|
{
|
||||||
if (!(*It)->has_refs())
|
if (!(*It)->has_refs())
|
||||||
{
|
{
|
||||||
vk::get_resource_manager()->dispose(*It);
|
auto ref = std::make_unique<query_pool_ref>(this, *It);
|
||||||
|
vk::get_resource_manager()->dispose(ref);
|
||||||
It = m_consumed_pools.erase(It);
|
It = m_consumed_pools.erase(It);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -219,4 +229,21 @@ namespace vk
|
|||||||
|
|
||||||
return ~0u;
|
return ~0u;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void query_pool_manager::on_query_pool_released(std::unique_ptr<vk::query_pool>& pool)
|
||||||
|
{
|
||||||
|
if (!vk::force_reuse_query_pools())
|
||||||
|
{
|
||||||
|
// Delete and let the driver recreate a new pool each time.
|
||||||
|
pool.reset();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_query_pool_cache.emplace_back(std::move(pool));
|
||||||
|
}
|
||||||
|
|
||||||
|
query_pool_manager::query_pool_ref::~query_pool_ref()
|
||||||
|
{
|
||||||
|
m_pool_man->on_query_pool_released(m_object);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,22 @@ namespace vk
|
|||||||
u32 data;
|
u32 data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class query_pool_ref
|
||||||
|
{
|
||||||
|
std::unique_ptr<query_pool> m_object;
|
||||||
|
query_pool_manager* m_pool_man;
|
||||||
|
|
||||||
|
public:
|
||||||
|
query_pool_ref(query_pool_manager* pool_man, std::unique_ptr<query_pool>& pool)
|
||||||
|
: m_object(std::move(pool))
|
||||||
|
, m_pool_man(pool_man)
|
||||||
|
{}
|
||||||
|
|
||||||
|
~query_pool_ref();
|
||||||
|
};
|
||||||
|
|
||||||
std::vector<std::unique_ptr<query_pool>> m_consumed_pools;
|
std::vector<std::unique_ptr<query_pool>> m_consumed_pools;
|
||||||
|
std::deque<std::unique_ptr<query_pool>> m_query_pool_cache;
|
||||||
std::unique_ptr<query_pool> m_current_query_pool;
|
std::unique_ptr<query_pool> m_current_query_pool;
|
||||||
std::deque<u32> m_available_slots;
|
std::deque<u32> m_available_slots;
|
||||||
u32 m_pool_lifetime_counter = 0;
|
u32 m_pool_lifetime_counter = 0;
|
||||||
@ -52,6 +67,8 @@ namespace vk
|
|||||||
u32 allocate_query(vk::command_buffer& cmd);
|
u32 allocate_query(vk::command_buffer& cmd);
|
||||||
void free_query(vk::command_buffer&/*cmd*/, u32 index);
|
void free_query(vk::command_buffer&/*cmd*/, u32 index);
|
||||||
|
|
||||||
|
void on_query_pool_released(std::unique_ptr<vk::query_pool>& pool);
|
||||||
|
|
||||||
template<template<class> class _List>
|
template<template<class> class _List>
|
||||||
void free_queries(vk::command_buffer& cmd, _List<u32>& list)
|
void free_queries(vk::command_buffer& cmd, _List<u32>& list)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user