From 9d05295679dbf34f4ada198f9c6f2397307c740d Mon Sep 17 00:00:00 2001 From: Collecting Date: Wed, 7 Jan 2026 23:57:25 +0000 Subject: [PATCH] revert b1192de0c4063b224f107e8e78a3f2ccdf8e11f7 revert vulkan: Add memory pressure handling and pipeline eviction Signed-off-by: Zephyron --- .../buffer_cache/buffer_cache_base.h | 7 -- .../renderer_vulkan/vk_pipeline_cache.cpp | 81 +------------------ .../renderer_vulkan/vk_pipeline_cache.h | 17 ---- .../renderer_vulkan/vk_rasterizer.cpp | 8 -- .../renderer_vulkan/vk_staging_buffer_pool.h | 6 -- .../texture_cache/texture_cache_base.h | 7 -- .../vulkan_common/vulkan_memory_allocator.cpp | 10 --- .../vulkan_common/vulkan_memory_allocator.h | 11 --- 8 files changed, 2 insertions(+), 145 deletions(-) diff --git a/src/video_core/buffer_cache/buffer_cache_base.h b/src/video_core/buffer_cache/buffer_cache_base.h index 2e6501419..240e9f015 100644 --- a/src/video_core/buffer_cache/buffer_cache_base.h +++ b/src/video_core/buffer_cache/buffer_cache_base.h @@ -1,5 +1,4 @@ // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project -// SPDX-FileCopyrightText: Copyright 2025 Citron Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later #pragma once @@ -344,12 +343,6 @@ private: void RunGarbageCollector(); -public: - /// Public interface to trigger garbage collection - void TriggerGarbageCollection() { - RunGarbageCollector(); - } - void BindHostIndexBuffer(); void BindHostVertexBuffers(); diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index c69f496da..08851144b 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -425,59 +425,6 @@ PipelineCache::~PipelineCache() { } } -void PipelineCache::EvictOldPipelines() { - constexpr u64 FRAMES_TO_KEEP = 2000; - - const u64 current_frame = scheduler.CurrentTick(); - - if (current_frame - last_memory_pressure_frame < MEMORY_PRESSURE_COOLDOWN) { - return; - } - last_memory_pressure_frame = current_frame; - - const u64 evict_before_frame = current_frame > FRAMES_TO_KEEP ? current_frame - FRAMES_TO_KEEP : 0; - - size_t evicted_graphics = 0; - size_t evicted_compute = 0; - - for (auto it = graphics_cache.begin(); it != graphics_cache.end();) { - const GraphicsPipeline* pipeline = it->second.get(); - if (pipeline && pipeline != current_pipeline) { - auto use_it = graphics_pipeline_last_use.find(pipeline); - if (use_it == graphics_pipeline_last_use.end() || use_it->second < evict_before_frame) { - graphics_pipeline_last_use.erase(pipeline); - it = graphics_cache.erase(it); - evicted_graphics++; - } else { - ++it; - } - } else { - ++it; - } - } - - for (auto it = compute_cache.begin(); it != compute_cache.end();) { - const ComputePipeline* pipeline = it->second.get(); - if (pipeline) { - auto use_it = compute_pipeline_last_use.find(pipeline); - if (use_it == compute_pipeline_last_use.end() || use_it->second < evict_before_frame) { - compute_pipeline_last_use.erase(pipeline); - it = compute_cache.erase(it); - evicted_compute++; - } else { - ++it; - } - } else { - ++it; - } - } - - if (evicted_graphics > 0 || evicted_compute > 0) { - LOG_INFO(Render_Vulkan, "Evicted {} graphics and {} compute pipelines to free memory", - evicted_graphics, evicted_compute); - } -} - GraphicsPipeline* PipelineCache::CurrentGraphicsPipeline() { MICROPROFILE_SCOPE(Vulkan_PipelineCache); @@ -491,16 +438,10 @@ GraphicsPipeline* PipelineCache::CurrentGraphicsPipeline() { GraphicsPipeline* const next{current_pipeline->Next(graphics_key)}; if (next) { current_pipeline = next; - // Update last use frame - graphics_pipeline_last_use[current_pipeline] = scheduler.CurrentTick(); return BuiltPipeline(current_pipeline); } } - GraphicsPipeline* result = CurrentGraphicsPipelineSlowPath(); - if (result) { - graphics_pipeline_last_use[result] = scheduler.CurrentTick(); - } - return result; + return CurrentGraphicsPipelineSlowPath(); } ComputePipeline* PipelineCache::CurrentComputePipeline() { @@ -518,14 +459,10 @@ ComputePipeline* PipelineCache::CurrentComputePipeline() { }; const auto [pair, is_new]{compute_cache.try_emplace(key)}; auto& pipeline{pair->second}; - if (!is_new && pipeline) { - compute_pipeline_last_use[pipeline.get()] = scheduler.CurrentTick(); + if (!is_new) { return pipeline.get(); } pipeline = CreateComputePipeline(key, shader); - if (pipeline) { - compute_pipeline_last_use[pipeline.get()] = scheduler.CurrentTick(); - } return pipeline.get(); } @@ -767,13 +704,6 @@ std::unique_ptr PipelineCache::CreateGraphicsPipeline( descriptor_pool, guest_descriptor_queue, thread_worker, statistics, render_pass_cache, key, std::move(modules), infos); -} catch (const vk::Exception& exception) { - if (exception.GetResult() == VK_ERROR_OUT_OF_DEVICE_MEMORY) { - LOG_ERROR(Render_Vulkan, "Out of device memory during graphics pipeline creation, attempting recovery"); - EvictOldPipelines(); - return nullptr; - } - throw; } catch (const Shader::Exception& exception) { auto hash = key.Hash(); size_t env_index{0}; @@ -870,13 +800,6 @@ std::unique_ptr PipelineCache::CreateComputePipeline( guest_descriptor_queue, thread_worker, statistics, &shader_notify, program.info, std::move(spv_module)); -} catch (const vk::Exception& exception) { - if (exception.GetResult() == VK_ERROR_OUT_OF_DEVICE_MEMORY) { - LOG_ERROR(Render_Vulkan, "Out of device memory during compute pipeline creation, attempting recovery"); - EvictOldPipelines(); - return nullptr; - } - throw; } catch (const Shader::Exception& exception) { LOG_ERROR(Render_Vulkan, "{}", exception.what()); return nullptr; diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.h b/src/video_core/renderer_vulkan/vk_pipeline_cache.h index 6fb1d1e12..797700128 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.h +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.h @@ -1,5 +1,4 @@ // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project -// SPDX-FileCopyrightText: Copyright 2025 Citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once @@ -141,15 +140,6 @@ private: vk::PipelineCache LoadVulkanPipelineCache(const std::filesystem::path& filename, u32 expected_cache_version); - /// Evicts old unused pipelines to free memory when under pressure - void EvictOldPipelines(); - -public: - /// Public interface to evict old pipelines (for memory pressure handling) - void TriggerPipelineEviction() { - EvictOldPipelines(); - } - const Device& device; Scheduler& scheduler; DescriptorPool& descriptor_pool; @@ -167,12 +157,6 @@ public: std::unordered_map> compute_cache; std::unordered_map> graphics_cache; - std::unordered_map graphics_pipeline_last_use; - std::unordered_map compute_pipeline_last_use; - - u64 last_memory_pressure_frame{0}; - static constexpr u64 MEMORY_PRESSURE_COOLDOWN = 300; - ShaderPools main_pools; Shader::Profile profile; @@ -186,7 +170,6 @@ public: Common::ThreadWorker workers; Common::ThreadWorker serialization_thread; DynamicFeatures dynamic_features; - }; } // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 33fea028e..2e18a1d0c 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -202,14 +202,6 @@ RasterizerVulkan::RasterizerVulkan(Core::Frontend::EmuWindow& emu_window_, Tegra fence_manager(*this, gpu, texture_cache, buffer_cache, query_cache, device, scheduler), wfi_event(device.GetLogical().CreateEvent()) { scheduler.SetQueryCache(query_cache); - - memory_allocator.SetMemoryPressureCallback([this]() { - pipeline_cache.TriggerPipelineEviction(); - texture_cache.TriggerGarbageCollection(); - buffer_cache.TriggerGarbageCollection(); - staging_pool.TriggerCacheRelease(MemoryUsage::Upload); - staging_pool.TriggerCacheRelease(MemoryUsage::Download); - }); } RasterizerVulkan::~RasterizerVulkan() = default; diff --git a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h index 149e10e1c..52b623ae1 100644 --- a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h +++ b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h @@ -101,12 +101,6 @@ private: void ReleaseCache(MemoryUsage usage); void ReleaseLevel(StagingBuffersCache& cache, size_t log2); - -public: - /// Public interface to release staging buffer cache - void TriggerCacheRelease(MemoryUsage usage) { - ReleaseCache(usage); - } size_t Region(size_t iter) const noexcept { return iter / region_size; } diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h index ee3ce8be1..7dd1fec82 100644 --- a/src/video_core/texture_cache/texture_cache_base.h +++ b/src/video_core/texture_cache/texture_cache_base.h @@ -1,5 +1,4 @@ // SPDX-FileCopyrightText: 2023 yuzu Emulator Project -// SPDX-FileCopyrightText: Copyright 2025 Citron Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later #pragma once @@ -290,12 +289,6 @@ private: /// Runs the Garbage Collector. void RunGarbageCollector(); -public: - /// Public interface to trigger garbage collection - void TriggerGarbageCollection() { - RunGarbageCollector(); - } - /// Fills image_view_ids in the image views in indices template void FillImageViews(DescriptorTable& table, diff --git a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp index eab9c8f73..8f4a57e3c 100644 --- a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp +++ b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp @@ -1,5 +1,4 @@ // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-FileCopyrightText: Copyright 2025 Citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include @@ -291,15 +290,6 @@ MemoryCommit MemoryAllocator::Commit(const VkMemoryRequirements& requirements, M // Commit has failed, allocate more memory. const u64 chunk_size = AllocationChunkSize(requirements.size); if (!TryAllocMemory(flags, type_mask, chunk_size)) { - if (memory_pressure_callback) { - LOG_WARNING(Render_Vulkan, "Memory allocation failed, attempting to free resources..."); - memory_pressure_callback(); - if (TryAllocMemory(flags, type_mask, chunk_size)) { - if (auto commit = TryCommit(requirements, flags)) { - return std::move(*commit); - } - } - } // TODO(Rodrigo): Handle out of memory situations in some way like flushing to guest memory. throw vk::Exception(VK_ERROR_OUT_OF_DEVICE_MEMORY); } diff --git a/src/video_core/vulkan_common/vulkan_memory_allocator.h b/src/video_core/vulkan_common/vulkan_memory_allocator.h index a52fe436a..38a182bcb 100644 --- a/src/video_core/vulkan_common/vulkan_memory_allocator.h +++ b/src/video_core/vulkan_common/vulkan_memory_allocator.h @@ -1,10 +1,8 @@ // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project -// SPDX-FileCopyrightText: Copyright 2025 Citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once -#include #include #include #include @@ -113,14 +111,6 @@ public: */ MemoryCommit Commit(const VkMemoryRequirements& requirements, MemoryUsage usage); - /** - * Sets a callback to be called when memory pressure is detected. - * This allows external systems (like caches) to free resources. - */ - void SetMemoryPressureCallback(std::function callback) { - memory_pressure_callback = std::move(callback); - } - /// Commits memory required by the buffer and binds it. MemoryCommit Commit(const vk::Buffer& buffer, MemoryUsage usage); @@ -148,7 +138,6 @@ private: VkDeviceSize buffer_image_granularity; // The granularity for adjacent offsets between buffers // and optimal images u32 valid_memory_types{~0u}; - std::function memory_pressure_callback; ///< Callback to free resources under memory pressure }; } // namespace Vulkan