diff --git a/rpcs3/Emu/RSX/Common/ring_buffer_helper.h b/rpcs3/Emu/RSX/Common/ring_buffer_helper.h index 398b355e39..2aebd546c3 100644 --- a/rpcs3/Emu/RSX/Common/ring_buffer_helper.h +++ b/rpcs3/Emu/RSX/Common/ring_buffer_helper.h @@ -76,9 +76,9 @@ public: data_heap(const data_heap&) = delete; data_heap(data_heap&&) = delete; - void init(usz heap_size, const char* buffer_name = "unnamed", usz min_guard_size=0x10000) + void init(usz heap_size, const char* buffer_name = nullptr, usz min_guard_size=0x10000) { - m_name = const_cast(buffer_name); + m_name = const_cast(buffer_name ? buffer_name : ""); m_size = heap_size; m_put_pos = 0; diff --git a/rpcs3/Emu/RSX/VK/vkutils/data_heap.cpp b/rpcs3/Emu/RSX/VK/vkutils/data_heap.cpp index 7493049639..ba1b4e79c1 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/data_heap.cpp +++ b/rpcs3/Emu/RSX/VK/vkutils/data_heap.cpp @@ -22,12 +22,17 @@ namespace vk if ((flags & heap_pool_low_latency) && g_cfg.video.vk.use_rebar_upload_heap) { // Prefer uploading to BAR if low latency is desired. - m_prefer_writethrough = memory_map.device_bar_total_bytes > (2048ull * 0x100000); + const int max_usage = memory_map.device_bar_total_bytes <= (256 * 0x100000) ? 75 : 90; + m_prefer_writethrough = can_allocate_heap(memory_map.device_bar, size, max_usage); // Log it - if (m_prefer_writethrough && name) + if (m_prefer_writethrough) { - rsx_log.notice("Data heap %s will attempt to use Re-BAR memory", name); + rsx_log.notice("Data heap %s will attempt to use Re-BAR memory", m_name); + } + else + { + rsx_log.warning("Could not fit heap '%s' into Re-BAR memory", m_name); } } @@ -86,6 +91,17 @@ namespace vk VkBufferUsageFlags usage = heap->info.usage; const auto& memory_map = g_render_device->get_memory_mapping(); + if (m_prefer_writethrough) + { + const int max_usage = memory_map.device_bar_total_bytes <= (256 * 0x100000) ? 75 : 90; + m_prefer_writethrough = can_allocate_heap(memory_map.device_bar, aligned_new_size, max_usage); + + if (!m_prefer_writethrough) + { + rsx_log.warning("Could not fit heap '%s' into Re-BAR memory during reallocation", m_name); + } + } + VkFlags memory_flags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; auto memory_index = m_prefer_writethrough ? memory_map.device_bar : memory_map.host_visible_coherent; @@ -116,6 +132,14 @@ namespace vk return true; } + bool data_heap::can_allocate_heap(const vk::memory_type_info& target_heap, usz size, int max_usage_percent) + { + const auto current_usage = vmm_get_application_memory_usage(target_heap); + const auto after_usage = current_usage + size; + const auto limit = (target_heap.total_bytes() * max_usage_percent) / 100; + return after_usage < limit; + } + void* data_heap::map(usz offset, usz size) { if (!_ptr) diff --git a/rpcs3/Emu/RSX/VK/vkutils/data_heap.h b/rpcs3/Emu/RSX/VK/vkutils/data_heap.h index e804bcdc59..6732f639dc 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/data_heap.h +++ b/rpcs3/Emu/RSX/VK/vkutils/data_heap.h @@ -32,6 +32,7 @@ namespace vk protected: bool grow(usz size) override; + bool can_allocate_heap(const vk::memory_type_info& target_heap, usz size, int max_usage_percent); public: std::unique_ptr heap; diff --git a/rpcs3/Emu/RSX/VK/vkutils/memory.cpp b/rpcs3/Emu/RSX/VK/vkutils/memory.cpp index ac7010f057..80ffc50295 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/memory.cpp +++ b/rpcs3/Emu/RSX/VK/vkutils/memory.cpp @@ -44,6 +44,16 @@ namespace vk return type_ids.size(); } + u64 memory_type_info::total_bytes() const + { + u64 result = 0; + for (const auto& size : type_sizes) + { + result += size; + } + return result; + } + memory_type_info::operator bool() const { return !type_ids.empty(); diff --git a/rpcs3/Emu/RSX/VK/vkutils/memory.h b/rpcs3/Emu/RSX/VK/vkutils/memory.h index eda4035ade..83e09cdd30 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/memory.h +++ b/rpcs3/Emu/RSX/VK/vkutils/memory.h @@ -49,6 +49,7 @@ namespace vk const_iterator end() const; u32 first() const; size_t count() const; + u64 total_bytes() const; operator bool() const; bool operator == (const memory_type_info& other) const;