From 321feed7289f8591414bcc63d08a246c9e498287 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 17 Jan 2019 02:32:09 +0100 Subject: [PATCH] [dxvk] Bump state cache version to v3 We're still going to try and fix up v2 entries. This may cause unnecessary pipelines to be created for games that actually use depth bias. --- src/dxvk/dxvk_state_cache.cpp | 55 +++++++++++++++++++++++++++++------ src/dxvk/dxvk_state_cache.h | 8 +++-- 2 files changed, 52 insertions(+), 11 deletions(-) diff --git a/src/dxvk/dxvk_state_cache.cpp b/src/dxvk/dxvk_state_cache.cpp index 999a797c7..5b0e440ee 100644 --- a/src/dxvk/dxvk_state_cache.cpp +++ b/src/dxvk/dxvk_state_cache.cpp @@ -266,11 +266,30 @@ namespace dxvk { // The header stores the state cache version, // we need to regenerate it if it's outdated - if (!readCacheHeader(ifile)) { + DxvkStateCacheHeader newHeader; + DxvkStateCacheHeader curHeader; + + if (!readCacheHeader(ifile, curHeader)) { + Logger::warn("DXVK: Failed to read state cache header"); + return false; + } + + // Struct size hasn't changed between v2/v3 + if (curHeader.entrySize != newHeader.entrySize) { + Logger::warn("DXVK: State cache entry size changed"); + return false; + } + + // Discard caches of unsupported versions + if (curHeader.version != 2 && curHeader.version != 3) { Logger::warn("DXVK: State cache out of date"); return false; } + // Notify user about format conversion + if (curHeader.version != newHeader.version) + Logger::warn(str::format("DXVK: Updating state cache version to v", newHeader.version)); + // Read actual cache entries from the file. // If we encounter invalid entries, we should // regenerate the entire state cache file. @@ -280,6 +299,9 @@ namespace dxvk { DxvkStateCacheEntry entry; if (readCacheEntry(ifile, entry)) { + if (curHeader.version == 2) + convertEntryV2(entry); + size_t entryId = m_entries.size(); m_entries.push_back(entry); @@ -304,30 +326,31 @@ namespace dxvk { Logger::warn(str::format( "DXVK: Skipped ", numInvalidEntries, " invalid state cache entries")); + return false; } - return !numInvalidEntries; + // Rewrite entire state cache if it is outdated + return curHeader.version == newHeader.version; } bool DxvkStateCache::readCacheHeader( - std::istream& stream) const { + std::istream& stream, + DxvkStateCacheHeader& header) const { DxvkStateCacheHeader expected; - DxvkStateCacheHeader actual; - auto data = reinterpret_cast(&actual); - auto size = sizeof(actual); + auto data = reinterpret_cast(&header); + auto size = sizeof(header); if (!stream.read(data, size)) return false; for (uint32_t i = 0; i < 4; i++) { - if (expected.magic[i] != actual.magic[i]) + if (expected.magic[i] != header.magic[i]) return false; } - return expected.version == actual.version - && expected.entrySize == actual.entrySize; + return true; } @@ -359,6 +382,20 @@ namespace dxvk { } + bool DxvkStateCache::convertEntryV2( + DxvkStateCacheEntry& entry) const { + // Semantics changed: + // v2: rsDepthClampEnable + // v3: rsDepthClipEnable + entry.gpState.rsDepthClipEnable = !entry.gpState.rsDepthClipEnable; + + // Frontend changed: Depth bias + // will typically be disabled + entry.gpState.rsDepthBiasEnable = VK_FALSE; + return true; + } + + void DxvkStateCache::workerFunc() { env::setThreadName("dxvk-shader"); diff --git a/src/dxvk/dxvk_state_cache.h b/src/dxvk/dxvk_state_cache.h index af8c1a73f..ca4b331a5 100644 --- a/src/dxvk/dxvk_state_cache.h +++ b/src/dxvk/dxvk_state_cache.h @@ -62,7 +62,7 @@ namespace dxvk { */ struct DxvkStateCacheHeader { char magic[4] = { 'D', 'X', 'V', 'K' }; - uint32_t version = 2; + uint32_t version = 3; uint32_t entrySize = sizeof(DxvkStateCacheEntry); }; @@ -190,7 +190,8 @@ namespace dxvk { bool readCacheFile(); bool readCacheHeader( - std::istream& stream) const; + std::istream& stream, + DxvkStateCacheHeader& header) const; bool readCacheEntry( std::istream& stream, @@ -200,6 +201,9 @@ namespace dxvk { std::ostream& stream, DxvkStateCacheEntry& entry) const; + bool convertEntryV2( + DxvkStateCacheEntry& entry) const; + void workerFunc(); void writerFunc();