GS: Add texture replacement dump/load indicators to OSD
Some checks failed
🐧 Linux Builds / AppImage (push) Has been cancelled
🐧 Linux Builds / Flatpak (push) Has been cancelled
🍎 MacOS Builds / Defaults (push) Has been cancelled
🖥️ Windows Builds / Lint VS Project Files (push) Has been cancelled
🖥️ Windows Builds / CMake (push) Has been cancelled
🖥️ Windows Builds / SSE4 (push) Has been cancelled
🖥️ Windows Builds / AVX2 (push) Has been cancelled

Signed-off-by: SternXD <stern@sidestore.io>
This commit is contained in:
SternXD 2025-11-23 07:47:16 -05:00 committed by Ty
parent 3376001d45
commit 9877129815
9 changed files with 88 additions and 4 deletions

View File

@ -149,6 +149,13 @@
</property>
</widget>
</item>
<item row="6" column="2">
<widget class="QCheckBox" name="showTextureReplacements">
<property name="text">
<string>Show Texture Replacement Status</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="showResolution">
<property name="text">
@ -391,6 +398,7 @@
<tabstop>showInputs</tabstop>
<tabstop>showVideoCapture</tabstop>
<tabstop>showInputRec</tabstop>
<tabstop>showTextureReplacements</tabstop>
<tabstop>warnAboutUnsafeSettings</tabstop>
</tabstops>
<resources/>

View File

@ -241,6 +241,7 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* settings_dialog,
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_osd.showInputs, "EmuCore/GS", "OsdShowInputs", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_osd.showVideoCapture, "EmuCore/GS", "OsdShowVideoCapture", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_osd.showInputRec, "EmuCore/GS", "OsdShowInputRec", true);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_osd.showTextureReplacements, "EmuCore/GS", "OsdShowTextureReplacements", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_osd.warnAboutUnsafeSettings, "EmuCore", "OsdWarnAboutUnsafeSettings", true);
//////////////////////////////////////////////////////////////////////////
@ -769,6 +770,9 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* settings_dialog,
dialog()->registerWidgetHelp(m_osd.showInputRec, tr("Show Input Recording Status"), tr("Checked"),
tr("Shows the status of the currently active input recording in the top-right corner of the display.."));
dialog()->registerWidgetHelp(m_osd.showTextureReplacements, tr("Show Texture Replacement Status"), tr("Checked"),
tr("Shows the status of the number of dumped and loaded texture replacements in the top-right corner of the display."));
dialog()->registerWidgetHelp(m_osd.warnAboutUnsafeSettings, tr("Warn About Unsafe Settings"), tr("Checked"),
tr("Displays warnings when settings are enabled which may break games."));

View File

@ -749,6 +749,7 @@ struct Pcsx2Config
OsdShowInputs : 1,
OsdShowVideoCapture : 1,
OsdShowInputRec : 1,
OsdShowTextureReplacements : 1,
HWSpinGPUForReadbacks : 1,
HWSpinCPUForReadbacks : 1,
GPUPaletteConversion : 1,

View File

@ -1134,6 +1134,7 @@ static void HotkeyToggleOSD()
GSConfig.OsdShowInputs ^= EmuConfig.GS.OsdShowInputs;
GSConfig.OsdShowInputRec ^= EmuConfig.GS.OsdShowInputRec;
GSConfig.OsdShowVideoCapture ^= EmuConfig.GS.OsdShowVideoCapture;
GSConfig.OsdShowTextureReplacements ^= EmuConfig.GS.OsdShowTextureReplacements;
GSConfig.OsdMessagesPos =
GSConfig.OsdMessagesPos == OsdOverlayPos::None ? EmuConfig.GS.OsdMessagesPos : OsdOverlayPos::None;

View File

@ -124,6 +124,7 @@ namespace GSTextureReplacements
/// Textures that have been dumped, to save stat() calls.
static std::unordered_set<TextureName> s_dumped_textures;
static std::mutex s_dumped_textures_mutex;
/// Lookup map of texture names to replacements, if they exist.
static std::unordered_map<TextureName, std::string> s_replacement_texture_filenames;
@ -802,10 +803,13 @@ void GSTextureReplacements::DumpTexture(const GSTextureCache::HashCacheKey& hash
{
// check if it's been dumped or replaced already
const TextureName name(CreateTextureName(hash, level));
{
std::unique_lock<std::mutex> lock(s_dumped_textures_mutex);
if (s_dumped_textures.find(name) != s_dumped_textures.end() || s_replacement_texture_filenames.find(name) != s_replacement_texture_filenames.end())
return;
s_dumped_textures.insert(name);
}
// already exists on disk?
std::string filename(GetDumpFilename(name, level));
@ -842,9 +846,22 @@ void GSTextureReplacements::DumpTexture(const GSTextureCache::HashCacheKey& hash
void GSTextureReplacements::ClearDumpedTextureList()
{
std::unique_lock<std::mutex> lock(s_dumped_textures_mutex);
s_dumped_textures.clear();
}
u32 GSTextureReplacements::GetDumpedTextureCount()
{
std::unique_lock<std::mutex> lock(s_dumped_textures_mutex);
return static_cast<u32>(s_dumped_textures.size());
}
u32 GSTextureReplacements::GetLoadedTextureCount()
{
std::unique_lock<std::mutex> lock(s_replacement_texture_cache_mutex);
return static_cast<u32>(s_replacement_texture_cache.size());
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Worker Thread
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -47,6 +47,12 @@ namespace GSTextureReplacements
GSTextureCache::SourceRegion region, GSLocalMemory& mem, u32 level);
void ClearDumpedTextureList();
/// Get the number of textures that have been dumped.
u32 GetDumpedTextureCount();
/// Get the number of replacement textures that have been loaded/cached.
u32 GetLoadedTextureCount();
/// Loader will take a filename and interpret the format (e.g. DDS, PNG, etc).
using ReplacementTextureLoader = bool (*)(const std::string& filename, GSTextureReplacements::ReplacementTexture* tex, bool only_base_image);
ReplacementTextureLoader GetLoader(const std::string_view filename);

View File

@ -4254,7 +4254,6 @@ void FullscreenUI::DrawInterfaceSettingsPage()
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_SLIDERS, "Show Settings"),
FSUI_CSTR("Shows the current configuration in the bottom-right corner of the display."),
"EmuCore/GS", "OsdShowSettings", false);
bool show_settings = (bsi->GetBoolValue("EmuCore/GS", "OsdShowSettings", false) == false);
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_HAMMER, "Show Patches"),
FSUI_CSTR("Shows the amount of currently active patches/cheats on the bottom-right corner of the display."), "EmuCore/GS",
@ -4268,6 +4267,9 @@ void FullscreenUI::DrawInterfaceSettingsPage()
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_KEYBOARD, "Show Input Recording Status"),
FSUI_CSTR("Shows the status of the currently active input recording."), "EmuCore/GS",
"OsdShowInputRec", true);
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_IMAGES, "Show Texture Replacement Status"),
FSUI_CSTR("Shows the number of dumped and loaded texture replacements on the OSD."), "EmuCore/GS",
"OsdShowTextureReplacements", true);
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_TRIANGLE_EXCLAMATION, "Warn About Unsafe Settings"),
FSUI_CSTR("Displays warnings when settings are enabled which may break games."), "EmuCore", "WarnAboutUnsafeSettings", true);

View File

@ -9,6 +9,7 @@
#include "GS/GSCapture.h"
#include "GS/GSVector.h"
#include "GS/Renderers/Common/GSDevice.h"
#include "GS/Renderers/HW/GSTextureReplacements.h"
#include "Host.h"
#include "IconsFontAwesome6.h"
#include "IconsPromptFont.h"
@ -148,6 +149,7 @@ namespace ImGuiManager
static void DrawInputsOverlay(float scale, float margin, float spacing);
static void DrawInputRecordingOverlay(float& position_y, float scale, float margin, float spacing);
static void DrawVideoCaptureOverlay(float& position_y, float scale, float margin, float spacing);
static void DrawTextureReplacementsOverlay(float& position_y, float scale, float margin, float spacing);
} // namespace ImGuiManager
static std::tuple<float, float> GetMinMax(std::span<const float> values)
@ -946,6 +948,46 @@ __ri void ImGuiManager::DrawVideoCaptureOverlay(float& position_y, float scale,
position_y += std::max(icon_size.y, text_size.y) + spacing;
}
__ri void ImGuiManager::DrawTextureReplacementsOverlay(float& position_y, float scale, float margin, float spacing)
{
if (!GSConfig.OsdShowTextureReplacements ||
FullscreenUI::HasActiveWindow())
return;
const bool dumping_active = GSConfig.DumpReplaceableTextures;
const bool replacement_active = GSConfig.LoadTextureReplacements;
if (!dumping_active && !replacement_active)
return;
const float shadow_offset = std::ceil(scale);
ImFont* const standard_font = ImGuiManager::GetStandardFont();
const float font_size = ImGuiManager::GetFontSizeStandard();
ImDrawList* dl = ImGui::GetBackgroundDrawList();
SmallString texture_line;
if (replacement_active)
{
const u32 loaded_count = GSTextureReplacements::GetLoadedTextureCount();
texture_line.format("{} Replaced: {}", ICON_FA_IMAGES, loaded_count);
}
if (dumping_active)
{
if (!texture_line.empty())
texture_line.append(" | ");
const u32 dumped_count = GSTextureReplacements::GetDumpedTextureCount();
texture_line.append_format("{} Dumped: {}", ICON_FA_DOWNLOAD, dumped_count);
}
ImVec2 text_size = standard_font->CalcTextSizeA(font_size, std::numeric_limits<float>::max(), -1.0f, texture_line.c_str(), nullptr, nullptr);
const ImVec2 text_pos(GetWindowWidth() - margin - text_size.x, position_y);
dl->AddText(standard_font, font_size, ImVec2(text_pos.x + shadow_offset, text_pos.y + shadow_offset), IM_COL32(0, 0, 0, 100), texture_line.c_str());
dl->AddText(standard_font, font_size, text_pos, white_color, texture_line.c_str());
position_y += text_size.y + spacing;
}
namespace SaveStateSelectorUI
{
namespace
@ -1381,6 +1423,7 @@ void ImGuiManager::RenderOverlays()
DrawVideoCaptureOverlay(position_y, scale, margin, spacing);
DrawInputRecordingOverlay(position_y, scale, margin, spacing);
DrawTextureReplacementsOverlay(position_y, scale, margin, spacing);
if (GSConfig.OsdPerformancePos != OsdOverlayPos::None)
DrawPerformanceOverlay(position_y, scale, margin, spacing);
DrawSettingsOverlay(scale, margin, spacing);

View File

@ -741,6 +741,7 @@ Pcsx2Config::GSOptions::GSOptions()
OsdShowInputs = false;
OsdShowVideoCapture = true;
OsdShowInputRec = true;
OsdShowTextureReplacements = true;
HWDownloadMode = GSHardwareDownloadMode::Enabled;
HWSpinGPUForReadbacks = false;
@ -960,6 +961,7 @@ void Pcsx2Config::GSOptions::LoadSave(SettingsWrapper& wrap)
SettingsWrapBitBool(OsdShowHardwareInfo);
SettingsWrapBitBool(OsdShowVideoCapture);
SettingsWrapBitBool(OsdShowInputRec);
SettingsWrapBitBool(OsdShowTextureReplacements);
SettingsWrapBitBool(HWSpinGPUForReadbacks);
SettingsWrapBitBool(HWSpinCPUForReadbacks);