mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 03:25:16 +00:00
vk: Rewrite resource management
This commit is contained in:
parent
48b54131f6
commit
f667b52cca
6 changed files with 85 additions and 77 deletions
|
@ -655,9 +655,6 @@ VKGSRender::~VKGSRender()
|
|||
// Upscaler (references some global resources)
|
||||
m_upscaler.reset();
|
||||
|
||||
// Global resources
|
||||
vk::destroy_global_resources();
|
||||
|
||||
// Heaps
|
||||
m_attrib_ring_info.destroy();
|
||||
m_fragment_env_ring_info.destroy();
|
||||
|
@ -722,6 +719,9 @@ VKGSRender::~VKGSRender()
|
|||
m_secondary_command_buffer.destroy();
|
||||
m_secondary_command_buffer_pool.destroy();
|
||||
|
||||
// Global resources
|
||||
vk::destroy_global_resources();
|
||||
|
||||
// Device handles/contexts
|
||||
m_swapchain->destroy();
|
||||
m_instance.destroy();
|
||||
|
|
|
@ -67,7 +67,6 @@ namespace vk
|
|||
vk::clear_framebuffer_cache();
|
||||
vk::clear_resolve_helpers();
|
||||
vk::clear_dma_resources();
|
||||
vk::vmm_reset();
|
||||
vk::clear_scratch_resources();
|
||||
|
||||
vk::get_upload_heap()->destroy();
|
||||
|
@ -82,6 +81,9 @@ namespace vk
|
|||
|
||||
// This must be the last item destroyed
|
||||
vk::get_resource_manager()->destroy();
|
||||
|
||||
// Statistics counter reset. Also verifies that everything was deleted.
|
||||
vk::vmm_reset();
|
||||
}
|
||||
|
||||
const vk::render_device *get_current_renderer()
|
||||
|
|
|
@ -13,6 +13,16 @@ namespace vk
|
|||
|
||||
void clear()
|
||||
{
|
||||
if (!allocations.empty())
|
||||
{
|
||||
rsx_log.error("Leaking memory allocations!");
|
||||
for (auto& leak : allocations)
|
||||
{
|
||||
rsx_log.error("Memory handle 0x%llx (%llu bytes) allocated from pool %d was not freed.",
|
||||
leak.first, leak.second.size, static_cast<int>(leak.second.pool));
|
||||
}
|
||||
}
|
||||
|
||||
allocations.clear();
|
||||
memory_usage.clear();
|
||||
pool_usage.clear();
|
||||
|
@ -44,12 +54,11 @@ namespace vk
|
|||
ensure(max_allowed_samplers);
|
||||
rsx_log.warning("Trimming allocated samplers. Allocated = %u, Max = %u", allocated_sampler_count, limits.maxSamplerAllocationCount);
|
||||
|
||||
auto& disposed_samplers_pool = get_current_eid_scope().m_disposed_samplers;
|
||||
for (auto It = m_sampler_pool.begin(); It != m_sampler_pool.end();)
|
||||
{
|
||||
if (!It->second->has_refs())
|
||||
{
|
||||
disposed_samplers_pool.emplace_back(std::move(It->second));
|
||||
dispose(It->second);
|
||||
It = m_sampler_pool.erase(It);
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
#include "vkutils/query_pool.hpp"
|
||||
#include "vkutils/sampler.h"
|
||||
|
||||
#include "Utilities/mutex.h"
|
||||
|
||||
#include <unordered_map>
|
||||
#include <deque>
|
||||
#include <memory>
|
||||
|
@ -14,22 +16,47 @@ namespace vk
|
|||
u64 last_completed_event_id();
|
||||
void on_event_completed(u64 event_id, bool flush = false);
|
||||
|
||||
struct disposable_t
|
||||
class disposable_t
|
||||
{
|
||||
virtual void dispose() = 0;
|
||||
void* ptr;
|
||||
std::function<void(void*)> deleter;
|
||||
|
||||
disposable_t(void* ptr_, std::function<void(void*)> deleter_) :
|
||||
ptr(ptr_), deleter(deleter_) {}
|
||||
public:
|
||||
|
||||
disposable_t() = delete;
|
||||
disposable_t(const disposable_t&) = delete;
|
||||
|
||||
disposable_t(disposable_t&& other):
|
||||
ptr(std::exchange(other.ptr, nullptr)),
|
||||
deleter(other.deleter)
|
||||
{}
|
||||
|
||||
~disposable_t()
|
||||
{
|
||||
if (ptr)
|
||||
{
|
||||
deleter(ptr);
|
||||
ptr = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static disposable_t make(T* raw)
|
||||
{
|
||||
return disposable_t(raw, [](void *raw)
|
||||
{
|
||||
delete static_cast<T*>(raw);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
struct eid_scope_t
|
||||
{
|
||||
u64 eid;
|
||||
const vk::render_device* m_device;
|
||||
std::vector<std::unique_ptr<vk::buffer>> m_disposed_buffers;
|
||||
std::vector<std::unique_ptr<vk::image_view>> m_disposed_image_views;
|
||||
std::vector<std::unique_ptr<vk::image>> m_disposed_images;
|
||||
std::vector<std::unique_ptr<vk::event>> m_disposed_events;
|
||||
std::vector<std::unique_ptr<vk::query_pool>> m_disposed_query_pools;
|
||||
std::vector<std::unique_ptr<vk::sampler>> m_disposed_samplers;
|
||||
std::vector<std::unique_ptr<vk::disposable_t>> m_disposables;
|
||||
std::vector<disposable_t> m_disposables;
|
||||
|
||||
eid_scope_t(u64 _eid):
|
||||
eid(_eid), m_device(g_render_device)
|
||||
|
@ -40,19 +67,15 @@ namespace vk
|
|||
discard();
|
||||
}
|
||||
|
||||
void swap(eid_scope_t& other)
|
||||
{
|
||||
std::swap(eid, other.eid);
|
||||
std::swap(m_device, other.m_device);
|
||||
std::swap(m_disposables, other.m_disposables);
|
||||
}
|
||||
|
||||
void discard()
|
||||
{
|
||||
m_disposed_buffers.clear();
|
||||
m_disposed_events.clear();
|
||||
m_disposed_image_views.clear();
|
||||
m_disposed_images.clear();
|
||||
m_disposed_query_pools.clear();
|
||||
m_disposed_samplers.clear();
|
||||
|
||||
for (auto& disposable : m_disposables)
|
||||
{
|
||||
disposable->dispose();
|
||||
}
|
||||
m_disposables.clear();
|
||||
}
|
||||
};
|
||||
|
@ -67,20 +90,18 @@ namespace vk
|
|||
|
||||
std::unordered_map<u64, std::unique_ptr<cached_sampler_object_t>> m_sampler_pool;
|
||||
std::deque<eid_scope_t> m_eid_map;
|
||||
shared_mutex m_eid_map_lock;
|
||||
|
||||
eid_scope_t& get_current_eid_scope()
|
||||
inline eid_scope_t& get_current_eid_scope()
|
||||
{
|
||||
const auto eid = current_event_id();
|
||||
if (!m_eid_map.empty())
|
||||
{
|
||||
// Elements are insterted in order, so just check the last entry for a match
|
||||
if (auto &old = m_eid_map.back(); old.eid == eid)
|
||||
std::lock_guard lock(m_eid_map_lock);
|
||||
if (m_eid_map.empty() || m_eid_map.back().eid != eid)
|
||||
{
|
||||
return old;
|
||||
m_eid_map.emplace_back(eid);
|
||||
}
|
||||
}
|
||||
|
||||
m_eid_map.emplace_back(eid);
|
||||
return m_eid_map.back();
|
||||
}
|
||||
|
||||
|
@ -161,47 +182,18 @@ namespace vk
|
|||
return ret;
|
||||
}
|
||||
|
||||
void dispose(std::unique_ptr<vk::buffer>& buf)
|
||||
{
|
||||
get_current_eid_scope().m_disposed_buffers.emplace_back(std::move(buf));
|
||||
}
|
||||
|
||||
void dispose(std::unique_ptr<vk::image_view>& view)
|
||||
{
|
||||
get_current_eid_scope().m_disposed_image_views.emplace_back(std::move(view));
|
||||
}
|
||||
|
||||
void dispose(std::unique_ptr<vk::image>& img)
|
||||
{
|
||||
get_current_eid_scope().m_disposed_images.emplace_back(std::move(img));
|
||||
}
|
||||
|
||||
void dispose(std::unique_ptr<vk::viewable_image>& img)
|
||||
{
|
||||
get_current_eid_scope().m_disposed_images.emplace_back(std::move(img));
|
||||
}
|
||||
|
||||
void dispose(std::unique_ptr<vk::event>& event)
|
||||
{
|
||||
get_current_eid_scope().m_disposed_events.emplace_back(std::move(event));
|
||||
event = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
void dispose(std::unique_ptr<vk::query_pool>& pool)
|
||||
{
|
||||
get_current_eid_scope().m_disposed_query_pools.emplace_back(std::move(pool));
|
||||
}
|
||||
|
||||
void dispose(std::unique_ptr<vk::sampler>& sampler)
|
||||
{
|
||||
get_current_eid_scope().m_disposed_samplers.emplace_back(std::move(sampler));
|
||||
}
|
||||
|
||||
void dispose(std::unique_ptr<vk::disposable_t>& disposable)
|
||||
inline void dispose(vk::disposable_t& disposable)
|
||||
{
|
||||
get_current_eid_scope().m_disposables.emplace_back(std::move(disposable));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void dispose(std::unique_ptr<T>& object)
|
||||
{
|
||||
auto ptr = vk::disposable_t::make(object.release());
|
||||
dispose(ptr);
|
||||
}
|
||||
|
||||
void eid_completed(u64 eid)
|
||||
{
|
||||
while (!m_eid_map.empty())
|
||||
|
@ -213,7 +205,12 @@ namespace vk
|
|||
}
|
||||
else
|
||||
{
|
||||
m_eid_map.pop_front();
|
||||
eid_scope_t tmp(0);
|
||||
{
|
||||
std::lock_guard lock(m_eid_map_lock);
|
||||
m_eid_map.front().swap(tmp);
|
||||
m_eid_map.pop_front();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace vk
|
|||
this->data = std::move(previous);
|
||||
}
|
||||
|
||||
void texture_cache::cached_image_reference_t::dispose()
|
||||
texture_cache::cached_image_reference_t::~cached_image_reference_t()
|
||||
{
|
||||
// Erase layout information to force TOP_OF_PIPE transition next time.
|
||||
data->current_layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
|
@ -208,7 +208,7 @@ namespace vk
|
|||
{
|
||||
if (tex.is_managed() && tex.exists())
|
||||
{
|
||||
auto disposable = std::unique_ptr<vk::disposable_t>(new cached_image_reference_t(this, tex.get_texture()));
|
||||
auto disposable = vk::disposable_t::make(new cached_image_reference_t(this, tex.get_texture()));
|
||||
vk::get_resource_manager()->dispose(disposable);
|
||||
}
|
||||
}
|
||||
|
@ -745,7 +745,7 @@ namespace vk
|
|||
ensure(resource);
|
||||
|
||||
auto image = std::unique_ptr<vk::viewable_image>(resource);
|
||||
auto disposable = std::unique_ptr<vk::disposable_t>(new cached_image_reference_t(this, image));
|
||||
auto disposable = vk::disposable_t::make(new cached_image_reference_t(this, image));
|
||||
vk::get_resource_manager()->dispose(disposable);
|
||||
}
|
||||
|
||||
|
@ -1288,7 +1288,7 @@ namespace vk
|
|||
|
||||
auto result = image.get();
|
||||
const auto resource_memory = image->memory->size();
|
||||
auto disposable = std::unique_ptr<vk::disposable_t>(new cached_image_reference_t(this, image));
|
||||
auto disposable = vk::disposable_t::make(new cached_image_reference_t(this, image));
|
||||
vk::get_resource_manager()->dispose(disposable);
|
||||
|
||||
return result;
|
||||
|
|
|
@ -356,13 +356,13 @@ namespace vk
|
|||
using baseclass = rsx::texture_cache<vk::texture_cache, vk::texture_cache_traits>;
|
||||
friend baseclass;
|
||||
|
||||
struct cached_image_reference_t : vk::disposable_t
|
||||
struct cached_image_reference_t
|
||||
{
|
||||
std::unique_ptr<vk::viewable_image> data;
|
||||
texture_cache* parent;
|
||||
|
||||
cached_image_reference_t(texture_cache* parent, std::unique_ptr<vk::viewable_image>& previous);
|
||||
void dispose() override;
|
||||
~cached_image_reference_t();
|
||||
};
|
||||
|
||||
struct cached_image_t
|
||||
|
|
Loading…
Add table
Reference in a new issue