From 6a51b628f910deb6356974c2eb6fb2dba1dfdb34 Mon Sep 17 00:00:00 2001
From: gdkchan <gab.dark.100@gmail.com>
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 aececbe8aa..015b0ec0ae 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 78e37ed64a..5e754d8052 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;