Просмотр исходного кода

Merge pull request #2851 from ReinUsesLisp/srgb

renderer_opengl: Fix sRGB blits
Fernando Sahmkow 6 лет назад
Родитель
Сommit
393cc3ef2f

+ 3 - 0
src/video_core/engines/maxwell_3d.cpp

@@ -89,6 +89,9 @@ void Maxwell3D::InitializeRegisterDefaults() {
 
 
     // Commercial games seem to assume this value is enabled and nouveau sets this value manually.
     // Commercial games seem to assume this value is enabled and nouveau sets this value manually.
     regs.rt_separate_frag_data = 1;
     regs.rt_separate_frag_data = 1;
+
+    // Some games (like Super Mario Odyssey) assume that SRGB is enabled.
+    regs.framebuffer_srgb = 1;
 }
 }
 
 
 #define DIRTY_REGS_POS(field_name) (offsetof(Maxwell3D::DirtyRegs, field_name))
 #define DIRTY_REGS_POS(field_name) (offsetof(Maxwell3D::DirtyRegs, field_name))

+ 1 - 8
src/video_core/renderer_opengl/gl_rasterizer.cpp

@@ -489,9 +489,6 @@ std::pair<bool, bool> RasterizerOpenGL::ConfigureFramebuffers(
                 // Assume that a surface will be written to if it is used as a framebuffer, even if
                 // Assume that a surface will be written to if it is used as a framebuffer, even if
                 // the shader doesn't actually write to it.
                 // the shader doesn't actually write to it.
                 texture_cache.MarkColorBufferInUse(*single_color_target);
                 texture_cache.MarkColorBufferInUse(*single_color_target);
-                // Workaround for and issue in nvidia drivers
-                // https://devtalk.nvidia.com/default/topic/776591/opengl/gl_framebuffer_srgb-functions-incorrectly/
-                state.framebuffer_srgb.enabled |= color_surface->GetSurfaceParams().srgb_conversion;
             }
             }
 
 
             fbkey.is_single_buffer = true;
             fbkey.is_single_buffer = true;
@@ -512,11 +509,6 @@ std::pair<bool, bool> RasterizerOpenGL::ConfigureFramebuffers(
                     // Assume that a surface will be written to if it is used as a framebuffer, even
                     // Assume that a surface will be written to if it is used as a framebuffer, even
                     // if the shader doesn't actually write to it.
                     // if the shader doesn't actually write to it.
                     texture_cache.MarkColorBufferInUse(index);
                     texture_cache.MarkColorBufferInUse(index);
-                    // Enable sRGB only for supported formats
-                    // Workaround for and issue in nvidia drivers
-                    // https://devtalk.nvidia.com/default/topic/776591/opengl/gl_framebuffer_srgb-functions-incorrectly/
-                    state.framebuffer_srgb.enabled |=
-                        color_surface->GetSurfaceParams().srgb_conversion;
                 }
                 }
 
 
                 fbkey.color_attachments[index] =
                 fbkey.color_attachments[index] =
@@ -906,6 +898,7 @@ bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& config,
     }
     }
 
 
     screen_info.display_texture = surface->GetTexture();
     screen_info.display_texture = surface->GetTexture();
+    screen_info.display_srgb = surface->GetSurfaceParams().srgb_conversion;
 
 
     return true;
     return true;
 }
 }

+ 0 - 3
src/video_core/renderer_opengl/gl_state.cpp

@@ -16,7 +16,6 @@ namespace OpenGL {
 using Maxwell = Tegra::Engines::Maxwell3D::Regs;
 using Maxwell = Tegra::Engines::Maxwell3D::Regs;
 
 
 OpenGLState OpenGLState::cur_state;
 OpenGLState OpenGLState::cur_state;
-bool OpenGLState::s_rgb_used;
 
 
 namespace {
 namespace {
 
 
@@ -282,8 +281,6 @@ void OpenGLState::ApplySRgb() const {
         return;
         return;
     cur_state.framebuffer_srgb.enabled = framebuffer_srgb.enabled;
     cur_state.framebuffer_srgb.enabled = framebuffer_srgb.enabled;
     if (framebuffer_srgb.enabled) {
     if (framebuffer_srgb.enabled) {
-        // Track if sRGB is used
-        s_rgb_used = true;
         glEnable(GL_FRAMEBUFFER_SRGB);
         glEnable(GL_FRAMEBUFFER_SRGB);
     } else {
     } else {
         glDisable(GL_FRAMEBUFFER_SRGB);
         glDisable(GL_FRAMEBUFFER_SRGB);

+ 0 - 10
src/video_core/renderer_opengl/gl_state.h

@@ -175,14 +175,6 @@ public:
         return cur_state;
         return cur_state;
     }
     }
 
 
-    static bool GetsRGBUsed() {
-        return s_rgb_used;
-    }
-
-    static void ClearsRGBUsed() {
-        s_rgb_used = false;
-    }
-
     void SetDefaultViewports();
     void SetDefaultViewports();
     /// Apply this state as the current OpenGL state
     /// Apply this state as the current OpenGL state
     void Apply();
     void Apply();
@@ -253,8 +245,6 @@ public:
 private:
 private:
     static OpenGLState cur_state;
     static OpenGLState cur_state;
 
 
-    // Workaround for sRGB problems caused by QT not supporting srgb output
-    static bool s_rgb_used;
     struct {
     struct {
         bool blend_state;
         bool blend_state;
         bool stencil_state;
         bool stencil_state;

+ 3 - 8
src/video_core/renderer_opengl/renderer_opengl.cpp

@@ -264,7 +264,6 @@ void RendererOpenGL::CreateRasterizer() {
     if (rasterizer) {
     if (rasterizer) {
         return;
         return;
     }
     }
-    OpenGLState::ClearsRGBUsed();
     rasterizer = std::make_unique<RasterizerOpenGL>(system, emu_window, screen_info);
     rasterizer = std::make_unique<RasterizerOpenGL>(system, emu_window, screen_info);
 }
 }
 
 
@@ -343,9 +342,7 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x,
     }};
     }};
 
 
     state.textures[0] = screen_info.display_texture;
     state.textures[0] = screen_info.display_texture;
-    // Workaround brigthness problems in SMO by enabling sRGB in the final output
-    // if it has been used in the frame. Needed because of this bug in QT: QTBUG-50987
-    state.framebuffer_srgb.enabled = OpenGLState::GetsRGBUsed();
+    state.framebuffer_srgb.enabled = screen_info.display_srgb;
     state.AllDirty();
     state.AllDirty();
     state.Apply();
     state.Apply();
     glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices), vertices.data());
     glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices), vertices.data());
@@ -355,8 +352,6 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x,
     state.textures[0] = 0;
     state.textures[0] = 0;
     state.AllDirty();
     state.AllDirty();
     state.Apply();
     state.Apply();
-    // Clear sRGB state for the next frame
-    OpenGLState::ClearsRGBUsed();
 }
 }
 
 
 /**
 /**
@@ -406,8 +401,8 @@ void RendererOpenGL::CaptureScreenshot() {
     GLuint renderbuffer;
     GLuint renderbuffer;
     glGenRenderbuffers(1, &renderbuffer);
     glGenRenderbuffers(1, &renderbuffer);
     glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
     glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
-    glRenderbufferStorage(GL_RENDERBUFFER, state.GetsRGBUsed() ? GL_SRGB8 : GL_RGB8, layout.width,
-                          layout.height);
+    glRenderbufferStorage(GL_RENDERBUFFER, screen_info.display_srgb ? GL_SRGB8 : GL_RGB8,
+                          layout.width, layout.height);
     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer);
     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer);
 
 
     DrawScreen(layout);
     DrawScreen(layout);

+ 2 - 1
src/video_core/renderer_opengl/renderer_opengl.h

@@ -38,7 +38,8 @@ struct TextureInfo {
 
 
 /// Structure used for storing information about the display target for the Switch screen
 /// Structure used for storing information about the display target for the Switch screen
 struct ScreenInfo {
 struct ScreenInfo {
-    GLuint display_texture;
+    GLuint display_texture{};
+    bool display_srgb{};
     const Common::Rectangle<float> display_texcoords{0.0f, 0.0f, 1.0f, 1.0f};
     const Common::Rectangle<float> display_texcoords{0.0f, 0.0f, 1.0f, 1.0f};
     TextureInfo texture;
     TextureInfo texture;
 };
 };