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
This commit is contained in:
		@@ -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<ComputePipeline> 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<const char*>(&cache_version), sizeof(cache_version));
 | 
			
		||||
 | 
			
		||||
    size_t cache_size = 0;
 | 
			
		||||
    std::vector<char> 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<char, 8> 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<char*>(&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));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user