aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn <john@eden-emu.dev>2026-02-26 03:57:25 +0100
committercrueter <crueter@eden-emu.dev>2026-02-26 03:57:25 +0100
commit0d950195e9cfbd89a3fb69e784437f3cc5c3e88e (patch)
treead82d2be09311172ccba42847ca529527e5f2544 /src
parent04e88ab82cd92c449e04d7a6114f607ca0289294 (diff)
[Settings] Add "Enable Legacy Rescale Pass" Toggle (#3582)
This PR introduces an optional Legacy Rescale Compatibility Mode that restores the previous rescale‑pass behavior for titles that rely on its quirks. While the new rescale logic is generally more correct, some games exhibit visual issues that the legacy behavior incidentally avoids. Enabling this mode can mitigate line artifacts on AMD GPUs and reduce grey‑texture flickering on Nvidia GPUs in Luigi’s Mansion 3. This is a compatibility workaround rather than a full fix, and should only be used for titles affected by these rare edge‑case rendering problems. Original Logic from MaranBR Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3582 Co-authored-by: John <john@eden-emu.dev> Co-committed-by: John <john@eden-emu.dev>
Diffstat (limited to 'src')
-rw-r--r--src/common/settings.h3
-rw-r--r--src/qt_common/config/shared_translation.cpp6
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate_program.cpp2
-rw-r--r--src/shader_recompiler/ir_opt/rescaling_pass.cpp17
4 files changed, 22 insertions, 6 deletions
diff --git a/src/common/settings.h b/src/common/settings.h
index dd3cd14a02..7ea4136576 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -557,6 +557,9 @@ struct Values {
SwitchableSetting<bool> fix_bloom_effects{linkage, false, "fix_bloom_effects",
Category::RendererHacks};
+ SwitchableSetting<bool> rescale_hack{linkage, false, "rescale_hack",
+ Category::RendererHacks};
+
SwitchableSetting<bool> use_asynchronous_shaders{linkage, false, "use_asynchronous_shaders",
Category::RendererHacks};
diff --git a/src/qt_common/config/shared_translation.cpp b/src/qt_common/config/shared_translation.cpp
index 9d33fa6979..5f3a6c18c0 100644
--- a/src/qt_common/config/shared_translation.cpp
+++ b/src/qt_common/config/shared_translation.cpp
@@ -356,6 +356,12 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QObject* parent)
tr("Fix bloom effects"),
tr("Removes bloom in Burnout."));
+ INSERT(Settings,
+ rescale_hack,
+ tr("Enable Legacy Rescale Pass"),
+ tr("May fix rescale issues in some games by relying on behavior from the previous implementation.\n"
+ "Legacy behavior workaround that fixes AMD GPU line artifacts and Nvidia GPU grey texture flicker in Luigis Mansion 3."));
+
// Renderer (Extensions)
INSERT(Settings, dyna_state, tr("Extended Dynamic State"),
tr("Controls the number of features that can be used in Extended Dynamic State.\n"
diff --git a/src/shader_recompiler/frontend/maxwell/translate_program.cpp b/src/shader_recompiler/frontend/maxwell/translate_program.cpp
index 81aee6453a..f156192c13 100644
--- a/src/shader_recompiler/frontend/maxwell/translate_program.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate_program.cpp
@@ -304,7 +304,7 @@ IR::Program TranslateProgram(ObjectPool<IR::Inst>& inst_pool, ObjectPool<IR::Blo
Optimization::GlobalMemoryToStorageBufferPass(program, host_info);
Optimization::TexturePass(env, program, host_info);
- if (Settings::values.resolution_info.active) {
+ if (Settings::values.resolution_info.active || Settings::values.rescale_hack.GetValue()) {
Optimization::RescalingPass(program);
}
Optimization::DeadCodeEliminationPass(program);
diff --git a/src/shader_recompiler/ir_opt/rescaling_pass.cpp b/src/shader_recompiler/ir_opt/rescaling_pass.cpp
index cae8110a26..1e639096a8 100644
--- a/src/shader_recompiler/ir_opt/rescaling_pass.cpp
+++ b/src/shader_recompiler/ir_opt/rescaling_pass.cpp
@@ -67,11 +67,18 @@ void VisitMark(IR::Block& block, IR::Inst& inst) {
if (must_patch_outside) {
const auto it{IR::Block::InstructionList::s_iterator_to(inst)};
IR::IREmitter ir{block, it};
- IR::Inst* const new_inst{&*block.PrependNewInst(it, inst)};
- const IR::F32 new_bitcast{ir.ConvertUToF(32, 32, IR::Value{new_inst})};
- const IR::F32 up_factor{ir.FPRecip(ir.ResolutionDownFactor())};
- const IR::Value converted{ir.FPMul(new_bitcast, up_factor)};
- inst.ReplaceUsesWith(converted);
+ if (Settings::values.rescale_hack.GetValue()) {
+ const IR::F32 new_inst{&*block.PrependNewInst(it, inst)};
+ const IR::F32 up_factor{ir.FPRecip(ir.ResolutionDownFactor())};
+ const IR::Value converted{ir.FPMul(new_inst, up_factor)};
+ inst.ReplaceUsesWith(converted);
+ } else {
+ IR::Inst* const new_inst{&*block.PrependNewInst(it, inst)};
+ const IR::F32 new_bitcast{ir.ConvertUToF(32, 32, IR::Value{new_inst})};
+ const IR::F32 up_factor{ir.FPRecip(ir.ResolutionDownFactor())};
+ const IR::Value converted{ir.FPMul(new_bitcast, up_factor)};
+ inst.ReplaceUsesWith(converted);
+ }
}
break;
}