mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu.git
				synced 2025-05-12 00:45:25 +00:00 
			
		
		
		
	gl_rasterizer: Implement stencil test.
- Used by Splatoon 2.
This commit is contained in:
		
							parent
							
								
									da3da6be90
								
							
						
					
					
						commit
						a4ac3bed6c
					
				@ -316,16 +316,14 @@ std::pair<Surface, Surface> RasterizerOpenGL::ConfigureFramebuffers(bool using_c
 | 
				
			|||||||
        using_color_fb = false;
 | 
					        using_color_fb = false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // TODO(bunnei): Implement this
 | 
					    const bool has_stencil = regs.stencil_enable;
 | 
				
			||||||
    const bool has_stencil = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const bool write_color_fb =
 | 
					    const bool write_color_fb =
 | 
				
			||||||
        state.color_mask.red_enabled == GL_TRUE || state.color_mask.green_enabled == GL_TRUE ||
 | 
					        state.color_mask.red_enabled == GL_TRUE || state.color_mask.green_enabled == GL_TRUE ||
 | 
				
			||||||
        state.color_mask.blue_enabled == GL_TRUE || state.color_mask.alpha_enabled == GL_TRUE;
 | 
					        state.color_mask.blue_enabled == GL_TRUE || state.color_mask.alpha_enabled == GL_TRUE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const bool write_depth_fb =
 | 
					    const bool write_depth_fb =
 | 
				
			||||||
        (state.depth.test_enabled && state.depth.write_mask == GL_TRUE) ||
 | 
					        (state.depth.test_enabled && state.depth.write_mask == GL_TRUE) ||
 | 
				
			||||||
        (has_stencil && state.stencil.test_enabled && state.stencil.write_mask != 0);
 | 
					        (has_stencil && (state.stencil.front.write_mask || state.stencil.back.write_mask));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Surface color_surface;
 | 
					    Surface color_surface;
 | 
				
			||||||
    Surface depth_surface;
 | 
					    Surface depth_surface;
 | 
				
			||||||
@ -481,6 +479,7 @@ void RasterizerOpenGL::DrawArrays() {
 | 
				
			|||||||
        ConfigureFramebuffers(true, regs.zeta.Address() != 0 && regs.zeta_enable != 0, true);
 | 
					        ConfigureFramebuffers(true, regs.zeta.Address() != 0 && regs.zeta_enable != 0, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SyncDepthTestState();
 | 
					    SyncDepthTestState();
 | 
				
			||||||
 | 
					    SyncStencilTestState();
 | 
				
			||||||
    SyncBlendState();
 | 
					    SyncBlendState();
 | 
				
			||||||
    SyncLogicOpState();
 | 
					    SyncLogicOpState();
 | 
				
			||||||
    SyncCullMode();
 | 
					    SyncCullMode();
 | 
				
			||||||
@ -871,6 +870,34 @@ void RasterizerOpenGL::SyncDepthTestState() {
 | 
				
			|||||||
    state.depth.test_func = MaxwellToGL::ComparisonOp(regs.depth_test_func);
 | 
					    state.depth.test_func = MaxwellToGL::ComparisonOp(regs.depth_test_func);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void RasterizerOpenGL::SyncStencilTestState() {
 | 
				
			||||||
 | 
					    const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
 | 
				
			||||||
 | 
					    state.stencil.test_enabled = regs.stencil_enable != 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!regs.stencil_enable) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // TODO(bunnei): Verify behavior when this is not set
 | 
				
			||||||
 | 
					    ASSERT(regs.stencil_two_side_enable);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    state.stencil.front.test_func = MaxwellToGL::ComparisonOp(regs.stencil_front_func_func);
 | 
				
			||||||
 | 
					    state.stencil.front.test_ref = regs.stencil_front_func_ref;
 | 
				
			||||||
 | 
					    state.stencil.front.test_mask = regs.stencil_front_func_mask;
 | 
				
			||||||
 | 
					    state.stencil.front.action_stencil_fail = MaxwellToGL::StencilOp(regs.stencil_front_op_fail);
 | 
				
			||||||
 | 
					    state.stencil.front.action_depth_fail = MaxwellToGL::StencilOp(regs.stencil_front_op_zfail);
 | 
				
			||||||
 | 
					    state.stencil.front.action_depth_pass = MaxwellToGL::StencilOp(regs.stencil_front_op_zpass);
 | 
				
			||||||
 | 
					    state.stencil.front.write_mask = regs.stencil_front_mask;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    state.stencil.back.test_func = MaxwellToGL::ComparisonOp(regs.stencil_back_func_func);
 | 
				
			||||||
 | 
					    state.stencil.back.test_ref = regs.stencil_back_func_ref;
 | 
				
			||||||
 | 
					    state.stencil.back.test_mask = regs.stencil_back_func_mask;
 | 
				
			||||||
 | 
					    state.stencil.back.action_stencil_fail = MaxwellToGL::StencilOp(regs.stencil_back_op_fail);
 | 
				
			||||||
 | 
					    state.stencil.back.action_depth_fail = MaxwellToGL::StencilOp(regs.stencil_back_op_zfail);
 | 
				
			||||||
 | 
					    state.stencil.back.action_depth_pass = MaxwellToGL::StencilOp(regs.stencil_back_op_zpass);
 | 
				
			||||||
 | 
					    state.stencil.back.write_mask = regs.stencil_back_mask;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void RasterizerOpenGL::SyncBlendState() {
 | 
					void RasterizerOpenGL::SyncBlendState() {
 | 
				
			||||||
    const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
 | 
					    const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -141,6 +141,9 @@ private:
 | 
				
			|||||||
    /// Syncs the depth test state to match the guest state
 | 
					    /// Syncs the depth test state to match the guest state
 | 
				
			||||||
    void SyncDepthTestState();
 | 
					    void SyncDepthTestState();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Syncs the stencil test state to match the guest state
 | 
				
			||||||
 | 
					    void SyncStencilTestState();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Syncs the blend state to match the guest state
 | 
					    /// Syncs the blend state to match the guest state
 | 
				
			||||||
    void SyncBlendState();
 | 
					    void SyncBlendState();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -295,6 +295,30 @@ inline GLenum ComparisonOp(Maxwell::ComparisonOp comparison) {
 | 
				
			|||||||
    return {};
 | 
					    return {};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline GLenum StencilOp(Maxwell::StencilOp stencil) {
 | 
				
			||||||
 | 
					    switch (stencil) {
 | 
				
			||||||
 | 
					    case Maxwell::StencilOp::Keep:
 | 
				
			||||||
 | 
					        return GL_KEEP;
 | 
				
			||||||
 | 
					    case Maxwell::StencilOp::Zero:
 | 
				
			||||||
 | 
					        return GL_ZERO;
 | 
				
			||||||
 | 
					    case Maxwell::StencilOp::Replace:
 | 
				
			||||||
 | 
					        return GL_REPLACE;
 | 
				
			||||||
 | 
					    case Maxwell::StencilOp::Incr:
 | 
				
			||||||
 | 
					        return GL_INCR;
 | 
				
			||||||
 | 
					    case Maxwell::StencilOp::Decr:
 | 
				
			||||||
 | 
					        return GL_DECR;
 | 
				
			||||||
 | 
					    case Maxwell::StencilOp::Invert:
 | 
				
			||||||
 | 
					        return GL_INVERT;
 | 
				
			||||||
 | 
					    case Maxwell::StencilOp::IncrWrap:
 | 
				
			||||||
 | 
					        return GL_INCR_WRAP;
 | 
				
			||||||
 | 
					    case Maxwell::StencilOp::DecrWrap:
 | 
				
			||||||
 | 
					        return GL_DECR_WRAP;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    LOG_CRITICAL(Render_OpenGL, "Unimplemented stencil op={}", static_cast<u32>(stencil));
 | 
				
			||||||
 | 
					    UNREACHABLE();
 | 
				
			||||||
 | 
					    return {};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
inline GLenum FrontFace(Maxwell::Cull::FrontFace front_face) {
 | 
					inline GLenum FrontFace(Maxwell::Cull::FrontFace front_face) {
 | 
				
			||||||
    switch (front_face) {
 | 
					    switch (front_face) {
 | 
				
			||||||
    case Maxwell::Cull::FrontFace::ClockWise:
 | 
					    case Maxwell::Cull::FrontFace::ClockWise:
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user