From 08ac410558a0d21c0e084d7a9b65a29f4b8fa6bb Mon Sep 17 00:00:00 2001 From: JPikachu Date: Tue, 8 Apr 2025 18:17:28 +0100 Subject: [PATCH] Implement LogicOP Workaround for Vulkan on AMD GPUs This fixes black sewers in Paper Mario: TTYD Credit: Antique - [Sudachi] Dev (https://sudachi.emuplace.app/) --- .../renderer_opengl/gl_rasterizer.cpp | 19 ++++++++++++++- .../renderer_vulkan/vk_rasterizer.cpp | 23 ++++++++++++++++++- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index d376d86d85..19f586518f 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -1204,7 +1204,24 @@ void RasterizerOpenGL::SyncLogicOpState() { } flags[Dirty::LogicOp] = false; - const auto& regs = maxwell3d->regs; + auto& regs = maxwell3d->regs; + + if (device.IsAmd()) { + using namespace Tegra::Engines; + struct In { + const Maxwell3D::Regs::VertexAttribute::Type d; + In(Maxwell3D::Regs::VertexAttribute::Type n) : d(n) {} + bool operator()(Maxwell3D::Regs::VertexAttribute n) const { + return n.type == d; + } + }; + + bool has_float = + std::any_of(regs.vertex_attrib_format.begin(), regs.vertex_attrib_format.end(), + In(Maxwell3D::Regs::VertexAttribute::Type::Float)); + regs.logic_op.enable = static_cast(!has_float); + } + if (regs.logic_op.enable) { glEnable(GL_COLOR_LOGIC_OP); glLogicOp(MaxwellToGL::LogicOp(regs.logic_op.op)); diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 8ba50a8344..d0cff37f61 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -952,7 +952,28 @@ void RasterizerVulkan::UpdateDynamicStates() { UpdateDepthBiasEnable(regs); } if (device.IsExtExtendedDynamicState3EnablesSupported()) { - UpdateLogicOpEnable(regs); + using namespace Tegra::Engines; + + if (device.GetDriverID() == VkDriverIdKHR::VK_DRIVER_ID_AMD_OPEN_SOURCE + || device.GetDriverID() == VkDriverIdKHR::VK_DRIVER_ID_AMD_PROPRIETARY) { + struct In { + const Maxwell3D::Regs::VertexAttribute::Type d; + In(Maxwell3D::Regs::VertexAttribute::Type n) : d(n) {} + bool operator()(Maxwell3D::Regs::VertexAttribute n) const { + return n.type == d; + } + }; + + auto has_float = std::any_of( + regs.vertex_attrib_format.begin(), regs.vertex_attrib_format.end(), + In(Maxwell3D::Regs::VertexAttribute::Type::Float)); + + if (regs.logic_op.enable) + regs.logic_op.enable = static_cast(!has_float); + + UpdateLogicOpEnable(regs); + } else + UpdateLogicOpEnable(regs); UpdateDepthClampEnable(regs); } }