Merge pull request #2851 from ReinUsesLisp/srgb
renderer_opengl: Fix sRGB blits
This commit is contained in:
commit
393cc3ef2f
|
@ -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))
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
Reference in New Issue