diff options
| -rw-r--r-- | src/video_core/engines/maxwell_3d.h | 23 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 23 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 3 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_state.cpp | 47 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_state.h | 8 |
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); | |||
| 1081 | ASSERT_REG_POSITION(stencil_back_func_ref, 0x3D5); | 1096 | ASSERT_REG_POSITION(stencil_back_func_ref, 0x3D5); |
| 1082 | ASSERT_REG_POSITION(stencil_back_mask, 0x3D6); | 1097 | ASSERT_REG_POSITION(stencil_back_mask, 0x3D6); |
| 1083 | ASSERT_REG_POSITION(stencil_back_func_mask, 0x3D7); | 1098 | ASSERT_REG_POSITION(stencil_back_func_mask, 0x3D7); |
| 1099 | ASSERT_REG_POSITION(color_mask_common, 0x3E4); | ||
| 1084 | ASSERT_REG_POSITION(rt_separate_frag_data, 0x3EB); | 1100 | ASSERT_REG_POSITION(rt_separate_frag_data, 0x3EB); |
| 1085 | ASSERT_REG_POSITION(zeta, 0x3F8); | 1101 | ASSERT_REG_POSITION(zeta, 0x3F8); |
| 1086 | ASSERT_REG_POSITION(vertex_attrib_format, 0x458); | 1102 | ASSERT_REG_POSITION(vertex_attrib_format, 0x458); |
| @@ -1127,6 +1143,7 @@ ASSERT_REG_POSITION(instanced_arrays, 0x620); | |||
| 1127 | ASSERT_REG_POSITION(cull, 0x646); | 1143 | ASSERT_REG_POSITION(cull, 0x646); |
| 1128 | ASSERT_REG_POSITION(logic_op, 0x671); | 1144 | ASSERT_REG_POSITION(logic_op, 0x671); |
| 1129 | ASSERT_REG_POSITION(clear_buffers, 0x674); | 1145 | ASSERT_REG_POSITION(clear_buffers, 0x674); |
| 1146 | ASSERT_REG_POSITION(color_mask, 0x680); | ||
| 1130 | ASSERT_REG_POSITION(query, 0x6C0); | 1147 | ASSERT_REG_POSITION(query, 0x6C0); |
| 1131 | ASSERT_REG_POSITION(vertex_array[0], 0x700); | 1148 | ASSERT_REG_POSITION(vertex_array[0], 0x700); |
| 1132 | ASSERT_REG_POSITION(independent_blend, 0x780); | 1149 | ASSERT_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 | ||
| 992 | void 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 | |||
| 992 | void RasterizerOpenGL::SyncBlendState() { | 1004 | void 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 | ||
| 138 | void 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 | |||
| 138 | void OpenGLState::ApplyDepth() const { | 164 | void 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; |