diff --git a/Source/Core/Core/Config/GraphicsSettings.cpp b/Source/Core/Core/Config/GraphicsSettings.cpp index 30ed2d69595c..83baf5ae05db 100644 --- a/Source/Core/Core/Config/GraphicsSettings.cpp +++ b/Source/Core/Core/Config/GraphicsSettings.cpp @@ -91,6 +91,8 @@ const ConfigInfo GFX_SHADER_COMPILER_THREADS{ {System::GFX, "Settings", "ShaderCompilerThreads"}, 1}; const ConfigInfo GFX_SHADER_PRECOMPILER_THREADS{ {System::GFX, "Settings", "ShaderPrecompilerThreads"}, 1}; +const ConfigInfo GFX_SAVE_TEXTURE_CACHE_TO_STATE{ + {System::GFX, "Settings", "SaveTextureCacheToState"}, true}; const ConfigInfo GFX_SW_ZCOMPLOC{{System::GFX, "Settings", "SWZComploc"}, true}; const ConfigInfo GFX_SW_ZFREEZE{{System::GFX, "Settings", "SWZFreeze"}, true}; diff --git a/Source/Core/Core/Config/GraphicsSettings.h b/Source/Core/Core/Config/GraphicsSettings.h index 1946e704fcc2..dc8d501fab21 100644 --- a/Source/Core/Core/Config/GraphicsSettings.h +++ b/Source/Core/Core/Config/GraphicsSettings.h @@ -67,6 +67,7 @@ extern const ConfigInfo GFX_WAIT_FOR_SHADERS_BEFORE_STARTING; extern const ConfigInfo GFX_SHADER_COMPILATION_MODE; extern const ConfigInfo GFX_SHADER_COMPILER_THREADS; extern const ConfigInfo GFX_SHADER_PRECOMPILER_THREADS; +extern const ConfigInfo GFX_SAVE_TEXTURE_CACHE_TO_STATE; extern const ConfigInfo GFX_SW_ZCOMPLOC; extern const ConfigInfo GFX_SW_ZFREEZE; diff --git a/Source/Core/Core/ConfigLoaders/IsSettingSaveable.cpp b/Source/Core/Core/ConfigLoaders/IsSettingSaveable.cpp index b60693000b71..15711a65b82c 100644 --- a/Source/Core/Core/ConfigLoaders/IsSettingSaveable.cpp +++ b/Source/Core/Core/ConfigLoaders/IsSettingSaveable.cpp @@ -90,6 +90,7 @@ bool IsSettingSaveable(const Config::ConfigLocation& config_location) Config::GFX_SHADER_COMPILATION_MODE.location, Config::GFX_SHADER_COMPILER_THREADS.location, Config::GFX_SHADER_PRECOMPILER_THREADS.location, + Config::GFX_SAVE_TEXTURE_CACHE_TO_STATE.location, Config::GFX_SW_ZCOMPLOC.location, Config::GFX_SW_ZFREEZE.location, diff --git a/Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp b/Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp index 319b7eb3099c..a615f6089609 100644 --- a/Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp +++ b/Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp @@ -100,10 +100,13 @@ void HacksWidget::CreateWidgets() m_disable_bounding_box = new GraphicsBool(tr("Disable Bounding Box"), Config::GFX_HACK_BBOX_ENABLE, true); m_vertex_rounding = new GraphicsBool(tr("Vertex Rounding"), Config::GFX_HACK_VERTEX_ROUDING); + m_save_texture_cache_state = + new GraphicsBool(tr("Save Texture Cache to State"), Config::GFX_SAVE_TEXTURE_CACHE_TO_STATE); other_layout->addWidget(m_fast_depth_calculation, 0, 0); other_layout->addWidget(m_disable_bounding_box, 0, 1); other_layout->addWidget(m_vertex_rounding, 1, 0); + other_layout->addWidget(m_save_texture_cache_state, 1, 1); main_layout->addWidget(efb_box); main_layout->addWidget(texture_cache_box); @@ -244,6 +247,10 @@ void HacksWidget::AddDescriptions() static const char TR_DISABLE_BOUNDINGBOX_DESCRIPTION[] = QT_TR_NOOP("Disables bounding box emulation.\n\nThis may improve GPU performance " "significantly, but some games will break.\n\nIf unsure, leave this checked."); + static const char TR_SAVE_TEXTURE_CACHE_TO_STATE_DESCRIPTION[] = QT_TR_NOOP( + "Includes the contents of the embedded frame buffer (EFB) and upscaled EFB copies " + "in save states. Fixes missing and/or non-upscaled textures/objects when loading " + "states at the cost of additional save/load time.\n\nIf unsure, leave this checked."); static const char TR_VERTEX_ROUNDING_DESCRIPTION[] = QT_TR_NOOP("Rounds 2D vertices to whole pixels.\n\nFixes graphical problems in some games at " "higher internal resolutions. This setting has no effect when native internal " @@ -259,6 +266,7 @@ void HacksWidget::AddDescriptions() AddDescription(m_gpu_texture_decoding, TR_GPU_DECODING_DESCRIPTION); AddDescription(m_fast_depth_calculation, TR_FAST_DEPTH_CALC_DESCRIPTION); AddDescription(m_disable_bounding_box, TR_DISABLE_BOUNDINGBOX_DESCRIPTION); + AddDescription(m_save_texture_cache_state, TR_SAVE_TEXTURE_CACHE_TO_STATE_DESCRIPTION); AddDescription(m_vertex_rounding, TR_VERTEX_ROUNDING_DESCRIPTION); } diff --git a/Source/Core/DolphinQt/Config/Graphics/HacksWidget.h b/Source/Core/DolphinQt/Config/Graphics/HacksWidget.h index 47de3c0287c9..d46cb6793295 100644 --- a/Source/Core/DolphinQt/Config/Graphics/HacksWidget.h +++ b/Source/Core/DolphinQt/Config/Graphics/HacksWidget.h @@ -42,6 +42,7 @@ class HacksWidget final : public GraphicsWidget QCheckBox* m_fast_depth_calculation; QCheckBox* m_disable_bounding_box; QCheckBox* m_vertex_rounding; + QCheckBox* m_save_texture_cache_state; QCheckBox* m_defer_efb_copies; void CreateWidgets(); diff --git a/Source/Core/VideoCommon/FramebufferManager.cpp b/Source/Core/VideoCommon/FramebufferManager.cpp index e28cf0b5cce0..f61ebcf4a97b 100644 --- a/Source/Core/VideoCommon/FramebufferManager.cpp +++ b/Source/Core/VideoCommon/FramebufferManager.cpp @@ -10,6 +10,7 @@ #include "Common/ChunkFile.h" #include "Common/Logging/Log.h" #include "Common/MsgHandler.h" +#include "Core/Config/GraphicsSettings.h" #include "VideoCommon/AbstractFramebuffer.h" #include "VideoCommon/AbstractPipeline.h" #include "VideoCommon/AbstractShader.h" @@ -862,6 +863,11 @@ void FramebufferManager::DoState(PointerWrap& p) { FlushEFBPokes(); + bool save_efb_state = Config::Get(Config::GFX_SAVE_TEXTURE_CACHE_TO_STATE); + p.Do(save_efb_state); + if (!save_efb_state) + return; + if (p.GetMode() == PointerWrap::MODE_WRITE || p.GetMode() == PointerWrap::MODE_MEASURE) DoSaveState(p); else diff --git a/Source/Core/VideoCommon/TextureCacheBase.cpp b/Source/Core/VideoCommon/TextureCacheBase.cpp index 974b121c562c..2f330bb2bcc9 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/TextureCacheBase.cpp @@ -24,6 +24,7 @@ #include "Common/MemoryUtil.h" #include "Common/StringUtil.h" +#include "Core/Config/GraphicsSettings.h" #include "Core/ConfigManager.h" #include "Core/FifoPlayer/FifoPlayer.h" #include "Core/FifoPlayer/FifoRecorder.h" @@ -469,7 +470,7 @@ std::optional TextureCacheBase::DeserializeTextu std::vector texture_data; p.Do(texture_data); - if (p.GetMode() != PointerWrap::MODE_READ) + if (p.GetMode() != PointerWrap::MODE_READ || texture_data.empty()) return std::nullopt; auto tex = AllocateTexture(config); @@ -546,20 +547,23 @@ void TextureCacheBase::DoSaveState(PointerWrap& p) // of address/hash to entry ID. std::vector> textures_by_address_list; std::vector> textures_by_hash_list; - for (const auto& it : textures_by_address) + if (Config::Get(Config::GFX_SAVE_TEXTURE_CACHE_TO_STATE)) { - if (ShouldSaveEntry(it.second)) + for (const auto& it : textures_by_address) { - u32 id = AddCacheEntryToMap(it.second); - textures_by_address_list.push_back(std::make_pair(it.first, id)); + if (ShouldSaveEntry(it.second)) + { + u32 id = AddCacheEntryToMap(it.second); + textures_by_address_list.push_back(std::make_pair(it.first, id)); + } } - } - for (const auto& it : textures_by_hash) - { - if (ShouldSaveEntry(it.second)) + for (const auto& it : textures_by_hash) { - u32 id = AddCacheEntryToMap(it.second); - textures_by_hash_list.push_back(std::make_pair(it.first, id)); + if (ShouldSaveEntry(it.second)) + { + u32 id = AddCacheEntryToMap(it.second); + textures_by_hash_list.push_back(std::make_pair(it.first, id)); + } } }