diff options
| author | MaranBr <maranbr@outlook.com> | 2026-10-08 23:11:34 +0200 |
|---|---|---|
| committer | crueter <crueter@eden-emu.dev> | 2026-10-08 23:11:34 +0200 |
| commit | 67bada77f8a43a90da2e94e89b8e7da73c256989 (patch) | |
| tree | bd04c6708c272cdcf21f853f265d8f47117d98c4 | |
| parent | 3cdd2ce141224079ce1dc8bfb4be7edc113aca02 (diff) | |
[video_core] Skip fragment shaders with known issues on non-NVIDIA drivers (#4503)
- [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions).
- [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md)
- [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability.
-------------------
Skip fragment shaders using a pattern that is not supported by non-NVIDIA drivers.
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4503
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
| -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/passes.h | 4 | ||||
| -rw-r--r-- | src/shader_recompiler/ir_opt/rescaling_pass.cpp | 17 | ||||
| -rw-r--r-- | src/shader_recompiler/ir_opt/vendor_workaround_pass.cpp | 43 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | 6 |
7 files changed, 59 insertions, 22 deletions
diff --git a/src/common/settings.h b/src/common/settings.h index 0eee48b55d..2a4bf3e9e4 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -657,9 +657,6 @@ struct Values { SwitchableSetting<bool> emulate_bgr565{linkage, false, "emulate_bgr565", 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 0fe2366dfc..964a4cdad4 100644 --- a/src/qt_common/config/shared_translation.cpp +++ b/src/qt_common/config/shared_translation.cpp @@ -279,12 +279,6 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QObject* parent) { "quality and performance consistency in some games.")); INSERT(Settings, fix_bloom_effects, 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 ebc5a825dd..1b2ec5502d 100644 --- a/src/shader_recompiler/frontend/maxwell/translate_program.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate_program.cpp @@ -301,7 +301,7 @@ IR::Program TranslateProgram(ObjectPool<IR::Inst>& inst_pool, ObjectPool<IR::Blo Optimization::GlobalMemoryToStorageBufferPass(program, normalized_host_info); Optimization::TexturePass(env, program, normalized_host_info); - if (Settings::values.resolution_info.active || Settings::values.rescale_hack.GetValue()) { + if (Settings::values.resolution_info.active) { Optimization::RescalingPass(program); } Optimization::DeadCodeEliminationPass(program); diff --git a/src/shader_recompiler/ir_opt/passes.h b/src/shader_recompiler/ir_opt/passes.h index 1e637cb23c..068d7fdfe8 100644 --- a/src/shader_recompiler/ir_opt/passes.h +++ b/src/shader_recompiler/ir_opt/passes.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -28,6 +31,7 @@ void TexturePass(Environment& env, IR::Program& program, const HostTranslateInfo void LayerPass(IR::Program& program, const HostTranslateInfo& host_info); void VendorWorkaroundPass(IR::Program& program); void VerificationPass(const IR::Program& program); +bool HasBrokenPattern(const IR::Program& program); // Dual Vertex void VertexATransformPass(IR::Program& program); diff --git a/src/shader_recompiler/ir_opt/rescaling_pass.cpp b/src/shader_recompiler/ir_opt/rescaling_pass.cpp index 1e639096a8..cae8110a26 100644 --- a/src/shader_recompiler/ir_opt/rescaling_pass.cpp +++ b/src/shader_recompiler/ir_opt/rescaling_pass.cpp @@ -67,18 +67,11 @@ 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}; - 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); - } + 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; } diff --git a/src/shader_recompiler/ir_opt/vendor_workaround_pass.cpp b/src/shader_recompiler/ir_opt/vendor_workaround_pass.cpp index 08c658cb81..5842f6135b 100644 --- a/src/shader_recompiler/ir_opt/vendor_workaround_pass.cpp +++ b/src/shader_recompiler/ir_opt/vendor_workaround_pass.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -76,4 +79,44 @@ void VendorWorkaroundPass(IR::Program& program) { } } +bool HasBrokenPattern(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()) { + switch (inst.GetOpcode()) { + case IR::Opcode::ShuffleIndex: + case IR::Opcode::ShuffleUp: + case IR::Opcode::ShuffleDown: + case IR::Opcode::ShuffleButterfly: + break; + default: + continue; + } + const IR::Value shuffle_arg{inst.Arg(0)}; + if (shuffle_arg.IsImmediate()) { + continue; + } + const IR::Inst* bitcast{shuffle_arg.InstRecursive()}; + if (!bitcast || bitcast->GetOpcode() != IR::Opcode::BitCastU32F32) { + continue; + } + const IR::Value bitcast_arg{bitcast->Arg(0)}; + if (bitcast_arg.IsImmediate()) { + continue; + } + const IR::Inst* attribute{bitcast_arg.InstRecursive()}; + if (!attribute || attribute->GetOpcode() != IR::Opcode::GetAttribute) { + continue; + } + const IR::Attribute attr{attribute->Arg(0).Attribute()}; + if (attr == IR::Attribute::PositionX || attr == IR::Attribute::PositionY) { + return true; + } + } + } + return false; +} + } // namespace Shader::Optimization diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 642b9fa223..5e057dd4cf 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -23,6 +23,7 @@ #include "shader_recompiler/environment.h" #include "shader_recompiler/frontend/maxwell/control_flow.h" #include "shader_recompiler/frontend/maxwell/translate_program.h" +#include "shader_recompiler/ir_opt/passes.h" #include "shader_recompiler/program_header.h" #include "video_core/engines/kepler_compute.h" #include "video_core/engines/maxwell_3d.h" @@ -826,6 +827,11 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline( programs[index] = MergeDualVertexPrograms(program_va, program_vb, env); } + if (device.GetDriverID() != VK_DRIVER_ID_NVIDIA_PROPRIETARY && Shader::Optimization::HasBrokenPattern(programs[index])) { + LOG_WARNING(Render_Vulkan, "0x{:016x}: Skipping shader with known issues", key.unique_hashes[index]); + return nullptr; + } + if (Settings::values.dump_guest_shaders) { env.Dump(hash, key.unique_hashes[index]); } |
