From 959bee479947c6d479cda08b5be2e22596974f03 Mon Sep 17 00:00:00 2001 From: nmzik Date: Thu, 15 Oct 2026 12:44:22 +0200 Subject: [PATCH] graphics: checkpoint live Vulkan pipeline cache after new compilations Co-authored-by: fxpw --- .../renderer/pipeline/pipelineCache.cpp | 31 +++++++++++++++---- .../renderer/pipeline/pipelineCache.h | 4 +++ 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/graphics/host_gpu/renderer/pipeline/pipelineCache.cpp b/src/graphics/host_gpu/renderer/pipeline/pipelineCache.cpp index 0d3e43380..86212bca1 100644 --- a/src/graphics/host_gpu/renderer/pipeline/pipelineCache.cpp +++ b/src/graphics/host_gpu/renderer/pipeline/pipelineCache.cpp @@ -40,6 +40,8 @@ namespace Libs::Graphics { namespace { +constexpr auto DriverCacheSaveInterval = std::chrono::minutes {5}; + uint8_t RemapSourceAlphaFactor(uint8_t factor) { switch (static_cast(factor)) { case Prospero::BlendFactor::kSrcAlpha: @@ -482,7 +484,8 @@ struct PipelineCache::ProgramCache { }; PipelineCache::PipelineCache(GraphicContext& graphics) - : m_graphics(graphics), m_program_cache(std::make_unique(graphics)) { + : m_graphics(graphics), m_program_cache(std::make_unique(graphics)), + m_next_driver_cache_save(std::chrono::steady_clock::now() + DriverCacheSaveInterval) { EXIT_NOT_IMPLEMENTED(!Common::Thread::IsMainThread()); InitializeDriverCache(); } @@ -590,10 +593,21 @@ void PipelineCache::InitializeDriverCache() { } } -void PipelineCache::Save() { +void PipelineCache::CheckpointDriverCache() { if (m_driver_cache == nullptr) { return; } + m_driver_cache_dirty = true; + if (std::chrono::steady_clock::now() >= m_next_driver_cache_save) { + Save(); + } +} + +void PipelineCache::Save() { + if (m_driver_cache == nullptr || !m_driver_cache_dirty) { + return; + } + m_next_driver_cache_save = std::chrono::steady_clock::now() + DriverCacheSaveInterval; size_t size = 0; vk::Result result; @@ -636,16 +650,19 @@ void PipelineCache::Save() { } const bool flushed = !file.IsInvalid() && file.Flush(); file.Close(); - if (prefix_written != prefix.size() || payload_written != payload.size() || !flushed || - !Common::File::RenameFile(temp_path, m_driver_cache_path)) { + const bool written = prefix_written == prefix.size() && payload_written == payload.size() && flushed; + std::error_code error; + if (written) { + std::filesystem::rename(temp_path, m_driver_cache_path, error); + } + if (!written || error) { PipelineCacheLog("Vulkan pipeline cache: failed to write {}", Common::PathToString(m_driver_cache_path)); return; } PipelineCacheLog("Vulkan pipeline cache: saved {} bytes to {}", payload.size(), Common::PathToString(m_driver_cache_path)); - m_graphics.device.destroyPipelineCache(m_driver_cache, nullptr); - m_driver_cache = nullptr; + m_driver_cache_dirty = false; } PipelineCache::GraphicsPrograms PipelineCache::GetGraphicsPrograms( @@ -984,6 +1001,7 @@ PipelineCache::Pipeline& PipelineCache::GetGraphicsPipeline( auto [iter, inserted] = m_graphics_pipelines.emplace(std::move(key), std::move(cached)); EXIT_IF(!inserted); + CheckpointDriverCache(); return *iter->second; } @@ -1012,6 +1030,7 @@ PipelineCache::GetComputePipeline(const ShaderComputeInputInfo& input_info, auto [iter, inserted] = m_compute_pipelines.emplace(compute_program.id, std::move(cached)); EXIT_IF(!inserted); + CheckpointDriverCache(); return *iter->second; } diff --git a/src/graphics/host_gpu/renderer/pipeline/pipelineCache.h b/src/graphics/host_gpu/renderer/pipeline/pipelineCache.h index 1554d5db8..87415984f 100644 --- a/src/graphics/host_gpu/renderer/pipeline/pipelineCache.h +++ b/src/graphics/host_gpu/renderer/pipeline/pipelineCache.h @@ -8,6 +8,7 @@ #include "graphics/host_gpu/vulkanCommon.h" #include "graphics/shader/shader.h" +#include #include #include #include @@ -173,11 +174,14 @@ private: std::unique_ptr m_program_cache; vk::PipelineCache m_driver_cache = nullptr; std::filesystem::path m_driver_cache_path; + std::chrono::steady_clock::time_point m_next_driver_cache_save; + bool m_driver_cache_dirty = false; std::unordered_map, GraphicsPipelineKeyHash> m_graphics_pipelines; std::unordered_map> m_compute_pipelines; void InitializeDriverCache(); + void CheckpointDriverCache(); }; void LogPipelineTrace(const char* phase, uint64_t vertex_program_id, uint64_t pixel_program_id);