mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-11-04 08:59:03 -06:00 
			
		
		
		
	gl_state_tracker: Implement dirty flags for viewports
This commit is contained in:
		@@ -906,13 +906,30 @@ void RasterizerOpenGL::SetupImage(u32 binding, const Tegra::Texture::TICEntry& t
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RasterizerOpenGL::SyncViewport() {
 | 
			
		||||
    const auto& regs = system.GPU().Maxwell3D().regs;
 | 
			
		||||
    for (std::size_t i = 0; i < Maxwell::NumViewports; ++i) {
 | 
			
		||||
        const auto& src = regs.viewports[i];
 | 
			
		||||
        const Common::Rectangle<f32> rect{regs.viewport_transform[i].GetRect()};
 | 
			
		||||
        glViewportIndexedf(static_cast<GLuint>(i), rect.left, rect.bottom, rect.GetWidth(),
 | 
			
		||||
                           rect.GetHeight());
 | 
			
		||||
        glDepthRangef(src.depth_range_near, src.depth_range_far);
 | 
			
		||||
    auto& gpu = system.GPU().Maxwell3D();
 | 
			
		||||
    auto& flags = gpu.dirty.flags;
 | 
			
		||||
    const auto& regs = gpu.regs;
 | 
			
		||||
 | 
			
		||||
    if (flags[Dirty::Viewports]) {
 | 
			
		||||
        flags[Dirty::Viewports] = false;
 | 
			
		||||
 | 
			
		||||
        const bool force = flags[Dirty::ViewportTransform];
 | 
			
		||||
        flags[Dirty::ViewportTransform] = false;
 | 
			
		||||
 | 
			
		||||
        for (std::size_t i = 0; i < Maxwell::NumViewports; ++i) {
 | 
			
		||||
            if (!force && !flags[Dirty::Viewport0 + i]) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            flags[Dirty::Viewport0 + i] = false;
 | 
			
		||||
 | 
			
		||||
            const Common::Rectangle<f32> rect{regs.viewport_transform[i].GetRect()};
 | 
			
		||||
            glViewportIndexedf(static_cast<GLuint>(i), rect.left, rect.bottom, rect.GetWidth(),
 | 
			
		||||
                               rect.GetHeight());
 | 
			
		||||
 | 
			
		||||
            const auto& src = regs.viewports[i];
 | 
			
		||||
            glDepthRangeIndexed(static_cast<GLuint>(i), static_cast<GLdouble>(src.depth_range_near),
 | 
			
		||||
                                static_cast<GLdouble>(src.depth_range_far));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool flip_y = false;
 | 
			
		||||
 
 | 
			
		||||
@@ -61,6 +61,22 @@ void SetupDirtyRenderTargets(Tables& tables) {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SetupDirtyViewports(Tables& tables) {
 | 
			
		||||
    for (std::size_t i = 0; i < Regs::NumViewports; ++i) {
 | 
			
		||||
        const std::size_t transf_offset = OFF(viewport_transform) + i * NUM(viewport_transform[0]);
 | 
			
		||||
        const std::size_t viewport_offset = OFF(viewports) + i * NUM(viewports[0]);
 | 
			
		||||
 | 
			
		||||
        FillBlock(tables[0], transf_offset, NUM(viewport_transform[0]), Viewport0 + i);
 | 
			
		||||
        FillBlock(tables[0], viewport_offset, NUM(viewports[0]), Viewport0 + i);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    FillBlock(tables[1], OFF(viewport_transform), NUM(viewport_transform), Viewports);
 | 
			
		||||
    FillBlock(tables[1], OFF(viewports), NUM(viewports), Viewports);
 | 
			
		||||
 | 
			
		||||
    tables[0][OFF(viewport_transform_enabled)] = ViewportTransform;
 | 
			
		||||
    tables[1][OFF(viewport_transform_enabled)] = Viewports;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // Anonymous namespace
 | 
			
		||||
 | 
			
		||||
StateTracker::StateTracker(Core::System& system) : system{system} {}
 | 
			
		||||
@@ -80,6 +96,7 @@ void StateTracker::Initialize() {
 | 
			
		||||
 | 
			
		||||
    auto& tables = dirty.tables;
 | 
			
		||||
    SetupDirtyRenderTargets(tables);
 | 
			
		||||
    SetupDirtyViewports(tables);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace OpenGL
 | 
			
		||||
 
 | 
			
		||||
@@ -23,6 +23,7 @@ enum : u8 {
 | 
			
		||||
    VertexInstances,
 | 
			
		||||
    Shaders,
 | 
			
		||||
    Viewports,
 | 
			
		||||
    ViewportTransform,
 | 
			
		||||
    CullTestEnable,
 | 
			
		||||
    FrontFace,
 | 
			
		||||
    CullFace,
 | 
			
		||||
@@ -33,7 +34,8 @@ enum : u8 {
 | 
			
		||||
    BlendState,
 | 
			
		||||
    PolygonOffset,
 | 
			
		||||
 | 
			
		||||
    VertexBuffer0 = PolygonOffset + 8,
 | 
			
		||||
    Viewport0,
 | 
			
		||||
    VertexBuffer0 = Viewport0 + 16,
 | 
			
		||||
    VertexInstance0 = VertexBuffer0 + 32,
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
@@ -44,6 +46,12 @@ public:
 | 
			
		||||
 | 
			
		||||
    void Initialize();
 | 
			
		||||
 | 
			
		||||
    void NotifyViewport0() {
 | 
			
		||||
        auto& flags = system.GPU().Maxwell3D().dirty.flags;
 | 
			
		||||
        flags[OpenGL::Dirty::Viewports] = true;
 | 
			
		||||
        flags[OpenGL::Dirty::Viewport0] = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void NotifyFramebuffer() {
 | 
			
		||||
        auto& flags = system.GPU().Maxwell3D().dirty.flags;
 | 
			
		||||
        flags[VideoCommon::Dirty::RenderTargets] = true;
 | 
			
		||||
 
 | 
			
		||||
@@ -576,6 +576,7 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
 | 
			
		||||
    glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices), std::data(vertices));
 | 
			
		||||
 | 
			
		||||
    // TODO: Signal state tracker about these changes
 | 
			
		||||
    state_tracker.NotifyViewport0();
 | 
			
		||||
    state_tracker.NotifyFramebuffer();
 | 
			
		||||
 | 
			
		||||
    program_manager.UseVertexShader(vertex_program.handle);
 | 
			
		||||
@@ -601,7 +602,9 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
 | 
			
		||||
    glFrontFace(GL_CW);
 | 
			
		||||
    glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
 | 
			
		||||
    glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE);
 | 
			
		||||
    glViewport(0, 0, layout.width, layout.height);
 | 
			
		||||
    glViewportIndexedf(0, 0.0f, 0.0f, static_cast<GLfloat>(layout.width),
 | 
			
		||||
                       static_cast<GLfloat>(layout.height));
 | 
			
		||||
    glDepthRangeIndexed(0, 0.0, 0.0);
 | 
			
		||||
 | 
			
		||||
    glVertexAttribFormat(PositionLocation, 2, GL_FLOAT, GL_FALSE,
 | 
			
		||||
                         offsetof(ScreenRectVertex, position));
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user