mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 14:19:46 -06:00
Merge pull request #8318 from iwubcode/dynamic_input_textures
InputCommon: Dynamic Input Textures
This commit is contained in:
@ -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));
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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 ||
|
||||
|
@ -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.
|
||||
|
Reference in New Issue
Block a user