From 8fa5995077d701c624e804015005c237db5aa4e1 Mon Sep 17 00:00:00 2001 From: Jannik Vogel Date: Fri, 1 Apr 2016 01:48:36 +0200 Subject: [PATCH] OpenGL: Respect depth-read allow register --- .../renderer_opengl/gl_rasterizer.cpp | 33 ++++++++++++++++--- src/video_core/renderer_opengl/pica_to_gl.h | 24 ++++++++++++++ 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 051b05cce..8348b0633 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -314,6 +314,11 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) { SyncBlendFuncs(); break; + // Stencil and depth read mask + case PICA_REG_INDEX(framebuffer.allow_stencil_read): + SyncDepthTest(); + break; + // Logic op case PICA_REG_INDEX(output_merger.logic_op): SyncLogicOp(); @@ -1032,10 +1037,30 @@ void RasterizerOpenGL::SyncStencilTest() { void RasterizerOpenGL::SyncDepthTest() { const auto& regs = Pica::g_state.regs; - state.depth.test_enabled = regs.output_merger.depth_test_enable == 1 || - regs.output_merger.depth_write_enable == 1; - state.depth.test_func = regs.output_merger.depth_test_enable == 1 ? - PicaToGL::CompareFunc(regs.output_merger.depth_test_func) : GL_ALWAYS; + + // Enable depth test so depth writes can still occur + state.depth.test_enabled = GL_TRUE; + + if (!regs.output_merger.depth_test_enable) { + state.depth.test_func = GL_ALWAYS; + } else { + + if (!regs.framebuffer.allow_depth_read) { + + // If reads are not allowed we have to patch the depth test accordingly + state.depth.test_func = PicaToGL::CompareXToZeroFunc(regs.output_merger.depth_test_func); + + // Check if the result is known at this point, if not it depends on the framebuffer really being zero + if (state.depth.test_func != GL_NEVER && state.depth.test_func != GL_ALWAYS) { + LOG_CRITICAL(Render_OpenGL, "Can't emulate disabled read on depth yet"); + UNIMPLEMENTED(); + } + + } else { + state.depth.test_func = PicaToGL::CompareFunc(regs.output_merger.depth_test_func); + } + + } } void RasterizerOpenGL::SyncCombinerColor() { diff --git a/src/video_core/renderer_opengl/pica_to_gl.h b/src/video_core/renderer_opengl/pica_to_gl.h index fd3617d77..1cb76bd21 100644 --- a/src/video_core/renderer_opengl/pica_to_gl.h +++ b/src/video_core/renderer_opengl/pica_to_gl.h @@ -155,6 +155,30 @@ inline GLenum CompareFunc(Pica::Regs::CompareFunc func) { return compare_func_table[(unsigned)func]; } +/// Pretend we compare 'x FUNC 0' (unsigned) +inline GLenum CompareXToZeroFunc(Pica::Regs::CompareFunc func) { + static const GLenum compare_func_table[] = { + GL_NEVER, // CompareFunc::Never + GL_ALWAYS, // CompareFunc::Always + GL_EQUAL, // CompareFunc::Equal + GL_NOTEQUAL, // CompareFunc::NotEqual + GL_NEVER, // CompareFunc::LessThan + GL_LEQUAL, // CompareFunc::LessThanOrEqual + GL_GREATER, // CompareFunc::GreaterThan + GL_ALWAYS, // CompareFunc::GreaterThanOrEqual + }; + + // Range check table for input + if (static_cast(func) >= ARRAY_SIZE(compare_func_table)) { + LOG_CRITICAL(Render_OpenGL, "Unknown compare function %d", func); + UNREACHABLE(); + + return GL_ALWAYS; + } + + return compare_func_table[(unsigned)func]; +} + inline GLenum StencilOp(Pica::Regs::StencilAction action) { static const GLenum stencil_op_table[] = { GL_KEEP, // StencilAction::Keep