mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-14 10:21:21 +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
|
||||
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
|
||||
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
|
||||
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);
|
||||
|
@ -31,6 +31,8 @@ namespace vk
|
||||
bool g_drv_sanitize_fp_values = false;
|
||||
bool g_drv_disable_fence_reset = 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_total_frames = 0;
|
||||
@ -231,6 +233,16 @@ namespace vk
|
||||
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)
|
||||
{
|
||||
g_runtime_state |= status;
|
||||
|
@ -62,6 +62,8 @@ namespace vk
|
||||
bool sanitize_fp_values();
|
||||
bool fence_reset_disabled();
|
||||
bool emulate_conditional_rendering();
|
||||
bool use_strict_query_scopes();
|
||||
bool force_reuse_query_pools();
|
||||
VkFlags get_heap_compatible_buffer_types();
|
||||
|
||||
// Sync helpers around vkQueueSubmit
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "stdafx.h"
|
||||
#include "VKHelpers.h"
|
||||
#include "VKQueryPool.h"
|
||||
#include "VKRenderPass.h"
|
||||
#include "VKResourceManager.h"
|
||||
@ -74,13 +75,20 @@ namespace vk
|
||||
{
|
||||
ensure(!m_current_query_pool);
|
||||
|
||||
const u32 count = ::size32(query_slot_status);
|
||||
m_current_query_pool = std::make_unique<query_pool>(*owner, query_type, count);
|
||||
if (m_query_pool_cache.size() > 0)
|
||||
{
|
||||
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."
|
||||
vkCmdResetQueryPool(cmd, *m_current_query_pool.get(), 0, count);
|
||||
|
||||
m_pool_lifetime_counter = count;
|
||||
vkCmdResetQueryPool(cmd, *m_current_query_pool.get(), 0, m_current_query_pool->size());
|
||||
m_pool_lifetime_counter = m_current_query_pool->size();
|
||||
}
|
||||
|
||||
void query_pool_manager::reallocate_pool(vk::command_buffer& cmd)
|
||||
@ -89,7 +97,8 @@ namespace vk
|
||||
{
|
||||
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
|
||||
{
|
||||
@ -112,7 +121,8 @@ namespace vk
|
||||
{
|
||||
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);
|
||||
}
|
||||
else
|
||||
@ -219,4 +229,21 @@ namespace vk
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
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::deque<std::unique_ptr<query_pool>> m_query_pool_cache;
|
||||
std::unique_ptr<query_pool> m_current_query_pool;
|
||||
std::deque<u32> m_available_slots;
|
||||
u32 m_pool_lifetime_counter = 0;
|
||||
@ -52,6 +67,8 @@ namespace vk
|
||||
u32 allocate_query(vk::command_buffer& cmd);
|
||||
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>
|
||||
void free_queries(vk::command_buffer& cmd, _List<u32>& list)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user