Merge pull request #2851 from ReinUsesLisp/srgb

renderer_opengl: Fix sRGB blits
This commit is contained in:
Fernando Sahmkow 2019-09-15 10:38:10 -04:00 committed by GitHub
commit 393cc3ef2f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 9 additions and 30 deletions

View file

@ -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))

View file

@ -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;
} }

View file

@ -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);

View file

@ -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;

View file

@ -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 state.framebuffer_srgb.enabled = screen_info.display_srgb;
// if it has been used in the frame. Needed because of this bug in QT: QTBUG-50987
state.framebuffer_srgb.enabled = OpenGLState::GetsRGBUsed();
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, glRenderbufferStorage(GL_RENDERBUFFER, screen_info.display_srgb ? GL_SRGB8 : GL_RGB8,
layout.height); 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);

View file

@ -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;
}; };