From d8c9335ef0801927b7d3ab8e0d809ffa7dcf3189 Mon Sep 17 00:00:00 2001
From: SomeDudeOnDiscord <122324510+SomeDudeOnDiscord@users.noreply.github.com>
Date: Sat, 18 Feb 2023 11:54:12 -0500
Subject: [PATCH] Resolve Black Screen on Intel GPU Regression (#6306)

* Get value for swap screen setting and check mono_render_option again

* resolve clang-format issue

* do not disable opengl blending since it is enabled by default

* reset blending state to default values after drawing second screen

* prevent resetting state blending when custom opacity is not used
---
 .../renderer_opengl/renderer_opengl.cpp       | 25 ++++++++++++++-----
 .../renderer_opengl/renderer_opengl.h         |  1 +
 2 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 89e58a9dc..0b7c8dd12 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -1002,7 +1002,7 @@ void RendererOpenGL::DrawScreens(const Layout::FramebufferLayout& layout, bool f
     }
 
     glUniform1i(uniform_layer, 0);
-    if (!Settings::values.swap_screen) {
+    if (!Settings::values.swap_screen.GetValue()) {
         DrawTopScreen(layout, top_screen, stereo_single_screen);
         glUniform1i(uniform_layer, 0);
         ApplySecondLayerOpacity();
@@ -1013,13 +1013,12 @@ void RendererOpenGL::DrawScreens(const Layout::FramebufferLayout& layout, bool f
         ApplySecondLayerOpacity();
         DrawTopScreen(layout, top_screen, stereo_single_screen);
     }
-    state.blend.enabled = false;
+    ResetSecondLayerOpacity();
 }
 
 void RendererOpenGL::ApplySecondLayerOpacity() {
     if (Settings::values.custom_layout &&
         Settings::values.custom_second_layer_opacity.GetValue() < 100) {
-        state.blend.enabled = true;
         state.blend.src_rgb_func = GL_CONSTANT_ALPHA;
         state.blend.src_a_func = GL_CONSTANT_ALPHA;
         state.blend.dst_a_func = GL_ONE_MINUS_CONSTANT_ALPHA;
@@ -1028,6 +1027,17 @@ void RendererOpenGL::ApplySecondLayerOpacity() {
     }
 }
 
+void RendererOpenGL::ResetSecondLayerOpacity() {
+    if (Settings::values.custom_layout &&
+        Settings::values.custom_second_layer_opacity.GetValue() < 100) {
+        state.blend.src_rgb_func = GL_ONE;
+        state.blend.dst_rgb_func = GL_ZERO;
+        state.blend.src_a_func = GL_ONE;
+        state.blend.dst_a_func = GL_ZERO;
+        state.blend.color.alpha = 0.0f;
+    }
+}
+
 void RendererOpenGL::DrawTopScreen(const Layout::FramebufferLayout& layout,
                                    const Common::Rectangle<u32>& top_screen,
                                    const bool stereo_single_screen) {
@@ -1037,8 +1047,10 @@ void RendererOpenGL::DrawTopScreen(const Layout::FramebufferLayout& layout,
 
     if (layout.is_rotated) {
         if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::Off) {
-            DrawSingleScreenRotated(screen_infos[0], (float)top_screen.left, (float)top_screen.top,
-                                    (float)top_screen.GetWidth(), (float)top_screen.GetHeight());
+            int eye = static_cast<int>(Settings::values.mono_render_option.GetValue());
+            DrawSingleScreenRotated(screen_infos[eye], (float)top_screen.left,
+                                    (float)top_screen.top, (float)top_screen.GetWidth(),
+                                    (float)top_screen.GetHeight());
         } else if (Settings::values.render_3d.GetValue() ==
                    Settings::StereoRenderOption::SideBySide) {
             DrawSingleScreenRotated(screen_infos[0], (float)top_screen.left / 2,
@@ -1064,7 +1076,8 @@ void RendererOpenGL::DrawTopScreen(const Layout::FramebufferLayout& layout,
         }
     } else {
         if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::Off) {
-            DrawSingleScreen(screen_infos[0], (float)top_screen.left, (float)top_screen.top,
+            int eye = static_cast<int>(Settings::values.mono_render_option.GetValue());
+            DrawSingleScreen(screen_infos[eye], (float)top_screen.left, (float)top_screen.top,
                              (float)top_screen.GetWidth(), (float)top_screen.GetHeight());
         } else if (Settings::values.render_3d.GetValue() ==
                    Settings::StereoRenderOption::SideBySide) {
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h
index a168b055e..c823730e9 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.h
+++ b/src/video_core/renderer_opengl/renderer_opengl.h
@@ -90,6 +90,7 @@ private:
                                      const GPU::Regs::FramebufferConfig& framebuffer);
     void DrawScreens(const Layout::FramebufferLayout& layout, bool flipped);
     void ApplySecondLayerOpacity();
+    void ResetSecondLayerOpacity();
     void DrawBottomScreen(const Layout::FramebufferLayout& layout,
                           const Common::Rectangle<u32>& bottom_screen,
                           const bool stereo_single_screen);