diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 041abf5735..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 @@ -59,31 +59,6 @@ public: /// Binds a rasterizer to this engine. void BindRasterizer(VideoCore::RasterizerInterface* rasterizer); - //TEMP: skips problematic lighting blend detected in ninja gaiden ragebound - //TODO: fix blending properly. seek (iterated_blend, FCSM_TR) - 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; - } - /// Register structure of the Maxwell3D engine. struct Regs { static constexpr std::size_t NUM_REGS = 0xE00; @@ -3156,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 df4e85bae9..4114046f38 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -1143,6 +1143,8 @@ void RasterizerOpenGL::SyncBlendState() { return; } glEnable(GL_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)) { glBlendFuncSeparate(GL_ONE, GL_ONE, GL_ONE_MINUS_SRC_COLOR, GL_ZERO); glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD); @@ -1153,6 +1155,7 @@ void RasterizerOpenGL::SyncBlendState() { 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 a7fd5e5940..929330ea2b 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -1550,6 +1550,8 @@ void RasterizerVulkan::UpdateBlending(Tegra::Engines::Maxwell3D::Regs& regs) { host_blend.alphaBlendOp = MaxwellToVK::BlendEquation(guest_blend.alpha_op); }; if (!regs.blend_per_target_enabled) { + //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;