From 719cde1ddbe4dd20dc2b63d2076b79d6b3b4b2ce Mon Sep 17 00:00:00 2001 From: Allison Cunha Date: Sun, 24 Aug 2025 19:54:35 -0300 Subject: [PATCH] temp fix for ng ragebound stage 4-1 problem --- src/video_core/engines/maxwell_3d.h | 29 +++++++++++++++++-- .../renderer_opengl/gl_rasterizer.cpp | 17 +++++++---- .../renderer_vulkan/vk_rasterizer.cpp | 13 ++++++++- 3 files changed, 51 insertions(+), 8 deletions(-) diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 6b4f1c570e..67b8a1158f 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -1,5 +1,5 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later #pragma once @@ -3131,6 +3131,31 @@ public: void ProcessCBData(u32 value); void ProcessCBMultiData(const u32* start_base, u32 amount); + //TEMP: skips problematic lighting blend detected in ninja gaiden ragebound + //TODO: fix blending properly. clue is FCSM_TR (src\shader_recompiler\frontend\ir\ir_emitter.cpp) + enum class UnimplementedBlendID : u32 { + NGR_00 = 0 + }; + inline static bool IsUnimplementedBlend(const Maxwell3D::Regs& _regs, UnimplementedBlendID id) { + using Blend = Maxwell3D::Regs::Blend; + bool result = true; + auto eq = [](u32 v, u32 a, u32 b) { return v == a || v == b; }; + if (id == UnimplementedBlendID::NGR_00) { + result &= !_regs.blend_per_target_enabled; + result &= _regs.blend.enable[0]; + result &= eq(static_cast(_regs.blend.color_source), static_cast(Blend::Factor::One_D3D), static_cast(Blend::Factor::One_GL)); + result &= eq(static_cast(_regs.blend.color_dest), static_cast(Blend::Factor::Zero_D3D), static_cast(Blend::Factor::Zero_GL)); + result &= eq(static_cast(_regs.blend.alpha_source), static_cast(Blend::Factor::One_D3D), static_cast(Blend::Factor::One_GL)); + result &= eq(static_cast(_regs.blend.alpha_dest), static_cast(Blend::Factor::OneMinusSourceAlpha_D3D), static_cast(Blend::Factor::OneMinusSourceAlpha_GL)); + result &= eq(static_cast(_regs.blend.color_op), static_cast(Blend::Equation::Add_D3D), static_cast(Blend::Equation::Add_GL)); + result &= eq(static_cast(_regs.blend.alpha_op), static_cast(Blend::Equation::Add_D3D), static_cast(Blend::Equation::Add_GL)); + result &= _regs.iterated_blend.enable; + result &= (_regs.iterated_blend.pass_count > 0); + return result; + } + return false; + } + private: void InitializeRegisterDefaults(); diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 2ea42abf4b..4114046f38 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -1143,12 +1143,19 @@ void RasterizerOpenGL::SyncBlendState() { return; } glEnable(GL_BLEND); - glBlendFuncSeparate(MaxwellToGL::BlendFunc(regs.blend.color_source), - MaxwellToGL::BlendFunc(regs.blend.color_dest), - MaxwellToGL::BlendFunc(regs.blend.alpha_source), - MaxwellToGL::BlendFunc(regs.blend.alpha_dest)); - glBlendEquationSeparate(MaxwellToGL::BlendEquation(regs.blend.color_op), + //TEMP: skips problematic lighting blend detected in ninja gaiden ragebound + //TODO: fix blending properly. clue is FCSM_TR (src\shader_recompiler\frontend\ir\ir_emitter.cpp) + if (Tegra::Engines::Maxwell3D::IsUnimplementedBlend(regs, Tegra::Engines::Maxwell3D::UnimplementedBlendID::NGR_00)) { + glBlendFuncSeparate(GL_ONE, GL_ONE, GL_ONE_MINUS_SRC_COLOR, GL_ZERO); + glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD); + } else { + glBlendFuncSeparate(MaxwellToGL::BlendFunc(regs.blend.color_source), + MaxwellToGL::BlendFunc(regs.blend.color_dest), + MaxwellToGL::BlendFunc(regs.blend.alpha_source), + MaxwellToGL::BlendFunc(regs.blend.alpha_dest)); + glBlendEquationSeparate(MaxwellToGL::BlendEquation(regs.blend.color_op), MaxwellToGL::BlendEquation(regs.blend.alpha_op)); + } return; } diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 2d12fc658f..929330ea2b 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -1550,7 +1550,18 @@ void RasterizerVulkan::UpdateBlending(Tegra::Engines::Maxwell3D::Regs& regs) { host_blend.alphaBlendOp = MaxwellToVK::BlendEquation(guest_blend.alpha_op); }; if (!regs.blend_per_target_enabled) { - blend_setup(regs.blend); + //TEMP: skips problematic lighting blend detected in ninja gaiden ragebound + //TODO: fix blending properly. clue is FCSM_TR (src\shader_recompiler\frontend\ir\ir_emitter.cpp) + if (Tegra::Engines::Maxwell3D::IsUnimplementedBlend(regs, Tegra::Engines::Maxwell3D::UnimplementedBlendID::NGR_00)) { + setup_blends[index].srcColorBlendFactor = VK_BLEND_FACTOR_ONE; + setup_blends[index].dstColorBlendFactor = VK_BLEND_FACTOR_ONE; + setup_blends[index].colorBlendOp = VK_BLEND_OP_ADD; + setup_blends[index].srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR; + setup_blends[index].dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; + setup_blends[index].alphaBlendOp = VK_BLEND_OP_ADD; + } else { + blend_setup(regs.blend); + } continue; } blend_setup(regs.blend_per_target[index]);