summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2019-09-03 01:05:23 -0300
committerGravatar ReinUsesLisp2019-09-10 19:31:42 -0300
commit78574746bddb1d62d85ae90707e1f0283af2a5db (patch)
tree281fa538f3a86d1bb56b5a3887287fa2d4a8883d /src
parentMerge pull request #2823 from ReinUsesLisp/shr-clamp (diff)
downloadyuzu-78574746bddb1d62d85ae90707e1f0283af2a5db.tar.gz
yuzu-78574746bddb1d62d85ae90707e1f0283af2a5db.tar.xz
yuzu-78574746bddb1d62d85ae90707e1f0283af2a5db.zip
renderer_opengl: Fix sRGB blits
Removes the sRGB hack of tracking if a frame used an sRGB rendertarget to apply at least once to blit the final texture as sRGB. Instead of doing this apply sRGB if the presented image has sRGB. Also enable sRGB by default on Maxwell3D registers as some games seem to assume this.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/maxwell_3d.cpp3
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp21
-rw-r--r--src/video_core/renderer_opengl/gl_state.cpp3
-rw-r--r--src/video_core/renderer_opengl/gl_state.h10
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp13
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.h3
6 files changed, 10 insertions, 43 deletions
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index c8c92757a..965c4c06b 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -89,6 +89,9 @@ void Maxwell3D::InitializeRegisterDefaults() {
89 89
90 // Commercial games seem to assume this value is enabled and nouveau sets this value manually. 90 // Commercial games seem to assume this value is enabled and nouveau sets this value manually.
91 regs.rt_separate_frag_data = 1; 91 regs.rt_separate_frag_data = 1;
92
93 // Some games (like Super Mario Odyssey) assume that SRGB is enabled.
94 regs.framebuffer_srgb = 1;
92} 95}
93 96
94#define DIRTY_REGS_POS(field_name) (offsetof(Maxwell3D::DirtyRegs, field_name)) 97#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..f7397dd64 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -485,15 +485,6 @@ std::pair<bool, bool> RasterizerOpenGL::ConfigureFramebuffers(
485 View color_surface{ 485 View color_surface{
486 texture_cache.GetColorBufferSurface(*single_color_target, preserve_contents)}; 486 texture_cache.GetColorBufferSurface(*single_color_target, preserve_contents)};
487 487
488 if (color_surface) {
489 // Assume that a surface will be written to if it is used as a framebuffer, even if
490 // the shader doesn't actually write to it.
491 texture_cache.MarkColorBufferInUse(*single_color_target);
492 // Workaround for and issue in nvidia drivers
493 // https://devtalk.nvidia.com/default/topic/776591/opengl/gl_framebuffer_srgb-functions-incorrectly/
494 state.framebuffer_srgb.enabled |= color_surface->GetSurfaceParams().srgb_conversion;
495 }
496
497 fbkey.is_single_buffer = true; 488 fbkey.is_single_buffer = true;
498 fbkey.color_attachments[0] = 489 fbkey.color_attachments[0] =
499 GL_COLOR_ATTACHMENT0 + static_cast<GLenum>(*single_color_target); 490 GL_COLOR_ATTACHMENT0 + static_cast<GLenum>(*single_color_target);
@@ -508,17 +499,6 @@ std::pair<bool, bool> RasterizerOpenGL::ConfigureFramebuffers(
508 for (std::size_t index = 0; index < Maxwell::NumRenderTargets; ++index) { 499 for (std::size_t index = 0; index < Maxwell::NumRenderTargets; ++index) {
509 View color_surface{texture_cache.GetColorBufferSurface(index, preserve_contents)}; 500 View color_surface{texture_cache.GetColorBufferSurface(index, preserve_contents)};
510 501
511 if (color_surface) {
512 // Assume that a surface will be written to if it is used as a framebuffer, even
513 // if the shader doesn't actually write to it.
514 texture_cache.MarkColorBufferInUse(index);
515 // Enable sRGB only for supported formats
516 // Workaround for and issue in nvidia drivers
517 // https://devtalk.nvidia.com/default/topic/776591/opengl/gl_framebuffer_srgb-functions-incorrectly/
518 state.framebuffer_srgb.enabled |=
519 color_surface->GetSurfaceParams().srgb_conversion;
520 }
521
522 fbkey.color_attachments[index] = 502 fbkey.color_attachments[index] =
523 GL_COLOR_ATTACHMENT0 + regs.rt_control.GetMap(index); 503 GL_COLOR_ATTACHMENT0 + regs.rt_control.GetMap(index);
524 fbkey.colors[index] = color_surface; 504 fbkey.colors[index] = color_surface;
@@ -906,6 +886,7 @@ bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& config,
906 } 886 }
907 887
908 screen_info.display_texture = surface->GetTexture(); 888 screen_info.display_texture = surface->GetTexture();
889 screen_info.display_srgb = surface->GetSurfaceParams().srgb_conversion;
909 890
910 return true; 891 return true;
911} 892}
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 {
16using Maxwell = Tegra::Engines::Maxwell3D::Regs; 16using Maxwell = Tegra::Engines::Maxwell3D::Regs;
17 17
18OpenGLState OpenGLState::cur_state; 18OpenGLState OpenGLState::cur_state;
19bool OpenGLState::s_rgb_used;
20 19
21namespace { 20namespace {
22 21
@@ -282,8 +281,6 @@ void OpenGLState::ApplySRgb() const {
282 return; 281 return;
283 cur_state.framebuffer_srgb.enabled = framebuffer_srgb.enabled; 282 cur_state.framebuffer_srgb.enabled = framebuffer_srgb.enabled;
284 if (framebuffer_srgb.enabled) { 283 if (framebuffer_srgb.enabled) {
285 // Track if sRGB is used
286 s_rgb_used = true;
287 glEnable(GL_FRAMEBUFFER_SRGB); 284 glEnable(GL_FRAMEBUFFER_SRGB);
288 } else { 285 } else {
289 glDisable(GL_FRAMEBUFFER_SRGB); 286 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:
175 return cur_state; 175 return cur_state;
176 } 176 }
177 177
178 static bool GetsRGBUsed() {
179 return s_rgb_used;
180 }
181
182 static void ClearsRGBUsed() {
183 s_rgb_used = false;
184 }
185
186 void SetDefaultViewports(); 178 void SetDefaultViewports();
187 /// Apply this state as the current OpenGL state 179 /// Apply this state as the current OpenGL state
188 void Apply(); 180 void Apply();
@@ -253,8 +245,6 @@ public:
253private: 245private:
254 static OpenGLState cur_state; 246 static OpenGLState cur_state;
255 247
256 // Workaround for sRGB problems caused by QT not supporting srgb output
257 static bool s_rgb_used;
258 struct { 248 struct {
259 bool blend_state; 249 bool blend_state;
260 bool stencil_state; 250 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..d6e1e5aba 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() {
264 if (rasterizer) { 264 if (rasterizer) {
265 return; 265 return;
266 } 266 }
267 OpenGLState::ClearsRGBUsed();
268 rasterizer = std::make_unique<RasterizerOpenGL>(system, emu_window, screen_info); 267 rasterizer = std::make_unique<RasterizerOpenGL>(system, emu_window, screen_info);
269} 268}
270 269
@@ -342,10 +341,8 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x,
342 ScreenRectVertex(x + w, y + h, texcoords.bottom * scale_u, right * scale_v), 341 ScreenRectVertex(x + w, y + h, texcoords.bottom * scale_u, right * scale_v),
343 }}; 342 }};
344 343
345 state.textures[0] = screen_info.display_texture; 344 state.textures[0].texture = screen_info.display_texture;
346 // Workaround brigthness problems in SMO by enabling sRGB in the final output 345 state.framebuffer_srgb.enabled = screen_info.display_srgb;
347 // if it has been used in the frame. Needed because of this bug in QT: QTBUG-50987
348 state.framebuffer_srgb.enabled = OpenGLState::GetsRGBUsed();
349 state.AllDirty(); 346 state.AllDirty();
350 state.Apply(); 347 state.Apply();
351 glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices), vertices.data()); 348 glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices), vertices.data());
@@ -355,8 +352,6 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x,
355 state.textures[0] = 0; 352 state.textures[0] = 0;
356 state.AllDirty(); 353 state.AllDirty();
357 state.Apply(); 354 state.Apply();
358 // Clear sRGB state for the next frame
359 OpenGLState::ClearsRGBUsed();
360} 355}
361 356
362/** 357/**
@@ -406,8 +401,8 @@ void RendererOpenGL::CaptureScreenshot() {
406 GLuint renderbuffer; 401 GLuint renderbuffer;
407 glGenRenderbuffers(1, &renderbuffer); 402 glGenRenderbuffers(1, &renderbuffer);
408 glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer); 403 glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
409 glRenderbufferStorage(GL_RENDERBUFFER, state.GetsRGBUsed() ? GL_SRGB8 : GL_RGB8, layout.width, 404 glRenderbufferStorage(GL_RENDERBUFFER, screen_info.display_srgb ? GL_SRGB8 : GL_RGB8,
410 layout.height); 405 layout.width, layout.height);
411 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer); 406 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer);
412 407
413 DrawScreen(layout); 408 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 {
38 38
39/// Structure used for storing information about the display target for the Switch screen 39/// Structure used for storing information about the display target for the Switch screen
40struct ScreenInfo { 40struct ScreenInfo {
41 GLuint display_texture; 41 GLuint display_texture{};
42 bool display_srgb{};
42 const Common::Rectangle<float> display_texcoords{0.0f, 0.0f, 1.0f, 1.0f}; 43 const Common::Rectangle<float> display_texcoords{0.0f, 0.0f, 1.0f, 1.0f};
43 TextureInfo texture; 44 TextureInfo texture;
44}; 45};