diff options
| author | Léo Lam <leo@leolam.fr> | 2020-10-20 02:10:29 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-10-20 02:10:29 +0200 |
| commit | fc3b474cceb2a24df21640140be4beb95b9b9fd1 (patch) | |
| tree | 84c89656ad79357c819b129a927db20cec1cdf9e /Source/Core/VideoCommon | |
| parent | b26c2e7adb80436f131f1a50e462ee7c25792c48 (diff) | |
| parent | 4fff04db3ce16c72d8b3b95df2285a129605fde4 (diff) | |
Merge pull request #8318 from iwubcode/dynamic_input_textures
InputCommon: Dynamic Input Textures
Diffstat (limited to 'Source/Core/VideoCommon')
| -rw-r--r-- | Source/Core/VideoCommon/HiresTextures.cpp | 27 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/HiresTextures.h | 6 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/RenderBase.cpp | 19 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/RenderBase.h | 5 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/TextureCacheBase.cpp | 11 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/TextureCacheBase.h | 1 |
6 files changed, 53 insertions, 16 deletions
diff --git a/Source/Core/VideoCommon/HiresTextures.cpp b/Source/Core/VideoCommon/HiresTextures.cpp index bcc0cac4c9..039bc87c5e 100644 --- a/Source/Core/VideoCommon/HiresTextures.cpp +++ b/Source/Core/VideoCommon/HiresTextures.cpp @@ -51,7 +51,7 @@ static std::thread s_prefetcher; void HiresTexture::Init() { - Update(); + // Note: Update is not called here so that we handle dynamic textures on startup more gracefully } void HiresTexture::Shutdown() @@ -76,8 +76,7 @@ void HiresTexture::Update() if (!g_ActiveConfig.bHiresTextures) { - s_textureMap.clear(); - s_textureCache.clear(); + Clear(); return; } @@ -87,7 +86,8 @@ void HiresTexture::Update() } const std::string& game_id = SConfig::GetInstance().GetGameID(); - const std::set<std::string> texture_directories = GetTextureDirectories(game_id); + const std::set<std::string> texture_directories = + GetTextureDirectoriesWithGameId(File::GetUserPath(D_HIRESTEXTURES_IDX), game_id); const std::vector<std::string> extensions{".png", ".dds"}; for (const auto& texture_directory : texture_directories) @@ -145,6 +145,12 @@ void HiresTexture::Update() } } +void HiresTexture::Clear() +{ + s_textureMap.clear(); + s_textureCache.clear(); +} + void HiresTexture::Prefetch() { Common::SetCurrentThreadName("Prefetcher"); @@ -454,10 +460,11 @@ bool HiresTexture::LoadTexture(Level& level, const std::vector<u8>& buffer) return true; } -std::set<std::string> HiresTexture::GetTextureDirectories(const std::string& game_id) +std::set<std::string> GetTextureDirectoriesWithGameId(const std::string& root_directory, + const std::string& game_id) { std::set<std::string> result; - const std::string texture_directory = File::GetUserPath(D_HIRESTEXTURES_IDX) + game_id; + const std::string texture_directory = root_directory + game_id; if (File::Exists(texture_directory)) { @@ -466,8 +473,7 @@ std::set<std::string> HiresTexture::GetTextureDirectories(const std::string& gam else { // If there's no directory with the region-specific ID, look for a 3-character region-free one - const std::string region_free_directory = - File::GetUserPath(D_HIRESTEXTURES_IDX) + game_id.substr(0, 3); + const std::string region_free_directory = root_directory + game_id.substr(0, 3); if (File::Exists(region_free_directory)) { @@ -482,7 +488,6 @@ std::set<std::string> HiresTexture::GetTextureDirectories(const std::string& gam }; // Look for any other directories that might be specific to the given gameid - const auto root_directory = File::GetUserPath(D_HIRESTEXTURES_IDX); const auto files = Common::DoFileSearch({root_directory}, {".txt"}, true); for (const auto& file : files) { @@ -490,8 +495,8 @@ std::set<std::string> HiresTexture::GetTextureDirectories(const std::string& gam { // The following code is used to calculate the top directory // of a found gameid.txt file - // ex: <dolphin dir>/Load/Textures/My folder/gameids/<gameid>.txt - // would insert "<dolphin dir>/Load/Textures/My folder" + // ex: <root directory>/My folder/gameids/<gameid>.txt + // would insert "<root directory>/My folder" const auto directory_path = file.substr(root_directory.size()); const std::size_t first_path_separator_position = directory_path.find_first_of(DIR_SEP_CHR); result.insert(root_directory + directory_path.substr(0, first_path_separator_position)); diff --git a/Source/Core/VideoCommon/HiresTextures.h b/Source/Core/VideoCommon/HiresTextures.h index ec0b188154..7adabbf94e 100644 --- a/Source/Core/VideoCommon/HiresTextures.h +++ b/Source/Core/VideoCommon/HiresTextures.h @@ -14,11 +14,15 @@ enum class TextureFormat; +std::set<std::string> GetTextureDirectoriesWithGameId(const std::string& root_directory, + const std::string& game_id); + class HiresTexture { public: static void Init(); static void Update(); + static void Clear(); static void Shutdown(); static std::shared_ptr<HiresTexture> Search(const u8* texture, size_t texture_size, @@ -54,8 +58,6 @@ private: static bool LoadTexture(Level& level, const std::vector<u8>& buffer); static void Prefetch(); - static std::set<std::string> GetTextureDirectories(const std::string& game_id); - HiresTexture() {} bool m_has_arbitrary_mipmaps; }; diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp index a60f9b9f91..4777314194 100644 --- a/Source/Core/VideoCommon/RenderBase.cpp +++ b/Source/Core/VideoCommon/RenderBase.cpp @@ -1138,6 +1138,11 @@ void Renderer::EndUIFrame() BeginImGuiFrame(); } +void Renderer::ForceReloadTextures() +{ + m_force_reload_textures.Set(); +} + // Heuristic to detect if a GameCube game is in 16:9 anamorphic widescreen mode. void Renderer::UpdateWidescreenHeuristic() { @@ -1302,9 +1307,17 @@ void Renderer::Swap(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height, u6 // state changes the specialized shader will not take over. g_vertex_manager->InvalidatePipelineObject(); - // Flush any outstanding EFB copies to RAM, in case the game is running at an uncapped frame - // rate and not waiting for vblank. Otherwise, we'd end up with a huge list of pending copies. - g_texture_cache->FlushEFBCopies(); + if (m_force_reload_textures.TestAndClear()) + { + g_texture_cache->ForceReload(); + } + else + { + // Flush any outstanding EFB copies to RAM, in case the game is running at an uncapped frame + // rate and not waiting for vblank. Otherwise, we'd end up with a huge list of pending + // copies. + g_texture_cache->FlushEFBCopies(); + } if (!is_duplicate_frame) { diff --git a/Source/Core/VideoCommon/RenderBase.h b/Source/Core/VideoCommon/RenderBase.h index 3b6de06fd8..4044af8e0b 100644 --- a/Source/Core/VideoCommon/RenderBase.h +++ b/Source/Core/VideoCommon/RenderBase.h @@ -259,6 +259,9 @@ public: void BeginUIFrame(); void EndUIFrame(); + // Will forcibly reload all textures on the next swap + void ForceReloadTextures(); + protected: // Bitmask containing information about which configuration has changed for the backend. enum ConfigChangeBits : u32 @@ -410,6 +413,8 @@ private: void FinishFrameData(); std::unique_ptr<NetPlayChatUI> m_netplay_chat_ui; + + Common::Flag m_force_reload_textures; }; extern std::unique_ptr<Renderer> g_renderer; diff --git a/Source/Core/VideoCommon/TextureCacheBase.cpp b/Source/Core/VideoCommon/TextureCacheBase.cpp index fdf3c0e6b3..ec54f59d9a 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/TextureCacheBase.cpp @@ -137,6 +137,17 @@ void TextureCacheBase::Invalidate() texture_pool.clear(); } +void TextureCacheBase::ForceReload() +{ + Invalidate(); + + // Clear all current hires textures, they are invalid + HiresTexture::Clear(); + + // Load fresh + HiresTexture::Update(); +} + void TextureCacheBase::OnConfigChanged(const VideoConfig& config) { if (config.bHiresTextures != backup_config.hires_textures || diff --git a/Source/Core/VideoCommon/TextureCacheBase.h b/Source/Core/VideoCommon/TextureCacheBase.h index e8ecf5b6fe..9245f7bf3f 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.h +++ b/Source/Core/VideoCommon/TextureCacheBase.h @@ -205,6 +205,7 @@ public: bool Initialize(); void OnConfigChanged(const VideoConfig& config); + void ForceReload(); // Removes textures which aren't used for more than TEXTURE_KILL_THRESHOLD frames, // frameCount is the current frame number. |
