mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-11-04 08:59:03 -06:00 
			
		
		
		
	gl_state_tracker: Implement dirty flags for blending
This commit is contained in:
		@@ -458,6 +458,7 @@ void RasterizerOpenGL::Clear() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // TODO: Signal state tracker about these changes
 | 
			
		||||
    state_tracker.NotifyBlend0();
 | 
			
		||||
    // TODO(Rodrigo): Find out if these changes affect clearing
 | 
			
		||||
    glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE);
 | 
			
		||||
    glDisablei(GL_BLEND, 0);
 | 
			
		||||
@@ -1102,31 +1103,53 @@ void RasterizerOpenGL::SyncFragmentColorClampState() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RasterizerOpenGL::SyncBlendState() {
 | 
			
		||||
    auto& maxwell3d = system.GPU().Maxwell3D();
 | 
			
		||||
    const auto& regs = maxwell3d.regs;
 | 
			
		||||
    auto& gpu = system.GPU().Maxwell3D();
 | 
			
		||||
    auto& flags = gpu.dirty.flags;
 | 
			
		||||
    const auto& regs = gpu.regs;
 | 
			
		||||
 | 
			
		||||
    glBlendColor(regs.blend_color.r, regs.blend_color.g, regs.blend_color.b, regs.blend_color.a);
 | 
			
		||||
    if (flags[Dirty::BlendColor]) {
 | 
			
		||||
        flags[Dirty::BlendColor] = false;
 | 
			
		||||
        glBlendColor(regs.blend_color.r, regs.blend_color.g, regs.blend_color.b,
 | 
			
		||||
                     regs.blend_color.a);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // TODO(Rodrigo): Revisit blending, there are several registers we are not reading
 | 
			
		||||
 | 
			
		||||
    if (!flags[Dirty::BlendStates]) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    flags[Dirty::BlendStates] = false;
 | 
			
		||||
 | 
			
		||||
    if (!regs.independent_blend_enable) {
 | 
			
		||||
        const auto& src = regs.blend;
 | 
			
		||||
        oglEnable(GL_BLEND, src.enable[0]);
 | 
			
		||||
        if (!src.enable[0]) {
 | 
			
		||||
        if (!regs.blend.enable[0]) {
 | 
			
		||||
            glDisable(GL_BLEND);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        glBlendFuncSeparate(MaxwellToGL::BlendFunc(src.factor_source_rgb),
 | 
			
		||||
                            MaxwellToGL::BlendFunc(src.factor_dest_rgb),
 | 
			
		||||
                            MaxwellToGL::BlendFunc(src.factor_source_a),
 | 
			
		||||
                            MaxwellToGL::BlendFunc(src.factor_dest_a));
 | 
			
		||||
        glBlendEquationSeparate(MaxwellToGL::BlendEquation(src.equation_rgb),
 | 
			
		||||
                                MaxwellToGL::BlendEquation(src.equation_a));
 | 
			
		||||
        glEnable(GL_BLEND);
 | 
			
		||||
        glBlendFuncSeparate(MaxwellToGL::BlendFunc(regs.blend.factor_source_rgb),
 | 
			
		||||
                            MaxwellToGL::BlendFunc(regs.blend.factor_dest_rgb),
 | 
			
		||||
                            MaxwellToGL::BlendFunc(regs.blend.factor_source_a),
 | 
			
		||||
                            MaxwellToGL::BlendFunc(regs.blend.factor_dest_a));
 | 
			
		||||
        glBlendEquationSeparate(MaxwellToGL::BlendEquation(regs.blend.equation_rgb),
 | 
			
		||||
                                MaxwellToGL::BlendEquation(regs.blend.equation_a));
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const bool force = flags[Dirty::BlendIndependentEnabled];
 | 
			
		||||
    flags[Dirty::BlendIndependentEnabled] = false;
 | 
			
		||||
 | 
			
		||||
    for (std::size_t i = 0; i < Maxwell::NumRenderTargets; ++i) {
 | 
			
		||||
        oglEnablei(GL_BLEND, regs.blend.enable[i], static_cast<GLuint>(i));
 | 
			
		||||
        if (!regs.blend.enable[i]) {
 | 
			
		||||
        if (!force && !flags[Dirty::BlendState0 + i]) {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        flags[Dirty::BlendState0 + i] = false;
 | 
			
		||||
 | 
			
		||||
        if (!regs.blend.enable[i]) {
 | 
			
		||||
            glDisablei(GL_BLEND, static_cast<GLuint>(i));
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        glEnablei(GL_BLEND, static_cast<GLuint>(i));
 | 
			
		||||
 | 
			
		||||
        const auto& src = regs.independent_blend[i];
 | 
			
		||||
        glBlendFuncSeparatei(static_cast<GLuint>(i), MaxwellToGL::BlendFunc(src.factor_source_rgb),
 | 
			
		||||
                             MaxwellToGL::BlendFunc(src.factor_dest_rgb),
 | 
			
		||||
 
 | 
			
		||||
@@ -129,6 +129,21 @@ void SetupDirtyShaders(Tables& tables) {
 | 
			
		||||
              Shaders);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SetupDirtyBlend(Tables& tables) {
 | 
			
		||||
    FillBlock(tables[0], OFF(blend_color), NUM(blend_color), BlendColor);
 | 
			
		||||
 | 
			
		||||
    tables[0][OFF(independent_blend_enable)] = BlendIndependentEnabled;
 | 
			
		||||
 | 
			
		||||
    for (std::size_t i = 0; i < Regs::NumRenderTargets; ++i) {
 | 
			
		||||
        const std::size_t offset = OFF(independent_blend) + i * NUM(independent_blend[0]);
 | 
			
		||||
        FillBlock(tables[0], offset, NUM(independent_blend[0]), BlendState0 + i);
 | 
			
		||||
 | 
			
		||||
        tables[0][OFF(blend.enable) + i] = static_cast<u8>(BlendState0 + i);
 | 
			
		||||
    }
 | 
			
		||||
    FillBlock(tables[1], OFF(independent_blend), NUM(independent_blend), BlendStates);
 | 
			
		||||
    FillBlock(tables[1], OFF(blend), NUM(blend), BlendStates);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SetupDirtyMisc(Tables& tables) {
 | 
			
		||||
    tables[0][OFF(clip_distance_enabled)] = ClipDistances;
 | 
			
		||||
}
 | 
			
		||||
@@ -147,6 +162,7 @@ void StateTracker::Initialize() {
 | 
			
		||||
    SetupDirtyVertexArrays(tables);
 | 
			
		||||
    SetupDirtyVertexFormat(tables);
 | 
			
		||||
    SetupDirtyShaders(tables);
 | 
			
		||||
    SetupDirtyBlend(tables);
 | 
			
		||||
    SetupDirtyMisc(tables);
 | 
			
		||||
 | 
			
		||||
    auto& store = dirty.on_write_stores;
 | 
			
		||||
 
 | 
			
		||||
@@ -47,8 +47,15 @@ enum : u8 {
 | 
			
		||||
    ColorMask0,
 | 
			
		||||
    ColorMask7 = ColorMask0 + 7,
 | 
			
		||||
 | 
			
		||||
    BlendColor,
 | 
			
		||||
    BlendIndependentEnabled,
 | 
			
		||||
    BlendStates,
 | 
			
		||||
    BlendState0,
 | 
			
		||||
    BlendState7 = BlendState0 + 7,
 | 
			
		||||
 | 
			
		||||
    Shaders,
 | 
			
		||||
    ClipDistances,
 | 
			
		||||
 | 
			
		||||
    CullTestEnable,
 | 
			
		||||
    FrontFace,
 | 
			
		||||
    CullFace,
 | 
			
		||||
@@ -56,7 +63,6 @@ enum : u8 {
 | 
			
		||||
    DepthTest,
 | 
			
		||||
    StencilTest,
 | 
			
		||||
    ColorMask,
 | 
			
		||||
    BlendState,
 | 
			
		||||
    PolygonOffset,
 | 
			
		||||
 | 
			
		||||
    Last
 | 
			
		||||
@@ -103,6 +109,12 @@ public:
 | 
			
		||||
        flags[OpenGL::Dirty::ColorMask0] = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void NotifyBlend0() {
 | 
			
		||||
        auto& flags = system.GPU().Maxwell3D().dirty.flags;
 | 
			
		||||
        flags[OpenGL::Dirty::BlendStates] = true;
 | 
			
		||||
        flags[OpenGL::Dirty::BlendState0] = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void NotifyFramebuffer() {
 | 
			
		||||
        auto& flags = system.GPU().Maxwell3D().dirty.flags;
 | 
			
		||||
        flags[VideoCommon::Dirty::RenderTargets] = true;
 | 
			
		||||
 
 | 
			
		||||
@@ -520,6 +520,7 @@ void TextureCacheOpenGL::ImageBlit(View& src_view, View& dst_view,
 | 
			
		||||
 | 
			
		||||
    // TODO: Signal state tracker about these changes
 | 
			
		||||
    state_tracker.NotifyScissor0();
 | 
			
		||||
    state_tracker.NotifyBlend0();
 | 
			
		||||
    state_tracker.NotifyFramebuffer();
 | 
			
		||||
 | 
			
		||||
    if (dst_params.srgb_conversion) {
 | 
			
		||||
 
 | 
			
		||||
@@ -580,6 +580,7 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
 | 
			
		||||
    state_tracker.NotifyViewport0();
 | 
			
		||||
    state_tracker.NotifyScissor0();
 | 
			
		||||
    state_tracker.NotifyColorMask0();
 | 
			
		||||
    state_tracker.NotifyBlend0();
 | 
			
		||||
    state_tracker.NotifyFramebuffer();
 | 
			
		||||
 | 
			
		||||
    program_manager.UseVertexShader(vertex_program.handle);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user