diff options
author | Dave Parks <davep@lindenlab.com> | 2023-01-09 18:12:54 -0600 |
---|---|---|
committer | Dave Parks <davep@lindenlab.com> | 2023-01-09 18:12:54 -0600 |
commit | a2d17d3c1e5a62f10ab3922b6b12f909f1cd4682 (patch) | |
tree | 1010a8f928b2e25bd06cff12b83c9b8be39cd9b0 /indra | |
parent | a710bf9067bd4c4217b9febc0ad277a1636ec882 (diff) |
SL-18869 Optimizations -- Decruftify LLRenderTarget, use a shader to copy color/depth instead of glCopyTexSubImage or glBlitFrameBuffer
Diffstat (limited to 'indra')
-rw-r--r-- | indra/llrender/llgl.cpp | 4 | ||||
-rw-r--r-- | indra/llrender/llrender.cpp | 5 | ||||
-rw-r--r-- | indra/llrender/llrendertarget.cpp | 128 | ||||
-rw-r--r-- | indra/llrender/llrendertarget.h | 16 | ||||
-rw-r--r-- | indra/newview/app_settings/shaders/class1/interface/copyF.glsl | 40 | ||||
-rw-r--r-- | indra/newview/app_settings/shaders/class1/interface/copyV.glsl | 34 | ||||
-rw-r--r-- | indra/newview/lldrawpoolwater.cpp | 17 | ||||
-rw-r--r-- | indra/newview/llviewerdisplay.cpp | 10 | ||||
-rw-r--r-- | indra/newview/llviewershadermgr.cpp | 23 | ||||
-rw-r--r-- | indra/newview/llviewershadermgr.h | 2 | ||||
-rw-r--r-- | indra/newview/pipeline.cpp | 163 | ||||
-rw-r--r-- | indra/newview/pipeline.h | 4 |
12 files changed, 166 insertions, 280 deletions
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index e15157af05..67bd9e277e 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -2413,7 +2413,7 @@ void LLGLState::checkStates(const std::string& msg) BOOL error = FALSE; - if (src != GL_SRC_ALPHA || dst != GL_ONE_MINUS_SRC_ALPHA) + /*if (src != GL_SRC_ALPHA || dst != GL_ONE_MINUS_SRC_ALPHA) { if (gDebugSession) { @@ -2424,7 +2424,7 @@ void LLGLState::checkStates(const std::string& msg) { LL_GL_ERRS << "Blend function corrupted: " << std::hex << src << " " << std::hex << dst << " " << msg << std::dec << LL_ENDL; } - } + }*/ for (boost::unordered_map<LLGLenum, LLGLboolean>::iterator iter = sStateMap.begin(); iter != sStateMap.end(); ++iter) diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index c58fbe6c8e..8ab8d3151b 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -370,9 +370,10 @@ bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth) if (bindDepth) { - if (renderTarget->hasStencil()) + + if (renderTarget->getDepth() && !renderTarget->canSampleDepth()) { - LL_ERRS() << "Cannot bind a render buffer for sampling. Allocate render target without a stencil buffer if sampling of depth buffer is required." << LL_ENDL; + LL_ERRS() << "Cannot bind a render buffer for sampling. Allocate render target with depth buffer sampling enabled." << LL_ENDL; } bindManual(renderTarget->getUsage(), renderTarget->getDepth()); diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index 01ccf3d314..9827db8084 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -67,9 +67,8 @@ LLRenderTarget::LLRenderTarget() : mPreviousResX(0), mPreviousResY(0), mDepth(0), - mStencil(0), mUseDepth(false), - mRenderDepth(false), + mSampleDepth(false), mUsage(LLTexUnit::TT_TEXTURE) { } @@ -98,11 +97,11 @@ void LLRenderTarget::resize(U32 resx, U32 resy) if (mDepth) { //resize depth attachment - if (mStencil) + if (!mSampleDepth) { //use render buffers where stencil buffers are in play glBindRenderbuffer(GL_RENDERBUFFER, mDepth); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, mResX, mResY); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, mResX, mResY); glBindRenderbuffer(GL_RENDERBUFFER, 0); } else @@ -117,7 +116,7 @@ void LLRenderTarget::resize(U32 resx, U32 resy) } -bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, S32 samples) +bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool sample_depth, LLTexUnit::eTextureType usage, bool use_fbo, S32 samples) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; resx = llmin(resx, (U32) gGLManager.mGLMaxTextureSize); @@ -130,9 +129,9 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, boo mResX = resx; mResY = resy; - mStencil = stencil; mUsage = usage; - mUseDepth = depth; + mUseDepth = depth; + mSampleDepth = sample_depth; if ((sUseFBO || use_fbo)) { @@ -150,13 +149,10 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, boo if (mDepth) { glBindFramebuffer(GL_FRAMEBUFFER, mFBO); - llassert(!mStencil); // use of stencil buffer is deprecated (performance penalty) - if (mStencil) + + if (!canSampleDepth()) { glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepth); - stop_glerror(); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mDepth); - stop_glerror(); } else { @@ -315,14 +311,12 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt) bool LLRenderTarget::allocateDepth() { LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; - if (mStencil) + if (!mSampleDepth) { - //use render buffers where stencil buffers are in play + //use render buffers if depth buffer won't be sampled glGenRenderbuffers(1, (GLuint *) &mDepth); glBindRenderbuffer(GL_RENDERBUFFER, mDepth); - stop_glerror(); - clear_glerror(); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, mResX, mResY); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, mResX, mResY); glBindRenderbuffer(GL_RENDERBUFFER, 0); } else @@ -367,23 +361,15 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target) if (mDepth) { - stop_glerror(); glBindFramebuffer(GL_FRAMEBUFFER, target.mFBO); - stop_glerror(); - - llassert(!mStencil); // deprecated -- performance penalty - if (mStencil) + + if (!mSampleDepth) { glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepth); - stop_glerror(); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mDepth); - stop_glerror(); - target.mStencil = true; } else { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), mDepth, 0); - stop_glerror(); } check_framebuffer_status(); @@ -399,15 +385,13 @@ void LLRenderTarget::release() LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; if (mDepth) { - if (mStencil) + if (!mSampleDepth) { glDeleteRenderbuffers(1, (GLuint*) &mDepth); - stop_glerror(); } else { LLImageGL::deleteTextures(1, &mDepth); - stop_glerror(); } mDepth = 0; @@ -419,12 +403,10 @@ void LLRenderTarget::release() if (mUseDepth) { //detach shared depth buffer - llassert(!mStencil); //deprecated, performance penalty - if (mStencil) + if (!mSampleDepth) { //attached as a renderbuffer - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); - mStencil = false; + mSampleDepth = false; } else { //attached as a texture @@ -624,84 +606,6 @@ void LLRenderTarget::flush(bool fetch_depth) } } -void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0, S32 srcX1, S32 srcY1, - S32 dstX0, S32 dstY0, S32 dstX1, S32 dstY1, U32 mask, U32 filter) -{ - LL_PROFILE_GPU_ZONE("LLRenderTarget::copyContents"); - - GLboolean write_depth = mask & GL_DEPTH_BUFFER_BIT ? TRUE : FALSE; - - LLGLDepthTest depth(write_depth, write_depth); - - gGL.flush(); - if (!source.mFBO || !mFBO) - { - LL_WARNS() << "Cannot copy framebuffer contents for non FBO render targets." << LL_ENDL; - return; - } - - - if (mask == GL_DEPTH_BUFFER_BIT && source.mStencil != mStencil) - { - stop_glerror(); - - glBindFramebuffer(GL_FRAMEBUFFER, source.mFBO); - check_framebuffer_status(); - gGL.getTexUnit(0)->bind(this, true); - stop_glerror(); - glCopyTexSubImage2D(LLTexUnit::getInternalType(mUsage), 0, srcX0, srcY0, dstX0, dstY0, dstX1, dstY1); - stop_glerror(); - glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO); - stop_glerror(); - } - else - { - glBindFramebuffer(GL_READ_FRAMEBUFFER, source.mFBO); - stop_glerror(); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFBO); - stop_glerror(); - check_framebuffer_status(); - stop_glerror(); - glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); - stop_glerror(); - glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); - stop_glerror(); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); - stop_glerror(); - glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO); - stop_glerror(); - } -} - -//static -void LLRenderTarget::copyContentsToFramebuffer(LLRenderTarget& source, S32 srcX0, S32 srcY0, S32 srcX1, S32 srcY1, - S32 dstX0, S32 dstY0, S32 dstX1, S32 dstY1, U32 mask, U32 filter) -{ - if (!source.mFBO) - { - LL_WARNS() << "Cannot copy framebuffer contents for non FBO render targets." << LL_ENDL; - return; - } - - { - LL_PROFILE_GPU_ZONE("copyContentsToFramebuffer"); - GLboolean write_depth = mask & GL_DEPTH_BUFFER_BIT ? TRUE : FALSE; - - LLGLDepthTest depth(write_depth, write_depth); - - glBindFramebuffer(GL_READ_FRAMEBUFFER, source.mFBO); - stop_glerror(); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); - stop_glerror(); - check_framebuffer_status(); - stop_glerror(); - glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); - stop_glerror(); - glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO); - stop_glerror(); - } -} - bool LLRenderTarget::isComplete() const { return (!mTex.empty() || mDepth) ? true : false; diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h index 584f224dca..5f3214add3 100644 --- a/indra/llrender/llrendertarget.h +++ b/indra/llrender/llrendertarget.h @@ -73,7 +73,7 @@ public: //allocate resources for rendering //must be called before use //multiple calls will release previously allocated resources - bool allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, bool use_fbo = false, S32 samples = 0); + bool allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool sample_depth, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, bool use_fbo = false, S32 samples = 0); //resize existing attachments to use new resolution and color format // CAUTION: if the GL runs out of memory attempting to resize, this render target will be undefined @@ -136,7 +136,7 @@ public: U32 getNumTextures() const; U32 getDepth(void) const { return mDepth; } - bool hasStencil() const { return mStencil; } + bool canSampleDepth() const { return mSampleDepth; } void bindTexture(U32 index, S32 channel, LLTexUnit::eTextureFilterOptions filter_options = LLTexUnit::TFO_BILINEAR); @@ -148,12 +148,6 @@ public: // the current depth texture. A depth texture will be allocated if needed. void flush(bool fetch_depth = FALSE); - void copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0, S32 srcX1, S32 srcY1, - S32 dstX0, S32 dstY0, S32 dstX1, S32 dstY1, U32 mask, U32 filter); - - static void copyContentsToFramebuffer(LLRenderTarget& source, S32 srcX0, S32 srcY0, S32 srcX1, S32 srcY1, - S32 dstX0, S32 dstY0, S32 dstX1, S32 dstY1, U32 mask, U32 filter); - //Returns TRUE if target is ready to be rendered into. //That is, if the target has been allocated with at least //one renderable attachment (i.e. color buffer, depth buffer). @@ -172,9 +166,9 @@ protected: U32 mPreviousResY; U32 mDepth; - bool mStencil; - bool mUseDepth; - bool mRenderDepth; + bool mUseDepth; + bool mSampleDepth; + LLTexUnit::eTextureType mUsage; static LLRenderTarget* sBoundTarget; diff --git a/indra/newview/app_settings/shaders/class1/interface/copyF.glsl b/indra/newview/app_settings/shaders/class1/interface/copyF.glsl new file mode 100644 index 0000000000..764bace621 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/copyF.glsl @@ -0,0 +1,40 @@ +/** + * @file copyF.glsl + * + * $LicenseInfo:firstyear=2023&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2023, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +in vec2 tc; + +uniform sampler2D depthMap; +uniform sampler2D diffuseMap; + +out vec4 frag_color; + +void main() +{ + frag_color = texture(diffuseMap, tc); +#if COPY_DEPTH + gl_FragDepth = texture(depthMap, tc).r; +#endif +} + diff --git a/indra/newview/app_settings/shaders/class1/interface/copyV.glsl b/indra/newview/app_settings/shaders/class1/interface/copyV.glsl new file mode 100644 index 0000000000..ace5da6578 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/copyV.glsl @@ -0,0 +1,34 @@ +/** + * @file copyV.glsl + * + * $LicenseInfo:firstyear=2023&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2023, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + + +in vec3 position; +out vec2 tc; + +void main() +{ + tc = position.xy * 0.5 + 0.5; + gl_Position = vec4(position, 1.0); +} diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index 77da29061d..c2fe52683b 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -133,11 +133,28 @@ void LLDrawPoolWater::beginPostDeferredPass(S32 pass) // reflections and refractions LLRenderTarget& src = gPipeline.mRT->screen; LLRenderTarget& dst = gPipeline.mWaterDis; + +#if 0 dst.copyContents(src, 0, 0, src.getWidth(), src.getHeight(), 0, 0, dst.getWidth(), dst.getHeight(), GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST); +#else + dst.bindTarget(); + gCopyDepthProgram.bind(); + + S32 diff_map = gCopyDepthProgram.enableTexture(LLShaderMgr::DIFFUSE_MAP); + S32 depth_map = gCopyDepthProgram.enableTexture(LLShaderMgr::DEFERRED_DEPTH); + + gGL.getTexUnit(diff_map)->bind(&src); + gGL.getTexUnit(depth_map)->bind(&src, true); + + gPipeline.mScreenTriangleVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + + dst.flush(); +#endif } } diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 58b1716caa..01fca47184 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -967,13 +967,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) LLRenderTarget &rt = (gPipeline.sRenderDeferred ? gPipeline.mRT->deferredScreen : gPipeline.mRT->screen); rt.flush(); - /*if (rt.sUseFBO) - { - LLRenderTarget::copyContentsToFramebuffer(rt, 0, 0, rt.getWidth(), rt.getHeight(), 0, 0, rt.getWidth(), - rt.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, - GL_NEAREST); - }*/ - if (LLPipeline::sRenderDeferred) { gPipeline.renderDeferredLighting(); @@ -1364,6 +1357,8 @@ void render_ui(F32 zoom_factor, int subfield) render_hud_elements(); render_hud_attachments(); + LLGLState::checkStates(); + LLGLSDefault gls_default; LLGLSUIDefault gls_ui; { @@ -1378,6 +1373,7 @@ void render_ui(F32 zoom_factor, int subfield) if (!gDisconnected) { LL_PROFILE_ZONE_NAMED_CATEGORY_UI("UI 3D"); //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_3D); + LLGLState::checkStates(); render_ui_3d(); LLGLState::checkStates(); } diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 757a946fda..8dd01a3a29 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -93,6 +93,8 @@ LLGLSLShader gDownsampleDepthRectProgram; LLGLSLShader gAlphaMaskProgram; LLGLSLShader gBenchmarkProgram; LLGLSLShader gReflectionProbeDisplayProgram; +LLGLSLShader gCopyProgram; +LLGLSLShader gCopyDepthProgram; //object shaders LLGLSLShader gObjectSimpleProgram; @@ -3916,6 +3918,27 @@ BOOL LLViewerShaderMgr::loadShadersInterface() success = gReflectionProbeDisplayProgram.createShader(NULL, NULL); } + if (success) + { + gCopyProgram.mName = "Copy Shader"; + gCopyProgram.mShaderFiles.clear(); + gCopyProgram.mShaderFiles.push_back(make_pair("interface/copyV.glsl", GL_VERTEX_SHADER)); + gCopyProgram.mShaderFiles.push_back(make_pair("interface/copyF.glsl", GL_FRAGMENT_SHADER)); + gCopyProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gCopyProgram.createShader(NULL, NULL); + } + + if (success) + { + gCopyDepthProgram.mName = "Copy Depth Shader"; + gCopyDepthProgram.mShaderFiles.clear(); + gCopyDepthProgram.mShaderFiles.push_back(make_pair("interface/copyV.glsl", GL_VERTEX_SHADER)); + gCopyDepthProgram.mShaderFiles.push_back(make_pair("interface/copyF.glsl", GL_FRAGMENT_SHADER)); + gCopyDepthProgram.clearPermutations(); + gCopyDepthProgram.addPermutation("COPY_DEPTH", "1"); + gCopyDepthProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + success = gCopyDepthProgram.createShader(NULL, NULL); + } if (success) { diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 9ded72c6a7..d9c8dc5b07 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -164,6 +164,8 @@ extern LLGLSLShader gDownsampleDepthProgram; extern LLGLSLShader gDownsampleDepthRectProgram; extern LLGLSLShader gBenchmarkProgram; extern LLGLSLShader gReflectionProbeDisplayProgram; +extern LLGLSLShader gCopyProgram; +extern LLGLSLShader gCopyDepthProgram; //output tex0[tc0] + tex1[tc1] extern LLGLSLShader gTwoTextureAddProgram; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 9851d4bc6a..b5271a6ca1 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -858,14 +858,12 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) const U32 occlusion_divisor = 3; //allocate deferred rendering color buffers - if (!mRT->deferredScreen.allocate(resX, resY, GL_RGBA, TRUE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false; - //if (!mRT->deferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false; - if (!mRT->occlusionDepth.allocate(resX/occlusion_divisor, resY/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false; + if (!mRT->deferredScreen.allocate(resX, resY, GL_RGBA, true, true, LLTexUnit::TT_TEXTURE, false, samples)) return false; if (!addDeferredAttachments(mRT->deferredScreen)) return false; GLuint screenFormat = GL_RGBA16; - if (!mRT->screen.allocate(resX, resY, screenFormat, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false; + if (!mRT->screen.allocate(resX, resY, screenFormat, FALSE, true, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false; mRT->deferredScreen.shareDepthBuffer(mRT->screen); @@ -905,9 +903,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) mRT->fxaaBuffer.release(); mRT->screen.release(); mRT->deferredScreen.release(); //make sure to release any render targets that share a depth buffer with mRT->deferredScreen first - //mRT->deferredDepth.release(); - mRT->occlusionDepth.release(); - + if (!mRT->screen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_TEXTURE, FALSE)) return false; } @@ -926,8 +922,6 @@ bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY) LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; S32 shadow_detail = RenderShadowDetail; - const U32 occlusion_divisor = 3; - F32 scale = llmax(0.f, RenderShadowResolutionScale); U32 sun_shadow_map_width = BlurHappySize(resX, scale); U32 sun_shadow_map_height = BlurHappySize(resY, scale); @@ -936,12 +930,7 @@ bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY) { //allocate 4 sun shadow maps for (U32 i = 0; i < 4; i++) { - if (!mRT->shadow[i].allocate(sun_shadow_map_width, sun_shadow_map_height, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) - { - return false; - } - - if (!mRT->shadowOcclusion[i].allocate(sun_shadow_map_width / occlusion_divisor, sun_shadow_map_height / occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) + if (!mRT->shadow[i].allocate(sun_shadow_map_width, sun_shadow_map_height, 0, true, true, LLTexUnit::TT_TEXTURE)) { return false; } @@ -966,11 +955,7 @@ bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY) U32 spot_shadow_map_height = height; for (U32 i = 0; i < 2; i++) { - if (!mSpotShadow[i].allocate(spot_shadow_map_width, spot_shadow_map_height, 0, TRUE, FALSE)) - { - return false; - } - if (!mSpotShadowOcclusion[i].allocate(spot_shadow_map_width / occlusion_divisor, height / occlusion_divisor, 0, TRUE, FALSE)) + if (!mSpotShadow[i].allocate(spot_shadow_map_width, spot_shadow_map_height, 0, true, true)) { return false; } @@ -1001,7 +986,7 @@ bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY) } } - if (shadow_detail > 1) + if (shadow_detail > 1 && !gCubeSnapshot) { for (U32 i = 0; i < 2; i++) { @@ -1198,7 +1183,6 @@ void LLPipeline::releaseScreenBuffers() mRT->deferredScreen.release(); mRT->deferredDepth.release(); mRT->deferredLight.release(); - mRT->occlusionDepth.release(); } @@ -1206,7 +1190,6 @@ void LLPipeline::releaseSunShadowTarget(U32 index) { llassert(index < 4); mRT->shadow[index].release(); - mRT->shadowOcclusion[index].release(); } void LLPipeline::releaseSunShadowTargets() @@ -1224,7 +1207,6 @@ void LLPipeline::releaseSpotShadowTargets() for (U32 i = 0; i < 2; i++) { mSpotShadow[i].release(); - mSpotShadowOcclusion[i].release(); } } } @@ -1239,7 +1221,7 @@ void LLPipeline::createGLBuffers() if (LLPipeline::sRenderTransparentWater) { //water reflection texture U32 res = (U32) llmax(gSavedSettings.getS32("RenderWaterRefResolution"), 512); - mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE,LLTexUnit::TT_TEXTURE); + mWaterDis.allocate(res,res,GL_RGBA,true,true,LLTexUnit::TT_TEXTURE); } // Use FBO for bake tex @@ -2355,9 +2337,6 @@ static LLTrace::BlockTimerStatHandle FTM_CULL("Object Culling"); void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* planep) { - static LLCachedControl<bool> use_occlusion(gSavedSettings,"UseOcclusion"); - static bool can_use_occlusion = LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion"); - LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_CULL); if (planep != nullptr) @@ -2373,56 +2352,6 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* pla sCull->clear(); - bool to_texture = LLPipeline::sUseOcclusion > 1 && gPipeline.shadersLoaded(); - - if (to_texture) - { - if (LLPipeline::sRenderDeferred && can_use_occlusion) - { - mRT->occlusionDepth.bindTarget(); - } - else - { - mRT->screen.bindTarget(); - } - } - - if (sUseOcclusion > 1) - { - gGL.setColorMask(false, false); - } - - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.pushMatrix(); - gGL.loadMatrix(gGLLastProjection); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.pushMatrix(); - gGLLastMatrix = NULL; - gGL.loadMatrix(gGLLastModelView); - - LLGLDisable blend(GL_BLEND); - LLGLDisable test(GL_ALPHA_TEST); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - LLGLDepthTest depth(GL_TRUE, GL_FALSE); - - bool bound_shader = false; - if (gPipeline.shadersLoaded() && LLGLSLShader::sCurBoundShader == 0) - { //if no shader is currently bound, use the occlusion shader instead of fixed function if we can - // (shadow render uses a special shader that clamps to clip planes) - bound_shader = true; - gOcclusionCubeProgram.bind(); - } - - if (sUseOcclusion > 1) - { - if (mCubeVB.isNull()) - { //cube VB will be used for issuing occlusion queries - mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW); - } - mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - } - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { @@ -2444,16 +2373,10 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* pla LLVOCachePartition* vo_part = region->getVOCachePartition(); if(vo_part) { - bool do_occlusion_cull = can_use_occlusion && use_occlusion && !gUseWireframe; - vo_part->cull(camera, do_occlusion_cull); + vo_part->cull(camera, sUseOcclusion > 0); } } - if (bound_shader) - { - gOcclusionCubeProgram.unbind(); - } - if (hasRenderType(LLPipeline::RENDER_TYPE_SKY) && gSky.mVOSkyp.notNull() && gSky.mVOSkyp->mDrawable.notNull()) @@ -2479,28 +2402,6 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* pla { LLWorld::getInstance()->precullWaterObjects(camera, sCull, render_water); } - - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.popMatrix(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.popMatrix(); - - if (sUseOcclusion > 1) - { - gGL.setColorMask(true, false); - } - - if (to_texture) - { - if (LLPipeline::sRenderDeferred && can_use_occlusion) - { - mRT->occlusionDepth.flush(); - } - else - { - mRT->screen.flush(); - } - } } void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera) @@ -2563,6 +2464,9 @@ void LLPipeline::markOccluder(LLSpatialGroup* group) void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; + LL_PROFILE_GPU_ZONE("downsampleDepthBuffer"); + LLGLSLShader* last_shader = LLGLSLShader::sCurBoundShaderPtr; LLGLSLShader* shader = NULL; @@ -2570,12 +2474,12 @@ void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& d if (scratch_space) { GLint bits = 0; - llassert(!source.hasStencil()); // stencil buffer usage is deprecated - bits |= (source.hasStencil() && dest.hasStencil()) ? GL_STENCIL_BUFFER_BIT : 0; - bits |= GL_DEPTH_BUFFER_BIT; + bits = GL_DEPTH_BUFFER_BIT; +#if 0 // TODO -- restore occlusion culling functionality scratch_space->copyContents(source, 0, 0, source.getWidth(), source.getHeight(), 0, 0, scratch_space->getWidth(), scratch_space->getHeight(), bits, GL_NEAREST); +#endif } dest.bindTarget(); @@ -2624,23 +2528,6 @@ void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& d } } -void LLPipeline::doOcclusion(LLCamera& camera, LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space) -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; - llassert(!gCubeSnapshot); -#if 0 - downsampleDepthBuffer(source, dest, scratch_space); - dest.bindTarget(); - doOcclusion(camera); - dest.flush(); -#else - // none of the above shenanigans should matter (enough) because we've preserved hierarchical Z before issuing occlusion queries - //source.bindTarget(); - doOcclusion(camera); - //source.flush(); -#endif -} - void LLPipeline::doOcclusion(LLCamera& camera) { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; @@ -9572,13 +9459,8 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera gDeferredShadowCubeProgram.bind(); } - LLRenderTarget& occlusion_target = LLViewerCamera::sCurCameraID >= LLViewerCamera::CAMERA_SPOT_SHADOW0 ? - mSpotShadowOcclusion[LLViewerCamera::sCurCameraID - LLViewerCamera::CAMERA_SPOT_SHADOW0] : - mRT->shadowOcclusion[LLViewerCamera::sCurCameraID - LLViewerCamera::CAMERA_SUN_SHADOW0]; - - occlusion_target.bindTarget(); + updateCull(shadow_cam, result); - occlusion_target.flush(); stateSort(shadow_cam, result); @@ -9661,6 +9543,12 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera } } + if (occlude > 1) + { // do occlusion culling against non-masked only to take advantage of hierarchical Z + doOcclusion(shadow_cam); + } + + if (use_shader) { LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow geom"); @@ -9760,15 +9648,6 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera gGLLastMatrix = NULL; gGL.loadMatrix(gGLModelView); - LLRenderTarget& occlusion_source = LLViewerCamera::sCurCameraID >= LLViewerCamera::CAMERA_SPOT_SHADOW0 ? - mSpotShadow[LLViewerCamera::sCurCameraID - LLViewerCamera::CAMERA_SPOT_SHADOW0] : - mRT->shadow[LLViewerCamera::sCurCameraID - LLViewerCamera::CAMERA_SUN_SHADOW0]; - - if (occlude > 1) - { - doOcclusion(shadow_cam, occlusion_source, occlusion_target); - } - if (use_shader) { gDeferredShadowProgram.unbind(); diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index c698374c8b..ae4ac4c7ff 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -173,7 +173,6 @@ public: // if source's depth buffer cannot be bound for reading, a scratch space depth buffer must be provided void downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space = NULL); - void doOcclusion(LLCamera& camera, LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space = NULL); void doOcclusion(LLCamera& camera); void markNotCulled(LLSpatialGroup* group, LLCamera &camera); void markMoved(LLDrawable *drawablep, bool damped_motion = false); @@ -673,12 +672,10 @@ public: LLRenderTarget fxaaBuffer; LLRenderTarget edgeMap; LLRenderTarget deferredDepth; - LLRenderTarget occlusionDepth; LLRenderTarget deferredLight; //sun shadow map LLRenderTarget shadow[4]; - LLRenderTarget shadowOcclusion[4]; }; // main full resoltuion render target @@ -691,7 +688,6 @@ public: RenderTargetPack* mRT; LLRenderTarget mSpotShadow[2]; - LLRenderTarget mSpotShadowOcclusion[2]; LLRenderTarget mPbrBrdfLut; |