From 887e3830bac95b0418201af337756564c89963d0 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Fri, 9 Feb 2018 21:41:31 +1000 Subject: VideoBackends: Restore the framebuffer as part of the API state It's not often we switch out to draw to the EFB anyway. --- Source/Core/VideoBackends/OGL/Render.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'Source/Core/VideoBackends/OGL/Render.cpp') diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp index 99666ed531..fab642e71b 100644 --- a/Source/Core/VideoBackends/OGL/Render.cpp +++ b/Source/Core/VideoBackends/OGL/Render.cpp @@ -1416,9 +1416,6 @@ void Renderer::SwapImpl(AbstractTexture* texture, const EFBRectangle& xfb_region g_texture_cache->Cleanup(frameCount); ProgramShaderCache::RetrieveAsyncShaders(); - // Render to the framebuffer. - FramebufferManager::SetFramebuffer(0); - RestoreAPIState(); g_Config.iSaveTargetId = 0; @@ -1499,6 +1496,8 @@ void Renderer::ResetAPIState() void Renderer::RestoreAPIState() { + FramebufferManager::SetFramebuffer(0); + // Gets us back into a more game-like state. glEnable(GL_SCISSOR_TEST); if (g_ActiveConfig.backend_info.bSupportsDepthClamp) -- cgit v1.2.3 From 4c24a697106471b33973da619a43167c947276aa Mon Sep 17 00:00:00 2001 From: Stenzek Date: Sun, 21 Jan 2018 20:22:45 +1000 Subject: VideoCommon: Add support for Abstract Framebuffers --- Source/Core/VideoBackends/OGL/Render.cpp | 56 +++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) (limited to 'Source/Core/VideoBackends/OGL/Render.cpp') diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp index fab642e71b..e7c15782ec 100644 --- a/Source/Core/VideoBackends/OGL/Render.cpp +++ b/Source/Core/VideoBackends/OGL/Render.cpp @@ -827,6 +827,8 @@ void Renderer::Init() // Initialize the FramebufferManager g_framebuffer_manager = std::make_unique( m_target_width, m_target_height, s_MSAASamples, BoundingBox::NeedsStencilBuffer()); + m_current_framebuffer_width = m_target_width; + m_current_framebuffer_height = m_target_height; m_post_processor = std::make_unique(); s_raster_font = std::make_unique(); @@ -843,6 +845,14 @@ std::unique_ptr Renderer::CreateStagingTexture(StagingTe return OGLStagingTexture::Create(type, config); } +std::unique_ptr +Renderer::CreateFramebuffer(const AbstractTexture* color_attachment, + const AbstractTexture* depth_attachment) +{ + return OGLFramebuffer::Create(static_cast(color_attachment), + static_cast(depth_attachment)); +} + void Renderer::RenderText(const std::string& text, int left, int top, u32 color) { s_raster_font->printMultilineText(text, @@ -1145,7 +1155,7 @@ void Renderer::SetViewport(float x, float y, float width, float height, float ne { // The x/y parameters here assume a upper-left origin. glViewport takes an offset from the // lower-left of the framebuffer, so we must set y to the distance from the lower-left. - y = static_cast(m_target_height) - y - height; + y = static_cast(m_current_framebuffer_height) - y - height; if (g_ogl_config.bSupportViewportFloat) { glViewportIndexedf(0, x, y, width, height); @@ -1238,6 +1248,44 @@ void Renderer::ReinterpretPixelData(unsigned int convtype) } } +void Renderer::SetFramebuffer(const AbstractFramebuffer* framebuffer) +{ + glBindFramebuffer(GL_FRAMEBUFFER, static_cast(framebuffer)->GetFBO()); + m_current_framebuffer = framebuffer; + m_current_framebuffer_width = framebuffer->GetWidth(); + m_current_framebuffer_height = framebuffer->GetHeight(); +} + +void Renderer::SetAndDiscardFramebuffer(const AbstractFramebuffer* framebuffer) +{ + // EXT_discard_framebuffer could be used here to save bandwidth on tilers. + SetFramebuffer(framebuffer); +} + +void Renderer::SetAndClearFramebuffer(const AbstractFramebuffer* framebuffer, + const ClearColor& color_value, float depth_value) +{ + SetFramebuffer(framebuffer); + + // NOTE: This disturbs the current scissor/mask setting. + // This won't be an issue when we implement proper state tracking. + glDisable(GL_SCISSOR_TEST); + GLbitfield clear_mask = 0; + if (framebuffer->HasColorBuffer()) + { + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glClearColor(color_value[0], color_value[1], color_value[2], color_value[3]); + clear_mask |= GL_COLOR_BUFFER_BIT; + } + if (framebuffer->HasDepthBuffer()) + { + glDepthMask(GL_TRUE); + glClearDepth(depth_value); + clear_mask |= GL_DEPTH_BUFFER_BIT; + } + glClear(clear_mask); +} + void Renderer::ApplyBlendingState(const BlendingState& state) { bool useDualSource = @@ -1351,6 +1399,9 @@ void Renderer::SwapImpl(AbstractTexture* texture, const EFBRectangle& xfb_region glBindFramebuffer(GL_FRAMEBUFFER, 0); glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + m_current_framebuffer = nullptr; + m_current_framebuffer_width = m_backbuffer_width; + m_current_framebuffer_height = m_backbuffer_height; // Copy the framebuffer to screen. BlitScreen(sourceRc, flipped_trc, xfb_texture->GetRawTexIdentifier(), @@ -1496,6 +1547,9 @@ void Renderer::ResetAPIState() void Renderer::RestoreAPIState() { + m_current_framebuffer = nullptr; + m_current_framebuffer_width = m_target_width; + m_current_framebuffer_height = m_target_height; FramebufferManager::SetFramebuffer(0); // Gets us back into a more game-like state. -- cgit v1.2.3