summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_opengl
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/renderer_opengl')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp23
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h3
-rw-r--r--src/video_core/renderer_opengl/gl_state.cpp47
-rw-r--r--src/video_core/renderer_opengl/gl_state.h8
4 files changed, 59 insertions, 22 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 73770ff69..bb263b6aa 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -511,10 +511,10 @@ void RasterizerOpenGL::Clear() {
OpenGLState clear_state;
clear_state.draw.draw_framebuffer = framebuffer.handle;
- clear_state.color_mask.red_enabled = regs.clear_buffers.R ? GL_TRUE : GL_FALSE;
- clear_state.color_mask.green_enabled = regs.clear_buffers.G ? GL_TRUE : GL_FALSE;
- clear_state.color_mask.blue_enabled = regs.clear_buffers.B ? GL_TRUE : GL_FALSE;
- clear_state.color_mask.alpha_enabled = regs.clear_buffers.A ? GL_TRUE : GL_FALSE;
+ clear_state.color_mask[0].red_enabled = regs.clear_buffers.R ? GL_TRUE : GL_FALSE;
+ clear_state.color_mask[0].green_enabled = regs.clear_buffers.G ? GL_TRUE : GL_FALSE;
+ clear_state.color_mask[0].blue_enabled = regs.clear_buffers.B ? GL_TRUE : GL_FALSE;
+ clear_state.color_mask[0].alpha_enabled = regs.clear_buffers.A ? GL_TRUE : GL_FALSE;
if (regs.clear_buffers.R || regs.clear_buffers.G || regs.clear_buffers.B ||
regs.clear_buffers.A) {
@@ -573,7 +573,7 @@ void RasterizerOpenGL::DrawArrays() {
ScopeAcquireGLContext acquire_context{emu_window};
ConfigureFramebuffers();
-
+ SyncColorMask();
SyncDepthTestState();
SyncStencilTestState();
SyncBlendState();
@@ -989,6 +989,18 @@ void RasterizerOpenGL::SyncStencilTestState() {
state.stencil.back.write_mask = regs.stencil_back_mask;
}
+void RasterizerOpenGL::SyncColorMask() {
+ const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
+ for (size_t i = 0; i < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets; i++) {
+ const auto& source = regs.color_mask[regs.color_mask_common ? 0 : i];
+ auto& dest = state.color_mask[i];
+ dest.red_enabled = (source.R == 0) ? GL_FALSE : GL_TRUE;
+ dest.green_enabled = (source.G == 0) ? GL_FALSE : GL_TRUE;
+ dest.blue_enabled = (source.B == 0) ? GL_FALSE : GL_TRUE;
+ dest.alpha_enabled = (source.A == 0) ? GL_FALSE : GL_TRUE;
+ }
+}
+
void RasterizerOpenGL::SyncBlendState() {
const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
@@ -1000,6 +1012,7 @@ void RasterizerOpenGL::SyncBlendState() {
state.independant_blend.enabled = regs.independent_blend_enable;
if (!state.independant_blend.enabled) {
auto& blend = state.blend[0];
+ blend.enabled = regs.blend.enable[0] != 0;
blend.separate_alpha = regs.blend.separate_alpha;
blend.rgb_equation = MaxwellToGL::BlendEquation(regs.blend.equation_rgb);
blend.src_rgb_func = MaxwellToGL::BlendFunc(regs.blend.factor_source_rgb);
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 8ec22df8d..60e783803 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -169,6 +169,9 @@ private:
/// Syncs the point state to match the guest state
void SyncPointState();
+ /// Syncs Color Mask
+ void SyncColorMask();
+
/// Check asserts for alpha testing.
void CheckAlphaTests();
diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp
index 2e1f81e26..9517285e5 100644
--- a/src/video_core/renderer_opengl/gl_state.cpp
+++ b/src/video_core/renderer_opengl/gl_state.cpp
@@ -25,12 +25,12 @@ OpenGLState::OpenGLState() {
primitive_restart.enabled = false;
primitive_restart.index = 0;
-
- color_mask.red_enabled = GL_TRUE;
- color_mask.green_enabled = GL_TRUE;
- color_mask.blue_enabled = GL_TRUE;
- color_mask.alpha_enabled = GL_TRUE;
-
+ for (auto& item : color_mask) {
+ item.red_enabled = GL_TRUE;
+ item.green_enabled = GL_TRUE;
+ item.blue_enabled = GL_TRUE;
+ item.alpha_enabled = GL_TRUE;
+ }
stencil.test_enabled = false;
auto reset_stencil = [](auto& config) {
config.test_func = GL_ALWAYS;
@@ -135,6 +135,32 @@ void OpenGLState::ApplyCulling() const {
}
}
+void OpenGLState::ApplyColorMask() const {
+ if (GLAD_GL_ARB_viewport_array) {
+ for (size_t i = 0; i < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets; i++) {
+ const auto& updated = color_mask[i];
+ const auto& current = cur_state.color_mask[i];
+ if (updated.red_enabled != current.red_enabled ||
+ updated.green_enabled != current.green_enabled ||
+ updated.blue_enabled != current.blue_enabled ||
+ updated.alpha_enabled != current.alpha_enabled) {
+ glColorMaski(static_cast<GLuint>(i), updated.red_enabled, updated.green_enabled,
+ updated.blue_enabled, updated.alpha_enabled);
+ }
+ }
+ } else {
+ const auto& updated = color_mask[0];
+ const auto& current = cur_state.color_mask[0];
+ if (updated.red_enabled != current.red_enabled ||
+ updated.green_enabled != current.green_enabled ||
+ updated.blue_enabled != current.blue_enabled ||
+ updated.alpha_enabled != current.alpha_enabled) {
+ glColorMask(updated.red_enabled, updated.green_enabled, updated.blue_enabled,
+ updated.alpha_enabled);
+ }
+ }
+}
+
void OpenGLState::ApplyDepth() const {
// Depth test
const bool depth_test_changed = depth.test_enabled != cur_state.depth.test_enabled;
@@ -444,18 +470,11 @@ void OpenGLState::Apply() const {
}
}
}
- // Color mask
- if (color_mask.red_enabled != cur_state.color_mask.red_enabled ||
- color_mask.green_enabled != cur_state.color_mask.green_enabled ||
- color_mask.blue_enabled != cur_state.color_mask.blue_enabled ||
- color_mask.alpha_enabled != cur_state.color_mask.alpha_enabled) {
- glColorMask(color_mask.red_enabled, color_mask.green_enabled, color_mask.blue_enabled,
- color_mask.alpha_enabled);
- }
// Point
if (point.size != cur_state.point.size) {
glPointSize(point.size);
}
+ ApplyColorMask();
ApplyViewport();
ApplyScissor();
ApplyStencilTest();
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h
index a027ca33c..b8cf1f637 100644
--- a/src/video_core/renderer_opengl/gl_state.h
+++ b/src/video_core/renderer_opengl/gl_state.h
@@ -56,13 +56,14 @@ public:
GLuint index;
} primitive_restart; // GL_PRIMITIVE_RESTART
- struct {
+ struct ColorMask {
GLboolean red_enabled;
GLboolean green_enabled;
GLboolean blue_enabled;
GLboolean alpha_enabled;
- } color_mask; // GL_COLOR_WRITEMASK
-
+ };
+ std::array<ColorMask, Tegra::Engines::Maxwell3D::Regs::NumRenderTargets>
+ color_mask; // GL_COLOR_WRITEMASK
struct {
bool test_enabled; // GL_STENCIL_TEST
struct {
@@ -198,6 +199,7 @@ private:
static bool s_rgb_used;
void ApplySRgb() const;
void ApplyCulling() const;
+ void ApplyColorMask() const;
void ApplyDepth() const;
void ApplyPrimitiveRestart() const;
void ApplyStencilTest() const;