From 6a51b628f910deb6356974c2eb6fb2dba1dfdb34 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Mon, 12 Oct 2020 21:50:41 -0300 Subject: [PATCH] Fix error when dual source blend is used (#1610) * Fix error when dual source blend is used * Ensure framebuffer --- Ryujinx.Graphics.OpenGL/Framebuffer.cs | 31 ++++++++++++++++++++++++++ Ryujinx.Graphics.OpenGL/Pipeline.cs | 26 +++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/Ryujinx.Graphics.OpenGL/Framebuffer.cs b/Ryujinx.Graphics.OpenGL/Framebuffer.cs index aececbe8..015b0ec0 100644 --- a/Ryujinx.Graphics.OpenGL/Framebuffer.cs +++ b/Ryujinx.Graphics.OpenGL/Framebuffer.cs @@ -13,6 +13,9 @@ namespace Ryujinx.Graphics.OpenGL private readonly TextureView[] _colors; + private int _colorsCount; + private bool _dualSourceBlend; + public Framebuffer() { Handle = GL.GenFramebuffer(); @@ -97,7 +100,35 @@ namespace Ryujinx.Graphics.OpenGL } } + public void SetDualSourceBlend(bool enable) + { + bool oldEnable = _dualSourceBlend; + + _dualSourceBlend = enable; + + // When dual source blend is used, + // we can only have one draw buffer. + if (enable) + { + GL.DrawBuffer(DrawBufferMode.ColorAttachment0); + } + else if (oldEnable) + { + SetDrawBuffersImpl(_colorsCount); + } + } + public void SetDrawBuffers(int colorsCount) + { + if (_colorsCount != colorsCount && !_dualSourceBlend) + { + SetDrawBuffersImpl(colorsCount); + } + + _colorsCount = colorsCount; + } + + private void SetDrawBuffersImpl(int colorsCount) { DrawBuffersEnum[] drawBuffers = new DrawBuffersEnum[colorsCount]; diff --git a/Ryujinx.Graphics.OpenGL/Pipeline.cs b/Ryujinx.Graphics.OpenGL/Pipeline.cs index 78e37ed6..5e754d80 100644 --- a/Ryujinx.Graphics.OpenGL/Pipeline.cs +++ b/Ryujinx.Graphics.OpenGL/Pipeline.cs @@ -557,6 +557,32 @@ namespace Ryujinx.Graphics.OpenGL (BlendingFactorSrc)blend.AlphaSrcFactor.Convert(), (BlendingFactorDest)blend.AlphaDstFactor.Convert()); + static bool IsDualSource(BlendFactor factor) + { + switch (factor) + { + case BlendFactor.Src1Color: + case BlendFactor.Src1ColorGl: + case BlendFactor.Src1Alpha: + case BlendFactor.Src1AlphaGl: + case BlendFactor.OneMinusSrc1Color: + case BlendFactor.OneMinusSrc1ColorGl: + case BlendFactor.OneMinusSrc1Alpha: + case BlendFactor.OneMinusSrc1AlphaGl: + return true; + } + + return false; + } + + EnsureFramebuffer(); + + _framebuffer.SetDualSourceBlend( + IsDualSource(blend.ColorSrcFactor) || + IsDualSource(blend.ColorDstFactor) || + IsDualSource(blend.AlphaSrcFactor) || + IsDualSource(blend.AlphaDstFactor)); + if (_blendConstant != blend.BlendConstant) { _blendConstant = blend.BlendConstant;