diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 35 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 3 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/maxwell_to_gl.h | 24 |
3 files changed, 58 insertions, 4 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 954ec10ca..8bfa75b84 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -316,16 +316,14 @@ std::pair<Surface, Surface> RasterizerOpenGL::ConfigureFramebuffers(bool using_c | |||
| 316 | using_color_fb = false; | 316 | using_color_fb = false; |
| 317 | } | 317 | } |
| 318 | 318 | ||
| 319 | // TODO(bunnei): Implement this | 319 | const bool has_stencil = regs.stencil_enable; |
| 320 | const bool has_stencil = false; | ||
| 321 | |||
| 322 | const bool write_color_fb = | 320 | const bool write_color_fb = |
| 323 | state.color_mask.red_enabled == GL_TRUE || state.color_mask.green_enabled == GL_TRUE || | 321 | state.color_mask.red_enabled == GL_TRUE || state.color_mask.green_enabled == GL_TRUE || |
| 324 | state.color_mask.blue_enabled == GL_TRUE || state.color_mask.alpha_enabled == GL_TRUE; | 322 | state.color_mask.blue_enabled == GL_TRUE || state.color_mask.alpha_enabled == GL_TRUE; |
| 325 | 323 | ||
| 326 | const bool write_depth_fb = | 324 | const bool write_depth_fb = |
| 327 | (state.depth.test_enabled && state.depth.write_mask == GL_TRUE) || | 325 | (state.depth.test_enabled && state.depth.write_mask == GL_TRUE) || |
| 328 | (has_stencil && state.stencil.test_enabled && state.stencil.write_mask != 0); | 326 | (has_stencil && (state.stencil.front.write_mask || state.stencil.back.write_mask)); |
| 329 | 327 | ||
| 330 | Surface color_surface; | 328 | Surface color_surface; |
| 331 | Surface depth_surface; | 329 | Surface depth_surface; |
| @@ -481,6 +479,7 @@ void RasterizerOpenGL::DrawArrays() { | |||
| 481 | ConfigureFramebuffers(true, regs.zeta.Address() != 0 && regs.zeta_enable != 0, true); | 479 | ConfigureFramebuffers(true, regs.zeta.Address() != 0 && regs.zeta_enable != 0, true); |
| 482 | 480 | ||
| 483 | SyncDepthTestState(); | 481 | SyncDepthTestState(); |
| 482 | SyncStencilTestState(); | ||
| 484 | SyncBlendState(); | 483 | SyncBlendState(); |
| 485 | SyncLogicOpState(); | 484 | SyncLogicOpState(); |
| 486 | SyncCullMode(); | 485 | SyncCullMode(); |
| @@ -871,6 +870,34 @@ void RasterizerOpenGL::SyncDepthTestState() { | |||
| 871 | state.depth.test_func = MaxwellToGL::ComparisonOp(regs.depth_test_func); | 870 | state.depth.test_func = MaxwellToGL::ComparisonOp(regs.depth_test_func); |
| 872 | } | 871 | } |
| 873 | 872 | ||
| 873 | void RasterizerOpenGL::SyncStencilTestState() { | ||
| 874 | const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; | ||
| 875 | state.stencil.test_enabled = regs.stencil_enable != 0; | ||
| 876 | |||
| 877 | if (!regs.stencil_enable) { | ||
| 878 | return; | ||
| 879 | } | ||
| 880 | |||
| 881 | // TODO(bunnei): Verify behavior when this is not set | ||
| 882 | ASSERT(regs.stencil_two_side_enable); | ||
| 883 | |||
| 884 | state.stencil.front.test_func = MaxwellToGL::ComparisonOp(regs.stencil_front_func_func); | ||
| 885 | state.stencil.front.test_ref = regs.stencil_front_func_ref; | ||
| 886 | state.stencil.front.test_mask = regs.stencil_front_func_mask; | ||
| 887 | state.stencil.front.action_stencil_fail = MaxwellToGL::StencilOp(regs.stencil_front_op_fail); | ||
| 888 | state.stencil.front.action_depth_fail = MaxwellToGL::StencilOp(regs.stencil_front_op_zfail); | ||
| 889 | state.stencil.front.action_depth_pass = MaxwellToGL::StencilOp(regs.stencil_front_op_zpass); | ||
| 890 | state.stencil.front.write_mask = regs.stencil_front_mask; | ||
| 891 | |||
| 892 | state.stencil.back.test_func = MaxwellToGL::ComparisonOp(regs.stencil_back_func_func); | ||
| 893 | state.stencil.back.test_ref = regs.stencil_back_func_ref; | ||
| 894 | state.stencil.back.test_mask = regs.stencil_back_func_mask; | ||
| 895 | state.stencil.back.action_stencil_fail = MaxwellToGL::StencilOp(regs.stencil_back_op_fail); | ||
| 896 | state.stencil.back.action_depth_fail = MaxwellToGL::StencilOp(regs.stencil_back_op_zfail); | ||
| 897 | state.stencil.back.action_depth_pass = MaxwellToGL::StencilOp(regs.stencil_back_op_zpass); | ||
| 898 | state.stencil.back.write_mask = regs.stencil_back_mask; | ||
| 899 | } | ||
| 900 | |||
| 874 | void RasterizerOpenGL::SyncBlendState() { | 901 | void RasterizerOpenGL::SyncBlendState() { |
| 875 | const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; | 902 | const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; |
| 876 | 903 | ||
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 59b727de0..531b04046 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h | |||
| @@ -141,6 +141,9 @@ private: | |||
| 141 | /// Syncs the depth test state to match the guest state | 141 | /// Syncs the depth test state to match the guest state |
| 142 | void SyncDepthTestState(); | 142 | void SyncDepthTestState(); |
| 143 | 143 | ||
| 144 | /// Syncs the stencil test state to match the guest state | ||
| 145 | void SyncStencilTestState(); | ||
| 146 | |||
| 144 | /// Syncs the blend state to match the guest state | 147 | /// Syncs the blend state to match the guest state |
| 145 | void SyncBlendState(); | 148 | void SyncBlendState(); |
| 146 | 149 | ||
diff --git a/src/video_core/renderer_opengl/maxwell_to_gl.h b/src/video_core/renderer_opengl/maxwell_to_gl.h index 0343759a6..67273e164 100644 --- a/src/video_core/renderer_opengl/maxwell_to_gl.h +++ b/src/video_core/renderer_opengl/maxwell_to_gl.h | |||
| @@ -295,6 +295,30 @@ inline GLenum ComparisonOp(Maxwell::ComparisonOp comparison) { | |||
| 295 | return {}; | 295 | return {}; |
| 296 | } | 296 | } |
| 297 | 297 | ||
| 298 | inline GLenum StencilOp(Maxwell::StencilOp stencil) { | ||
| 299 | switch (stencil) { | ||
| 300 | case Maxwell::StencilOp::Keep: | ||
| 301 | return GL_KEEP; | ||
| 302 | case Maxwell::StencilOp::Zero: | ||
| 303 | return GL_ZERO; | ||
| 304 | case Maxwell::StencilOp::Replace: | ||
| 305 | return GL_REPLACE; | ||
| 306 | case Maxwell::StencilOp::Incr: | ||
| 307 | return GL_INCR; | ||
| 308 | case Maxwell::StencilOp::Decr: | ||
| 309 | return GL_DECR; | ||
| 310 | case Maxwell::StencilOp::Invert: | ||
| 311 | return GL_INVERT; | ||
| 312 | case Maxwell::StencilOp::IncrWrap: | ||
| 313 | return GL_INCR_WRAP; | ||
| 314 | case Maxwell::StencilOp::DecrWrap: | ||
| 315 | return GL_DECR_WRAP; | ||
| 316 | } | ||
| 317 | LOG_CRITICAL(Render_OpenGL, "Unimplemented stencil op={}", static_cast<u32>(stencil)); | ||
| 318 | UNREACHABLE(); | ||
| 319 | return {}; | ||
| 320 | } | ||
| 321 | |||
| 298 | inline GLenum FrontFace(Maxwell::Cull::FrontFace front_face) { | 322 | inline GLenum FrontFace(Maxwell::Cull::FrontFace front_face) { |
| 299 | switch (front_face) { | 323 | switch (front_face) { |
| 300 | case Maxwell::Cull::FrontFace::ClockWise: | 324 | case Maxwell::Cull::FrontFace::ClockWise: |