diff options
5 files changed, 67 insertions, 14 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 717f127e9..cedfe5db1 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -458,6 +458,7 @@ void RasterizerOpenGL::Clear() { } // TODO: Signal state tracker about these changes + state_tracker.NotifyBlend0(); // TODO(Rodrigo): Find out if these changes affect clearing glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE); glDisablei(GL_BLEND, 0); @@ -1102,31 +1103,53 @@ void RasterizerOpenGL::SyncFragmentColorClampState() { } void RasterizerOpenGL::SyncBlendState() { - auto& maxwell3d = system.GPU().Maxwell3D(); - const auto& regs = maxwell3d.regs; + auto& gpu = system.GPU().Maxwell3D(); + auto& flags = gpu.dirty.flags; + const auto& regs = gpu.regs; + + if (flags[Dirty::BlendColor]) { + flags[Dirty::BlendColor] = false; + glBlendColor(regs.blend_color.r, regs.blend_color.g, regs.blend_color.b, + regs.blend_color.a); + } - glBlendColor(regs.blend_color.r, regs.blend_color.g, regs.blend_color.b, regs.blend_color.a); + // TODO(Rodrigo): Revisit blending, there are several registers we are not reading + + if (!flags[Dirty::BlendStates]) { + return; + } + flags[Dirty::BlendStates] = false; if (!regs.independent_blend_enable) { - const auto& src = regs.blend; - oglEnable(GL_BLEND, src.enable[0]); - if (!src.enable[0]) { + if (!regs.blend.enable[0]) { + glDisable(GL_BLEND); return; } - glBlendFuncSeparate(MaxwellToGL::BlendFunc(src.factor_source_rgb), - MaxwellToGL::BlendFunc(src.factor_dest_rgb), - MaxwellToGL::BlendFunc(src.factor_source_a), - MaxwellToGL::BlendFunc(src.factor_dest_a)); - glBlendEquationSeparate(MaxwellToGL::BlendEquation(src.equation_rgb), - MaxwellToGL::BlendEquation(src.equation_a)); + glEnable(GL_BLEND); + glBlendFuncSeparate(MaxwellToGL::BlendFunc(regs.blend.factor_source_rgb), + MaxwellToGL::BlendFunc(regs.blend.factor_dest_rgb), + MaxwellToGL::BlendFunc(regs.blend.factor_source_a), + MaxwellToGL::BlendFunc(regs.blend.factor_dest_a)); + glBlendEquationSeparate(MaxwellToGL::BlendEquation(regs.blend.equation_rgb), + MaxwellToGL::BlendEquation(regs.blend.equation_a)); return; } + const bool force = flags[Dirty::BlendIndependentEnabled]; + flags[Dirty::BlendIndependentEnabled] = false; + for (std::size_t i = 0; i < Maxwell::NumRenderTargets; ++i) { - oglEnablei(GL_BLEND, regs.blend.enable[i], static_cast<GLuint>(i)); + if (!force && !flags[Dirty::BlendState0 + i]) { + continue; + } + flags[Dirty::BlendState0 + i] = false; + if (!regs.blend.enable[i]) { + glDisablei(GL_BLEND, static_cast<GLuint>(i)); continue; } + glEnablei(GL_BLEND, static_cast<GLuint>(i)); + const auto& src = regs.independent_blend[i]; glBlendFuncSeparatei(static_cast<GLuint>(i), MaxwellToGL::BlendFunc(src.factor_source_rgb), MaxwellToGL::BlendFunc(src.factor_dest_rgb), diff --git a/src/video_core/renderer_opengl/gl_state_tracker.cpp b/src/video_core/renderer_opengl/gl_state_tracker.cpp index bc5942a7f..2da1b65fc 100644 --- a/src/video_core/renderer_opengl/gl_state_tracker.cpp +++ b/src/video_core/renderer_opengl/gl_state_tracker.cpp @@ -129,6 +129,21 @@ void SetupDirtyShaders(Tables& tables) { Shaders); } +void SetupDirtyBlend(Tables& tables) { + FillBlock(tables[0], OFF(blend_color), NUM(blend_color), BlendColor); + + tables[0][OFF(independent_blend_enable)] = BlendIndependentEnabled; + + for (std::size_t i = 0; i < Regs::NumRenderTargets; ++i) { + const std::size_t offset = OFF(independent_blend) + i * NUM(independent_blend[0]); + FillBlock(tables[0], offset, NUM(independent_blend[0]), BlendState0 + i); + + tables[0][OFF(blend.enable) + i] = static_cast<u8>(BlendState0 + i); + } + FillBlock(tables[1], OFF(independent_blend), NUM(independent_blend), BlendStates); + FillBlock(tables[1], OFF(blend), NUM(blend), BlendStates); +} + void SetupDirtyMisc(Tables& tables) { tables[0][OFF(clip_distance_enabled)] = ClipDistances; } @@ -147,6 +162,7 @@ void StateTracker::Initialize() { SetupDirtyVertexArrays(tables); SetupDirtyVertexFormat(tables); SetupDirtyShaders(tables); + SetupDirtyBlend(tables); SetupDirtyMisc(tables); auto& store = dirty.on_write_stores; diff --git a/src/video_core/renderer_opengl/gl_state_tracker.h b/src/video_core/renderer_opengl/gl_state_tracker.h index 11fdc6de4..a9b470eee 100644 --- a/src/video_core/renderer_opengl/gl_state_tracker.h +++ b/src/video_core/renderer_opengl/gl_state_tracker.h @@ -47,8 +47,15 @@ enum : u8 { ColorMask0, ColorMask7 = ColorMask0 + 7, + BlendColor, + BlendIndependentEnabled, + BlendStates, + BlendState0, + BlendState7 = BlendState0 + 7, + Shaders, ClipDistances, + CullTestEnable, FrontFace, CullFace, @@ -56,7 +63,6 @@ enum : u8 { DepthTest, StencilTest, ColorMask, - BlendState, PolygonOffset, Last @@ -103,6 +109,12 @@ public: flags[OpenGL::Dirty::ColorMask0] = true; } + void NotifyBlend0() { + auto& flags = system.GPU().Maxwell3D().dirty.flags; + flags[OpenGL::Dirty::BlendStates] = true; + flags[OpenGL::Dirty::BlendState0] = true; + } + void NotifyFramebuffer() { auto& flags = system.GPU().Maxwell3D().dirty.flags; flags[VideoCommon::Dirty::RenderTargets] = true; diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index a02326b9f..46572eb43 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp @@ -520,6 +520,7 @@ void TextureCacheOpenGL::ImageBlit(View& src_view, View& dst_view, // TODO: Signal state tracker about these changes state_tracker.NotifyScissor0(); + state_tracker.NotifyBlend0(); state_tracker.NotifyFramebuffer(); if (dst_params.srgb_conversion) { diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index cbe916488..d81c68077 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -580,6 +580,7 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) { state_tracker.NotifyViewport0(); state_tracker.NotifyScissor0(); state_tracker.NotifyColorMask0(); + state_tracker.NotifyBlend0(); state_tracker.NotifyFramebuffer(); program_manager.UseVertexShader(vertex_program.handle); |