From 490dd612b3d662b4f190f34dc37e4367fddedc61 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Wed, 5 Oct 2016 03:56:58 +0200 Subject: [PATCH] Keep using render buffers when ssao is off, for better performance --- src/gl/renderer/gl_renderbuffers.cpp | 91 ++++++++++++++++++++-------- src/gl/renderer/gl_renderbuffers.h | 4 +- 2 files changed, 70 insertions(+), 25 deletions(-) diff --git a/src/gl/renderer/gl_renderbuffers.cpp b/src/gl/renderer/gl_renderbuffers.cpp index 54d597c4d..9915b024c 100644 --- a/src/gl/renderer/gl_renderbuffers.cpp +++ b/src/gl/renderer/gl_renderbuffers.cpp @@ -83,9 +83,18 @@ void FGLRenderBuffers::ClearScene() { DeleteFrameBuffer(mSceneFB); DeleteFrameBuffer(mSceneDataFB); - DeleteTexture(mSceneMultisample); - DeleteTexture(mSceneData); - DeleteTexture(mSceneDepthStencil); + if (mSceneUsesTextures) + { + DeleteTexture(mSceneMultisample); + DeleteTexture(mSceneData); + DeleteTexture(mSceneDepthStencil); + } + else + { + DeleteRenderBuffer(mSceneMultisample); + DeleteRenderBuffer(mSceneData); + DeleteRenderBuffer(mSceneDepthStencil); + } } void FGLRenderBuffers::ClearPipeline() @@ -188,6 +197,7 @@ bool FGLRenderBuffers::Setup(int width, int height, int sceneWidth, int sceneHei I_FatalError("Requested invalid render buffer sizes: screen = %dx%d", width, height); int samples = clamp((int)gl_multisample, 0, mMaxSamples); + bool needsSceneTextures = (gl_ssao != 0); GLint activeTex; GLint textureBinding; @@ -195,19 +205,16 @@ bool FGLRenderBuffers::Setup(int width, int height, int sceneWidth, int sceneHei glActiveTexture(GL_TEXTURE0); glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding); - if (width == mWidth && height == mHeight && mSamples != samples) - { - CreateScene(mWidth, mHeight, samples); - mSamples = samples; - } - else if (width != mWidth || height != mHeight) - { + if (width != mWidth || height != mHeight) CreatePipeline(width, height); - CreateScene(width, height, samples); - mWidth = width; - mHeight = height; - mSamples = samples; - } + + if (width != mWidth || height != mHeight || mSamples != samples || mSceneUsesTextures != needsSceneTextures) + CreateScene(width, height, samples, needsSceneTextures); + + mWidth = width; + mHeight = height; + mSamples = samples; + mSceneUsesTextures = needsSceneTextures; // Bloom bluring buffers need to match the scene to avoid bloom bleeding artifacts if (mSceneWidth != sceneWidth || mSceneHeight != sceneHeight) @@ -247,24 +254,44 @@ bool FGLRenderBuffers::Setup(int width, int height, int sceneWidth, int sceneHei // //========================================================================== -void FGLRenderBuffers::CreateScene(int width, int height, int samples) +void FGLRenderBuffers::CreateScene(int width, int height, int samples, bool needsSceneTextures) { ClearScene(); if (samples > 1) { - mSceneMultisample = Create2DMultisampleTexture("SceneMultisample", GL_RGBA16F, width, height, samples, false); - mSceneDepthStencil = Create2DMultisampleTexture("SceneDepthStencil", GL_DEPTH24_STENCIL8, width, height, samples, false); - mSceneData = Create2DMultisampleTexture("SceneSSAOData", GL_RGBA8, width, height, samples, false); + if (needsSceneTextures) + { + mSceneMultisample = Create2DMultisampleTexture("SceneMultisample", GL_RGBA16F, width, height, samples, false); + mSceneDepthStencil = Create2DMultisampleTexture("SceneDepthStencil", GL_DEPTH24_STENCIL8, width, height, samples, false); + mSceneData = Create2DMultisampleTexture("SceneSSAOData", GL_RGBA8, width, height, samples, false); + mSceneFB = CreateFrameBuffer("SceneFB", mSceneMultisample, 0, mSceneDepthStencil, true); + mSceneDataFB = CreateFrameBuffer("SSAOSceneFB", mSceneMultisample, mSceneData, mSceneDepthStencil, true); + } + else + { + mSceneMultisample = CreateRenderBuffer("SceneMultisample", GL_RGBA16F, width, height, samples); + mSceneDepthStencil = CreateRenderBuffer("SceneDepthStencil", GL_DEPTH24_STENCIL8, width, height, samples); + mSceneFB = CreateFrameBuffer("SceneFB", mSceneMultisample, mSceneDepthStencil, true); + mSceneDataFB = CreateFrameBuffer("SSAOSceneFB", mSceneMultisample, mSceneDepthStencil, true); + } } else { - mSceneDepthStencil = Create2DTexture("SceneDepthStencil", GL_DEPTH24_STENCIL8, width, height); - mSceneData = Create2DTexture("SceneSSAOData", GL_RGBA8, width, height); + if (needsSceneTextures) + { + mSceneDepthStencil = Create2DTexture("SceneDepthStencil", GL_DEPTH24_STENCIL8, width, height); + mSceneData = Create2DTexture("SceneSSAOData", GL_RGBA8, width, height); + mSceneFB = CreateFrameBuffer("SceneFB", mPipelineTexture[0], 0, mSceneDepthStencil, false); + mSceneDataFB = CreateFrameBuffer("SSAOSceneFB", mPipelineTexture[0], mSceneData, mSceneDepthStencil, false); + } + else + { + mSceneDepthStencil = CreateRenderBuffer("SceneDepthStencil", GL_DEPTH24_STENCIL8, width, height); + mSceneFB = CreateFrameBuffer("SceneFB", mPipelineTexture[0], mSceneDepthStencil, false); + mSceneDataFB = CreateFrameBuffer("SSAOSceneFB", mPipelineTexture[0], mSceneDepthStencil, false); + } } - - mSceneFB = CreateFrameBuffer("SceneFB", samples > 1 ? mSceneMultisample : mPipelineTexture[0], 0, mSceneDepthStencil, samples > 1); - mSceneDataFB = CreateFrameBuffer("SSAOSceneFB", samples > 1 ? mSceneMultisample : mPipelineTexture[0], mSceneData, mSceneDepthStencil, samples > 1); } //========================================================================== @@ -517,6 +544,22 @@ GLuint FGLRenderBuffers::CreateFrameBuffer(const FString &name, GLuint colorbuff return handle; } +GLuint FGLRenderBuffers::CreateFrameBuffer(const FString &name, GLuint colorbuffer, GLuint depthstencil, bool colorIsARenderBuffer) +{ + GLuint handle = 0; + glGenFramebuffers(1, &handle); + glBindFramebuffer(GL_FRAMEBUFFER, handle); + FGLDebug::LabelObject(GL_FRAMEBUFFER, handle, name); + if (colorIsARenderBuffer) + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorbuffer); + else + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer, 0); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthstencil); + if (CheckFrameBufferCompleteness()) + ClearFrameBuffer(true, true); + return handle; +} + GLuint FGLRenderBuffers::CreateFrameBuffer(const FString &name, GLuint colorbuffer0, GLuint colorbuffer1, GLuint depthstencil, bool multisample) { GLuint handle = 0; diff --git a/src/gl/renderer/gl_renderbuffers.h b/src/gl/renderer/gl_renderbuffers.h index 2ca58149f..3fcc2c07b 100644 --- a/src/gl/renderer/gl_renderbuffers.h +++ b/src/gl/renderer/gl_renderbuffers.h @@ -81,7 +81,7 @@ private: void ClearBloom(); void ClearExposureLevels(); void ClearAmbientOcclusion(); - void CreateScene(int width, int height, int samples); + void CreateScene(int width, int height, int samples, bool needsSceneTextures); void CreatePipeline(int width, int height); void CreateBloom(int width, int height); void CreateExposureLevels(int width, int height); @@ -92,6 +92,7 @@ private: GLuint CreateRenderBuffer(const FString &name, GLuint format, int width, int height); GLuint CreateRenderBuffer(const FString &name, GLuint format, int samples, int width, int height); GLuint CreateFrameBuffer(const FString &name, GLuint colorbuffer); + GLuint CreateFrameBuffer(const FString &name, GLuint colorbuffer, GLuint depthstencil, bool colorIsARenderBuffer); GLuint CreateFrameBuffer(const FString &name, GLuint colorbuffer0, GLuint colorbuffer1, GLuint depthstencil, bool multisample); bool CheckFrameBufferCompleteness(); void ClearFrameBuffer(bool stencil, bool depth); @@ -115,6 +116,7 @@ private: GLuint mSceneData = 0; GLuint mSceneFB = 0; GLuint mSceneDataFB = 0; + bool mSceneUsesTextures = false; // Effect/HUD buffers GLuint mPipelineTexture[NumPipelineTextures];