diff options
| author | John <john@eden-emu.dev> | 2026-02-26 03:57:25 +0100 |
|---|---|---|
| committer | crueter <crueter@eden-emu.dev> | 2026-02-26 03:57:25 +0100 |
| commit | 0d950195e9cfbd89a3fb69e784437f3cc5c3e88e (patch) | |
| tree | ad82d2be09311172ccba42847ca529527e5f2544 /src | |
| parent | 04e88ab82cd92c449e04d7a6114f607ca0289294 (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.h | 3 | ||||
| -rw-r--r-- | src/qt_common/config/shared_translation.cpp | 6 | ||||
| -rw-r--r-- | src/shader_recompiler/frontend/maxwell/translate_program.cpp | 2 | ||||
| -rw-r--r-- | src/shader_recompiler/ir_opt/rescaling_pass.cpp | 17 |
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; } |
