mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-11-04 08:59:03 -06:00 
			
		
		
		
	gl_state: Remove framebuffer tracking
This commit is contained in:
		@@ -36,8 +36,7 @@ OGLFramebuffer FramebufferCacheOpenGL::CreateFramebuffer(const FramebufferCacheK
 | 
			
		||||
    framebuffer.Create();
 | 
			
		||||
 | 
			
		||||
    // TODO(Rodrigo): Use DSA here after Nvidia fixes their framebuffer DSA bugs.
 | 
			
		||||
    local_state.draw.draw_framebuffer = framebuffer.handle;
 | 
			
		||||
    local_state.ApplyFramebufferState();
 | 
			
		||||
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer.handle);
 | 
			
		||||
 | 
			
		||||
    if (key.zeta) {
 | 
			
		||||
        const bool stencil = key.zeta->GetSurfaceParams().type == SurfaceType::DepthStencil;
 | 
			
		||||
 
 | 
			
		||||
@@ -359,7 +359,7 @@ void RasterizerOpenGL::ConfigureFramebuffers() {
 | 
			
		||||
 | 
			
		||||
    texture_cache.GuardRenderTargets(false);
 | 
			
		||||
 | 
			
		||||
    state.draw.draw_framebuffer = framebuffer_cache.GetFramebuffer(key);
 | 
			
		||||
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer_cache.GetFramebuffer(key));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RasterizerOpenGL::ConfigureClearFramebuffer(OpenGLState& current_state, bool using_color_fb,
 | 
			
		||||
@@ -384,8 +384,7 @@ void RasterizerOpenGL::ConfigureClearFramebuffer(OpenGLState& current_state, boo
 | 
			
		||||
    key.colors[0] = color_surface;
 | 
			
		||||
    key.zeta = depth_surface;
 | 
			
		||||
 | 
			
		||||
    current_state.draw.draw_framebuffer = framebuffer_cache.GetFramebuffer(key);
 | 
			
		||||
    current_state.ApplyFramebufferState();
 | 
			
		||||
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer_cache.GetFramebuffer(key));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RasterizerOpenGL::Clear() {
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,7 @@ void OGLRenderbuffer::Create() {
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    MICROPROFILE_SCOPE(OpenGL_ResourceCreation);
 | 
			
		||||
    glGenRenderbuffers(1, &handle);
 | 
			
		||||
    glCreateRenderbuffers(1, &handle);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OGLRenderbuffer::Release() {
 | 
			
		||||
@@ -29,7 +29,6 @@ void OGLRenderbuffer::Release() {
 | 
			
		||||
 | 
			
		||||
    MICROPROFILE_SCOPE(OpenGL_ResourceDeletion);
 | 
			
		||||
    glDeleteRenderbuffers(1, &handle);
 | 
			
		||||
    OpenGLState::GetCurState().ResetRenderbuffer(handle).Apply();
 | 
			
		||||
    handle = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -200,7 +199,6 @@ void OGLFramebuffer::Release() {
 | 
			
		||||
 | 
			
		||||
    MICROPROFILE_SCOPE(OpenGL_ResourceDeletion);
 | 
			
		||||
    glDeleteFramebuffers(1, &handle);
 | 
			
		||||
    OpenGLState::GetCurState().ResetFramebuffer(handle).Apply();
 | 
			
		||||
    handle = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -85,15 +85,6 @@ void Enable(GLenum cap, GLuint index, bool& current_value, bool new_value) {
 | 
			
		||||
 | 
			
		||||
OpenGLState::OpenGLState() = default;
 | 
			
		||||
 | 
			
		||||
void OpenGLState::ApplyFramebufferState() {
 | 
			
		||||
    if (UpdateValue(cur_state.draw.read_framebuffer, draw.read_framebuffer)) {
 | 
			
		||||
        glBindFramebuffer(GL_READ_FRAMEBUFFER, draw.read_framebuffer);
 | 
			
		||||
    }
 | 
			
		||||
    if (UpdateValue(cur_state.draw.draw_framebuffer, draw.draw_framebuffer)) {
 | 
			
		||||
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, draw.draw_framebuffer);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OpenGLState::ApplyShaderProgram() {
 | 
			
		||||
    if (UpdateValue(cur_state.draw.shader_program, draw.shader_program)) {
 | 
			
		||||
        glUseProgram(draw.shader_program);
 | 
			
		||||
@@ -106,19 +97,10 @@ void OpenGLState::ApplyProgramPipeline() {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OpenGLState::ApplyRenderBuffer() {
 | 
			
		||||
    if (cur_state.renderbuffer != renderbuffer) {
 | 
			
		||||
        cur_state.renderbuffer = renderbuffer;
 | 
			
		||||
        glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OpenGLState::Apply() {
 | 
			
		||||
    MICROPROFILE_SCOPE(OpenGL_State);
 | 
			
		||||
    ApplyFramebufferState();
 | 
			
		||||
    ApplyShaderProgram();
 | 
			
		||||
    ApplyProgramPipeline();
 | 
			
		||||
    ApplyRenderBuffer();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
OpenGLState& OpenGLState::ResetProgram(GLuint handle) {
 | 
			
		||||
@@ -135,21 +117,4 @@ OpenGLState& OpenGLState::ResetPipeline(GLuint handle) {
 | 
			
		||||
    return *this;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
OpenGLState& OpenGLState::ResetFramebuffer(GLuint handle) {
 | 
			
		||||
    if (draw.read_framebuffer == handle) {
 | 
			
		||||
        draw.read_framebuffer = 0;
 | 
			
		||||
    }
 | 
			
		||||
    if (draw.draw_framebuffer == handle) {
 | 
			
		||||
        draw.draw_framebuffer = 0;
 | 
			
		||||
    }
 | 
			
		||||
    return *this;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
OpenGLState& OpenGLState::ResetRenderbuffer(GLuint handle) {
 | 
			
		||||
    if (renderbuffer == handle) {
 | 
			
		||||
        renderbuffer = 0;
 | 
			
		||||
    }
 | 
			
		||||
    return *this;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace OpenGL
 | 
			
		||||
 
 | 
			
		||||
@@ -14,14 +14,10 @@ namespace OpenGL {
 | 
			
		||||
class OpenGLState {
 | 
			
		||||
public:
 | 
			
		||||
    struct {
 | 
			
		||||
        GLuint read_framebuffer = 0; // GL_READ_FRAMEBUFFER_BINDING
 | 
			
		||||
        GLuint draw_framebuffer = 0; // GL_DRAW_FRAMEBUFFER_BINDING
 | 
			
		||||
        GLuint shader_program = 0;   // GL_CURRENT_PROGRAM
 | 
			
		||||
        GLuint program_pipeline = 0; // GL_PROGRAM_PIPELINE_BINDING
 | 
			
		||||
    } draw;
 | 
			
		||||
 | 
			
		||||
    GLuint renderbuffer{}; // GL_RENDERBUFFER_BINDING
 | 
			
		||||
 | 
			
		||||
    OpenGLState();
 | 
			
		||||
 | 
			
		||||
    /// Get the currently active OpenGL state
 | 
			
		||||
@@ -32,16 +28,12 @@ public:
 | 
			
		||||
    /// Apply this state as the current OpenGL state
 | 
			
		||||
    void Apply();
 | 
			
		||||
 | 
			
		||||
    void ApplyFramebufferState();
 | 
			
		||||
    void ApplyShaderProgram();
 | 
			
		||||
    void ApplyProgramPipeline();
 | 
			
		||||
    void ApplyRenderBuffer();
 | 
			
		||||
 | 
			
		||||
    /// Resets any references to the given resource
 | 
			
		||||
    OpenGLState& ResetProgram(GLuint handle);
 | 
			
		||||
    OpenGLState& ResetPipeline(GLuint handle);
 | 
			
		||||
    OpenGLState& ResetFramebuffer(GLuint handle);
 | 
			
		||||
    OpenGLState& ResetRenderbuffer(GLuint handle);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    static OpenGLState cur_state;
 | 
			
		||||
 
 | 
			
		||||
@@ -515,14 +515,8 @@ void TextureCacheOpenGL::ImageBlit(View& src_view, View& dst_view,
 | 
			
		||||
                                   const Tegra::Engines::Fermi2D::Config& copy_config) {
 | 
			
		||||
    const auto& src_params{src_view->GetSurfaceParams()};
 | 
			
		||||
    const auto& dst_params{dst_view->GetSurfaceParams()};
 | 
			
		||||
 | 
			
		||||
    OpenGLState prev_state{OpenGLState::GetCurState()};
 | 
			
		||||
    SCOPE_EXIT({ prev_state.Apply(); });
 | 
			
		||||
 | 
			
		||||
    OpenGLState state;
 | 
			
		||||
    state.draw.read_framebuffer = src_framebuffer.handle;
 | 
			
		||||
    state.draw.draw_framebuffer = dst_framebuffer.handle;
 | 
			
		||||
    state.Apply();
 | 
			
		||||
    UNIMPLEMENTED_IF(src_params.target == SurfaceTarget::Texture3D);
 | 
			
		||||
    UNIMPLEMENTED_IF(dst_params.target == SurfaceTarget::Texture3D);
 | 
			
		||||
 | 
			
		||||
    // TODO: Signal state tracker about these changes
 | 
			
		||||
    if (dst_params.srgb_conversion) {
 | 
			
		||||
@@ -538,11 +532,10 @@ void TextureCacheOpenGL::ImageBlit(View& src_view, View& dst_view,
 | 
			
		||||
    glDisablei(GL_BLEND, 0);
 | 
			
		||||
    glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE);
 | 
			
		||||
 | 
			
		||||
    u32 buffers{};
 | 
			
		||||
 | 
			
		||||
    UNIMPLEMENTED_IF(src_params.target == SurfaceTarget::Texture3D);
 | 
			
		||||
    UNIMPLEMENTED_IF(dst_params.target == SurfaceTarget::Texture3D);
 | 
			
		||||
    glBindFramebuffer(GL_READ_FRAMEBUFFER, src_framebuffer.handle);
 | 
			
		||||
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dst_framebuffer.handle);
 | 
			
		||||
 | 
			
		||||
    GLenum buffers = 0;
 | 
			
		||||
    if (src_params.type == SurfaceType::ColorTexture) {
 | 
			
		||||
        src_view->Attach(GL_COLOR_ATTACHMENT0, GL_READ_FRAMEBUFFER);
 | 
			
		||||
        glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0,
 | 
			
		||||
 
 | 
			
		||||
@@ -86,28 +86,22 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void ReloadRenderFrame(Frame* frame, u32 width, u32 height) {
 | 
			
		||||
        OpenGLState prev_state = OpenGLState::GetCurState();
 | 
			
		||||
        OpenGLState state = OpenGLState::GetCurState();
 | 
			
		||||
 | 
			
		||||
        // Recreate the color texture attachment
 | 
			
		||||
        frame->color.Release();
 | 
			
		||||
        frame->color.Create();
 | 
			
		||||
        state.renderbuffer = frame->color.handle;
 | 
			
		||||
        state.Apply();
 | 
			
		||||
        glRenderbufferStorage(GL_RENDERBUFFER, frame->is_srgb ? GL_SRGB8 : GL_RGB8, width, height);
 | 
			
		||||
        const GLenum internal_format = frame->is_srgb ? GL_SRGB8 : GL_RGB8;
 | 
			
		||||
        glNamedRenderbufferStorage(frame->color.handle, internal_format, width, height);
 | 
			
		||||
 | 
			
		||||
        // Recreate the FBO for the render target
 | 
			
		||||
        frame->render.Release();
 | 
			
		||||
        frame->render.Create();
 | 
			
		||||
        state.draw.read_framebuffer = frame->render.handle;
 | 
			
		||||
        state.draw.draw_framebuffer = frame->render.handle;
 | 
			
		||||
        state.Apply();
 | 
			
		||||
        glBindFramebuffer(GL_FRAMEBUFFER, frame->render.handle);
 | 
			
		||||
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
 | 
			
		||||
                                  frame->color.handle);
 | 
			
		||||
        if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
 | 
			
		||||
            LOG_CRITICAL(Render_OpenGL, "Failed to recreate render FBO!");
 | 
			
		||||
        }
 | 
			
		||||
        prev_state.Apply();
 | 
			
		||||
 | 
			
		||||
        frame->width = width;
 | 
			
		||||
        frame->height = height;
 | 
			
		||||
        frame->color_reloaded = true;
 | 
			
		||||
@@ -353,8 +347,7 @@ void RendererOpenGL::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
 | 
			
		||||
            frame->is_srgb = screen_info.display_srgb;
 | 
			
		||||
            frame_mailbox->ReloadRenderFrame(frame, layout.width, layout.height);
 | 
			
		||||
        }
 | 
			
		||||
        state.draw.draw_framebuffer = frame->render.handle;
 | 
			
		||||
        state.Apply();
 | 
			
		||||
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frame->render.handle);
 | 
			
		||||
        DrawScreen(layout);
 | 
			
		||||
        // Create a fence for the frontend to wait on and swap this frame to OffTex
 | 
			
		||||
        frame->render_fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
 | 
			
		||||
@@ -647,12 +640,14 @@ void RendererOpenGL::RenderScreenshot() {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    GLint old_read_fb;
 | 
			
		||||
    GLint old_draw_fb;
 | 
			
		||||
    glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &old_read_fb);
 | 
			
		||||
    glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &old_draw_fb);
 | 
			
		||||
 | 
			
		||||
    // Draw the current frame to the screenshot framebuffer
 | 
			
		||||
    screenshot_framebuffer.Create();
 | 
			
		||||
    GLuint old_read_fb = state.draw.read_framebuffer;
 | 
			
		||||
    GLuint old_draw_fb = state.draw.draw_framebuffer;
 | 
			
		||||
    state.draw.read_framebuffer = state.draw.draw_framebuffer = screenshot_framebuffer.handle;
 | 
			
		||||
    state.Apply();
 | 
			
		||||
    glBindFramebuffer(GL_FRAMEBUFFER, screenshot_framebuffer.handle);
 | 
			
		||||
 | 
			
		||||
    Layout::FramebufferLayout layout{renderer_settings.screenshot_framebuffer_layout};
 | 
			
		||||
 | 
			
		||||
@@ -669,11 +664,11 @@ void RendererOpenGL::RenderScreenshot() {
 | 
			
		||||
                 renderer_settings.screenshot_bits);
 | 
			
		||||
 | 
			
		||||
    screenshot_framebuffer.Release();
 | 
			
		||||
    state.draw.read_framebuffer = old_read_fb;
 | 
			
		||||
    state.draw.draw_framebuffer = old_draw_fb;
 | 
			
		||||
    state.Apply();
 | 
			
		||||
    glDeleteRenderbuffers(1, &renderbuffer);
 | 
			
		||||
 | 
			
		||||
    glBindFramebuffer(GL_READ_FRAMEBUFFER, old_read_fb);
 | 
			
		||||
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, old_draw_fb);
 | 
			
		||||
 | 
			
		||||
    renderer_settings.screenshot_complete_callback();
 | 
			
		||||
    renderer_settings.screenshot_requested = false;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user