mirror of
https://github.com/cemu-project/Cemu.git
synced 2024-11-22 17:19:18 +01:00
Wait for gfx pack init before loading shaders (#168)
2.0 introduced a race condition where the shader cache loading screen could load shaders before the graphic packs finished activating, potentially bypassing custom shaders. Also removed legacy GraphicPack interface (GraphicPack.cpp/.h) since it was only kept around for Cemuhook and removed u8string variant of cemuLog_force since it's no longer used
This commit is contained in:
parent
8dd1688ca7
commit
33167196d9
@ -10,7 +10,7 @@
|
||||
#include "config/ActiveSettings.h"
|
||||
#include "Cafe/TitleList/GameInfo.h"
|
||||
#include "util/helpers/SystemException.h"
|
||||
#include "Cafe/GraphicPack/GraphicPack.h"
|
||||
#include "Cafe/GraphicPack/GraphicPack2.h"
|
||||
|
||||
#include "input/InputManager.h"
|
||||
|
||||
@ -399,7 +399,7 @@ void cemu_initForGame()
|
||||
debugger_handleEntryBreakpoint(_entryPoint);
|
||||
// load graphic packs
|
||||
forceLog_printf("------- Activate graphic packs -------");
|
||||
graphicPack_activateForCurrentTitle(CafeSystem::GetForegroundTitleId());
|
||||
GraphicPack2::ActivateForCurrentTitle();
|
||||
// print audio log
|
||||
IAudioAPI::PrintLogging();
|
||||
// everything initialized
|
||||
@ -766,6 +766,7 @@ namespace CafeSystem
|
||||
iosu::act::Stop();
|
||||
iosu::mcp::Shutdown();
|
||||
iosu::fsa::Shutdown();
|
||||
GraphicPack2::Reset();
|
||||
UnmountCurrentTitle();
|
||||
sSystemRunning = false;
|
||||
}
|
||||
|
@ -1,127 +0,0 @@
|
||||
#include "gui/wxgui.h"
|
||||
#include "GraphicPack.h"
|
||||
|
||||
#include "config/ActiveSettings.h"
|
||||
#include "Cafe/GraphicPack/GraphicPack2.h"
|
||||
|
||||
/*
|
||||
* Loads the graphic pack if the titleId is referenced in rules.ini
|
||||
*/
|
||||
void graphicPack_loadGraphicPack(wchar_t* graphicPackPath)
|
||||
{
|
||||
fs::path rulesPath = fs::path(graphicPackPath);
|
||||
rulesPath.append("rules.txt");
|
||||
std::unique_ptr<FileStream> fs_rules(FileStream::openFile2(rulesPath));
|
||||
if (!fs_rules)
|
||||
return;
|
||||
std::vector<uint8> rulesData;
|
||||
fs_rules->extract(rulesData);
|
||||
IniParser iniParser(rulesData, rulesPath.string());
|
||||
|
||||
if (!iniParser.NextSection())
|
||||
{
|
||||
cemuLog_force(u8"{}: Does not contain any sections", rulesPath.generic_u8string());
|
||||
return;
|
||||
}
|
||||
if (!boost::iequals(iniParser.GetCurrentSectionName(), "Definition"))
|
||||
{
|
||||
cemuLog_force(u8"{}: [Definition] must be the first section", rulesPath.generic_u8string());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
auto option_version = iniParser.FindOption("version");
|
||||
if (option_version)
|
||||
{
|
||||
sint32 versionNum = -1;
|
||||
auto [ptr, ec] = std::from_chars(option_version->data(), option_version->data() + option_version->size(), versionNum);
|
||||
if (ec != std::errc{})
|
||||
{
|
||||
cemuLog_force(u8"{}: Unable to parse version", rulesPath.generic_u8string());
|
||||
return;
|
||||
}
|
||||
|
||||
if (versionNum > GP_LEGACY_VERSION)
|
||||
{
|
||||
GraphicPack2::LoadGraphicPack(rulesPath.generic_wstring(), iniParser);
|
||||
return;
|
||||
}
|
||||
}
|
||||
cemuLog_force(u8"{}: Outdated graphic pack", rulesPath.generic_u8string());
|
||||
}
|
||||
|
||||
void graphicPack_scanForGFXPackFolders(const fs::path& currentPath, std::wstring& relativePath)
|
||||
{
|
||||
// check if this directory has rules txt
|
||||
fs::path rulesPath = fs::path(currentPath);
|
||||
rulesPath.append("rules.txt");
|
||||
|
||||
if (fs::exists(rulesPath) && relativePath.length() != 0)
|
||||
{
|
||||
graphicPack_loadGraphicPack((wchar_t*)currentPath.generic_wstring().c_str());
|
||||
return; // when a rules.txt file is found stop recursion
|
||||
}
|
||||
|
||||
if (!fs::exists(currentPath))
|
||||
return;
|
||||
|
||||
for (auto& p : fs::directory_iterator(currentPath))
|
||||
{
|
||||
auto& path = p.path();
|
||||
if (fs::is_directory(p.status()))
|
||||
{
|
||||
// dir
|
||||
sint32 origSize = relativePath.size();
|
||||
relativePath.append(L"/");
|
||||
relativePath.append(path.filename().generic_wstring());
|
||||
graphicPack_scanForGFXPackFolders(path, relativePath);
|
||||
relativePath.resize(origSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void graphicPack_loadAll()
|
||||
{
|
||||
// recursively iterate all directories in graphicPacks/ folder
|
||||
std::wstring graphicPackRelativePath;
|
||||
graphicPack_scanForGFXPackFolders(ActiveSettings::GetPath("graphicPacks/"), graphicPackRelativePath);
|
||||
}
|
||||
|
||||
void graphicPack_activateForCurrentTitle(uint64 titleId)
|
||||
{
|
||||
// activate graphic packs
|
||||
for (const auto& gp : GraphicPack2::GetGraphicPacks())
|
||||
{
|
||||
if (!gp->IsEnabled())
|
||||
continue;
|
||||
|
||||
if (!gp->ContainsTitleId(titleId))
|
||||
continue;
|
||||
|
||||
if(GraphicPack2::ActivateGraphicPack(gp))
|
||||
{
|
||||
if (gp->GetPresets().empty())
|
||||
{
|
||||
forceLog_printf("Activate graphic pack: %s", gp->GetPath().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string logLine;
|
||||
logLine.assign(fmt::format("Activate graphic pack: {} [Presets: ", gp->GetPath()));
|
||||
bool isFirst = true;
|
||||
for (auto& itr : gp->GetPresets())
|
||||
{
|
||||
if(!itr->active)
|
||||
continue;
|
||||
if (isFirst)
|
||||
isFirst = false;
|
||||
else
|
||||
logLine.append(",");
|
||||
logLine.append(itr->name);
|
||||
}
|
||||
logLine.append("]");
|
||||
cemuLog_log(LogType::Force, logLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
#define GP_LEGACY_VERSION (2)
|
||||
|
||||
void graphicPack_loadAll();
|
||||
void graphicPack_activateForCurrentTitle(uint64 titleId);
|
@ -1,6 +1,6 @@
|
||||
#include "Cafe/GraphicPack/GraphicPack2.h"
|
||||
#include "GraphicPack.h"
|
||||
#include "config/CemuConfig.h"
|
||||
#include "config/ActiveSettings.h"
|
||||
#include "openssl/sha.h"
|
||||
#include "Cafe/HW/Latte/Renderer/RendererOuputShader.h"
|
||||
#include "Cafe/Filesystem/fsc.h"
|
||||
@ -14,6 +14,69 @@
|
||||
|
||||
std::vector<GraphicPackPtr> GraphicPack2::s_graphic_packs;
|
||||
std::vector<GraphicPackPtr> GraphicPack2::s_active_graphic_packs;
|
||||
std::atomic_bool GraphicPack2::s_isReady;
|
||||
|
||||
#define GP_LEGACY_VERSION (2)
|
||||
|
||||
void GraphicPack2::LoadGraphicPack(fs::path graphicPackPath)
|
||||
{
|
||||
fs::path rulesPath = graphicPackPath;
|
||||
rulesPath.append("rules.txt");
|
||||
std::unique_ptr<FileStream> fs_rules(FileStream::openFile2(rulesPath));
|
||||
if (!fs_rules)
|
||||
return;
|
||||
std::vector<uint8> rulesData;
|
||||
fs_rules->extract(rulesData);
|
||||
IniParser iniParser(rulesData, rulesPath.string());
|
||||
|
||||
if (!iniParser.NextSection())
|
||||
{
|
||||
cemuLog_force("{}: Does not contain any sections", _utf8Wrapper(rulesPath));
|
||||
return;
|
||||
}
|
||||
if (!boost::iequals(iniParser.GetCurrentSectionName(), "Definition"))
|
||||
{
|
||||
cemuLog_force("{}: [Definition] must be the first section", _utf8Wrapper(rulesPath));
|
||||
return;
|
||||
}
|
||||
|
||||
auto option_version = iniParser.FindOption("version");
|
||||
if (option_version)
|
||||
{
|
||||
sint32 versionNum = -1;
|
||||
auto [ptr, ec] = std::from_chars(option_version->data(), option_version->data() + option_version->size(), versionNum);
|
||||
if (ec != std::errc{})
|
||||
{
|
||||
cemuLog_force("{}: Unable to parse version", _utf8Wrapper(rulesPath));
|
||||
return;
|
||||
}
|
||||
|
||||
if (versionNum > GP_LEGACY_VERSION)
|
||||
{
|
||||
GraphicPack2::LoadGraphicPack(rulesPath.generic_wstring(), iniParser);
|
||||
return;
|
||||
}
|
||||
}
|
||||
cemuLog_force("{}: Outdated graphic pack", _utf8Wrapper(rulesPath));
|
||||
}
|
||||
|
||||
void GraphicPack2::LoadAll()
|
||||
{
|
||||
std::error_code ec;
|
||||
fs::path basePath = ActiveSettings::GetPath("graphicPacks");
|
||||
for (fs::recursive_directory_iterator it(basePath, ec); it != end(it); ++it)
|
||||
{
|
||||
if (!it->is_directory(ec))
|
||||
continue;
|
||||
fs::path gfxPackPath = it->path();
|
||||
if (fs::exists(gfxPackPath / "rules.txt", ec))
|
||||
{
|
||||
LoadGraphicPack(gfxPackPath);
|
||||
it.disable_recursion_pending(); // dont recurse deeper in a gfx pack directory
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool GraphicPack2::LoadGraphicPack(const std::wstring& filename, IniParser& rules)
|
||||
{
|
||||
@ -60,7 +123,6 @@ bool GraphicPack2::LoadGraphicPack(const std::wstring& filename, IniParser& rule
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool GraphicPack2::ActivateGraphicPack(const std::shared_ptr<GraphicPack2>& graphic_pack)
|
||||
@ -94,12 +156,65 @@ bool GraphicPack2::DeactivateGraphicPack(const std::shared_ptr<GraphicPack2>& gr
|
||||
return true;
|
||||
}
|
||||
|
||||
void GraphicPack2::ActivateForCurrentTitle()
|
||||
{
|
||||
uint64 titleId = CafeSystem::GetForegroundTitleId();
|
||||
// activate graphic packs
|
||||
for (const auto& gp : GraphicPack2::GetGraphicPacks())
|
||||
{
|
||||
if (!gp->IsEnabled())
|
||||
continue;
|
||||
|
||||
if (!gp->ContainsTitleId(titleId))
|
||||
continue;
|
||||
|
||||
if (GraphicPack2::ActivateGraphicPack(gp))
|
||||
{
|
||||
if (gp->GetPresets().empty())
|
||||
{
|
||||
forceLog_printf("Activate graphic pack: %s", gp->GetPath().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string logLine;
|
||||
logLine.assign(fmt::format("Activate graphic pack: {} [Presets: ", gp->GetPath()));
|
||||
bool isFirst = true;
|
||||
for (auto& itr : gp->GetPresets())
|
||||
{
|
||||
if (!itr->active)
|
||||
continue;
|
||||
if (isFirst)
|
||||
isFirst = false;
|
||||
else
|
||||
logLine.append(",");
|
||||
logLine.append(itr->name);
|
||||
}
|
||||
logLine.append("]");
|
||||
cemuLog_log(LogType::Force, logLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
s_isReady = true;
|
||||
}
|
||||
|
||||
void GraphicPack2::Reset()
|
||||
{
|
||||
s_active_graphic_packs.clear();
|
||||
s_isReady = false;
|
||||
}
|
||||
|
||||
void GraphicPack2::ClearGraphicPacks()
|
||||
{
|
||||
s_graphic_packs.clear();
|
||||
s_active_graphic_packs.clear();
|
||||
}
|
||||
|
||||
void GraphicPack2::WaitUntilReady()
|
||||
{
|
||||
while (!s_isReady)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||||
}
|
||||
|
||||
GraphicPack2::GraphicPack2(std::wstring filename)
|
||||
: m_filename(std::move(filename))
|
||||
{
|
||||
|
@ -159,18 +159,26 @@ public:
|
||||
LatteTextureView::MagFilter GetDownscalingMagFilter() const { return m_output_settings.downscale_filter; }
|
||||
|
||||
// static methods
|
||||
static void LoadAll();
|
||||
|
||||
static const std::vector<std::shared_ptr<GraphicPack2>>& GetGraphicPacks() { return s_graphic_packs; }
|
||||
static const std::vector<std::shared_ptr<GraphicPack2>>& GetActiveGraphicPacks() { return s_active_graphic_packs; }
|
||||
static void LoadGraphicPack(fs::path graphicPackPath);
|
||||
static bool LoadGraphicPack(const std::wstring& filename, class IniParser& rules);
|
||||
static bool ActivateGraphicPack(const std::shared_ptr<GraphicPack2>& graphic_pack);
|
||||
static bool DeactivateGraphicPack(const std::shared_ptr<GraphicPack2>& graphic_pack);
|
||||
static void ClearGraphicPacks();
|
||||
static void WaitUntilReady(); // wait until all graphic packs finished activation
|
||||
|
||||
static void ActivateForCurrentTitle();
|
||||
static void Reset();
|
||||
private:
|
||||
bool Activate();
|
||||
bool Deactivate();
|
||||
|
||||
static std::vector<std::shared_ptr<GraphicPack2>> s_graphic_packs;
|
||||
static std::vector<std::shared_ptr<GraphicPack2>> s_active_graphic_packs;
|
||||
static std::atomic_bool s_isReady;
|
||||
|
||||
template<typename TType>
|
||||
void FillPresetConstants(TExpressionParser<TType>& parser) const
|
||||
|
@ -5,7 +5,6 @@
|
||||
#include "Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompiler.h"
|
||||
#include "Cafe/HW/Latte/Core/FetchShader.h"
|
||||
#include "Cemu/FileCache/FileCache.h"
|
||||
#include "Cafe/GraphicPack/GraphicPack.h"
|
||||
#include "Cafe/GameProfile/GameProfile.h"
|
||||
#include "gui/guiWrapper.h"
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include "Cafe/HW/Latte/Core/LatteTexture.h"
|
||||
#include "Cafe/HW/Latte/Core/LatteTextureView.h"
|
||||
#include "Cafe/HW/Latte/Core/Latte.h"
|
||||
#include "Cafe/GraphicPack/GraphicPack.h"
|
||||
#include "Cafe/GraphicPack/GraphicPack2.h"
|
||||
|
||||
LatteTextureView::LatteTextureView(LatteTexture* texture, sint32 firstMip, sint32 mipCount, sint32 firstSlice, sint32 sliceCount, Latte::E_DIM dim, Latte::E_GX2SURFFMT format, bool registerView)
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "Cafe/HW/Latte/Core/LatteShader.h"
|
||||
#include "Cafe/HW/Latte/Core/LatteAsyncCommands.h"
|
||||
#include "Cafe/GameProfile/GameProfile.h"
|
||||
#include "Cafe/GraphicPack/GraphicPack2.h"
|
||||
#include "gui/guiWrapper.h"
|
||||
|
||||
#include "Cafe/HW/Latte/Core/LatteBufferCache.h"
|
||||
@ -188,6 +189,8 @@ int Latte_ThreadEntry()
|
||||
|
||||
g_renderer->DrawEmptyFrame(true);
|
||||
|
||||
// before doing anything with game specific shaders, we need to wait for graphic packs to finish loading
|
||||
GraphicPack2::WaitUntilReady();
|
||||
// load/init shader cache file
|
||||
LatteShaderCache_load();
|
||||
|
||||
|
@ -119,11 +119,6 @@ inline bool cemuLog_force(std::string_view msg)
|
||||
return cemuLog_log(LogType::Force, msg);
|
||||
}
|
||||
|
||||
inline bool cemuLog_force(std::u8string_view msg)
|
||||
{
|
||||
return cemuLog_log(LogType::Force, msg);
|
||||
}
|
||||
|
||||
inline bool cemuLog_force(std::wstring_view msg)
|
||||
{
|
||||
return cemuLog_log(LogType::Force, msg);
|
||||
|
@ -92,7 +92,7 @@ void deleteDownloadedGraphicPacks()
|
||||
{
|
||||
const auto path = ActiveSettings::GetPath("graphicPacks/downloadedGraphicPacks");
|
||||
std::error_code er;
|
||||
if (!fs::exists(path))
|
||||
if (!fs::exists(path, er))
|
||||
return;
|
||||
try
|
||||
{
|
||||
|
@ -3,7 +3,6 @@
|
||||
#include "gui/DownloadGraphicPacksWindow.h"
|
||||
#include "Cafe/GraphicPack/GraphicPack2.h"
|
||||
#include "config/CemuConfig.h"
|
||||
#include "Cafe/GraphicPack/GraphicPack.h"
|
||||
|
||||
#include "Cafe/HW/Latte/Core/LatteAsyncCommands.h"
|
||||
|
||||
@ -184,7 +183,7 @@ void GraphicPacksWindow2::ExpandChildren(const std::vector<wxTreeItemId>& ids, s
|
||||
void GraphicPacksWindow2::RefreshGraphicPacks()
|
||||
{
|
||||
GraphicPack2::ClearGraphicPacks();
|
||||
graphicPack_loadAll();
|
||||
GraphicPack2::LoadAll();
|
||||
}
|
||||
|
||||
GraphicPacksWindow2::GraphicPacksWindow2(wxWindow* parent, uint64_t title_id_filter)
|
||||
|
@ -34,7 +34,6 @@
|
||||
#include "gui/TitleManager.h"
|
||||
|
||||
#include "Cafe/CafeSystem.h"
|
||||
#include "Cafe/GraphicPack/GraphicPack.h"
|
||||
#include "Cafe/TitleList/GameInfo.h"
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "Cafe/OS/RPL/rpl_symbol_storage.h"
|
||||
#include "Cafe/OS/libs/gx2/GX2.h"
|
||||
#include "Cafe/GameProfile/GameProfile.h"
|
||||
#include "Cafe/GraphicPack/GraphicPack.h"
|
||||
#include "Cafe/GraphicPack/GraphicPack2.h"
|
||||
#include "config/CemuConfig.h"
|
||||
#include "gui/CemuApp.h"
|
||||
#include "Cafe/HW/Latte/Core/LatteOverlay.h"
|
||||
@ -221,7 +221,7 @@ void mainEmulatorCommonInit()
|
||||
// static initialization
|
||||
IAudioAPI::InitializeStatic();
|
||||
// load graphic packs (must happen before config is loaded)
|
||||
graphicPack_loadAll();
|
||||
GraphicPack2::LoadAll();
|
||||
// initialize file system
|
||||
fsc_init();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user