mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 02:32:36 +01:00
vk: Keep the total number of allocated samplers under control
This commit is contained in:
parent
8c3fb3998c
commit
2331dc3256
@ -285,8 +285,14 @@ void VKGSRender::load_texture_env()
|
||||
|
||||
if (replace)
|
||||
{
|
||||
fs_sampler_handles[i] = vk::get_resource_manager()->find_sampler(*m_device, wrap_s, wrap_t, wrap_r, false, lod_bias, af_level, min_lod, max_lod,
|
||||
min_filter.filter, mag_filter, min_filter.mipmap_mode, border_color, compare_enabled, depth_compare_mode);
|
||||
fs_sampler_handles[i] = vk::get_resource_manager()->get_sampler(
|
||||
*m_device,
|
||||
fs_sampler_handles[i],
|
||||
wrap_s, wrap_t, wrap_r,
|
||||
false,
|
||||
lod_bias, af_level, min_lod, max_lod,
|
||||
min_filter.filter, mag_filter, min_filter.mipmap_mode,
|
||||
border_color, compare_enabled, depth_compare_mode);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -338,8 +344,9 @@ void VKGSRender::load_texture_env()
|
||||
|
||||
if (replace)
|
||||
{
|
||||
vs_sampler_handles[i] = vk::get_resource_manager()->find_sampler(
|
||||
vs_sampler_handles[i] = vk::get_resource_manager()->get_sampler(
|
||||
*m_device,
|
||||
vs_sampler_handles[i],
|
||||
VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_REPEAT,
|
||||
unnormalized_coords,
|
||||
0.f, 1.f, min_lod, max_lod,
|
||||
|
@ -223,6 +223,8 @@ void VKGSRender::frame_context_cleanup(vk::frame_context_t *ctx, bool free_resou
|
||||
m_overlay_manager->dispose(uids_to_dispose);
|
||||
}
|
||||
|
||||
vk::get_resource_manager()->trim();
|
||||
|
||||
vk::reset_global_resources();
|
||||
|
||||
ctx->buffer_views_to_clean.clear();
|
||||
|
@ -31,6 +31,34 @@ namespace vk
|
||||
return &g_resource_manager;
|
||||
}
|
||||
|
||||
void resource_manager::trim()
|
||||
{
|
||||
// For any managed resources, try to keep the number of unused/idle resources as low as possible.
|
||||
// Improves search times as well as keeping us below the hardware limit.
|
||||
const auto limits = get_current_renderer()->gpu().get_limits();
|
||||
const auto allocated_sampler_count = vmm_get_application_pool_usage(VMM_ALLOCATION_POOL_SAMPLER);
|
||||
const auto max_allowed_samplers = std::min((limits.maxSamplerAllocationCount * 3u) / 4u, 2048u);
|
||||
|
||||
if (allocated_sampler_count > max_allowed_samplers)
|
||||
{
|
||||
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));
|
||||
It = m_sampler_pool.erase(It);
|
||||
continue;
|
||||
}
|
||||
|
||||
++It;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u64 get_event_id()
|
||||
{
|
||||
return g_event_ctr++;
|
||||
@ -212,4 +240,16 @@ namespace vk
|
||||
vmm_handle_memory_pressure(load_severity);
|
||||
}
|
||||
}
|
||||
|
||||
void vmm_notify_object_allocated(vmm_allocation_pool pool)
|
||||
{
|
||||
ensure(pool >= VMM_ALLOCATION_POOL_SAMPLER);
|
||||
g_vmm_stats.pool_usage[pool]++;
|
||||
}
|
||||
|
||||
void vmm_notify_object_freed(vmm_allocation_pool pool)
|
||||
{
|
||||
ensure(pool >= VMM_ALLOCATION_POOL_SAMPLER);
|
||||
g_vmm_stats.pool_usage[pool]--;
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ namespace vk
|
||||
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;
|
||||
|
||||
eid_scope_t(u64 _eid):
|
||||
eid(_eid), m_device(g_render_device)
|
||||
@ -40,13 +41,19 @@ namespace vk
|
||||
m_disposed_image_views.clear();
|
||||
m_disposed_images.clear();
|
||||
m_disposed_query_pools.clear();
|
||||
m_disposed_samplers.clear();
|
||||
}
|
||||
};
|
||||
|
||||
class resource_manager
|
||||
{
|
||||
private:
|
||||
std::unordered_map<u64, std::unique_ptr<vk::sampler>> m_sampler_pool;
|
||||
struct cached_sampler_object_t : public vk::sampler, public rsx::ref_counted
|
||||
{
|
||||
using vk::sampler::sampler;
|
||||
};
|
||||
|
||||
std::unordered_map<u64, std::unique_ptr<cached_sampler_object_t>> m_sampler_pool;
|
||||
std::deque<eid_scope_t> m_eid_map;
|
||||
|
||||
eid_scope_t& get_current_eid_scope()
|
||||
@ -98,7 +105,8 @@ namespace vk
|
||||
m_sampler_pool.clear();
|
||||
}
|
||||
|
||||
vk::sampler* find_sampler(const vk::render_device& dev, VkSamplerAddressMode clamp_u, VkSamplerAddressMode clamp_v, VkSamplerAddressMode clamp_w,
|
||||
vk::sampler* get_sampler(const vk::render_device& dev, vk::sampler* previous,
|
||||
VkSamplerAddressMode clamp_u, VkSamplerAddressMode clamp_v, VkSamplerAddressMode clamp_w,
|
||||
VkBool32 unnormalized_coordinates, float mipLodBias, float max_anisotropy, float min_lod, float max_lod,
|
||||
VkFilter min_filter, VkFilter mag_filter, VkSamplerMipmapMode mipmap_mode, VkBorderColor border_color,
|
||||
VkBool32 depth_compare = VK_FALSE, VkCompareOp depth_compare_mode = VK_COMPARE_OP_NEVER)
|
||||
@ -115,20 +123,30 @@ namespace vk
|
||||
key |= u64(encode_fxp<true>(mipLodBias)) << 44; // 13 bits
|
||||
key |= u64(max_anisotropy) << 57; // 4 bits
|
||||
|
||||
if (previous)
|
||||
{
|
||||
auto as_cached_object = static_cast<cached_sampler_object_t*>(previous);
|
||||
ensure(as_cached_object->has_refs());
|
||||
as_cached_object->release();
|
||||
}
|
||||
|
||||
if (const auto found = m_sampler_pool.find(key);
|
||||
found != m_sampler_pool.end())
|
||||
{
|
||||
found->second->add_ref();
|
||||
return found->second.get();
|
||||
}
|
||||
|
||||
auto result = std::make_unique<vk::sampler>(
|
||||
auto result = std::make_unique<cached_sampler_object_t>(
|
||||
dev, clamp_u, clamp_v, clamp_w, unnormalized_coordinates,
|
||||
mipLodBias, max_anisotropy, min_lod, max_lod,
|
||||
min_filter, mag_filter, mipmap_mode, border_color,
|
||||
depth_compare, depth_compare_mode);
|
||||
|
||||
auto It = m_sampler_pool.emplace(key, std::move(result));
|
||||
return It.first->second.get();
|
||||
auto ret = It.first->second.get();
|
||||
ret->add_ref();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void dispose(std::unique_ptr<vk::buffer>& buf)
|
||||
@ -162,6 +180,11 @@ namespace vk
|
||||
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 eid_completed(u64 eid)
|
||||
{
|
||||
while (!m_eid_map.empty())
|
||||
@ -177,6 +200,8 @@ namespace vk
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void trim();
|
||||
};
|
||||
|
||||
struct vmm_allocation_t
|
||||
|
@ -18,6 +18,7 @@ namespace vk
|
||||
VMM_ALLOCATION_POOL_TEXTURE_CACHE,
|
||||
VMM_ALLOCATION_POOL_SWAPCHAIN,
|
||||
VMM_ALLOCATION_POOL_SCRATCH,
|
||||
VMM_ALLOCATION_POOL_SAMPLER,
|
||||
};
|
||||
}
|
||||
|
||||
@ -173,6 +174,7 @@ namespace vk
|
||||
void* m_host_pointer;
|
||||
};
|
||||
|
||||
// Tracking for memory usage. Constrained largely by amount of VRAM + shared video memory.
|
||||
void vmm_notify_memory_allocated(void* handle, u32 memory_type, u64 memory_size, vmm_allocation_pool pool);
|
||||
void vmm_notify_memory_freed(void* handle);
|
||||
void vmm_reset();
|
||||
@ -182,5 +184,9 @@ namespace vk
|
||||
bool vmm_handle_memory_pressure(rsx::problem_severity severity);
|
||||
rsx::problem_severity vmm_determine_memory_load_severity();
|
||||
|
||||
// Tracking for host memory objects. Allocated count is more important than actual memory amount.
|
||||
void vmm_notify_object_allocated(vmm_allocation_pool pool);
|
||||
void vmm_notify_object_freed(vmm_allocation_pool pool);
|
||||
|
||||
mem_allocator_base* get_current_mem_allocator();
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include "memory.h"
|
||||
#include "sampler.h"
|
||||
#include "../../rsx_utils.h"
|
||||
|
||||
@ -27,11 +28,13 @@ namespace vk
|
||||
info.borderColor = border_color;
|
||||
|
||||
CHECK_RESULT(vkCreateSampler(m_device, &info, nullptr, &value));
|
||||
vmm_notify_object_allocated(VMM_ALLOCATION_POOL_SAMPLER);
|
||||
}
|
||||
|
||||
sampler::~sampler()
|
||||
{
|
||||
vkDestroySampler(m_device, value, nullptr);
|
||||
vmm_notify_object_freed(VMM_ALLOCATION_POOL_SAMPLER);
|
||||
}
|
||||
|
||||
bool sampler::matches(VkSamplerAddressMode clamp_u, VkSamplerAddressMode clamp_v, VkSamplerAddressMode clamp_w,
|
||||
|
Loading…
Reference in New Issue
Block a user