From 06b83115a5acf48ac22a58123ceb01ad1f466592 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 10 Mar 2023 12:20:55 +0100 Subject: [PATCH] Replacer: Avoid tracking video textures --- Common/GPU/Vulkan/VulkanDebug.cpp | 6 ++++++ GPU/Common/ReplacedTexture.h | 2 ++ GPU/Common/TextureCacheCommon.cpp | 11 ++++++++++- GPU/Common/TextureCacheCommon.h | 6 ++++-- GPU/Common/TextureReplacer.h | 3 +++ GPU/GPU.h | 4 ++++ GPU/GPUCommonHW.cpp | 3 +++ 7 files changed, 32 insertions(+), 3 deletions(-) diff --git a/Common/GPU/Vulkan/VulkanDebug.cpp b/Common/GPU/Vulkan/VulkanDebug.cpp index 4daf41bdf7..29a71cf61e 100644 --- a/Common/GPU/Vulkan/VulkanDebug.cpp +++ b/Common/GPU/Vulkan/VulkanDebug.cpp @@ -62,6 +62,12 @@ VKAPI_ATTR VkBool32 VKAPI_CALL VulkanDebugUtilsCallback( // See https://github.com/hrydgard/ppsspp/pull/16354 return false; } + if (messageCode == -375211665) { + // VUID-vkAllocateMemory-pAllocateInfo-01713 + // Can happen when VMA aggressively tries to allocate aperture memory for upload. It gracefully + // falls back to regular video memory, so we just ignore this. I'd argue this is a VMA bug, actually. + return false; + } int count; { diff --git a/GPU/Common/ReplacedTexture.h b/GPU/Common/ReplacedTexture.h index 4e00d8df28..735be70590 100644 --- a/GPU/Common/ReplacedTexture.h +++ b/GPU/Common/ReplacedTexture.h @@ -59,6 +59,8 @@ struct ReplacedTextureLevel { ReplacedImageType Identify(VFSBackend *vfs, VFSOpenFile *openFile, std::string *outMagic); +// These aren't actually all replaced, they can also represent a placeholder for a not-found +// replacement. struct ReplacedTexture { ~ReplacedTexture(); diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 8751efbb6e..5d914c061b 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -144,6 +144,11 @@ void TextureCacheCommon::StartFrame() { timesInvalidatedAllThisFrame_ = 0; replacementTimeThisFrame_ = 0.0; + if (g_Config.bShowDebugStats) { + gpuStats.numReplacerTrackedTex = replacer_.GetNumTrackedTextures(); + gpuStats.numCachedReplacedTextures = replacer_.GetNumCachedReplacedTextures(); + } + if (texelsScaledThisFrame_) { VERBOSE_LOG(G3D, "Scaled %d texels", texelsScaledThisFrame_); } @@ -1497,6 +1502,10 @@ ReplacedTexture *TextureCacheCommon::FindReplacement(TexCacheEntry *entry, int & return nullptr; } + if (entry->status & TexCacheEntry::STATUS_VIDEO) { + return nullptr; + } + // Allow some delay to reduce pop-in. constexpr double MAX_BUDGET_PER_TEX = 0.25 / 60.0; @@ -2039,7 +2048,7 @@ void TextureCacheCommon::ApplyTexture() { // Regardless of hash fails or otherwise, if this is a video, mark it frequently changing. // This prevents temporary scaling perf hits on the first second of video. if (IsVideo(entry->addr)) { - entry->status |= TexCacheEntry::STATUS_CHANGE_FREQUENT; + entry->status |= TexCacheEntry::STATUS_CHANGE_FREQUENT | TexCacheEntry::STATUS_VIDEO; } if (nextNeedsRehash_) { diff --git a/GPU/Common/TextureCacheCommon.h b/GPU/Common/TextureCacheCommon.h index 7db6507b13..a51660d364 100644 --- a/GPU/Common/TextureCacheCommon.h +++ b/GPU/Common/TextureCacheCommon.h @@ -149,10 +149,12 @@ struct TexCacheEntry { STATUS_3D = 0x4000, STATUS_CLUT_GPU = 0x8000, + + STATUS_VIDEO = 0x10000, }; - // Status, but int so we can zero initialize. - int status; + // TexStatus enum flag combination. + u32 status; u32 addr; u32 minihash; diff --git a/GPU/Common/TextureReplacer.h b/GPU/Common/TextureReplacer.h index 1efc9d7a54..27c6b1b83f 100644 --- a/GPU/Common/TextureReplacer.h +++ b/GPU/Common/TextureReplacer.h @@ -127,6 +127,9 @@ public: static bool GenerateIni(const std::string &gameID, Path &generatedFilename); static bool IniExists(const std::string &gameID); + int GetNumTrackedTextures() const { return (int)cache_.size(); } + int GetNumCachedReplacedTextures() const { return (int)levelCache_.size(); } + protected: bool LoadIni(); bool LoadIniValues(IniFile &ini, bool isOverride = false); diff --git a/GPU/GPU.h b/GPU/GPU.h index 12274e51fb..c44749cb63 100644 --- a/GPU/GPU.h +++ b/GPU/GPU.h @@ -100,6 +100,8 @@ struct GPUStatistics { numColorCopies = 0; numCopiesForShaderBlend = 0; numCopiesForSelfTex = 0; + numReplacerTrackedTex = 0; + numCachedReplacedTextures = 0; msProcessingDisplayLists = 0; vertexGPUCycles = 0; otherGPUCycles = 0; @@ -133,6 +135,8 @@ struct GPUStatistics { int numColorCopies; int numCopiesForShaderBlend; int numCopiesForSelfTex; + int numReplacerTrackedTex; + int numCachedReplacedTextures; double msProcessingDisplayLists; int vertexGPUCycles; int otherGPUCycles; diff --git a/GPU/GPUCommonHW.cpp b/GPU/GPUCommonHW.cpp index 01d6dd02c2..e5fd62a0ae 100644 --- a/GPU/GPUCommonHW.cpp +++ b/GPU/GPUCommonHW.cpp @@ -1636,6 +1636,7 @@ size_t GPUCommonHW::FormatGPUStatsCommon(char *buffer, size_t size) { "FBOs active: %d (evaluations: %d)\n" "Textures: %d, dec: %d, invalidated: %d, hashed: %d kB\n" "readbacks %d (%d non-block), uploads %d, depal %d\n" + "replacer: tracks %d textures, %d unique loaded\n" "Copies: depth %d, color %d, reint %d, blend %d, selftex %d\n" "GPU cycles executed: %d (%f per vertex)\n", gpuStats.msProcessingDisplayLists * 1000.0f, @@ -1659,6 +1660,8 @@ size_t GPUCommonHW::FormatGPUStatsCommon(char *buffer, size_t size) { gpuStats.numReadbacks, gpuStats.numUploads, gpuStats.numDepal, + gpuStats.numReplacerTrackedTex, + gpuStats.numCachedReplacedTextures, gpuStats.numDepthCopies, gpuStats.numColorCopies, gpuStats.numReinterpretCopies,