diff --git a/Source/Core/Core/Config/GraphicsSettings.cpp b/Source/Core/Core/Config/GraphicsSettings.cpp index 9a9bf4148561..5c880176b83d 100644 --- a/Source/Core/Core/Config/GraphicsSettings.cpp +++ b/Source/Core/Core/Config/GraphicsSettings.cpp @@ -41,6 +41,8 @@ const Info GFX_LOG_RENDER_TIME_TO_FILE{{System::GFX, "Settings", "LogRende const Info GFX_OVERLAY_STATS{{System::GFX, "Settings", "OverlayStats"}, false}; const Info GFX_OVERLAY_PROJ_STATS{{System::GFX, "Settings", "OverlayProjStats"}, false}; const Info GFX_OVERLAY_SCISSOR_STATS{{System::GFX, "Settings", "OverlayScissorStats"}, false}; +const Info GFX_OVERLAY_ASSET_LOADER_STATS{ + {System::GFX, "Settings", "OverlayAssetLoaderStats"}, false}; const Info GFX_DUMP_TEXTURES{{System::GFX, "Settings", "DumpTextures"}, false}; const Info GFX_DUMP_MIP_TEXTURES{{System::GFX, "Settings", "DumpMipTextures"}, true}; const Info GFX_DUMP_BASE_TEXTURES{{System::GFX, "Settings", "DumpBaseTextures"}, true}; diff --git a/Source/Core/Core/Config/GraphicsSettings.h b/Source/Core/Core/Config/GraphicsSettings.h index c1f301a4a99b..a1b997518b76 100644 --- a/Source/Core/Core/Config/GraphicsSettings.h +++ b/Source/Core/Core/Config/GraphicsSettings.h @@ -43,6 +43,7 @@ extern const Info GFX_LOG_RENDER_TIME_TO_FILE; extern const Info GFX_OVERLAY_STATS; extern const Info GFX_OVERLAY_PROJ_STATS; extern const Info GFX_OVERLAY_SCISSOR_STATS; +extern const Info GFX_OVERLAY_ASSET_LOADER_STATS; extern const Info GFX_DUMP_TEXTURES; extern const Info GFX_DUMP_MIP_TEXTURES; extern const Info GFX_DUMP_BASE_TEXTURES; diff --git a/Source/Core/DolphinLib.props b/Source/Core/DolphinLib.props index 24c539caa072..32c35df2477f 100644 --- a/Source/Core/DolphinLib.props +++ b/Source/Core/DolphinLib.props @@ -663,6 +663,7 @@ + @@ -1269,6 +1270,7 @@ + diff --git a/Source/Core/VideoCommon/CMakeLists.txt b/Source/Core/VideoCommon/CMakeLists.txt index a457c30db9db..67523bb37e3e 100644 --- a/Source/Core/VideoCommon/CMakeLists.txt +++ b/Source/Core/VideoCommon/CMakeLists.txt @@ -71,6 +71,8 @@ add_library(videocommon GraphicsModSystem/Runtime/CustomAssetLibrary.h GraphicsModSystem/Runtime/CustomAssetLoader.cpp GraphicsModSystem/Runtime/CustomAssetLoader.h + GraphicsModSystem/Runtime/CustomAssetLoaderStats.cpp + GraphicsModSystem/Runtime/CustomAssetLoaderStats.h GraphicsModSystem/Runtime/CustomTextureData.cpp GraphicsModSystem/Runtime/CustomTextureData.h GraphicsModSystem/Runtime/FBInfo.cpp diff --git a/Source/Core/VideoCommon/GraphicsModSystem/Runtime/CustomAsset.cpp b/Source/Core/VideoCommon/GraphicsModSystem/Runtime/CustomAsset.cpp index b21e9825c24c..f6c8ad14b091 100644 --- a/Source/Core/VideoCommon/GraphicsModSystem/Runtime/CustomAsset.cpp +++ b/Source/Core/VideoCommon/GraphicsModSystem/Runtime/CustomAsset.cpp @@ -29,9 +29,9 @@ CustomAsset::CustomAsset(std::shared_ptr library, { } -bool CustomAsset::Load() +bool CustomAsset::Load(CustomAssetLoaderStats* stats) { - const auto bytes_loaded = LoadImpl(m_asset_id); + const auto bytes_loaded = LoadImpl(m_asset_id, stats); if (bytes_loaded > 0) { m_bytes_loaded = bytes_loaded; @@ -40,6 +40,11 @@ bool CustomAsset::Load() return bytes_loaded != 0; } +void CustomAsset::Unload(CustomAssetLoaderStats* stats) +{ + UnloadImpl(stats); +} + const std::optional& CustomAsset::GetLastWriteTime() const { return m_last_write_time; @@ -60,24 +65,54 @@ std::size_t CustomAsset::GetBytesLoaded() const return m_bytes_loaded; } -std::size_t CustomTextureAsset::LoadImpl(const std::filesystem::path& asset_id) +std::size_t CustomTextureAsset::LoadImpl(const std::filesystem::path& asset_id, + CustomAssetLoaderStats* stats) { - std::lock_guard lk(m_lock); - const bool result = m_owning_library->LoadTexture(asset_id, &m_data); - if (!result) - return 0; - m_loaded = true; - return GetAssetSize(m_data); + std::size_t result = 0; + { + std::lock_guard lk(m_lock); + if (!m_owning_library->LoadTexture(asset_id, &m_data)) + return 0; + m_loaded = true; + result = GetAssetSize(m_data); + } + if (stats) [[likely]] + { + stats->AddTexture(); + } + return result; } -std::size_t CustomGameTextureAsset::LoadImpl(const std::filesystem::path& asset_id) +void CustomTextureAsset::UnloadImpl(CustomAssetLoaderStats* stats) { - std::lock_guard lk(m_lock); - const bool result = m_owning_library->LoadGameTexture(asset_id, &m_data); - if (!result) - return 0; - m_loaded = true; - return GetAssetSize(m_data); + if (!stats) [[unlikely]] + return; + stats->RemoveGameTexture(); +} + +std::size_t CustomGameTextureAsset::LoadImpl(const std::filesystem::path& asset_id, + CustomAssetLoaderStats* stats) +{ + std::size_t result = 0; + { + std::lock_guard lk(m_lock); + if (!m_owning_library->LoadGameTexture(asset_id, &m_data)) + return 0; + m_loaded = true; + result = GetAssetSize(m_data); + } + if (stats) [[likely]] + { + stats->AddGameTexture(); + } + return result; +} + +void CustomGameTextureAsset::UnloadImpl(CustomAssetLoaderStats* stats) +{ + if (!stats) [[unlikely]] + return; + stats->RemoveGameTexture(); } bool CustomGameTextureAsset::Validate(u32 width, u32 height) const diff --git a/Source/Core/VideoCommon/GraphicsModSystem/Runtime/CustomAsset.h b/Source/Core/VideoCommon/GraphicsModSystem/Runtime/CustomAsset.h index eb91cf0dd8cf..9e9c89b00ab4 100644 --- a/Source/Core/VideoCommon/GraphicsModSystem/Runtime/CustomAsset.h +++ b/Source/Core/VideoCommon/GraphicsModSystem/Runtime/CustomAsset.h @@ -4,6 +4,7 @@ #pragma once #include "Common/CommonTypes.h" +#include "VideoCommon/GraphicsModSystem/Runtime/CustomAssetLoaderStats.h" #include "VideoCommon/GraphicsModSystem/Runtime/CustomTextureData.h" #include @@ -24,7 +25,8 @@ class CustomAsset CustomAsset& operator=(const CustomAsset&) = default; CustomAsset& operator=(CustomAsset&&) = default; - bool Load(); + bool Load(CustomAssetLoaderStats* stats); + void Unload(CustomAssetLoaderStats* stats); const std::optional& GetLastWriteTime() const; const std::filesystem::path& GetAssetId() const; const std::shared_ptr& GetOwningLibrary() const; @@ -34,7 +36,9 @@ class CustomAsset std::shared_ptr m_owning_library; private: - virtual std::size_t LoadImpl(const std::filesystem::path& asset_id) = 0; + virtual std::size_t LoadImpl(const std::filesystem::path& asset_id, + CustomAssetLoaderStats* stats) = 0; + virtual void UnloadImpl(CustomAssetLoaderStats* stats) = 0; std::filesystem::path m_asset_id; std::size_t m_bytes_loaded = 0; std::optional m_last_write_time = std::nullopt; @@ -64,14 +68,18 @@ class CustomTextureAsset final : public CustomLoadableAsset { public: using CustomLoadableAsset::CustomLoadableAsset; - std::size_t LoadImpl(const std::filesystem::path& asset_id) override; + std::size_t LoadImpl(const std::filesystem::path& asset_id, + CustomAssetLoaderStats* stats) override; + void UnloadImpl(CustomAssetLoaderStats* stats) override; }; class CustomGameTextureAsset final : public CustomLoadableAsset { public: using CustomLoadableAsset::CustomLoadableAsset; - std::size_t LoadImpl(const std::filesystem::path& asset_id) override; + std::size_t LoadImpl(const std::filesystem::path& asset_id, + CustomAssetLoaderStats* stats) override; + void UnloadImpl(CustomAssetLoaderStats* stats) override; bool Validate(u32 width, u32 height) const; }; diff --git a/Source/Core/VideoCommon/GraphicsModSystem/Runtime/CustomAssetLoader.cpp b/Source/Core/VideoCommon/GraphicsModSystem/Runtime/CustomAssetLoader.cpp index facc6501e013..86ab57e38bec 100644 --- a/Source/Core/VideoCommon/GraphicsModSystem/Runtime/CustomAssetLoader.cpp +++ b/Source/Core/VideoCommon/GraphicsModSystem/Runtime/CustomAssetLoader.cpp @@ -40,7 +40,8 @@ void CustomAssetLoader::Init() if (write_time > file_to_monitor.m_cached_write_time) { file_to_monitor.m_cached_write_time = write_time; - (void)ptr->Load(); + ptr->Unload(&m_stats); + (void)ptr->Load(&m_stats); } } } @@ -50,7 +51,7 @@ void CustomAssetLoader::Init() m_asset_load_thread.Reset("Custom Asset Loader", [this](std::weak_ptr asset) { if (auto ptr = asset.lock()) { - if (ptr->Load()) + if (ptr->Load(&m_stats)) { if (m_max_memory_available >= m_total_bytes_loaded + ptr->GetBytesLoaded()) { @@ -65,6 +66,7 @@ void CustomAssetLoader::Init() { ERROR_LOG_FMT(VIDEO, "Failed to load asset {} because there was not enough memory.", PathToString(ptr->GetAssetId())); + ptr->Unload(&m_stats); } } } @@ -79,6 +81,7 @@ void CustomAssetLoader ::Shutdown() m_file_monitor_thread.join(); m_files_to_monitor.clear(); m_total_bytes_loaded = 0; + m_stats.Reset(); } std::shared_ptr @@ -94,4 +97,9 @@ CustomAssetLoader::LoadGameTexture(const std::filesystem::path& texture_path, { return Load(texture_path, m_game_textures, std::move(library)); } + +const CustomAssetLoaderStats* CustomAssetLoader::GetStats() const +{ + return &m_stats; +} } // namespace VideoCommon diff --git a/Source/Core/VideoCommon/GraphicsModSystem/Runtime/CustomAssetLoader.h b/Source/Core/VideoCommon/GraphicsModSystem/Runtime/CustomAssetLoader.h index 6a55d0af0dad..d0d5fb7cae4d 100644 --- a/Source/Core/VideoCommon/GraphicsModSystem/Runtime/CustomAssetLoader.h +++ b/Source/Core/VideoCommon/GraphicsModSystem/Runtime/CustomAssetLoader.h @@ -12,6 +12,7 @@ #include "Common/Flag.h" #include "Common/WorkQueueThread.h" #include "VideoCommon/GraphicsModSystem/Runtime/CustomAsset.h" +#include "VideoCommon/GraphicsModSystem/Runtime/CustomAssetLoaderStats.h" namespace VideoCommon { @@ -35,6 +36,8 @@ class CustomAssetLoader LoadGameTexture(const std::filesystem::path& texture_path, std::shared_ptr library); + const CustomAssetLoaderStats* GetStats() const; + private: // TODO C++20: use a 'derived_from' concept when compilers catch up template @@ -49,6 +52,7 @@ class CustomAssetLoader std::shared_ptr ptr(new AssetType(std::move(library), asset_path), [&](AssetType* a) { asset_map.erase(a->GetAssetId()); + a->Unload(&m_stats); m_total_bytes_loaded -= a->GetBytesLoaded(); std::lock_guard lk(m_files_lock); m_files_to_monitor.erase(a->GetAssetId()); @@ -76,5 +80,7 @@ class CustomAssetLoader std::map m_files_to_monitor; std::mutex m_files_lock; Common::WorkQueueThread> m_asset_load_thread; + + CustomAssetLoaderStats m_stats; }; } // namespace VideoCommon diff --git a/Source/Core/VideoCommon/GraphicsModSystem/Runtime/CustomAssetLoaderStats.cpp b/Source/Core/VideoCommon/GraphicsModSystem/Runtime/CustomAssetLoaderStats.cpp new file mode 100644 index 000000000000..6aade4cfd20a --- /dev/null +++ b/Source/Core/VideoCommon/GraphicsModSystem/Runtime/CustomAssetLoaderStats.cpp @@ -0,0 +1,70 @@ +// Copyright 2023 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "VideoCommon/GraphicsModSystem/Runtime/CustomAssetLoaderStats.h" + +#include + +namespace VideoCommon +{ +void CustomAssetLoaderStats::Display() const +{ + const float scale = ImGui::GetIO().DisplayFramebufferScale.x; + // TODO: This is the same position as the regular statistics text + ImGui::SetNextWindowPos(ImVec2(10.0f * scale, 10.0f * scale), ImGuiCond_FirstUseEver); + ImGui::SetNextWindowSizeConstraints(ImVec2(200.0f * scale, 100.0f * scale), + ImGui::GetIO().DisplaySize); + if (!ImGui::Begin("Asset Loader", nullptr, ImGuiWindowFlags_NoNavInputs)) + { + ImGui::End(); + return; + } + + ImGui::Columns(2, "Asset Loader", true); + + const auto draw_statistic = [](const char* name, const char* format, auto&&... args) { + ImGui::TextUnformatted(name); + ImGui::NextColumn(); + ImGui::Text(format, std::forward(args)...); + ImGui::NextColumn(); + }; + + { + std::lock_guard lk(m_lock); + draw_statistic("Textures", "%d", m_textures_loaded); + draw_statistic("Game Textures", "%d", m_game_textures_loaded); + } + + ImGui::End(); +} + +void CustomAssetLoaderStats::AddTexture() +{ + std::lock_guard lk(m_lock); + m_textures_loaded++; +} + +void CustomAssetLoaderStats::RemoveTexture() +{ + std::lock_guard lk(m_lock); + m_textures_loaded--; +} + +void CustomAssetLoaderStats::AddGameTexture() +{ + std::lock_guard lk(m_lock); + m_game_textures_loaded++; +} +void CustomAssetLoaderStats::RemoveGameTexture() +{ + std::lock_guard lk(m_lock); + m_game_textures_loaded--; +} + +void CustomAssetLoaderStats::Reset() +{ + std::lock_guard lk(m_lock); + m_textures_loaded = 0; + m_game_textures_loaded = 0; +} +} // namespace VideoCommon diff --git a/Source/Core/VideoCommon/GraphicsModSystem/Runtime/CustomAssetLoaderStats.h b/Source/Core/VideoCommon/GraphicsModSystem/Runtime/CustomAssetLoaderStats.h new file mode 100644 index 000000000000..edb6a1066c0f --- /dev/null +++ b/Source/Core/VideoCommon/GraphicsModSystem/Runtime/CustomAssetLoaderStats.h @@ -0,0 +1,30 @@ +// Copyright 2023 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include + +#include "Common/CommonTypes.h" + +namespace VideoCommon +{ +class CustomAssetLoaderStats +{ +public: + void Display() const; + + void AddTexture(); + void RemoveTexture(); + + void AddGameTexture(); + void RemoveGameTexture(); + + void Reset(); + +private: + mutable std::mutex m_lock; + u64 m_textures_loaded = 0; + u64 m_game_textures_loaded = 0; +}; +} // namespace VideoCommon diff --git a/Source/Core/VideoCommon/OnScreenUI.cpp b/Source/Core/VideoCommon/OnScreenUI.cpp index e2fa2593a709..3612b0d24c97 100644 --- a/Source/Core/VideoCommon/OnScreenUI.cpp +++ b/Source/Core/VideoCommon/OnScreenUI.cpp @@ -10,11 +10,13 @@ #include "Core/Config/MainSettings.h" #include "Core/Config/NetplaySettings.h" #include "Core/Movie.h" +#include "Core/System.h" #include "VideoCommon/AbstractGfx.h" #include "VideoCommon/AbstractPipeline.h" #include "VideoCommon/AbstractShader.h" #include "VideoCommon/FramebufferShaderGen.h" +#include "VideoCommon/GraphicsModSystem/Runtime/CustomAssetLoader.h" #include "VideoCommon/NetPlayChatUI.h" #include "VideoCommon/NetPlayGolfUI.h" #include "VideoCommon/OnScreenDisplay.h" @@ -318,6 +320,16 @@ void OnScreenUI::DrawDebugText() if (g_ActiveConfig.bOverlayScissorStats) g_stats.DisplayScissor(); + if (g_ActiveConfig.bOverlayAssetLoaderStats) + { + auto& system = Core::System::GetInstance(); + const VideoCommon::CustomAssetLoaderStats* stats = system.GetCustomAssetLoader().GetStats(); + if (stats) + { + stats->Display(); + } + } + const std::string profile_output = Common::Profiler::ToString(); if (!profile_output.empty()) ImGui::TextUnformatted(profile_output.c_str()); diff --git a/Source/Core/VideoCommon/VideoConfig.cpp b/Source/Core/VideoCommon/VideoConfig.cpp index 38ee680bf39b..26b4e38674f1 100644 --- a/Source/Core/VideoCommon/VideoConfig.cpp +++ b/Source/Core/VideoCommon/VideoConfig.cpp @@ -93,6 +93,7 @@ void VideoConfig::Refresh() bOverlayStats = Config::Get(Config::GFX_OVERLAY_STATS); bOverlayProjStats = Config::Get(Config::GFX_OVERLAY_PROJ_STATS); bOverlayScissorStats = Config::Get(Config::GFX_OVERLAY_SCISSOR_STATS); + bOverlayAssetLoaderStats = Config::Get(Config::GFX_OVERLAY_ASSET_LOADER_STATS); bDumpTextures = Config::Get(Config::GFX_DUMP_TEXTURES); bDumpMipmapTextures = Config::Get(Config::GFX_DUMP_MIP_TEXTURES); bDumpBaseTextures = Config::Get(Config::GFX_DUMP_BASE_TEXTURES); diff --git a/Source/Core/VideoCommon/VideoConfig.h b/Source/Core/VideoCommon/VideoConfig.h index a479276e6c56..98ba178a82cd 100644 --- a/Source/Core/VideoCommon/VideoConfig.h +++ b/Source/Core/VideoCommon/VideoConfig.h @@ -116,6 +116,7 @@ struct VideoConfig final bool bOverlayStats = false; bool bOverlayProjStats = false; bool bOverlayScissorStats = false; + bool bOverlayAssetLoaderStats = false; bool bTexFmtOverlayEnable = false; bool bTexFmtOverlayCenter = false; bool bLogRenderTimeToFile = false;