diff options
Diffstat (limited to 'src/video_core/renderer_opengl')
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 39 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_state_tracker.cpp | 11 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_state_tracker.h | 11 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.cpp | 1 |
4 files changed, 53 insertions, 9 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 2ec4c9f55..b4cec274d 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -410,8 +410,9 @@ void RasterizerOpenGL::Clear() { } if (use_color) { // TODO: Signal state tracker about these changes - glColorMaski(0, regs.clear_buffers.R, regs.clear_buffers.G, regs.clear_buffers.B, - regs.clear_buffers.A); + state_tracker.NotifyColorMask0(); + glColorMaski(0, regs.clear_buffers.R != 0, regs.clear_buffers.G != 0, + regs.clear_buffers.B != 0, regs.clear_buffers.A != 0); SyncFramebufferSRGB(); // TODO(Rodrigo): Determine if clamping is used on clears @@ -1030,17 +1031,37 @@ void RasterizerOpenGL::SyncRasterizeEnable() { } void RasterizerOpenGL::SyncColorMask() { - auto& maxwell3d = system.GPU().Maxwell3D(); - const auto& regs = maxwell3d.regs; + auto& gpu = system.GPU().Maxwell3D(); + auto& flags = gpu.dirty.flags; + if (!flags[Dirty::ColorMasks]) { + return; + } + flags[Dirty::ColorMasks] = false; + + const bool force = flags[Dirty::ColorMaskCommon]; + flags[Dirty::ColorMaskCommon] = false; + const auto& regs = gpu.regs; if (regs.color_mask_common) { + if (!force && !flags[Dirty::ColorMask0]) { + return; + } + flags[Dirty::ColorMask0] = false; + auto& mask = regs.color_mask[0]; - glColorMask(mask.R, mask.B, mask.G, mask.A); - } else { - for (std::size_t i = 0; i < Maxwell::NumRenderTargets; ++i) { - const auto& mask = regs.color_mask[regs.color_mask_common ? 0 : i]; - glColorMaski(static_cast<GLuint>(i), mask.R, mask.G, mask.B, mask.A); + glColorMask(mask.R != 0, mask.B != 0, mask.G != 0, mask.A != 0); + return; + } + + // Path without color_mask_common set + for (std::size_t i = 0; i < Maxwell::NumRenderTargets; ++i) { + if (!force && !flags[Dirty::ColorMask0 + i]) { + continue; } + flags[Dirty::ColorMask0 + i] = false; + + const auto& mask = regs.color_mask[i]; + glColorMaski(static_cast<GLuint>(i), mask.R != 0, mask.G != 0, mask.B != 0, mask.A != 0); } } diff --git a/src/video_core/renderer_opengl/gl_state_tracker.cpp b/src/video_core/renderer_opengl/gl_state_tracker.cpp index 9e1db59ae..3c6231d58 100644 --- a/src/video_core/renderer_opengl/gl_state_tracker.cpp +++ b/src/video_core/renderer_opengl/gl_state_tracker.cpp @@ -61,6 +61,16 @@ void SetupDirtyRenderTargets(Tables& tables) { } } +void SetupDirtyColorMasks(Tables& tables) { + tables[0][OFF(color_mask_common)] = ColorMaskCommon; + for (std::size_t rt = 0; rt < Regs::NumRenderTargets; ++rt) { + const std::size_t offset = OFF(color_mask) + rt * NUM(color_mask[0]); + FillBlock(tables[0], offset, NUM(color_mask[0]), ColorMask0 + rt); + } + + FillBlock(tables[1], OFF(color_mask), NUM(color_mask), ColorMasks); +} + void SetupDirtyViewports(Tables& tables) { for (std::size_t i = 0; i < Regs::NumViewports; ++i) { const std::size_t transf_offset = OFF(viewport_transform) + i * NUM(viewport_transform[0]); @@ -104,6 +114,7 @@ void StateTracker::Initialize() { auto& tables = dirty.tables; SetupDirtyRenderTargets(tables); + SetupDirtyColorMasks(tables); SetupDirtyViewports(tables); SetupDirtyScissors(tables); } diff --git a/src/video_core/renderer_opengl/gl_state_tracker.h b/src/video_core/renderer_opengl/gl_state_tracker.h index 5153dc5d1..0ad7c349a 100644 --- a/src/video_core/renderer_opengl/gl_state_tracker.h +++ b/src/video_core/renderer_opengl/gl_state_tracker.h @@ -38,6 +38,11 @@ enum : u8 { Scissor0, Scissor15 = Scissor0 + 15, + ColorMaskCommon, + ColorMasks, + ColorMask0, + ColorMask7 = ColorMask0 + 7, + Shaders, CullTestEnable, FrontFace, @@ -73,6 +78,12 @@ public: flags[OpenGL::Dirty::Scissor0] = true; } + void NotifyColorMask0() { + auto& flags = system.GPU().Maxwell3D().dirty.flags; + flags[OpenGL::Dirty::ColorMasks] = true; + flags[OpenGL::Dirty::ColorMask0] = true; + } + void NotifyFramebuffer() { auto& flags = system.GPU().Maxwell3D().dirty.flags; flags[VideoCommon::Dirty::RenderTargets] = true; diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index f2b07ac81..3ff7c8fb1 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -578,6 +578,7 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) { // TODO: Signal state tracker about these changes state_tracker.NotifyViewport0(); state_tracker.NotifyScissor0(); + state_tracker.NotifyColorMask0(); state_tracker.NotifyFramebuffer(); program_manager.UseVertexShader(vertex_program.handle); |