graphics: checkpoint live Vulkan pipeline cache after new compilations

Co-authored-by: fxpw <fxpw@outlook.com>
This commit is contained in:
nmzik
2026-10-15 12:44:22 +02:00
parent 232e2f2593
commit 959bee4799
2 changed files with 29 additions and 6 deletions
@@ -40,6 +40,8 @@ namespace Libs::Graphics {
namespace { namespace {
constexpr auto DriverCacheSaveInterval = std::chrono::minutes {5};
uint8_t RemapSourceAlphaFactor(uint8_t factor) { uint8_t RemapSourceAlphaFactor(uint8_t factor) {
switch (static_cast<Prospero::BlendFactor>(factor)) { switch (static_cast<Prospero::BlendFactor>(factor)) {
case Prospero::BlendFactor::kSrcAlpha: case Prospero::BlendFactor::kSrcAlpha:
@@ -482,7 +484,8 @@ struct PipelineCache::ProgramCache {
}; };
PipelineCache::PipelineCache(GraphicContext& graphics) PipelineCache::PipelineCache(GraphicContext& graphics)
: m_graphics(graphics), m_program_cache(std::make_unique<ProgramCache>(graphics)) { : m_graphics(graphics), m_program_cache(std::make_unique<ProgramCache>(graphics)),
m_next_driver_cache_save(std::chrono::steady_clock::now() + DriverCacheSaveInterval) {
EXIT_NOT_IMPLEMENTED(!Common::Thread::IsMainThread()); EXIT_NOT_IMPLEMENTED(!Common::Thread::IsMainThread());
InitializeDriverCache(); InitializeDriverCache();
} }
@@ -590,10 +593,21 @@ void PipelineCache::InitializeDriverCache() {
} }
} }
void PipelineCache::Save() { void PipelineCache::CheckpointDriverCache() {
if (m_driver_cache == nullptr) { if (m_driver_cache == nullptr) {
return; 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; size_t size = 0;
vk::Result result; vk::Result result;
@@ -636,16 +650,19 @@ void PipelineCache::Save() {
} }
const bool flushed = !file.IsInvalid() && file.Flush(); const bool flushed = !file.IsInvalid() && file.Flush();
file.Close(); file.Close();
if (prefix_written != prefix.size() || payload_written != payload.size() || !flushed || const bool written = prefix_written == prefix.size() && payload_written == payload.size() && flushed;
!Common::File::RenameFile(temp_path, m_driver_cache_path)) { 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 {}", PipelineCacheLog("Vulkan pipeline cache: failed to write {}",
Common::PathToString(m_driver_cache_path)); Common::PathToString(m_driver_cache_path));
return; return;
} }
PipelineCacheLog("Vulkan pipeline cache: saved {} bytes to {}", payload.size(), PipelineCacheLog("Vulkan pipeline cache: saved {} bytes to {}", payload.size(),
Common::PathToString(m_driver_cache_path)); Common::PathToString(m_driver_cache_path));
m_graphics.device.destroyPipelineCache(m_driver_cache, nullptr); m_driver_cache_dirty = false;
m_driver_cache = nullptr;
} }
PipelineCache::GraphicsPrograms PipelineCache::GetGraphicsPrograms( 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)); auto [iter, inserted] = m_graphics_pipelines.emplace(std::move(key), std::move(cached));
EXIT_IF(!inserted); EXIT_IF(!inserted);
CheckpointDriverCache();
return *iter->second; 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)); auto [iter, inserted] = m_compute_pipelines.emplace(compute_program.id, std::move(cached));
EXIT_IF(!inserted); EXIT_IF(!inserted);
CheckpointDriverCache();
return *iter->second; return *iter->second;
} }
@@ -8,6 +8,7 @@
#include "graphics/host_gpu/vulkanCommon.h" #include "graphics/host_gpu/vulkanCommon.h"
#include "graphics/shader/shader.h" #include "graphics/shader/shader.h"
#include <chrono>
#include <cstddef> #include <cstddef>
#include <filesystem> #include <filesystem>
#include <memory> #include <memory>
@@ -173,11 +174,14 @@ private:
std::unique_ptr<ProgramCache> m_program_cache; std::unique_ptr<ProgramCache> m_program_cache;
vk::PipelineCache m_driver_cache = nullptr; vk::PipelineCache m_driver_cache = nullptr;
std::filesystem::path m_driver_cache_path; 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<GraphicsPipelineKey, std::unique_ptr<Pipeline>, GraphicsPipelineKeyHash> std::unordered_map<GraphicsPipelineKey, std::unique_ptr<Pipeline>, GraphicsPipelineKeyHash>
m_graphics_pipelines; m_graphics_pipelines;
std::unordered_map<uint64_t, std::unique_ptr<Pipeline>> m_compute_pipelines; std::unordered_map<uint64_t, std::unique_ptr<Pipeline>> m_compute_pipelines;
void InitializeDriverCache(); void InitializeDriverCache();
void CheckpointDriverCache();
}; };
void LogPipelineTrace(const char* phase, uint64_t vertex_program_id, uint64_t pixel_program_id); void LogPipelineTrace(const char* phase, uint64_t vertex_program_id, uint64_t pixel_program_id);