diff --git a/src/common/settings.h b/src/common/settings.h index 7ea4136576..dd3cd14a02 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -557,9 +557,6 @@ struct Values { SwitchableSetting fix_bloom_effects{linkage, false, "fix_bloom_effects", Category::RendererHacks}; - SwitchableSetting rescale_hack{linkage, false, "rescale_hack", - Category::RendererHacks}; - SwitchableSetting 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 f49c43ee2a..9d33fa6979 100644 --- a/src/qt_common/config/shared_translation.cpp +++ b/src/qt_common/config/shared_translation.cpp @@ -356,12 +356,6 @@ std::unique_ptr 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 line artifacts on AMD and Intel GPUs, and grey texture flicker on Nvidia GPUs 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 f156192c13..c89c918d61 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& inst_pool, ObjectPoolGetOpcode() == IR::Opcode::GetAttribute) { const IR::Attribute attr{bitcast_inst->Arg(0).Attribute()}; - switch (attr) { - case IR::Attribute::PositionX: - case IR::Attribute::PositionY: + if (attr >= IR::Attribute::PositionX && attr <= IR::Attribute::PositionW) { bitcast_inst->SetFlags(0xDEADBEEF); must_patch_outside = true; - break; - default: - break; } } if (must_patch_outside) { const auto it{IR::Block::InstructionList::s_iterator_to(inst)}; IR::IREmitter ir{block, it}; - if (Settings::values.rescale_hack.GetValue()) { + + if (needs_hack) { 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)}; @@ -347,12 +343,44 @@ void Visit(const IR::Program& program, IR::Block& block, IR::Inst& inst) { } } // Anonymous namespace +bool FragmentShaderNeedsRescalingPass(const IR::Program& program) { + if (program.stage != Stage::Fragment) return false; + + for (const IR::Block* block : program.post_order_blocks) { + for (const IR::Inst& inst : block->Instructions()) { + const auto op = inst.GetOpcode(); + if (op != IR::Opcode::ShuffleIndex && op != IR::Opcode::ShuffleUp && + op != IR::Opcode::ShuffleDown && op != IR::Opcode::ShuffleButterfly) { + continue; + } + + if (inst.Arg(0).IsImmediate()) continue; + const IR::Inst* arg_inst = inst.Arg(0).InstRecursive(); + + if (arg_inst->GetOpcode() != IR::Opcode::BitCastU32F32 || arg_inst->Arg(0).IsImmediate()) continue; + const IR::Inst* bitcast_inst = arg_inst->Arg(0).InstRecursive(); + + if (bitcast_inst->GetOpcode() == IR::Opcode::GetAttribute) { + const auto attr = bitcast_inst->Arg(0).Attribute(); + if (attr >= IR::Attribute::PositionX && attr <= IR::Attribute::PositionW) { + return true; + } + } + } + } + return false; +} + void RescalingPass(IR::Program& program) { const bool is_fragment_shader{program.stage == Stage::Fragment}; + const bool needs_hack{FragmentShaderNeedsRescalingPass(program)}; + if (needs_hack) { + LOG_WARNING(Shader, "F32/U32 bitcast detected. Applying rescaling workaround."); + } if (is_fragment_shader) { for (IR::Block* const block : program.post_order_blocks) { for (IR::Inst& inst : block->Instructions()) { - VisitMark(*block, inst); + VisitMark(*block, inst, needs_hack); } } }