summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/OGL/Render.cpp
diff options
context:
space:
mode:
authorStenzek <stenzek@users.noreply.github.com>2018-03-08 00:52:49 +1000
committerGitHub <noreply@github.com>2018-03-08 00:52:49 +1000
commit24a46dc6af007ba5085a0425de7a7937623eb333 (patch)
tree05f61d35ff03d15e07455c458ae2069af455264f /Source/Core/VideoBackends/OGL/Render.cpp
parentaee977e32a0054e6a32a750c90c941d979db9d5a (diff)
parent4c24a697106471b33973da619a43167c947276aa (diff)
Merge pull request #6315 from stenzek/abstract-framebuffers
Abstract Framebuffers
Diffstat (limited to 'Source/Core/VideoBackends/OGL/Render.cpp')
-rw-r--r--Source/Core/VideoBackends/OGL/Render.cpp61
1 files changed, 57 insertions, 4 deletions
diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp
index 99666ed531..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<FramebufferManager>(
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<OpenGLPostProcessing>();
s_raster_font = std::make_unique<RasterFont>();
@@ -843,6 +845,14 @@ std::unique_ptr<AbstractStagingTexture> Renderer::CreateStagingTexture(StagingTe
return OGLStagingTexture::Create(type, config);
}
+std::unique_ptr<AbstractFramebuffer>
+Renderer::CreateFramebuffer(const AbstractTexture* color_attachment,
+ const AbstractTexture* depth_attachment)
+{
+ return OGLFramebuffer::Create(static_cast<const OGLTexture*>(color_attachment),
+ static_cast<const OGLTexture*>(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<float>(m_target_height) - y - height;
+ y = static_cast<float>(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<const OGLFramebuffer*>(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(),
@@ -1416,9 +1467,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 +1547,11 @@ 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.
glEnable(GL_SCISSOR_TEST);
if (g_ActiveConfig.backend_info.bSupportsDepthClamp)