From e07976a22bcbfe8a2a3c166cc35c654f9b893a5d Mon Sep 17 00:00:00 2001 From: Wollnashorn Date: Thu, 5 Jan 2023 04:36:17 +0100 Subject: [PATCH] video_core/vulkan: Vulkan driver pipelines now contain cache version So that old cache can get deleted when the cache version changes and does not grow infinitely --- .../renderer_vulkan/vk_pipeline_cache.cpp | 39 ++++++++++++------- .../renderer_vulkan/vk_pipeline_cache.h | 5 ++- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 7bded3ec5..67e5bc648 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -366,7 +366,8 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device PipelineCache::~PipelineCache() { if (use_vulkan_pipeline_cache && !vulkan_pipeline_cache_filename.empty()) { - SerializeVulkanPipelineCache(vulkan_pipeline_cache_filename, vulkan_pipeline_cache); + SerializeVulkanPipelineCache(vulkan_pipeline_cache_filename, vulkan_pipeline_cache, + CACHE_VERSION); } } @@ -426,7 +427,8 @@ void PipelineCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading if (use_vulkan_pipeline_cache) { vulkan_pipeline_cache_filename = base_dir / "vulkan_pipelines.bin"; - vulkan_pipeline_cache = LoadVulkanPipelineCache(vulkan_pipeline_cache_filename); + vulkan_pipeline_cache = + LoadVulkanPipelineCache(vulkan_pipeline_cache_filename, CACHE_VERSION); } struct { @@ -508,7 +510,8 @@ void PipelineCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading workers.WaitForRequests(stop_loading); if (use_vulkan_pipeline_cache) { - SerializeVulkanPipelineCache(vulkan_pipeline_cache_filename, vulkan_pipeline_cache); + SerializeVulkanPipelineCache(vulkan_pipeline_cache_filename, vulkan_pipeline_cache, + CACHE_VERSION); } if (state.statistics) { @@ -714,15 +717,17 @@ std::unique_ptr PipelineCache::CreateComputePipeline( } void PipelineCache::SerializeVulkanPipelineCache(const std::filesystem::path& filename, - const vk::PipelineCache& pipeline_cache) try { + const vk::PipelineCache& pipeline_cache, + u32 cache_version) try { std::ofstream file(filename, std::ios::binary); file.exceptions(std::ifstream::failbit); if (!file.is_open()) { - LOG_ERROR(Common_Filesystem, "Failed to open Vulkan pipeline cache file {}", + LOG_ERROR(Common_Filesystem, "Failed to open Vulkan driver pipeline cache file {}", Common::FS::PathToUTF8String(filename)); return; } - file.write(VULKAN_CACHE_MAGIC_NUMBER.data(), VULKAN_CACHE_MAGIC_NUMBER.size()); + file.write(VULKAN_CACHE_MAGIC_NUMBER.data(), VULKAN_CACHE_MAGIC_NUMBER.size()) + .write(reinterpret_cast(&cache_version), sizeof(cache_version)); size_t cache_size = 0; std::vector cache_data; @@ -733,18 +738,19 @@ void PipelineCache::SerializeVulkanPipelineCache(const std::filesystem::path& fi } file.write(cache_data.data(), cache_size); - LOG_INFO(Render_Vulkan, "Vulkan pipelines cached at: {}", + LOG_INFO(Render_Vulkan, "Vulkan driver pipelines cached at: {}", Common::FS::PathToUTF8String(filename)); } catch (const std::ios_base::failure& e) { LOG_ERROR(Common_Filesystem, "{}", e.what()); if (!Common::FS::RemoveFile(filename)) { - LOG_ERROR(Common_Filesystem, "Failed to delete Vulkan pipeline cache file {}", + LOG_ERROR(Common_Filesystem, "Failed to delete Vulkan driver pipeline cache file {}", Common::FS::PathToUTF8String(filename)); } } -vk::PipelineCache PipelineCache::LoadVulkanPipelineCache(const std::filesystem::path& filename) { +vk::PipelineCache PipelineCache::LoadVulkanPipelineCache(const std::filesystem::path& filename, + u32 expected_cache_version) { const auto create_pipeline_cache = [this](size_t data_size, const void* data) { VkPipelineCacheCreateInfo pipeline_cache_ci = { .sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, @@ -764,12 +770,17 @@ vk::PipelineCache PipelineCache::LoadVulkanPipelineCache(const std::filesystem:: file.seekg(0, std::ios::beg); std::array magic_number; - file.read(magic_number.data(), magic_number.size()); - if (magic_number != VULKAN_CACHE_MAGIC_NUMBER) { + u32 cache_version; + file.read(magic_number.data(), magic_number.size()) + .read(reinterpret_cast(&cache_version), sizeof(cache_version)); + if (magic_number != VULKAN_CACHE_MAGIC_NUMBER || cache_version != expected_cache_version) { file.close(); if (Common::FS::RemoveFile(filename)) { if (magic_number != VULKAN_CACHE_MAGIC_NUMBER) { - LOG_ERROR(Common_Filesystem, "Invalid Vulkan pipeline cache file"); + LOG_ERROR(Common_Filesystem, "Invalid Vulkan driver pipeline cache file"); + } + if (cache_version != expected_cache_version) { + LOG_INFO(Common_Filesystem, "Deleting old Vulkan driver pipeline cache"); } } else { LOG_ERROR(Common_Filesystem, @@ -784,14 +795,14 @@ vk::PipelineCache PipelineCache::LoadVulkanPipelineCache(const std::filesystem:: file.read(cache_data.data(), cache_size); LOG_INFO(Render_Vulkan, - "Loaded Vulkan pipeline cache: ", Common::FS::PathToUTF8String(filename)); + "Loaded Vulkan driver pipeline cache: ", Common::FS::PathToUTF8String(filename)); return create_pipeline_cache(cache_size, cache_data.data()); } catch (const std::ios_base::failure& e) { LOG_ERROR(Common_Filesystem, "{}", e.what()); if (!Common::FS::RemoveFile(filename)) { - LOG_ERROR(Common_Filesystem, "Failed to delete Vulkan pipeline cache file {}", + LOG_ERROR(Common_Filesystem, "Failed to delete Vulkan driver pipeline cache file {}", Common::FS::PathToUTF8String(filename)); } diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.h b/src/video_core/renderer_vulkan/vk_pipeline_cache.h index cf3bd6b85..5171912d7 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.h +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.h @@ -136,9 +136,10 @@ private: bool build_in_parallel); void SerializeVulkanPipelineCache(const std::filesystem::path& filename, - const vk::PipelineCache& pipeline_cache); + const vk::PipelineCache& pipeline_cache, u32 cache_version); - vk::PipelineCache LoadVulkanPipelineCache(const std::filesystem::path& filename); + vk::PipelineCache LoadVulkanPipelineCache(const std::filesystem::path& filename, + u32 expected_cache_version); const Device& device; Scheduler& scheduler;