diff --git a/dep/imgui/include/IconsEmoji.h b/dep/imgui/include/IconsEmoji.h index 81b164b96..5290f5ffb 100644 --- a/dep/imgui/include/IconsEmoji.h +++ b/dep/imgui/include/IconsEmoji.h @@ -27,3 +27,4 @@ #define ICON_EMOJI_MAGNIFIYING_GLASS_TILTED_LEFT "\xf0\x9f\x94\x8d" #define ICON_EMOJI_LOCKED "\xf0\x9f\x94\x92" #define ICON_EMOJI_UNLOCKED "\xf0\x9f\x94\x93" +#define ICON_EMOJI_REFRESH "\xf0\x9f\x94\x84" diff --git a/src/core/gpu_hw_texture_cache.cpp b/src/core/gpu_hw_texture_cache.cpp index db245109b..5d9eef5ce 100644 --- a/src/core/gpu_hw_texture_cache.cpp +++ b/src/core/gpu_hw_texture_cache.cpp @@ -10,6 +10,7 @@ #include "system.h" #include "util/gpu_device.h" +#include "util/imgui_manager.h" #include "util/state_wrapper.h" #include "common/error.h" @@ -20,6 +21,8 @@ #include "common/string_util.h" #include "common/timer.h" +#include "IconsEmoji.h" + #define XXH_STATIC_LINKING_ONLY #include "xxhash.h" #ifdef CPU_ARCH_SSE @@ -233,6 +236,7 @@ using TextureReplacementMap = static bool ShouldTrackVRAMWrites(); static bool IsDumpingVRAMWriteTextures(); +static void UpdateVRAMTrackingState(); static bool CompilePipelines(); static void DestroyPipelines(); @@ -245,9 +249,17 @@ static void ApplyTextureReplacements(SourceKey key, HashType tex_hash, HashType static void RemoveFromHashCache(HashCache::iterator it); static void ClearHashCache(); +static bool IsPageDrawn(u32 page_index, const GSVector4i rect); +static void InvalidatePageSources(u32 pn); +static void InvalidatePageSources(u32 pn, const GSVector4i rc); +static void InvalidateSources(); +static void DestroySource(Source* src); + static HashType HashPage(u8 page, GPUTextureMode mode); static HashType HashPalette(GPUTexturePaletteReg palette, GPUTextureMode mode); static HashType HashPartialPalette(const u16* palette, u32 min, u32 max); +static HashType HashPartialPalette(GPUTexturePaletteReg palette, GPUTextureMode mode, u32 min, u32 max); +static HashType HashRect(const GSVector4i rc); static std::pair ReducePaletteBounds(const GSVector4i rect, GPUTextureMode mode, GPUTexturePaletteReg palette); @@ -262,6 +274,8 @@ static void RemoveVRAMWrite(VRAMWrite* entry); static void DumpTexturesFromVRAMWrite(VRAMWrite* entry); static void DumpTextureFromPage(const Source* src); +static void DecodeTexture(GPUTextureMode mode, const u16* page_ptr, const u16* palette, u32* dest, u32 dest_stride, + u32 width, u32 height); static void DecodeTexture4(const u16* page, const u16* palette, u32 width, u32 height, u32* dest, u32 dest_stride); static void DecodeTexture8(const u16* page, const u16* palette, u32 width, u32 height, u32* dest, u32 dest_stride); static void DecodeTexture16(const u16* page, u32 width, u32 height, u32* dest, u32 dest_stride); @@ -561,7 +575,7 @@ void GPUTextureCache::UpdateSettings(const Settings& old_settings) // Reload textures if configuration changes. if (LoadLocalConfiguration(false, false)) - ReloadTextureReplacements(); + ReloadTextureReplacements(false); } bool GPUTextureCache::DoState(StateWrapper& sw, bool skip) @@ -1221,11 +1235,6 @@ const GPUTextureCache::Source* GPUTextureCache::ReturnSource(Source* source, con return source; } -bool GPUTextureCache::IsPageDrawn(u32 page_index) -{ - return (s_pages[page_index].num_draw_rects > 0); -} - bool GPUTextureCache::IsPageDrawn(u32 page_index, const GSVector4i rect) { const PageEntry& page = s_pages[page_index]; @@ -1321,6 +1330,15 @@ void GPUTextureCache::Invalidate() ClearHashCache(); } +void GPUTextureCache::InvalidateSources() +{ + // keep draw rects and vram writes + for (u32 i = 0; i < NUM_VRAM_PAGES; i++) + InvalidatePageSources(i); + + ClearHashCache(); +} + void GPUTextureCache::InvalidatePageSources(u32 pn) { DebugAssert(pn < NUM_VRAM_PAGES); @@ -2397,7 +2415,7 @@ void GPUTextureCache::SetGameID(std::string game_id) return; s_game_id = game_id; - ReloadTextureReplacements(); + ReloadTextureReplacements(false); } const GPUTextureCache::TextureReplacementImage* GPUTextureCache::GetVRAMReplacement(u32 width, u32 height, @@ -2917,7 +2935,7 @@ const GPUTextureCache::TextureReplacementImage* GPUTextureCache::GetTextureRepla return nullptr; } - INFO_LOG("Loaded '{}': {}x{}", Path::GetFileName(filename), image.GetWidth(), image.GetHeight()); + VERBOSE_LOG("Loaded '{}': {}x{}", Path::GetFileName(filename), image.GetWidth(), image.GetHeight()); it = s_replacement_image_cache.emplace(filename, std::move(image)).first; return &it->second; } @@ -3098,7 +3116,7 @@ bool GPUTextureCache::LoadLocalConfiguration(bool load_vram_write_replacement_al return (s_config != old_config); } -void GPUTextureCache::ReloadTextureReplacements() +void GPUTextureCache::ReloadTextureReplacements(bool show_info) { s_vram_replacements.clear(); s_vram_write_texture_replacements.clear(); @@ -3118,7 +3136,19 @@ void GPUTextureCache::ReloadTextureReplacements() PurgeUnreferencedTexturesFromCache(); DebugAssert(g_gpu); - GPUTextureCache::UpdateVRAMTrackingState(); + UpdateVRAMTrackingState(); + InvalidateSources(); + + if (show_info) + { + const int total = static_cast(s_vram_replacements.size() + s_vram_write_texture_replacements.size() + + s_texture_page_texture_replacements.size()); + Host::AddIconOSDMessage("ReloadTextureReplacements", ICON_EMOJI_REFRESH, + (total > 0) ? TRANSLATE_PLURAL_STR("GPU_HW", "%n replacement textures found.", + "Replacement texture count", total) : + TRANSLATE_STR("GPU_HW", "No replacement textures found."), + Host::OSD_INFO_DURATION); + } } void GPUTextureCache::PurgeUnreferencedTexturesFromCache() diff --git a/src/core/gpu_hw_texture_cache.h b/src/core/gpu_hw_texture_cache.h index 3bb1d8e3a..f070b8859 100644 --- a/src/core/gpu_hw_texture_cache.h +++ b/src/core/gpu_hw_texture_cache.h @@ -116,28 +116,16 @@ void CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height, const GSVector4i src_bounds, const GSVector4i dst_bounds); void WriteVRAM(u32 x, u32 y, u32 width, u32 height, const void* data, bool set_mask, bool check_mask, const GSVector4i bounds); -void UpdateVRAMTrackingState(); const Source* LookupSource(SourceKey key, const GSVector4i uv_rect, PaletteRecordFlags flags); -bool IsPageDrawn(u32 page_index); -bool IsPageDrawn(u32 page_index, const GSVector4i rect); bool IsRectDrawn(const GSVector4i rect); bool AreSourcePagesDrawn(SourceKey key, const GSVector4i rect); -void InvalidatePageSources(u32 pn); -void InvalidatePageSources(u32 pn, const GSVector4i rc); -void DestroySource(Source* src); - void Compact(); -void DecodeTexture(GPUTextureMode mode, const u16* page_ptr, const u16* palette, u32* dest, u32 dest_stride, u32 width, - u32 height); -HashType HashPartialPalette(GPUTexturePaletteReg palette, GPUTextureMode mode, u32 min, u32 max); -HashType HashRect(const GSVector4i rc); - void SetGameID(std::string game_id); -void ReloadTextureReplacements(); +void ReloadTextureReplacements(bool show_info); // VRAM Write Replacements const TextureReplacementImage* GetVRAMReplacement(u32 width, u32 height, const void* pixels); diff --git a/src/core/hotkeys.cpp b/src/core/hotkeys.cpp index 9897ff7ae..6d800756a 100644 --- a/src/core/hotkeys.cpp +++ b/src/core/hotkeys.cpp @@ -438,11 +438,7 @@ DEFINE_HOTKEY("ReloadPostProcessingShaders", TRANSLATE_NOOP("Hotkeys", "Graphics DEFINE_HOTKEY("ReloadTextureReplacements", TRANSLATE_NOOP("Hotkeys", "Graphics"), TRANSLATE_NOOP("Hotkeys", "Reload Texture Replacements"), [](s32 pressed) { if (!pressed && System::IsValid()) - { - Host::AddKeyedOSDMessage("ReloadTextureReplacements", - TRANSLATE_STR("OSDMessage", "Texture replacements reloaded."), 10.0f); - GPUTextureCache::ReloadTextureReplacements(); - } + GPUTextureCache::ReloadTextureReplacements(true); }) DEFINE_HOTKEY("ToggleWidescreen", TRANSLATE_NOOP("Hotkeys", "Graphics"), TRANSLATE_NOOP("Hotkeys", "Toggle Widescreen"), diff --git a/src/duckstation-qt/qthost.cpp b/src/duckstation-qt/qthost.cpp index ea39688e2..35c6c7c0d 100644 --- a/src/duckstation-qt/qthost.cpp +++ b/src/duckstation-qt/qthost.cpp @@ -1361,7 +1361,7 @@ void EmuThread::reloadTextureReplacements() } if (System::IsValid()) - GPUTextureCache::ReloadTextureReplacements(); + GPUTextureCache::ReloadTextureReplacements(true); } void EmuThread::runOnEmuThread(std::function callback) diff --git a/src/duckstation-qt/translations/duckstation-qt_en.ts b/src/duckstation-qt/translations/duckstation-qt_en.ts index 46ccf17c1..d49240459 100644 --- a/src/duckstation-qt/translations/duckstation-qt_en.ts +++ b/src/duckstation-qt/translations/duckstation-qt_en.ts @@ -16,7 +16,7 @@ Achievements - + You have unlocked {} of %n achievements Achievement popup @@ -25,7 +25,7 @@ - + and earned {} of %n points Achievement popup @@ -34,7 +34,7 @@ - + %n achievements Mastery popup @@ -43,8 +43,8 @@ - - + + %n points Achievement points @@ -53,7 +53,7 @@ - + You have unlocked all achievements and earned %n points! Point count @@ -62,7 +62,7 @@ - + This game has %n leaderboards. Leaderboard count @@ -82,6 +82,18 @@ + + GPU_HW + + + %n replacement textures found. + Replacement texture count + + %n replacement texture found. + %n replacement textures found. + + + GameList @@ -128,7 +140,7 @@ System - + %n cheat(s) are now active. %n cheat is now active. @@ -136,7 +148,7 @@ - + %n cheat(s) are now inactive. %n cheat is now inactive. @@ -144,7 +156,7 @@ - + %n cheat(s) are enabled. This may crash games. %n cheat is enabled. This may crash games. diff --git a/src/util/imgui_glyph_ranges.inl b/src/util/imgui_glyph_ranges.inl index 5155b38d9..ffb70aedb 100644 --- a/src/util/imgui_glyph_ranges.inl +++ b/src/util/imgui_glyph_ranges.inl @@ -5,4 +5,4 @@ static constexpr ImWchar FA_ICON_RANGE[] = { 0xe06f,0xe06f,0xe086,0xe086,0xf002, static constexpr ImWchar PF_ICON_RANGE[] = { 0x2196,0x2199,0x219e,0x21a1,0x21b0,0x21b3,0x21ba,0x21c3,0x21c7,0x21ca,0x21d0,0x21d4,0x21dc,0x21dd,0x21e0,0x21e3,0x21ed,0x21ee,0x21f7,0x21f8,0x21fa,0x21fb,0x227a,0x227f,0x2284,0x2284,0x2349,0x2349,0x235e,0x235e,0x2360,0x2361,0x2364,0x2366,0x23b2,0x23b4,0x23ce,0x23ce,0x23f4,0x23f7,0x2427,0x243a,0x243c,0x243e,0x2460,0x246b,0x24f5,0x24fd,0x24ff,0x24ff,0x2717,0x2717,0x278a,0x278e,0x27fc,0x27fc,0xe001,0xe001,0xff21,0xff3a,0x1f52b,0x1f52b,0x0,0x0 }; -static constexpr ImWchar EMOJI_ICON_RANGE[] = { 0x2139,0x2139,0x23e9,0x23ea,0x23f8,0x23f8,0x26a0,0x26a0,0x1f4be,0x1f4be,0x1f4c2,0x1f4c2,0x1f4f7,0x1f4f8,0x1f507,0x1f507,0x1f509,0x1f50a,0x1f50d,0x1f50d,0x1f513,0x1f513,0x0,0x0 }; +static constexpr ImWchar EMOJI_ICON_RANGE[] = { 0x2139,0x2139,0x23e9,0x23ea,0x23f8,0x23f8,0x26a0,0x26a0,0x1f4be,0x1f4be,0x1f4c2,0x1f4c2,0x1f4f7,0x1f4f8,0x1f504,0x1f504,0x1f507,0x1f507,0x1f509,0x1f50a,0x1f50d,0x1f50d,0x1f513,0x1f513,0x0,0x0 };