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:
Wollnashorn 2023-01-05 04:36:17 +01:00
parent 9c9008ac81
commit e07976a22b
2 changed files with 28 additions and 16 deletions

View File

@ -366,7 +366,8 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device
PipelineCache::~PipelineCache() { PipelineCache::~PipelineCache() {
if (use_vulkan_pipeline_cache && !vulkan_pipeline_cache_filename.empty()) { 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) { if (use_vulkan_pipeline_cache) {
vulkan_pipeline_cache_filename = base_dir / "vulkan_pipelines.bin"; 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 { struct {
@ -508,7 +510,8 @@ void PipelineCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading
workers.WaitForRequests(stop_loading); workers.WaitForRequests(stop_loading);
if (use_vulkan_pipeline_cache) { 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) { if (state.statistics) {
@ -714,15 +717,17 @@ std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline(
} }
void PipelineCache::SerializeVulkanPipelineCache(const std::filesystem::path& filename, 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); std::ofstream file(filename, std::ios::binary);
file.exceptions(std::ifstream::failbit); file.exceptions(std::ifstream::failbit);
if (!file.is_open()) { 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)); Common::FS::PathToUTF8String(filename));
return; 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; size_t cache_size = 0;
std::vector<char> cache_data; std::vector<char> cache_data;
@ -733,18 +738,19 @@ void PipelineCache::SerializeVulkanPipelineCache(const std::filesystem::path& fi
} }
file.write(cache_data.data(), cache_size); 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)); Common::FS::PathToUTF8String(filename));
} catch (const std::ios_base::failure& e) { } catch (const std::ios_base::failure& e) {
LOG_ERROR(Common_Filesystem, "{}", e.what()); LOG_ERROR(Common_Filesystem, "{}", e.what());
if (!Common::FS::RemoveFile(filename)) { 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)); 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) { const auto create_pipeline_cache = [this](size_t data_size, const void* data) {
VkPipelineCacheCreateInfo pipeline_cache_ci = { VkPipelineCacheCreateInfo pipeline_cache_ci = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, .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); file.seekg(0, std::ios::beg);
std::array<char, 8> magic_number; std::array<char, 8> magic_number;
file.read(magic_number.data(), magic_number.size()); u32 cache_version;
if (magic_number != VULKAN_CACHE_MAGIC_NUMBER) { 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(); file.close();
if (Common::FS::RemoveFile(filename)) { if (Common::FS::RemoveFile(filename)) {
if (magic_number != VULKAN_CACHE_MAGIC_NUMBER) { 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 { } else {
LOG_ERROR(Common_Filesystem, LOG_ERROR(Common_Filesystem,
@ -784,14 +795,14 @@ vk::PipelineCache PipelineCache::LoadVulkanPipelineCache(const std::filesystem::
file.read(cache_data.data(), cache_size); file.read(cache_data.data(), cache_size);
LOG_INFO(Render_Vulkan, 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()); return create_pipeline_cache(cache_size, cache_data.data());
} catch (const std::ios_base::failure& e) { } catch (const std::ios_base::failure& e) {
LOG_ERROR(Common_Filesystem, "{}", e.what()); LOG_ERROR(Common_Filesystem, "{}", e.what());
if (!Common::FS::RemoveFile(filename)) { 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)); Common::FS::PathToUTF8String(filename));
} }

View File

@ -136,9 +136,10 @@ private:
bool build_in_parallel); bool build_in_parallel);
void SerializeVulkanPipelineCache(const std::filesystem::path& filename, 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; const Device& device;
Scheduler& scheduler; Scheduler& scheduler;