From 06fb93daf09ad6ccaa0ccd061b98ca9eccbfb090 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 9 Jan 2023 18:29:15 +0100 Subject: [PATCH] [dxvk] Only create state cache file on demand If no pipelines are ever written to it, we should not create the cache file in the first place. --- src/dxvk/dxvk_state_cache.cpp | 84 +++++++++++++++++++++++------------ src/dxvk/dxvk_state_cache.h | 7 ++- 2 files changed, 62 insertions(+), 29 deletions(-) diff --git a/src/dxvk/dxvk_state_cache.cpp b/src/dxvk/dxvk_state_cache.cpp index fa3322821..b1d71b6ca 100644 --- a/src/dxvk/dxvk_state_cache.cpp +++ b/src/dxvk/dxvk_state_cache.cpp @@ -242,26 +242,7 @@ namespace dxvk { bool newFile = (useStateCache == "reset") || (!readCacheFile()); if (newFile) { - Logger::warn("DXVK: Creating new state cache file"); - - // Start with an empty file - std::ofstream file(getCacheFileName().c_str(), - std::ios_base::binary | - std::ios_base::trunc); - - if (!file && env::createDirectory(getCacheDir())) { - file = std::ofstream(getCacheFileName().c_str(), - std::ios_base::binary | - std::ios_base::trunc); - } - - // Write header with the current version number - DxvkStateCacheHeader header; - - auto data = reinterpret_cast(&header); - auto size = sizeof(header); - - file.write(data, size); + auto file = openCacheFileForWrite(true); // Write all valid entries to the cache file in // case we're recovering a corrupted cache file @@ -454,12 +435,13 @@ namespace dxvk { bool DxvkStateCache::readCacheFile() { - // Open state file and just fail if it doesn't exist - std::ifstream ifile(getCacheFileName().c_str(), std::ios_base::binary); + // Return success if the file was not found. + // This way we will only create it on demand. + std::ifstream ifile = openCacheFileForRead(); if (!ifile) { Logger::warn("DXVK: No state cache file found"); - return false; + return true; } // The header stores the state cache version, @@ -771,11 +753,8 @@ namespace dxvk { m_writerQueue.pop(); } - if (!file.is_open()) { - file.open(getCacheFileName().c_str(), - std::ios_base::binary | - std::ios_base::app); - } + if (!file.is_open()) + file = openCacheFileForWrite(false); writeCacheEntry(file, entry); } @@ -806,6 +785,55 @@ namespace dxvk { } + std::ifstream DxvkStateCache::openCacheFileForRead() const { + return std::ifstream(getCacheFileName().c_str(), std::ios_base::binary); + } + + + std::ofstream DxvkStateCache::openCacheFileForWrite(bool recreate) const { + std::ofstream file; + + if (!recreate) { + // Apparently there's no other way to check whether + // the file is empty after creating an ofstream + recreate = !openCacheFileForRead(); + } + + if (recreate) { + file = std::ofstream(getCacheFileName().c_str(), + std::ios_base::binary | + std::ios_base::trunc); + + if (!file && env::createDirectory(getCacheDir())) { + file = std::ofstream(getCacheFileName().c_str(), + std::ios_base::binary | + std::ios_base::trunc); + } + } else { + file = std::ofstream(getCacheFileName().c_str(), + std::ios_base::binary | + std::ios_base::app); + } + + if (!file) + return file; + + if (recreate) { + Logger::warn("DXVK: Creating new state cache file"); + + // Write header with the current version number + DxvkStateCacheHeader header; + + auto data = reinterpret_cast(&header); + auto size = sizeof(header); + + file.write(data, size); + } + + return file; + } + + std::string DxvkStateCache::getCacheDir() const { return env::getEnvVar("DXVK_STATE_CACHE_PATH"); } diff --git a/src/dxvk/dxvk_state_cache.h b/src/dxvk/dxvk_state_cache.h index 3df28a4f9..24ec1001c 100644 --- a/src/dxvk/dxvk_state_cache.h +++ b/src/dxvk/dxvk_state_cache.h @@ -160,7 +160,12 @@ namespace dxvk { void createWriter(); str::path_string getCacheFileName() const; - + + std::ifstream openCacheFileForRead() const; + + std::ofstream openCacheFileForWrite( + bool recreate) const; + std::string getCacheDir() const; };