summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/engines/maxwell_3d.h23
-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
5 files changed, 79 insertions, 25 deletions
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index 33eb57360..0509ba3a2 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -462,6 +462,16 @@ public:
462 } 462 }
463 }; 463 };
464 464
465 struct ColorMask {
466 union {
467 u32 raw;
468 BitField<0, 4, u32> R;
469 BitField<4, 4, u32> G;
470 BitField<8, 4, u32> B;
471 BitField<12, 4, u32> A;
472 };
473 };
474
465 bool IsShaderConfigEnabled(std::size_t index) const { 475 bool IsShaderConfigEnabled(std::size_t index) const {
466 // The VertexB is always enabled. 476 // The VertexB is always enabled.
467 if (index == static_cast<std::size_t>(Regs::ShaderProgram::VertexB)) { 477 if (index == static_cast<std::size_t>(Regs::ShaderProgram::VertexB)) {
@@ -571,7 +581,11 @@ public:
571 u32 stencil_back_mask; 581 u32 stencil_back_mask;
572 u32 stencil_back_func_mask; 582 u32 stencil_back_func_mask;
573 583
574 INSERT_PADDING_WORDS(0x13); 584 INSERT_PADDING_WORDS(0xC);
585
586 u32 color_mask_common;
587
588 INSERT_PADDING_WORDS(0x6);
575 589
576 u32 rt_separate_frag_data; 590 u32 rt_separate_frag_data;
577 591
@@ -847,8 +861,9 @@ public:
847 BitField<6, 4, u32> RT; 861 BitField<6, 4, u32> RT;
848 BitField<10, 11, u32> layer; 862 BitField<10, 11, u32> layer;
849 } clear_buffers; 863 } clear_buffers;
850 864 INSERT_PADDING_WORDS(0xB);
851 INSERT_PADDING_WORDS(0x4B); 865 std::array<ColorMask, NumRenderTargets> color_mask;
866 INSERT_PADDING_WORDS(0x38);
852 867
853 struct { 868 struct {
854 u32 query_address_high; 869 u32 query_address_high;
@@ -1081,6 +1096,7 @@ ASSERT_REG_POSITION(scissor_test, 0x380);
1081ASSERT_REG_POSITION(stencil_back_func_ref, 0x3D5); 1096ASSERT_REG_POSITION(stencil_back_func_ref, 0x3D5);
1082ASSERT_REG_POSITION(stencil_back_mask, 0x3D6); 1097ASSERT_REG_POSITION(stencil_back_mask, 0x3D6);
1083ASSERT_REG_POSITION(stencil_back_func_mask, 0x3D7); 1098ASSERT_REG_POSITION(stencil_back_func_mask, 0x3D7);
1099ASSERT_REG_POSITION(color_mask_common, 0x3E4);
1084ASSERT_REG_POSITION(rt_separate_frag_data, 0x3EB); 1100ASSERT_REG_POSITION(rt_separate_frag_data, 0x3EB);
1085ASSERT_REG_POSITION(zeta, 0x3F8); 1101ASSERT_REG_POSITION(zeta, 0x3F8);
1086ASSERT_REG_POSITION(vertex_attrib_format, 0x458); 1102ASSERT_REG_POSITION(vertex_attrib_format, 0x458);
@@ -1127,6 +1143,7 @@ ASSERT_REG_POSITION(instanced_arrays, 0x620);
1127ASSERT_REG_POSITION(cull, 0x646); 1143ASSERT_REG_POSITION(cull, 0x646);
1128ASSERT_REG_POSITION(logic_op, 0x671); 1144ASSERT_REG_POSITION(logic_op, 0x671);
1129ASSERT_REG_POSITION(clear_buffers, 0x674); 1145ASSERT_REG_POSITION(clear_buffers, 0x674);
1146ASSERT_REG_POSITION(color_mask, 0x680);
1130ASSERT_REG_POSITION(query, 0x6C0); 1147ASSERT_REG_POSITION(query, 0x6C0);
1131ASSERT_REG_POSITION(vertex_array[0], 0x700); 1148ASSERT_REG_POSITION(vertex_array[0], 0x700);
1132ASSERT_REG_POSITION(independent_blend, 0x780); 1149ASSERT_REG_POSITION(independent_blend, 0x780);
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() {
511 511
512 OpenGLState clear_state; 512 OpenGLState clear_state;
513 clear_state.draw.draw_framebuffer = framebuffer.handle; 513 clear_state.draw.draw_framebuffer = framebuffer.handle;
514 clear_state.color_mask.red_enabled = regs.clear_buffers.R ? GL_TRUE : GL_FALSE; 514 clear_state.color_mask[0].red_enabled = regs.clear_buffers.R ? GL_TRUE : GL_FALSE;
515 clear_state.color_mask.green_enabled = regs.clear_buffers.G ? GL_TRUE : GL_FALSE; 515 clear_state.color_mask[0].green_enabled = regs.clear_buffers.G ? GL_TRUE : GL_FALSE;
516 clear_state.color_mask.blue_enabled = regs.clear_buffers.B ? GL_TRUE : GL_FALSE; 516 clear_state.color_mask[0].blue_enabled = regs.clear_buffers.B ? GL_TRUE : GL_FALSE;
517 clear_state.color_mask.alpha_enabled = regs.clear_buffers.A ? GL_TRUE : GL_FALSE; 517 clear_state.color_mask[0].alpha_enabled = regs.clear_buffers.A ? GL_TRUE : GL_FALSE;
518 518
519 if (regs.clear_buffers.R || regs.clear_buffers.G || regs.clear_buffers.B || 519 if (regs.clear_buffers.R || regs.clear_buffers.G || regs.clear_buffers.B ||
520 regs.clear_buffers.A) { 520 regs.clear_buffers.A) {
@@ -573,7 +573,7 @@ void RasterizerOpenGL::DrawArrays() {
573 ScopeAcquireGLContext acquire_context{emu_window}; 573 ScopeAcquireGLContext acquire_context{emu_window};
574 574
575 ConfigureFramebuffers(); 575 ConfigureFramebuffers();
576 576 SyncColorMask();
577 SyncDepthTestState(); 577 SyncDepthTestState();
578 SyncStencilTestState(); 578 SyncStencilTestState();
579 SyncBlendState(); 579 SyncBlendState();
@@ -989,6 +989,18 @@ void RasterizerOpenGL::SyncStencilTestState() {
989 state.stencil.back.write_mask = regs.stencil_back_mask; 989 state.stencil.back.write_mask = regs.stencil_back_mask;
990} 990}
991 991
992void RasterizerOpenGL::SyncColorMask() {
993 const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
994 for (size_t i = 0; i < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets; i++) {
995 const auto& source = regs.color_mask[regs.color_mask_common ? 0 : i];
996 auto& dest = state.color_mask[i];
997 dest.red_enabled = (source.R == 0) ? GL_FALSE : GL_TRUE;
998 dest.green_enabled = (source.G == 0) ? GL_FALSE : GL_TRUE;
999 dest.blue_enabled = (source.B == 0) ? GL_FALSE : GL_TRUE;
1000 dest.alpha_enabled = (source.A == 0) ? GL_FALSE : GL_TRUE;
1001 }
1002}
1003
992void RasterizerOpenGL::SyncBlendState() { 1004void RasterizerOpenGL::SyncBlendState() {
993 const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; 1005 const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
994 1006
@@ -1000,6 +1012,7 @@ void RasterizerOpenGL::SyncBlendState() {
1000 state.independant_blend.enabled = regs.independent_blend_enable; 1012 state.independant_blend.enabled = regs.independent_blend_enable;
1001 if (!state.independant_blend.enabled) { 1013 if (!state.independant_blend.enabled) {
1002 auto& blend = state.blend[0]; 1014 auto& blend = state.blend[0];
1015 blend.enabled = regs.blend.enable[0] != 0;
1003 blend.separate_alpha = regs.blend.separate_alpha; 1016 blend.separate_alpha = regs.blend.separate_alpha;
1004 blend.rgb_equation = MaxwellToGL::BlendEquation(regs.blend.equation_rgb); 1017 blend.rgb_equation = MaxwellToGL::BlendEquation(regs.blend.equation_rgb);
1005 blend.src_rgb_func = MaxwellToGL::BlendFunc(regs.blend.factor_source_rgb); 1018 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:
169 /// Syncs the point state to match the guest state 169 /// Syncs the point state to match the guest state
170 void SyncPointState(); 170 void SyncPointState();
171 171
172 /// Syncs Color Mask
173 void SyncColorMask();
174
172 /// Check asserts for alpha testing. 175 /// Check asserts for alpha testing.
173 void CheckAlphaTests(); 176 void CheckAlphaTests();
174 177
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() {
25 25
26 primitive_restart.enabled = false; 26 primitive_restart.enabled = false;
27 primitive_restart.index = 0; 27 primitive_restart.index = 0;
28 28 for (auto& item : color_mask) {
29 color_mask.red_enabled = GL_TRUE; 29 item.red_enabled = GL_TRUE;
30 color_mask.green_enabled = GL_TRUE; 30 item.green_enabled = GL_TRUE;
31 color_mask.blue_enabled = GL_TRUE; 31 item.blue_enabled = GL_TRUE;
32 color_mask.alpha_enabled = GL_TRUE; 32 item.alpha_enabled = GL_TRUE;
33 33 }
34 stencil.test_enabled = false; 34 stencil.test_enabled = false;
35 auto reset_stencil = [](auto& config) { 35 auto reset_stencil = [](auto& config) {
36 config.test_func = GL_ALWAYS; 36 config.test_func = GL_ALWAYS;
@@ -135,6 +135,32 @@ void OpenGLState::ApplyCulling() const {
135 } 135 }
136} 136}
137 137
138void OpenGLState::ApplyColorMask() const {
139 if (GLAD_GL_ARB_viewport_array) {
140 for (size_t i = 0; i < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets; i++) {
141 const auto& updated = color_mask[i];
142 const auto& current = cur_state.color_mask[i];
143 if (updated.red_enabled != current.red_enabled ||
144 updated.green_enabled != current.green_enabled ||
145 updated.blue_enabled != current.blue_enabled ||
146 updated.alpha_enabled != current.alpha_enabled) {
147 glColorMaski(static_cast<GLuint>(i), updated.red_enabled, updated.green_enabled,
148 updated.blue_enabled, updated.alpha_enabled);
149 }
150 }
151 } else {
152 const auto& updated = color_mask[0];
153 const auto& current = cur_state.color_mask[0];
154 if (updated.red_enabled != current.red_enabled ||
155 updated.green_enabled != current.green_enabled ||
156 updated.blue_enabled != current.blue_enabled ||
157 updated.alpha_enabled != current.alpha_enabled) {
158 glColorMask(updated.red_enabled, updated.green_enabled, updated.blue_enabled,
159 updated.alpha_enabled);
160 }
161 }
162}
163
138void OpenGLState::ApplyDepth() const { 164void OpenGLState::ApplyDepth() const {
139 // Depth test 165 // Depth test
140 const bool depth_test_changed = depth.test_enabled != cur_state.depth.test_enabled; 166 const bool depth_test_changed = depth.test_enabled != cur_state.depth.test_enabled;
@@ -444,18 +470,11 @@ void OpenGLState::Apply() const {
444 } 470 }
445 } 471 }
446 } 472 }
447 // Color mask
448 if (color_mask.red_enabled != cur_state.color_mask.red_enabled ||
449 color_mask.green_enabled != cur_state.color_mask.green_enabled ||
450 color_mask.blue_enabled != cur_state.color_mask.blue_enabled ||
451 color_mask.alpha_enabled != cur_state.color_mask.alpha_enabled) {
452 glColorMask(color_mask.red_enabled, color_mask.green_enabled, color_mask.blue_enabled,
453 color_mask.alpha_enabled);
454 }
455 // Point 473 // Point
456 if (point.size != cur_state.point.size) { 474 if (point.size != cur_state.point.size) {
457 glPointSize(point.size); 475 glPointSize(point.size);
458 } 476 }
477 ApplyColorMask();
459 ApplyViewport(); 478 ApplyViewport();
460 ApplyScissor(); 479 ApplyScissor();
461 ApplyStencilTest(); 480 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:
56 GLuint index; 56 GLuint index;
57 } primitive_restart; // GL_PRIMITIVE_RESTART 57 } primitive_restart; // GL_PRIMITIVE_RESTART
58 58
59 struct { 59 struct ColorMask {
60 GLboolean red_enabled; 60 GLboolean red_enabled;
61 GLboolean green_enabled; 61 GLboolean green_enabled;
62 GLboolean blue_enabled; 62 GLboolean blue_enabled;
63 GLboolean alpha_enabled; 63 GLboolean alpha_enabled;
64 } color_mask; // GL_COLOR_WRITEMASK 64 };
65 65 std::array<ColorMask, Tegra::Engines::Maxwell3D::Regs::NumRenderTargets>
66 color_mask; // GL_COLOR_WRITEMASK
66 struct { 67 struct {
67 bool test_enabled; // GL_STENCIL_TEST 68 bool test_enabled; // GL_STENCIL_TEST
68 struct { 69 struct {
@@ -198,6 +199,7 @@ private:
198 static bool s_rgb_used; 199 static bool s_rgb_used;
199 void ApplySRgb() const; 200 void ApplySRgb() const;
200 void ApplyCulling() const; 201 void ApplyCulling() const;
202 void ApplyColorMask() const;
201 void ApplyDepth() const; 203 void ApplyDepth() const;
202 void ApplyPrimitiveRestart() const; 204 void ApplyPrimitiveRestart() const;
203 void ApplyStencilTest() const; 205 void ApplyStencilTest() const;