summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp35
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h3
-rw-r--r--src/video_core/renderer_opengl/maxwell_to_gl.h24
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
873void 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
874void RasterizerOpenGL::SyncBlendState() { 901void 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
298inline 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
298inline GLenum FrontFace(Maxwell::Cull::FrontFace front_face) { 322inline 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: