gl_state_tracker: Implement dirty flags for stencil testing

This commit is contained in:
ReinUsesLisp 2019-12-29 23:08:32 -03:00
parent 40a2c57df5
commit 37536d7a49
4 changed files with 29 additions and 3 deletions

View file

@ -1045,14 +1045,20 @@ void RasterizerOpenGL::SyncDepthTestState() {
} }
void RasterizerOpenGL::SyncStencilTestState() { void RasterizerOpenGL::SyncStencilTestState() {
auto& maxwell3d = system.GPU().Maxwell3D(); auto& gpu = system.GPU().Maxwell3D();
const auto& regs = maxwell3d.regs; 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) { if (!regs.stencil_enable) {
glDisable(GL_STENCIL_TEST);
return; return;
} }
glEnable(GL_STENCIL_TEST);
glStencilFuncSeparate(GL_FRONT, MaxwellToGL::ComparisonOp(regs.stencil_front_func_func), glStencilFuncSeparate(GL_FRONT, MaxwellToGL::ComparisonOp(regs.stencil_front_func_func),
regs.stencil_front_func_ref, regs.stencil_front_func_mask); regs.stencil_front_func_ref, regs.stencil_front_func_mask);
glStencilOpSeparate(GL_FRONT, MaxwellToGL::StencilOp(regs.stencil_front_op_fail), glStencilOpSeparate(GL_FRONT, MaxwellToGL::StencilOp(regs.stencil_front_op_fail),

View file

@ -136,6 +136,19 @@ void SetupDirtyDepthTest(Tables& tables) {
table[OFF(depth_test_func)] = DepthTest; 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) { void SetupDirtyBlend(Tables& tables) {
FillBlock(tables[0], OFF(blend_color), NUM(blend_color), BlendColor); FillBlock(tables[0], OFF(blend_color), NUM(blend_color), BlendColor);
@ -177,6 +190,7 @@ void StateTracker::Initialize() {
SetupDirtyVertexFormat(tables); SetupDirtyVertexFormat(tables);
SetupDirtyShaders(tables); SetupDirtyShaders(tables);
SetupDirtyDepthTest(tables); SetupDirtyDepthTest(tables);
SetupDirtyStencilTest(tables);
SetupDirtyBlend(tables); SetupDirtyBlend(tables);
SetupDirtyMisc(tables); SetupDirtyMisc(tables);

View file

@ -135,6 +135,11 @@ public:
flags[OpenGL::Dirty::DepthTest] = true; flags[OpenGL::Dirty::DepthTest] = true;
} }
void NotifyStencilTest() {
auto& flags = system.GPU().Maxwell3D().dirty.flags;
flags[OpenGL::Dirty::StencilTest] = true;
}
private: private:
Core::System& system; Core::System& system;
}; };

View file

@ -585,6 +585,7 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
state_tracker.NotifyFrontFace(); state_tracker.NotifyFrontFace();
state_tracker.NotifyCullTest(); state_tracker.NotifyCullTest();
state_tracker.NotifyDepthTest(); state_tracker.NotifyDepthTest();
state_tracker.NotifyStencilTest();
program_manager.UseVertexShader(vertex_program.handle); program_manager.UseVertexShader(vertex_program.handle);
program_manager.UseGeometryShader(0); program_manager.UseGeometryShader(0);