From 37536d7a4996d0008d8988f50dcbc7c126a99c14 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sun, 29 Dec 2019 23:08:32 -0300 Subject: gl_state_tracker: Implement dirty flags for stencil testing --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 12 +++++++++--- src/video_core/renderer_opengl/gl_state_tracker.cpp | 14 ++++++++++++++ src/video_core/renderer_opengl/gl_state_tracker.h | 5 +++++ src/video_core/renderer_opengl/renderer_opengl.cpp | 1 + 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index d747e29ad..bc4542b69 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -1045,14 +1045,20 @@ void RasterizerOpenGL::SyncDepthTestState() { } void RasterizerOpenGL::SyncStencilTestState() { - auto& maxwell3d = system.GPU().Maxwell3D(); - const auto& regs = maxwell3d.regs; + auto& gpu = system.GPU().Maxwell3D(); + auto& flags = gpu.dirty.flags; + if (!flags[Dirty::StencilTest]) { + return; + } + flags[Dirty::StencilTest] = false; - oglEnable(GL_STENCIL_TEST, regs.stencil_enable); + const auto& regs = gpu.regs; if (!regs.stencil_enable) { + glDisable(GL_STENCIL_TEST); return; } + glEnable(GL_STENCIL_TEST); glStencilFuncSeparate(GL_FRONT, MaxwellToGL::ComparisonOp(regs.stencil_front_func_func), regs.stencil_front_func_ref, regs.stencil_front_func_mask); glStencilOpSeparate(GL_FRONT, MaxwellToGL::StencilOp(regs.stencil_front_op_fail), diff --git a/src/video_core/renderer_opengl/gl_state_tracker.cpp b/src/video_core/renderer_opengl/gl_state_tracker.cpp index 999440656..eae47827b 100644 --- a/src/video_core/renderer_opengl/gl_state_tracker.cpp +++ b/src/video_core/renderer_opengl/gl_state_tracker.cpp @@ -136,6 +136,19 @@ void SetupDirtyDepthTest(Tables& tables) { table[OFF(depth_test_func)] = DepthTest; } +void SetupDirtyStencilTest(Tables& tables) { + static constexpr std::array offsets = { + OFF(stencil_enable), OFF(stencil_front_func_func), OFF(stencil_front_func_ref), + OFF(stencil_front_func_mask), OFF(stencil_front_op_fail), OFF(stencil_front_op_zfail), + OFF(stencil_front_op_zpass), OFF(stencil_front_mask), OFF(stencil_two_side_enable), + OFF(stencil_back_func_func), OFF(stencil_back_func_ref), OFF(stencil_back_func_mask), + OFF(stencil_back_op_fail), OFF(stencil_back_op_zfail), OFF(stencil_back_op_zpass), + OFF(stencil_back_mask)}; + for (const auto offset : offsets) { + tables[0][offset] = StencilTest; + } +} + void SetupDirtyBlend(Tables& tables) { FillBlock(tables[0], OFF(blend_color), NUM(blend_color), BlendColor); @@ -177,6 +190,7 @@ void StateTracker::Initialize() { SetupDirtyVertexFormat(tables); SetupDirtyShaders(tables); SetupDirtyDepthTest(tables); + SetupDirtyStencilTest(tables); SetupDirtyBlend(tables); SetupDirtyMisc(tables); diff --git a/src/video_core/renderer_opengl/gl_state_tracker.h b/src/video_core/renderer_opengl/gl_state_tracker.h index dd6cfe02a..2eaec2a0d 100644 --- a/src/video_core/renderer_opengl/gl_state_tracker.h +++ b/src/video_core/renderer_opengl/gl_state_tracker.h @@ -135,6 +135,11 @@ public: flags[OpenGL::Dirty::DepthTest] = true; } + void NotifyStencilTest() { + auto& flags = system.GPU().Maxwell3D().dirty.flags; + flags[OpenGL::Dirty::StencilTest] = true; + } + private: Core::System& system; }; diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 8fa4ecb28..2449e28ac 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -585,6 +585,7 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) { state_tracker.NotifyFrontFace(); state_tracker.NotifyCullTest(); state_tracker.NotifyDepthTest(); + state_tracker.NotifyStencilTest(); program_manager.UseVertexShader(vertex_program.handle); program_manager.UseGeometryShader(0); -- cgit v1.2.3