summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon
diff options
context:
space:
mode:
authorLéo Lam <leo@leolam.fr>2020-10-20 02:10:29 +0200
committerGitHub <noreply@github.com>2020-10-20 02:10:29 +0200
commitfc3b474cceb2a24df21640140be4beb95b9b9fd1 (patch)
tree84c89656ad79357c819b129a927db20cec1cdf9e /Source/Core/VideoCommon
parentb26c2e7adb80436f131f1a50e462ee7c25792c48 (diff)
parent4fff04db3ce16c72d8b3b95df2285a129605fde4 (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.cpp27
-rw-r--r--Source/Core/VideoCommon/HiresTextures.h6
-rw-r--r--Source/Core/VideoCommon/RenderBase.cpp19
-rw-r--r--Source/Core/VideoCommon/RenderBase.h5
-rw-r--r--Source/Core/VideoCommon/TextureCacheBase.cpp11
-rw-r--r--Source/Core/VideoCommon/TextureCacheBase.h1
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.