diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 5d516cdb3..c7a3c85a0 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/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. 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)) diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 4e266cdad..4dd08bccb 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -489,9 +489,6 @@ std::pair RasterizerOpenGL::ConfigureFramebuffers( // 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. 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; @@ -512,11 +509,6 @@ std::pair RasterizerOpenGL::ConfigureFramebuffers( // 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. 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] = @@ -906,6 +898,7 @@ bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& config, } screen_info.display_texture = surface->GetTexture(); + screen_info.display_srgb = surface->GetSurfaceParams().srgb_conversion; return true; } diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp index 6eabf4fac..bf86b5a0b 100644 --- a/src/video_core/renderer_opengl/gl_state.cpp +++ b/src/video_core/renderer_opengl/gl_state.cpp @@ -16,7 +16,6 @@ namespace OpenGL { using Maxwell = Tegra::Engines::Maxwell3D::Regs; OpenGLState OpenGLState::cur_state; -bool OpenGLState::s_rgb_used; namespace { @@ -282,8 +281,6 @@ void OpenGLState::ApplySRgb() const { return; cur_state.framebuffer_srgb.enabled = framebuffer_srgb.enabled; if (framebuffer_srgb.enabled) { - // Track if sRGB is used - s_rgb_used = true; glEnable(GL_FRAMEBUFFER_SRGB); } else { glDisable(GL_FRAMEBUFFER_SRGB); diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h index 949b13051..c358d3b38 100644 --- a/src/video_core/renderer_opengl/gl_state.h +++ b/src/video_core/renderer_opengl/gl_state.h @@ -175,14 +175,6 @@ public: return cur_state; } - static bool GetsRGBUsed() { - return s_rgb_used; - } - - static void ClearsRGBUsed() { - s_rgb_used = false; - } - void SetDefaultViewports(); /// Apply this state as the current OpenGL state void Apply(); @@ -253,8 +245,6 @@ public: private: static OpenGLState cur_state; - // Workaround for sRGB problems caused by QT not supporting srgb output - static bool s_rgb_used; struct { bool blend_state; bool stencil_state; diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 839178152..1e6ef66ab 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -264,7 +264,6 @@ void RendererOpenGL::CreateRasterizer() { if (rasterizer) { return; } - OpenGLState::ClearsRGBUsed(); rasterizer = std::make_unique(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; - // 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.Apply(); 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.AllDirty(); state.Apply(); - // Clear sRGB state for the next frame - OpenGLState::ClearsRGBUsed(); } /** @@ -406,8 +401,8 @@ void RendererOpenGL::CaptureScreenshot() { GLuint renderbuffer; glGenRenderbuffers(1, &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); DrawScreen(layout); diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h index 9bd086368..cf26628ca 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.h +++ b/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 struct ScreenInfo { - GLuint display_texture; + GLuint display_texture{}; + bool display_srgb{}; const Common::Rectangle display_texcoords{0.0f, 0.0f, 1.0f, 1.0f}; TextureInfo texture; };