Browse Source

[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>
master
MaranBr 2 days ago
committed by crueter
parent
commit
67bada77f8
No known key found for this signature in database GPG Key ID: 425ACD2D4830EBC6
  1. 3
      src/common/settings.h
  2. 6
      src/qt_common/config/shared_translation.cpp
  3. 2
      src/shader_recompiler/frontend/maxwell/translate_program.cpp
  4. 4
      src/shader_recompiler/ir_opt/passes.h
  5. 17
      src/shader_recompiler/ir_opt/rescaling_pass.cpp
  6. 43
      src/shader_recompiler/ir_opt/vendor_workaround_pass.cpp
  7. 6
      src/video_core/renderer_vulkan/vk_pipeline_cache.cpp

3
src/common/settings.h

@ -657,9 +657,6 @@ struct Values {
SwitchableSetting<bool> emulate_bgr565{linkage, false, "emulate_bgr565", SwitchableSetting<bool> emulate_bgr565{linkage, false, "emulate_bgr565",
Category::RendererHacks}; Category::RendererHacks};
SwitchableSetting<bool> rescale_hack{linkage, false, "rescale_hack",
Category::RendererHacks};
SwitchableSetting<bool> use_asynchronous_shaders{linkage, false, "use_asynchronous_shaders", SwitchableSetting<bool> use_asynchronous_shaders{linkage, false, "use_asynchronous_shaders",
Category::RendererHacks}; Category::RendererHacks};

6
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.")); "quality and performance consistency in some games."));
INSERT(Settings, fix_bloom_effects, tr("Fix bloom effects"), tr("Removes bloom in Burnout.")); 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) // Renderer (Extensions)
INSERT(Settings, dyna_state, tr("Extended Dynamic State"), INSERT(Settings, dyna_state, tr("Extended Dynamic State"),
tr("Controls the number of features that can be used in Extended Dynamic State.\n" tr("Controls the number of features that can be used in Extended Dynamic State.\n"

2
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::GlobalMemoryToStorageBufferPass(program, normalized_host_info);
Optimization::TexturePass(env, 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::RescalingPass(program);
} }
Optimization::DeadCodeEliminationPass(program); Optimization::DeadCodeEliminationPass(program);

4
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-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // 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 LayerPass(IR::Program& program, const HostTranslateInfo& host_info);
void VendorWorkaroundPass(IR::Program& program); void VendorWorkaroundPass(IR::Program& program);
void VerificationPass(const IR::Program& program); void VerificationPass(const IR::Program& program);
bool HasBrokenPattern(const IR::Program& program);
// Dual Vertex // Dual Vertex
void VertexATransformPass(IR::Program& program); void VertexATransformPass(IR::Program& program);

17
src/shader_recompiler/ir_opt/rescaling_pass.cpp

@ -67,18 +67,11 @@ void VisitMark(IR::Block& block, IR::Inst& inst) {
if (must_patch_outside) { if (must_patch_outside) {
const auto it{IR::Block::InstructionList::s_iterator_to(inst)}; const auto it{IR::Block::InstructionList::s_iterator_to(inst)};
IR::IREmitter ir{block, it}; 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; break;
} }

43
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-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // 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 } // namespace Shader::Optimization

6
src/video_core/renderer_vulkan/vk_pipeline_cache.cpp

@ -23,6 +23,7 @@
#include "shader_recompiler/environment.h" #include "shader_recompiler/environment.h"
#include "shader_recompiler/frontend/maxwell/control_flow.h" #include "shader_recompiler/frontend/maxwell/control_flow.h"
#include "shader_recompiler/frontend/maxwell/translate_program.h" #include "shader_recompiler/frontend/maxwell/translate_program.h"
#include "shader_recompiler/ir_opt/passes.h"
#include "shader_recompiler/program_header.h" #include "shader_recompiler/program_header.h"
#include "video_core/engines/kepler_compute.h" #include "video_core/engines/kepler_compute.h"
#include "video_core/engines/maxwell_3d.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); 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) { if (Settings::values.dump_guest_shaders) {
env.Dump(hash, key.unique_hashes[index]); env.Dump(hash, key.unique_hashes[index]);
} }

Loading…
Cancel
Save