SL-18869 Optimizations -- Decruftify LLRenderTarget, use a shader to copy color/depth instead of glCopyTexSubImage or glBlitFrameBuffer
parent
a710bf9067
commit
a2d17d3c1e
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue