From 06c94c83feac1f7c3ee3e71d9654f6acd8679f24 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 1 Dec 2021 22:13:17 +0200 Subject: [PATCH 1/6] SL-16420 Upload's physics LODs are broken in preview --- indra/newview/llmodelpreview.cpp | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 566a89e24d..1ce15e04da 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -2661,6 +2661,8 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights) *(index_strider++) = vf.mIndices[i]; } + vb->flush(); + mVertexBuffer[lod][mdl].push_back(vb); vertex_count += num_vertices; @@ -3136,6 +3138,11 @@ BOOL LLModelPreview::render() genBuffers(mPreviewLOD, skin_weight); } + if (physics && mVertexBuffer[LLModel::LOD_PHYSICS].empty()) + { + genBuffers(LLModel::LOD_PHYSICS, false); + } + if (!skin_weight) { for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter) @@ -3290,11 +3297,6 @@ BOOL LLModelPreview::render() if (render_mesh) { - if (mVertexBuffer[LLModel::LOD_PHYSICS].empty()) - { - genBuffers(LLModel::LOD_PHYSICS, false); - } - U32 num_models = mVertexBuffer[LLModel::LOD_PHYSICS][model].size(); if (pass > 0){ for (U32 i = 0; i < num_models; ++i) @@ -3358,11 +3360,6 @@ BOOL LLModelPreview::render() if (physics.mHull.empty()) { - if (mVertexBuffer[LLModel::LOD_PHYSICS].empty()) - { - genBuffers(LLModel::LOD_PHYSICS, false); - } - U32 num_models = mVertexBuffer[LLModel::LOD_PHYSICS][model].size(); for (U32 v = 0; v < num_models; ++v) { From 7929230c045f2daf6de53e880f3d716044b96792 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 2 Dec 2021 01:14:07 +0200 Subject: [PATCH 2/6] mac build fix remove unused variable --- indra/llrender/llrender.cpp | 19 +------------------ indra/llrender/llrender.h | 9 --------- 2 files changed, 1 insertion(+), 27 deletions(-) diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index c426c769f3..235f8a8eb0 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -71,18 +71,6 @@ static const GLint sGLAddressMode[] = GL_CLAMP_TO_EDGE }; -static const GLenum sGLCompareFunc[] = -{ - GL_NEVER, - GL_ALWAYS, - GL_LESS, - GL_LEQUAL, - GL_EQUAL, - GL_NOTEQUAL, - GL_GEQUAL, - GL_GREATER -}; - const U32 immediate_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXCOORD0; static const GLenum sGLBlendFactor[] = @@ -102,10 +90,7 @@ static const GLenum sGLBlendFactor[] = }; LLTexUnit::LLTexUnit(S32 index) - : mCurrTexType(TT_NONE), mCurrBlendType(TB_MULT), - mCurrColorOp(TBO_MULT), mCurrAlphaOp(TBO_MULT), - mCurrColorSrc1(TBS_TEX_COLOR), mCurrColorSrc2(TBS_PREV_COLOR), - mCurrAlphaSrc1(TBS_TEX_ALPHA), mCurrAlphaSrc2(TBS_PREV_ALPHA), + : mCurrTexType(TT_NONE), mCurrColorScale(1), mCurrAlphaScale(1), mCurrTexture(0), mTexColorSpace(TCS_LINEAR), mHasMipMaps(false), mIndex(index) @@ -847,8 +832,6 @@ LLRender::LLRender() mCurrColorMask[i] = true; } - mCurrAlphaFunc = CF_DEFAULT; - mCurrAlphaFuncVal = 0.01f; mCurrBlendColorSFactor = BF_UNDEF; mCurrBlendAlphaSFactor = BF_UNDEF; mCurrBlendColorDFactor = BF_UNDEF; diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index cdf4075244..e2489876e4 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -214,13 +214,6 @@ protected: const S32 mIndex; U32 mCurrTexture; eTextureType mCurrTexType; - eTextureBlendType mCurrBlendType; - eTextureBlendOp mCurrColorOp; - eTextureBlendSrc mCurrColorSrc1; - eTextureBlendSrc mCurrColorSrc2; - eTextureBlendOp mCurrAlphaOp; - eTextureBlendSrc mCurrAlphaSrc1; - eTextureBlendSrc mCurrAlphaSrc2; eTextureColorSpace mTexColorSpace; S32 mCurrColorScale; S32 mCurrAlphaScale; @@ -481,8 +474,6 @@ private: U32 mMode; U32 mCurrTextureUnitIndex; bool mCurrColorMask[4]; - eCompareFunc mCurrAlphaFunc; - F32 mCurrAlphaFuncVal; LLPointer mBuffer; LLStrider mVerticesp; From 1cd1d3fbe2a5aae2e5736bb62c1b4aa413eba7fb Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 2 Dec 2021 02:28:29 +0200 Subject: [PATCH 3/6] SL-16420 Upload's physics LODs are broken in preview #2 --- indra/newview/llmodelpreview.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 1ce15e04da..e22a04006e 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -3204,6 +3204,7 @@ BOOL LLModelPreview::render() glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glLineWidth(1.f); } + buffer->flush(); } gGL.popMatrix(); } @@ -3316,6 +3317,8 @@ BOOL LLModelPreview::render() glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glLineWidth(1.f); + + buffer->flush(); } } } @@ -3386,6 +3389,8 @@ BOOL LLModelPreview::render() buffer->draw(LLRender::POINTS, 3, i); } } + + buffer->flush(); } } } From 2ed229473d7473593e8d502003991487bb622018 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 2 Dec 2021 17:35:03 +0200 Subject: [PATCH 4/6] SL-14403 Remove unused shader binds remains from glod --- indra/newview/llmodelpreview.cpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index e22a04006e..907b5ec418 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -1691,12 +1691,6 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d end = which_lod; } - LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - if (shader) - { - shader->unbind(); - } - for (S32 lod = start; lod >= end; --lod) { if (which_lod == -1) @@ -1855,12 +1849,6 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d } mResourceCost = calcResourceCost(); - - LLVertexBuffer::unbind(); - if (shader) - { - shader->bind(); - } } void LLModelPreview::updateStatusMessages() From 511de439a35ddb22c6f174b85c599d4881b9c139 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 2 Dec 2021 20:11:43 +0000 Subject: [PATCH 5/6] =?UTF-8?q?SL-16405=20Remove=20=E2=80=9Cpass=20=3D=3D?= =?UTF-8?q?=20=E2=80=9D=20anti-pattern=20from=20various=20?= =?UTF-8?q?drawpools.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- indra/newview/lldrawpoolalpha.cpp | 360 ++++++--------- indra/newview/lldrawpoolalpha.h | 16 +- indra/newview/lldrawpoolbump.cpp | 352 ++++----------- indra/newview/lldrawpoolbump.h | 27 +- indra/newview/lldrawpoolsimple.cpp | 697 ++++++++--------------------- indra/newview/lldrawpoolsimple.h | 34 +- 6 files changed, 463 insertions(+), 1023 deletions(-) diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 9b298b120a..cecdefd7e8 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -80,213 +80,162 @@ void LLDrawPoolAlpha::prerender() S32 LLDrawPoolAlpha::getNumPostDeferredPasses() { - if (LLPipeline::sImpostorRender) - { //skip depth buffer filling pass when rendering impostors - return 1; - } - else if (gSavedSettings.getBOOL("RenderDepthOfField")) - { - return 2; - } - else - { - return 1; - } + return 1; } -void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass) -{ - LL_PROFILE_ZONE_SCOPED; +// set some common parameters on the given shader to prepare for alpha rendering +static void prepare_alpha_shader(LLGLSLShader* shader, bool textureGamma) +{ + static LLCachedControl displayGamma(gSavedSettings, "RenderDeferredDisplayGamma"); + F32 gamma = displayGamma; - F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma"); + shader->bind(); + shader->uniform1i(LLShaderMgr::NO_ATMO, (LLPipeline::sRenderingHUDs) ? 1 : 0); + shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f / 2.2f)); - emissive_shader[0] = (LLPipeline::sUnderWaterRender) ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram; - emissive_shader[1] = emissive_shader[0]->mRiggedVariant; - - for (int i = 0; i < 2; ++i) + if (LLPipeline::sImpostorRender) { - emissive_shader[i]->bind(); - emissive_shader[i]->uniform1i(LLShaderMgr::NO_ATMO, (LLPipeline::sRenderingHUDs) ? 1 : 0); - emissive_shader[i]->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); - emissive_shader[i]->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f / 2.2f)); + shader->setMinimumAlpha(0.5f); + } + else + { + shader->setMinimumAlpha(0.f); + } + if (textureGamma) + { + shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); } - if (pass == 0) - { - fullbright_shader[0] = (LLPipeline::sImpostorRender) ? &gDeferredFullbrightProgram : - (LLPipeline::sUnderWaterRender) ? &gDeferredFullbrightWaterProgram : &gDeferredFullbrightProgram; - fullbright_shader[1] = fullbright_shader[0]->mRiggedVariant; - - for (int i = 0; i < 2; ++i) - { - fullbright_shader[i]->bind(); - fullbright_shader[i]->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); - fullbright_shader[i]->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f / 2.2f)); - fullbright_shader[i]->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0); - fullbright_shader[i]->unbind(); - } - - simple_shader[0] = (LLPipeline::sImpostorRender) ? &gDeferredAlphaImpostorProgram : - (LLPipeline::sUnderWaterRender) ? &gDeferredAlphaWaterProgram : &gDeferredAlphaProgram; - simple_shader[1] = simple_shader[0]->mRiggedVariant; - - //prime simple shader (loads shadow relevant uniforms) - for (int i = 0; i < 2; ++i) - { - gPipeline.bindDeferredShader(*simple_shader[i]); - simple_shader[i]->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f / 2.2f)); - simple_shader[i]->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0); - } - } - else if (!LLPipeline::sImpostorRender) - { - //update depth buffer sampler - gPipeline.mScreen.flush(); - gPipeline.mDeferredDepth.copyContents(gPipeline.mDeferredScreen, 0, 0, gPipeline.mDeferredScreen.getWidth(), gPipeline.mDeferredScreen.getHeight(), - 0, 0, gPipeline.mDeferredDepth.getWidth(), gPipeline.mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST); - gPipeline.mDeferredDepth.bindTarget(); - simple_shader[0] = fullbright_shader[0] = &gObjectFullbrightAlphaMaskProgram; - simple_shader[1] = fullbright_shader[1] = simple_shader[0]->mRiggedVariant; - - for (int i = 0; i < 2; ++i) - { - simple_shader[i]->bind(); - simple_shader[i]->setMinimumAlpha(0.33f); - } - } - - deferred_render = TRUE; - if (mShaderLevel > 0) - { - // Start out with no shaders. - target_shader = NULL; - } - gPipeline.enableLightsDynamic(); -} - -void LLDrawPoolAlpha::endPostDeferredPass(S32 pass) -{ - LL_PROFILE_ZONE_SCOPED; - - if (pass == 1 && !LLPipeline::sImpostorRender) - { - gPipeline.mDeferredDepth.flush(); - gPipeline.mScreen.bindTarget(); - LLGLSLShader::sCurBoundShaderPtr->unbind(); - } - - deferred_render = FALSE; - endRenderPass(pass); + //also prepare rigged variant + if (shader->mRiggedVariant && shader->mRiggedVariant != shader) + { + prepare_alpha_shader(shader->mRiggedVariant, textureGamma); + } } void LLDrawPoolAlpha::renderPostDeferred(S32 pass) { LL_PROFILE_ZONE_SCOPED; - render(pass); -} + deferred_render = TRUE; -void LLDrawPoolAlpha::beginRenderPass(S32 pass) -{ - LL_PROFILE_ZONE_SCOPED; - - simple_shader[0] = (LLPipeline::sImpostorRender) ? &gObjectSimpleImpostorProgram : - (LLPipeline::sUnderWaterRender) ? &gObjectSimpleWaterProgram : &gObjectSimpleProgram; + // first pass, regular forward alpha rendering + { + emissive_shader = (LLPipeline::sUnderWaterRender) ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram; + prepare_alpha_shader(emissive_shader, true); - fullbright_shader[0] = (LLPipeline::sImpostorRender) ? &gObjectFullbrightProgram : - (LLPipeline::sUnderWaterRender) ? &gObjectFullbrightWaterProgram : &gObjectFullbrightProgram; + fullbright_shader = (LLPipeline::sImpostorRender) ? &gDeferredFullbrightProgram : + (LLPipeline::sUnderWaterRender) ? &gDeferredFullbrightWaterProgram : &gDeferredFullbrightProgram; + prepare_alpha_shader(fullbright_shader, true); - emissive_shader[0] = (LLPipeline::sImpostorRender) ? &gObjectEmissiveProgram : - (LLPipeline::sUnderWaterRender) ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram; - - simple_shader[1] = simple_shader[0]->mRiggedVariant; - fullbright_shader[1] = fullbright_shader[0]->mRiggedVariant; - emissive_shader[1] = emissive_shader[0]->mRiggedVariant; - - if (LLPipeline::sImpostorRender) - { - for (int i = 0; i < 2; ++i) - { - fullbright_shader[i]->bind(); - fullbright_shader[i]->setMinimumAlpha(0.5f); - fullbright_shader[i]->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0); - simple_shader[i]->bind(); - simple_shader[i]->setMinimumAlpha(0.5f); - simple_shader[i]->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0); - } - } - else - { - for (int i = 0; i < 2; ++i) - { - fullbright_shader[i]->bind(); - fullbright_shader[i]->setMinimumAlpha(0.f); - fullbright_shader[i]->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0); - simple_shader[i]->bind(); - simple_shader[i]->setMinimumAlpha(0.f); - simple_shader[i]->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0); - } + simple_shader = (LLPipeline::sImpostorRender) ? &gDeferredAlphaImpostorProgram : + (LLPipeline::sUnderWaterRender) ? &gDeferredAlphaWaterProgram : &gDeferredAlphaProgram; + prepare_alpha_shader(simple_shader, false); + + forwardRender(); } - gPipeline.enableLightsDynamic(); - LLGLSLShader::bindNoShader(); + // second pass, render to depth for depth of field effects + if (!LLPipeline::sImpostorRender && gSavedSettings.getBOOL("RenderDepthOfField")) + { + //update depth buffer sampler + gPipeline.mScreen.flush(); + gPipeline.mDeferredDepth.copyContents(gPipeline.mDeferredScreen, 0, 0, gPipeline.mDeferredScreen.getWidth(), gPipeline.mDeferredScreen.getHeight(), + 0, 0, gPipeline.mDeferredDepth.getWidth(), gPipeline.mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST); + gPipeline.mDeferredDepth.bindTarget(); + simple_shader = fullbright_shader = &gObjectFullbrightAlphaMaskProgram; + + simple_shader->bind(); + simple_shader->setMinimumAlpha(0.33f); + + // mask off color buffer writes as we're only writing to depth buffer + gGL.setColorMask(false, false); + + // If the face is more than 90% transparent, then don't update the Depth buffer for Dof + // We don't want the nearly invisible objects to cause of DoF effects + renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, + true); // <--- discard mostly transparent faces + + gPipeline.mDeferredDepth.flush(); + gPipeline.mScreen.bindTarget(); + gGL.setColorMask(true, false); + } + + renderDebugAlpha(); + + deferred_render = FALSE; } -void LLDrawPoolAlpha::endRenderPass( S32 pass ) +//set some generic parameters for forward (non-deferred) rendering +static void prepare_forward_shader(LLGLSLShader* shader, F32 minimum_alpha) { - LL_PROFILE_ZONE_SCOPED; - LLRenderPass::endRenderPass(pass); + shader->bind(); + shader->setMinimumAlpha(minimum_alpha); + shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0); - if(gPipeline.canUseWindLightShaders()) - { - LLGLSLShader::bindNoShader(); - } + //also prepare rigged variant + if (shader->mRiggedVariant && shader->mRiggedVariant != shader) + { + prepare_forward_shader(shader->mRiggedVariant, minimum_alpha); + } } void LLDrawPoolAlpha::render(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA); + LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA); - LLGLSPipelineAlpha gls_pipeline_alpha; + simple_shader = (LLPipeline::sImpostorRender) ? &gObjectSimpleImpostorProgram : + (LLPipeline::sUnderWaterRender) ? &gObjectSimpleWaterProgram : &gObjectSimpleProgram; - if (deferred_render && pass == 1) - { //depth only - gGL.setColorMask(false, false); - } - else - { - gGL.setColorMask(true, true); - } - - bool write_depth = LLDrawPoolWater::sSkipScreenCopy - || (deferred_render && pass == 1) - // we want depth written so that rendered alpha will - // contribute to the alpha mask used for impostors - || LLPipeline::sImpostorRenderAlphaDepthPass; + fullbright_shader = (LLPipeline::sImpostorRender) ? &gObjectFullbrightProgram : + (LLPipeline::sUnderWaterRender) ? &gObjectFullbrightWaterProgram : &gObjectFullbrightProgram; - LLGLDepthTest depth(GL_TRUE, write_depth ? GL_TRUE : GL_FALSE); + emissive_shader = (LLPipeline::sImpostorRender) ? &gObjectEmissiveProgram : + (LLPipeline::sUnderWaterRender) ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram; - if (deferred_render && pass == 1) - { - gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA); - } - else - { - mColorSFactor = LLRender::BF_SOURCE_ALPHA; // } regular alpha blend - mColorDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // } - mAlphaSFactor = LLRender::BF_ZERO; // } glow suppression - mAlphaDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // } - gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor); - } + F32 minimum_alpha = 0.f; + if (LLPipeline::sImpostorRender) + { + minimum_alpha = 0.5f; + } + prepare_forward_shader(fullbright_shader, minimum_alpha); + prepare_forward_shader(simple_shader, minimum_alpha); - renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, pass); + forwardRender(); - gGL.setColorMask(true, false); + renderDebugAlpha(); +} - if (deferred_render && pass == 1) - { - gGL.setSceneBlendType(LLRender::BT_ALPHA); - } +void LLDrawPoolAlpha::forwardRender() +{ + gPipeline.enableLightsDynamic(); + LLGLSPipelineAlpha gls_pipeline_alpha; + + //enable writing to alpha for emissive effects + gGL.setColorMask(true, true); + + bool write_depth = LLDrawPoolWater::sSkipScreenCopy + // we want depth written so that rendered alpha will + // contribute to the alpha mask used for impostors + || LLPipeline::sImpostorRenderAlphaDepthPass; + + LLGLDepthTest depth(GL_TRUE, write_depth ? GL_TRUE : GL_FALSE); + + mColorSFactor = LLRender::BF_SOURCE_ALPHA; // } regular alpha blend + mColorDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // } + mAlphaSFactor = LLRender::BF_ZERO; // } glow suppression + mAlphaDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // } + gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor); + + // If the face is more than 90% transparent, then don't update the Depth buffer for Dof + // We don't want the nearly invisible objects to cause of DoF effects + renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2); + + gGL.setColorMask(true, false); +} + +void LLDrawPoolAlpha::renderDebugAlpha() +{ if (sShowDebugAlpha) { gHighlightProgram.bind(); @@ -403,7 +352,7 @@ bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_material) current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, draw->mSpecularMap); } } - else if (current_shader == simple_shader[0] || current_shader == simple_shader[1]) + else if (current_shader == simple_shader || current_shader == simple_shader->mRiggedVariant) { current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep); current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep); @@ -470,14 +419,8 @@ void LLDrawPoolAlpha::drawEmissive(U32 mask, LLDrawInfo* draw) void LLDrawPoolAlpha::renderEmissives(U32 mask, std::vector& emissives) { - emissive_shader[0]->bind(); - emissive_shader[0]->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.f); - - gPipeline.enableLightsDynamic(); - - // install glow-accumulating blend mode - // don't touch color, add to alpha (glow) - gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, LLRender::BF_ONE, LLRender::BF_ONE); + emissive_shader->bind(); + emissive_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.f); for (LLDrawInfo* draw : emissives) { @@ -485,24 +428,13 @@ void LLDrawPoolAlpha::renderEmissives(U32 mask, std::vector& emissi drawEmissive(mask, draw); RestoreTexSetup(tex_setup); } - - // restore our alpha blend mode - gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor); - - emissive_shader[0]->unbind(); } void LLDrawPoolAlpha::renderRiggedEmissives(U32 mask, std::vector& emissives) { - emissive_shader[1]->bind(); - emissive_shader[1]->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.f); - - gPipeline.enableLightsDynamic(); - - mask |= LLVertexBuffer::MAP_WEIGHT4; - // install glow-accumulating blend mode - // don't touch color, add to alpha (glow) - gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, LLRender::BF_ONE, LLRender::BF_ONE); + LLGLSLShader* shader = emissive_shader->mRiggedVariant; + shader->bind(); + shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.f); LLVOAvatar* lastAvatar = nullptr; U64 lastMeshId = 0; @@ -522,14 +454,9 @@ void LLDrawPoolAlpha::renderRiggedEmissives(U32 mask, std::vector& drawEmissive(mask, draw); RestoreTexSetup(tex_setup); } - - // restore our alpha blend mode - gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor); - - emissive_shader[1]->unbind(); } -void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) +void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only) { LL_PROFILE_ZONE_SCOPED; BOOL initialized_lighting = FALSE; @@ -577,17 +504,15 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) continue; } - // Fix for bug - NORSPEC-271 - // If the face is more than 90% transparent, then don't update the Depth buffer for Dof - // We don't want the nearly invisible objects to cause of DoF effects - if(pass == 1 && !LLPipeline::sImpostorRender) + if(depth_only) { + // when updating depth buffer, discard faces that are more than 90% transparent LLFace* face = params.mFace; if(face) { const LLTextureEntry* tep = face->getTextureEntry(); if(tep) - { + { // don't render faces that are more than 90% transparent if(tep->getColor().mV[3] < 0.1f) continue; } @@ -609,7 +534,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) if (light_enabled || !initialized_lighting) { initialized_lighting = TRUE; - target_shader = fullbright_shader[0]; + target_shader = fullbright_shader; light_enabled = FALSE; } @@ -618,7 +543,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) else if (!light_enabled || !initialized_lighting) { initialized_lighting = TRUE; - target_shader = simple_shader[0]; + target_shader = simple_shader; light_enabled = TRUE; } @@ -647,11 +572,11 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) } else if (!params.mFullbright) { - target_shader = simple_shader[0]; + target_shader = simple_shader; } else { - target_shader = fullbright_shader[0]; + target_shader = fullbright_shader; } if (params.mAvatar != nullptr) @@ -748,7 +673,15 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) } } + // render emissive faces into alpha channel for bloom effects + if (!depth_only) { + gPipeline.enableLightsDynamic(); + + // install glow-accumulating blend mode + // don't touch color, add to alpha (glow) + gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, LLRender::BF_ONE, LLRender::BF_ONE); + bool rebind = false; LLGLSLShader* lastShader = current_shader; if (!emissives.empty()) @@ -765,6 +698,9 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) rebind = true; } + // restore our alpha blend mode + gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor); + if (lastShader && rebind) { lastShader->bind(); diff --git a/indra/newview/lldrawpoolalpha.h b/indra/newview/lldrawpoolalpha.h index 64c17c3fef..1f6909e282 100644 --- a/indra/newview/lldrawpoolalpha.h +++ b/indra/newview/lldrawpoolalpha.h @@ -51,19 +51,17 @@ public: /*virtual*/ ~LLDrawPoolAlpha(); /*virtual*/ S32 getNumPostDeferredPasses(); - /*virtual*/ void beginPostDeferredPass(S32 pass); - /*virtual*/ void endPostDeferredPass(S32 pass); /*virtual*/ void renderPostDeferred(S32 pass); - - /*virtual*/ void beginRenderPass(S32 pass = 0); - /*virtual*/ void endRenderPass( S32 pass ); /*virtual*/ S32 getNumPasses() { return 1; } virtual void render(S32 pass = 0); + void forwardRender(); /*virtual*/ void prerender(); + void renderDebugAlpha(); + void renderGroupAlpha(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE); - void renderAlpha(U32 mask, S32 pass); + void renderAlpha(U32 mask, bool depth_only = false); void renderAlphaHighlight(U32 mask); bool uploadMatrixPalette(const LLDrawInfo& params); @@ -73,9 +71,9 @@ private: LLGLSLShader* target_shader; // setup by beginFooPass, [0] is static variant, [1] is rigged variant - LLGLSLShader* simple_shader[2] = { nullptr }; - LLGLSLShader* fullbright_shader[2] = { nullptr }; - LLGLSLShader* emissive_shader[2] = { nullptr }; + LLGLSLShader* simple_shader = nullptr; + LLGLSLShader* fullbright_shader = nullptr; + LLGLSLShader* emissive_shader = nullptr; void drawEmissive(U32 mask, LLDrawInfo* draw); void renderEmissives(U32 mask, std::vector& emissives); diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index dc52fc7680..b01450bba9 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -200,21 +200,7 @@ void LLDrawPoolBump::prerender() // static S32 LLDrawPoolBump::numBumpPasses() { - if (gSavedSettings.getBOOL("RenderObjectBump")) - { - if (mShaderLevel > 1) - { - return 6; - } - else - { - return 4; - } - } - else - { - return 0; - } + return 1; } S32 LLDrawPoolBump::getNumPasses() @@ -222,108 +208,49 @@ S32 LLDrawPoolBump::getNumPasses() return numBumpPasses(); } -void LLDrawPoolBump::beginRenderPass(S32 pass) -{ - LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP); - mRigged = ((pass % 2) == 1); - pass /= 2; - switch( pass ) - { - case 0: - beginShiny(); - break; - case 1: - if (mShaderLevel > 1) - { - beginFullbrightShiny(); - } - else - { - beginBump(); - } - break; - case 2: - beginBump(); - break; - default: - llassert(0); - break; - } -} - void LLDrawPoolBump::render(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP); - - if (!gPipeline.hasRenderType(LLDrawPool::POOL_SIMPLE)) - { - return; - } - pass /= 2; - switch( pass ) - { - case 0: - renderShiny(); - break; - case 1: - if (mShaderLevel > 1) - { - renderFullbrightShiny(); - } - else - { - renderBump(); - } - break; - case 2: - renderBump(); - break; - default: - llassert(0); - break; - } + LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP); + + if (!gPipeline.hasRenderType(LLDrawPool::POOL_SIMPLE)) + { + return; + } + + for (int i = 0; i < 2; ++i) + { + mRigged = i == 1; + + // first pass -- shiny + beginShiny(); + renderShiny(); + endShiny(); + + //second pass -- fullbright shiny + if (mShaderLevel > 1) + { + beginFullbrightShiny(); + renderFullbrightShiny(); + endFullbrightShiny(); + } + + //third pass -- bump + beginBump(); + renderBump(LLRenderPass::PASS_BUMP); + endBump(); + } } -void LLDrawPoolBump::endRenderPass(S32 pass) -{ - LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP); - pass /= 2; - switch( pass ) - { - case 0: - endShiny(); - break; - case 1: - if (mShaderLevel > 1) - { - endFullbrightShiny(); - } - else - { - endBump(); - } - break; - case 2: - endBump(); - break; - default: - llassert(0); - break; - } - - //to cleanup texture channels - LLRenderPass::endRenderPass(pass); -} //static -void LLDrawPoolBump::beginShiny(bool invisible) +void LLDrawPoolBump::beginShiny() { LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY); mShiny = TRUE; sVertexMask = VERTEX_MASK_SHINY; // Second pass: environment map - if (!invisible && mShaderLevel > 1) + if (mShaderLevel > 1) { sVertexMask = VERTEX_MASK_SHINY | LLVertexBuffer::MAP_TEXCOORD0; } @@ -353,7 +280,7 @@ void LLDrawPoolBump::beginShiny(bool invisible) shader->uniform1i(LLShaderMgr::NO_ATMO, 0); } - bindCubeMap(shader, mShaderLevel, diffuse_channel, cube_channel, invisible); + bindCubeMap(shader, mShaderLevel, diffuse_channel, cube_channel); if (mShaderLevel > 1) { //indexed texture rendering, channel 0 is always diffuse @@ -362,12 +289,12 @@ void LLDrawPoolBump::beginShiny(bool invisible) } //static -void LLDrawPoolBump::bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel, bool invisible) +void LLDrawPoolBump::bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel) { LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; if( cube_map ) { - if (!invisible && shader ) + if (shader ) { LLMatrix4 mat; mat.initRows(LLVector4(gGLModelView+0), @@ -405,14 +332,14 @@ void LLDrawPoolBump::bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& di } } -void LLDrawPoolBump::renderShiny(bool invisible) +void LLDrawPoolBump::renderShiny() { LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY); if( gSky.mVOSkyp->getCubeMap() ) { LLGLEnable blend_enable(GL_BLEND); - if (!invisible && mShaderLevel > 1) + if (mShaderLevel > 1) { if (mRigged) { @@ -423,7 +350,7 @@ void LLDrawPoolBump::renderShiny(bool invisible) LLRenderPass::pushBatches(LLRenderPass::PASS_SHINY, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); } } - else if (!invisible) + else { if (mRigged) { @@ -438,12 +365,12 @@ void LLDrawPoolBump::renderShiny(bool invisible) } //static -void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel, bool invisible) +void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel) { LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; if( cube_map ) { - if (!invisible && shader_level > 1) + if (shader_level > 1) { shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); @@ -461,11 +388,11 @@ void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& } } -void LLDrawPoolBump::endShiny(bool invisible) +void LLDrawPoolBump::endShiny() { LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY); - unbindCubeMap(shader, mShaderLevel, diffuse_channel, cube_channel, invisible); + unbindCubeMap(shader, mShaderLevel, diffuse_channel, cube_channel); if (shader) { shader->unbind(); @@ -737,7 +664,7 @@ S32 LLDrawPoolBump::getNumDeferredPasses() { if (gSavedSettings.getBOOL("RenderObjectBump")) { - return 2; + return 1; } else { @@ -745,122 +672,81 @@ S32 LLDrawPoolBump::getNumDeferredPasses() } } -void LLDrawPoolBump::beginDeferredPass(S32 pass) -{ - if (!gPipeline.hasRenderBatches( pass == 0 ? LLRenderPass::PASS_BUMP : LLRenderPass::PASS_BUMP_RIGGED)) - { - return; - } - LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP); - mShiny = TRUE; - gDeferredBumpProgram.bind(pass == 1); - diffuse_channel = LLGLSLShader::sCurBoundShaderPtr->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); - bump_channel = LLGLSLShader::sCurBoundShaderPtr->enableTexture(LLViewerShaderMgr::BUMP_MAP); - gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(bump_channel)->unbind(LLTexUnit::TT_TEXTURE); -} - -void LLDrawPoolBump::endDeferredPass(S32 pass) -{ - if (!gPipeline.hasRenderBatches(pass == 0 ? LLRenderPass::PASS_BUMP : LLRenderPass::PASS_BUMP_RIGGED)) - { - return; - } - LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP); - mShiny = FALSE; - LLGLSLShader::sCurBoundShaderPtr->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); - LLGLSLShader::sCurBoundShaderPtr->disableTexture(LLViewerShaderMgr::BUMP_MAP); - LLGLSLShader::sCurBoundShaderPtr->unbind(); - gGL.getTexUnit(0)->activate(); -} - void LLDrawPoolBump::renderDeferred(S32 pass) { - if (!gPipeline.hasRenderBatches(pass == 0 ? LLRenderPass::PASS_BUMP : LLRenderPass::PASS_BUMP_RIGGED)) - { - return; - } LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP); - bool rigged = pass == 1; - U32 type = rigged ? LLRenderPass::PASS_BUMP_RIGGED : LLRenderPass::PASS_BUMP; - LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type); - LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type); - - U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_COLOR; - - LLVOAvatar* avatar = nullptr; - U64 skin = 0; - - for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i) + mShiny = TRUE; + for (int i = 0; i < 2; ++i) { - LLDrawInfo& params = **i; + bool rigged = i == 1; + gDeferredBumpProgram.bind(rigged); + diffuse_channel = LLGLSLShader::sCurBoundShaderPtr->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); + bump_channel = LLGLSLShader::sCurBoundShaderPtr->enableTexture(LLViewerShaderMgr::BUMP_MAP); + gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(bump_channel)->unbind(LLTexUnit::TT_TEXTURE); - LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(params.mAlphaMaskCutoff); - LLDrawPoolBump::bindBumpMap(params, bump_channel); + U32 type = rigged ? LLRenderPass::PASS_BUMP_RIGGED : LLRenderPass::PASS_BUMP; + LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type); + LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type); - if (rigged) + U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_COLOR; + + LLVOAvatar* avatar = nullptr; + U64 skin = 0; + + for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i) { - if (avatar != params.mAvatar || skin != params.mSkinInfo->mHash) + LLDrawInfo& params = **i; + + LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(params.mAlphaMaskCutoff); + LLDrawPoolBump::bindBumpMap(params, bump_channel); + + if (rigged) { - uploadMatrixPalette(params); - avatar = params.mAvatar; - skin = params.mSkinInfo->mHash; + if (avatar != params.mAvatar || skin != params.mSkinInfo->mHash) + { + uploadMatrixPalette(params); + avatar = params.mAvatar; + skin = params.mSkinInfo->mHash; + } + pushBatch(params, mask | LLVertexBuffer::MAP_WEIGHT4, TRUE, FALSE); + } + else + { + pushBatch(params, mask, TRUE, FALSE); } - pushBatch(params, mask | LLVertexBuffer::MAP_WEIGHT4, TRUE, FALSE); - } - else - { - pushBatch(params, mask, TRUE, FALSE); } + + LLGLSLShader::sCurBoundShaderPtr->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); + LLGLSLShader::sCurBoundShaderPtr->disableTexture(LLViewerShaderMgr::BUMP_MAP); + LLGLSLShader::sCurBoundShaderPtr->unbind(); + gGL.getTexUnit(0)->activate(); } + + mShiny = FALSE; } -void LLDrawPoolBump::beginPostDeferredPass(S32 pass) -{ - mRigged = ((pass % 2) == 1); - pass /= 2; - switch (pass) - { - case 0: - beginFullbrightShiny(); - break; - case 1: - beginBump(); - break; - } -} - -void LLDrawPoolBump::endPostDeferredPass(S32 pass) -{ - switch (pass) - { - case 0: - endFullbrightShiny(); - break; - case 1: - endBump(LLRenderPass::PASS_POST_BUMP); - break; - } - - //to disable texture channels - LLRenderPass::endRenderPass(pass); -} void LLDrawPoolBump::renderPostDeferred(S32 pass) { - pass /= 2; - switch (pass) - { - case 0: - renderFullbrightShiny(); - break; - case 1: - renderBump(LLRenderPass::PASS_POST_BUMP); - break; - } + for (int i = 0; i < 2; ++i) + { // two passes -- static and rigged + mRigged = (i == 1); + + // render shiny + beginFullbrightShiny(); + renderFullbrightShiny(); + endFullbrightShiny(); + + //render bump + beginBump(); + renderBump(LLRenderPass::PASS_POST_BUMP); + endBump(); + } } + //////////////////////////////////////////////////////////////// // List of bump-maps created from other textures. @@ -1526,44 +1412,4 @@ void LLDrawPoolInvisible::render(S32 pass) { gOcclusionProgram.unbind(); } - - if (gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY)) - { - beginShiny(true); - renderShiny(true); - endShiny(true); - } -} - -void LLDrawPoolInvisible::beginDeferredPass(S32 pass) -{ - beginRenderPass(pass); -} - -void LLDrawPoolInvisible::endDeferredPass( S32 pass ) -{ - endRenderPass(pass); -} - -void LLDrawPoolInvisible::renderDeferred( S32 pass ) -{ //render invisiprims; this doesn't work becaue it also blocks all the post-deferred stuff -#if 0 - LL_RECORD_BLOCK_TIME(FTM_RENDER_INVISIBLE); - - U32 invisi_mask = LLVertexBuffer::MAP_VERTEX; - glStencilMask(0); - glStencilOp(GL_ZERO, GL_KEEP, GL_REPLACE); - gGL.setColorMask(false, false); - pushBatches(LLRenderPass::PASS_INVISIBLE, invisi_mask, FALSE); - gGL.setColorMask(true, true); - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - glStencilMask(0xFFFFFFFF); - - if (gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY)) - { - beginShiny(true); - renderShiny(true); - endShiny(true); - } -#endif } diff --git a/indra/newview/lldrawpoolbump.h b/indra/newview/lldrawpoolbump.h index 624dbe3034..38744a7d98 100644 --- a/indra/newview/lldrawpoolbump.h +++ b/indra/newview/lldrawpoolbump.h @@ -53,8 +53,6 @@ public: LLDrawPoolBump(); virtual void render(S32 pass = 0) override; - virtual void beginRenderPass( S32 pass ) override; - virtual void endRenderPass( S32 pass ) override; virtual S32 getNumPasses() override; /*virtual*/ void prerender() override; void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE) override; @@ -64,9 +62,9 @@ public: S32 numBumpPasses(); - void beginShiny(bool invisible = false); - void renderShiny(bool invisible = false); - void endShiny(bool invisible = false); + void beginShiny(); + void renderShiny(); + void endShiny(); void beginFullbrightShiny(); void renderFullbrightShiny(); @@ -76,17 +74,13 @@ public: void renderBump(U32 pass = LLRenderPass::PASS_BUMP); void endBump(U32 pass = LLRenderPass::PASS_BUMP); - static void bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel, bool invisible); - static void unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel, bool invisible); + static void bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel); + static void unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel); virtual S32 getNumDeferredPasses() override; - /*virtual*/ void beginDeferredPass(S32 pass) override; - /*virtual*/ void endDeferredPass(S32 pass) override; /*virtual*/ void renderDeferred(S32 pass) override; - virtual S32 getNumPostDeferredPasses() override { return 4; } - /*virtual*/ void beginPostDeferredPass(S32 pass) override; - /*virtual*/ void endPostDeferredPass(S32 pass) override; + virtual S32 getNumPostDeferredPasses() override { return 1; } /*virtual*/ void renderPostDeferred(S32 pass) override; static BOOL bindBumpMap(LLDrawInfo& params, S32 channel = -2); @@ -171,10 +165,10 @@ private: extern LLBumpImageList gBumpImageList; -class LLDrawPoolInvisible : public LLDrawPoolBump +class LLDrawPoolInvisible : public LLRenderPass { public: - LLDrawPoolInvisible() : LLDrawPoolBump(LLDrawPool::POOL_INVISIBLE) { } + LLDrawPoolInvisible() : LLRenderPass(LLDrawPool::POOL_INVISIBLE) { } enum { @@ -189,11 +183,6 @@ public: virtual void beginRenderPass( S32 pass ) { } virtual void endRenderPass( S32 pass ) { } virtual S32 getNumPasses() {return 1;} - - virtual S32 getNumDeferredPasses() { return 1; } - /*virtual*/ void beginDeferredPass(S32 pass); - /*virtual*/ void endDeferredPass(S32 pass); - /*virtual*/ void renderDeferred(S32 pass); }; diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp index a1d769bc83..4ada753355 100644 --- a/indra/newview/lldrawpoolsimple.cpp +++ b/indra/newview/lldrawpoolsimple.cpp @@ -38,37 +38,54 @@ #include "llrender.h" static LLGLSLShader* simple_shader = NULL; -static LLGLSLShader* fullbright_shader = NULL; static LLTrace::BlockTimerStatHandle FTM_RENDER_SIMPLE_DEFERRED("Deferred Simple"); static LLTrace::BlockTimerStatHandle FTM_RENDER_GRASS_DEFERRED("Deferred Grass"); -void LLDrawPoolGlow::beginPostDeferredPass(S32 pass) + +static void setup_simple_shader(LLGLSLShader* shader) { - if (pass == 0) + shader->bind(); + + if (LLPipeline::sRenderingHUDs) { - gDeferredEmissiveProgram.bind(); + shader->uniform1i(LLShaderMgr::NO_ATMO, 1); } else { - llassert(gDeferredEmissiveProgram.mRiggedVariant); - gDeferredEmissiveProgram.mRiggedVariant->bind(); + shader->uniform1i(LLShaderMgr::NO_ATMO, 0); } - - LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); - if (LLPipeline::sRenderingHUDs) - { - LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::NO_ATMO, 1); - } - else - { - LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::NO_ATMO, 0); - } } +static void setup_glow_shader(LLGLSLShader* shader) +{ + setup_simple_shader(shader); + if (LLPipeline::sRenderDeferred && !LLPipeline::sRenderingHUDs) + { + shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); + } + else + { + shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.f); + } +} + +static void setup_fullbright_shader(LLGLSLShader* shader) +{ + setup_glow_shader(shader); + shader->uniform1f(LLViewerShaderMgr::FULLBRIGHT, 1.f); +} + + void LLDrawPoolGlow::renderPostDeferred(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_GLOW); + LL_RECORD_BLOCK_TIME(FTM_RENDER_GLOW); + render(&gDeferredEmissiveProgram); +} + +void LLDrawPoolGlow::render(LLGLSLShader* shader) +{ + LL_RECORD_BLOCK_TIME(FTM_RENDER_GLOW); LLGLEnable blend(GL_BLEND); LLGLDisable test(GL_ALPHA_TEST); gGL.flush(); @@ -80,98 +97,29 @@ void LLDrawPoolGlow::renderPostDeferred(S32 pass) LLGLDepthTest depth(GL_TRUE, GL_FALSE); gGL.setColorMask(false, true); - if (pass == 0) - { - pushBatches(LLRenderPass::PASS_GLOW, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - } - else - { - pushRiggedBatches(LLRenderPass::PASS_GLOW_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - } - - gGL.setColorMask(true, false); - gGL.setSceneBlendType(LLRender::BT_ALPHA); -} - -void LLDrawPoolGlow::endPostDeferredPass(S32 pass) -{ - LLGLSLShader::sCurBoundShaderPtr->unbind(); - - LLRenderPass::endRenderPass(pass); + //first pass -- static objects + setup_glow_shader(shader); + pushBatches(LLRenderPass::PASS_GLOW, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + + // second pass -- rigged objects + shader = shader->mRiggedVariant; + setup_glow_shader(shader); + pushRiggedBatches(LLRenderPass::PASS_GLOW_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + + gGL.setColorMask(true, false); + gGL.setSceneBlendType(LLRender::BT_ALPHA); } S32 LLDrawPoolGlow::getNumPasses() { - if (LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0) - { - return 2; - } - else - { - return 0; - } + return 1; } void LLDrawPoolGlow::render(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_GLOW); - LLGLEnable blend(GL_BLEND); - LLGLDisable test(GL_ALPHA_TEST); - gGL.flush(); - /// Get rid of z-fighting with non-glow pass. - LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL); - glPolygonOffset(-1.0f, -1.0f); - gGL.setSceneBlendType(LLRender::BT_ADD); - - U32 shader_level = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT); - - //should never get here without basic shaders enabled - llassert(shader_level > 0); - - LLGLSLShader* shader = LLPipeline::sUnderWaterRender ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram; - if (pass == 1) - { - llassert(shader->mRiggedVariant); - shader = shader->mRiggedVariant; - } - shader->bind(); - if (LLPipeline::sRenderDeferred) - { - shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); - } - else - { - shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.f); - } - - if (LLPipeline::sRenderingHUDs) - { - shader->uniform1i(LLShaderMgr::NO_ATMO, 1); - } - else - { - shader->uniform1i(LLShaderMgr::NO_ATMO, 0); - } - - LLGLDepthTest depth(GL_TRUE, GL_FALSE); - gGL.setColorMask(false, true); - - if (pass == 0) - { - pushBatches(LLRenderPass::PASS_GLOW, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - } - else - { - pushRiggedBatches(LLRenderPass::PASS_GLOW_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - } - - gGL.setColorMask(true, false); - gGL.setSceneBlendType(LLRender::BT_ALPHA); - - if (shader_level > 0 && fullbright_shader) - { - shader->unbind(); - } + LL_PROFILE_ZONE_SCOPED; + LLGLSLShader* shader = LLPipeline::sUnderWaterRender ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram; + render(shader); } LLDrawPoolSimple::LLDrawPoolSimple() : @@ -186,65 +134,38 @@ void LLDrawPoolSimple::prerender() S32 LLDrawPoolSimple::getNumPasses() { - return 2; -} - -void LLDrawPoolSimple::beginRenderPass(S32 pass) -{ - LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE); - - if (LLPipeline::sImpostorRender) - { - simple_shader = &gObjectSimpleImpostorProgram; - } - else if (LLPipeline::sUnderWaterRender) - { - simple_shader = &gObjectSimpleWaterProgram; - } - else - { - simple_shader = &gObjectSimpleProgram; - } - - if (pass == 1) - { - llassert(simple_shader->mRiggedVariant); - simple_shader = simple_shader->mRiggedVariant; - } - - simple_shader->bind(); - - if (LLPipeline::sRenderingHUDs) - { - simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1); - } - else - { - simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0); - } -} - -void LLDrawPoolSimple::endRenderPass(S32 pass) -{ - LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE); - stop_glerror(); - LLRenderPass::endRenderPass(pass); - stop_glerror(); - simple_shader->unbind(); + return 1; } void LLDrawPoolSimple::render(S32 pass) { + LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE); + LLGLDisable blend(GL_BLEND); + LLGLSLShader* shader = nullptr; + if (LLPipeline::sImpostorRender) + { + shader = &gObjectSimpleImpostorProgram; + } + else if (LLPipeline::sUnderWaterRender) + { + shader = &gObjectSimpleWaterProgram; + } + else + { + shader = &gObjectSimpleProgram; + } + { //render simple - LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE); + gPipeline.enableLightsDynamic(); U32 mask = getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX; - if (pass == 0) + // first pass -- static objects { + setup_simple_shader(shader); pushBatches(LLRenderPass::PASS_SIMPLE, mask, TRUE, TRUE); if (LLPipeline::sRenderDeferred) @@ -257,8 +178,11 @@ void LLDrawPoolSimple::render(S32 pass) pushBatches(LLRenderPass::PASS_NORMSPEC, mask, TRUE, TRUE); } } - else + + //second pass, rigged { + shader = shader->mRiggedVariant; + setup_simple_shader(shader); pushRiggedBatches(LLRenderPass::PASS_SIMPLE_RIGGED, mask, TRUE, TRUE); if (LLPipeline::sRenderDeferred) @@ -275,9 +199,6 @@ void LLDrawPoolSimple::render(S32 pass) } - - - static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_MASK("Alpha Mask"); LLDrawPoolAlphaMask::LLDrawPoolAlphaMask() : @@ -290,84 +211,36 @@ void LLDrawPoolAlphaMask::prerender() mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT); } -void LLDrawPoolAlphaMask::beginRenderPass(S32 pass) -{ - LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK); - - if (LLPipeline::sUnderWaterRender) - { - simple_shader = &gObjectSimpleWaterAlphaMaskProgram; - } - else - { - simple_shader = &gObjectSimpleAlphaMaskProgram; - } - - if (pass == 1) - { - llassert(simple_shader->mRiggedVariant); - simple_shader = simple_shader->mRiggedVariant; - } - - simple_shader->bind(); - - if (LLPipeline::sRenderingHUDs) - { - simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1); - } - else - { - simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0); - } -} - -void LLDrawPoolAlphaMask::endRenderPass(S32 pass) -{ - LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK); - stop_glerror(); - LLRenderPass::endRenderPass(pass); - stop_glerror(); - if (mShaderLevel > 0) - { - simple_shader->unbind(); - } -} - void LLDrawPoolAlphaMask::render(S32 pass) { LLGLDisable blend(GL_BLEND); LL_PROFILE_ZONE_SCOPED; - - - simple_shader->bind(); - simple_shader->setMinimumAlpha(0.33f); - - if (LLPipeline::sRenderingHUDs) - { - simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1); - } - else - { - simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0); - } - - if (pass == 0) + LLGLSLShader* shader = nullptr; + if (LLPipeline::sUnderWaterRender) { - pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - pushMaskBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - pushMaskBatches(LLRenderPass::PASS_SPECMAP_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - pushMaskBatches(LLRenderPass::PASS_NORMMAP_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - pushMaskBatches(LLRenderPass::PASS_NORMSPEC_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - } - else - { - pushRiggedMaskBatches(LLRenderPass::PASS_ALPHA_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - pushRiggedMaskBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - pushRiggedMaskBatches(LLRenderPass::PASS_SPECMAP_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - pushRiggedMaskBatches(LLRenderPass::PASS_NORMMAP_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - pushRiggedMaskBatches(LLRenderPass::PASS_NORMSPEC_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - } + shader = &gObjectSimpleWaterAlphaMaskProgram; + } + else + { + shader = &gObjectSimpleAlphaMaskProgram; + } + + // render static + setup_simple_shader(shader); + pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + pushMaskBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + pushMaskBatches(LLRenderPass::PASS_SPECMAP_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + pushMaskBatches(LLRenderPass::PASS_NORMMAP_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + pushMaskBatches(LLRenderPass::PASS_NORMSPEC_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + + // render rigged + setup_simple_shader(shader->mRiggedVariant); + pushRiggedMaskBatches(LLRenderPass::PASS_ALPHA_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + pushRiggedMaskBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + pushRiggedMaskBatches(LLRenderPass::PASS_SPECMAP_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + pushRiggedMaskBatches(LLRenderPass::PASS_NORMMAP_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + pushRiggedMaskBatches(LLRenderPass::PASS_NORMSPEC_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); } LLDrawPoolFullbrightAlphaMask::LLDrawPoolFullbrightAlphaMask() : @@ -380,61 +253,27 @@ void LLDrawPoolFullbrightAlphaMask::prerender() mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT); } -void LLDrawPoolFullbrightAlphaMask::beginRenderPass(S32 pass) -{ - LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK); - - bool rigged = (pass == 1); - if (LLPipeline::sUnderWaterRender) - { - gObjectFullbrightWaterAlphaMaskProgram.bind(rigged); - } - else - { - gObjectFullbrightAlphaMaskProgram.bind(rigged); - } - - if (LLPipeline::sRenderingHUDs) - { - LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::NO_ATMO, 1); - LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.f); - } - else - { - LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::NO_ATMO, 0); - if (LLPipeline::sRenderDeferred) - { - LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); - } - else - { - LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f); - } - } -} - -void LLDrawPoolFullbrightAlphaMask::endRenderPass(S32 pass) -{ - LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK); - stop_glerror(); - LLRenderPass::endRenderPass(pass); - stop_glerror(); - LLGLSLShader::sCurBoundShaderPtr->unbind(); -} - void LLDrawPoolFullbrightAlphaMask::render(S32 pass) { LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK); - if (pass == 0) + LLGLSLShader* shader = nullptr; + if (LLPipeline::sUnderWaterRender) { - pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + shader = &gObjectFullbrightWaterAlphaMaskProgram; } else { - pushRiggedMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + shader = &gObjectFullbrightAlphaMaskProgram; } - + + // render static + setup_fullbright_shader(shader); + pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + + // render rigged + setup_fullbright_shader(shader->mRiggedVariant); + pushRiggedMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); } //=============================== @@ -443,112 +282,41 @@ void LLDrawPoolFullbrightAlphaMask::render(S32 pass) S32 LLDrawPoolSimple::getNumDeferredPasses() { - if (LLPipeline::sRenderingHUDs) - { - return 1; - } - else - { - return 2; - } -} -void LLDrawPoolSimple::beginDeferredPass(S32 pass) -{ - LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE_DEFERRED); - - mShader = &gDeferredDiffuseProgram; - - if (pass == 1) - { - llassert(mShader->mRiggedVariant != nullptr); - mShader = mShader->mRiggedVariant; - } - - - mShader->bind(); - - if (LLPipeline::sRenderingHUDs) - { - mShader->uniform1i(LLShaderMgr::NO_ATMO, 1); - } - else - { - mShader->uniform1i(LLShaderMgr::NO_ATMO, 0); - } -} - -void LLDrawPoolSimple::endDeferredPass(S32 pass) -{ - LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE_DEFERRED); - LLRenderPass::endRenderPass(pass); - - mShader->unbind(); + return 1; } void LLDrawPoolSimple::renderDeferred(S32 pass) { - LL_PROFILE_ZONE_SCOPED; + LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE_DEFERRED); LLGLDisable blend(GL_BLEND); LLGLDisable alpha_test(GL_ALPHA_TEST); - if (pass == 0) - { //render simple - LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE_DEFERRED); - pushBatches(LLRenderPass::PASS_SIMPLE, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - } - else - { - //render simple rigged - pushRiggedBatches(LLRenderPass::PASS_SIMPLE_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - } + //render static + setup_simple_shader(&gDeferredDiffuseProgram); + pushBatches(LLRenderPass::PASS_SIMPLE, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + + //render rigged + setup_simple_shader(gDeferredDiffuseProgram.mRiggedVariant); + pushRiggedBatches(LLRenderPass::PASS_SIMPLE_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); } static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_MASK_DEFERRED("Deferred Alpha Mask"); -void LLDrawPoolAlphaMask::beginDeferredPass(S32 pass) -{ - if (pass == 0) - { - gDeferredDiffuseAlphaMaskProgram.bind(); - } - else - { - llassert(gDeferredDiffuseAlphaMaskProgram.mRiggedVariant); - gDeferredDiffuseAlphaMaskProgram.mRiggedVariant->bind(); - } - -} - -void LLDrawPoolAlphaMask::endDeferredPass(S32 pass) -{ - LLGLSLShader::sCurBoundShaderPtr->unbind(); -} void LLDrawPoolAlphaMask::renderDeferred(S32 pass) { LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK_DEFERRED); - LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(0.33f); + LLGLSLShader* shader = &gDeferredDiffuseAlphaMaskProgram; - if (LLPipeline::sRenderingHUDs) - { - LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::NO_ATMO, 1); - } - else - { - LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::NO_ATMO, 0); - } + //render static + setup_simple_shader(shader); + pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - if (pass == 0) - { - pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - } - else - { - pushRiggedMaskBatches(LLRenderPass::PASS_ALPHA_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - } + //render rigged + setup_simple_shader(shader->mRiggedVariant); + pushRiggedMaskBatches(LLRenderPass::PASS_ALPHA_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); } - // grass drawpool LLDrawPoolGrass::LLDrawPoolGrass() : LLRenderPass(POOL_GRASS) @@ -667,83 +435,31 @@ void LLDrawPoolFullbright::prerender() mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT); } -void LLDrawPoolFullbright::beginPostDeferredPass(S32 pass) -{ - bool rigged = (pass == 1); - if (LLPipeline::sUnderWaterRender) - { - gDeferredFullbrightWaterProgram.bind(rigged); - } - else - { - gDeferredFullbrightProgram.bind(rigged); - - if (LLPipeline::sRenderingHUDs) - { - LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::NO_ATMO, 1); - } - else - { - LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::NO_ATMO, 0); - } - } -} void LLDrawPoolFullbright::renderPostDeferred(S32 pass) { LL_RECORD_BLOCK_TIME(FTM_RENDER_FULLBRIGHT); - - gGL.setSceneBlendType(LLRender::BT_ALPHA); - U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX; - if (pass == 0) + + LLGLSLShader* shader = nullptr; + if (LLPipeline::sUnderWaterRender) { - pushBatches(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask, TRUE, TRUE); + shader = &gDeferredFullbrightWaterProgram; } else { - pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_RIGGED, fullbright_mask, TRUE, TRUE); + shader = &gDeferredFullbrightProgram; } -} -void LLDrawPoolFullbright::endPostDeferredPass(S32 pass) -{ - LLGLSLShader::sCurBoundShaderPtr->unbind(); - LLRenderPass::endRenderPass(pass); -} - -void LLDrawPoolFullbright::beginRenderPass(S32 pass) -{ - LL_RECORD_BLOCK_TIME(FTM_RENDER_FULLBRIGHT); - - if (LLPipeline::sUnderWaterRender) - { - fullbright_shader = &gObjectFullbrightWaterProgram; - } - else - { - fullbright_shader = &gObjectFullbrightProgram; - } - - if (pass == 1) - { - llassert(fullbright_shader->mRiggedVariant); - fullbright_shader = fullbright_shader->mRiggedVariant; - } -} - -void LLDrawPoolFullbright::endRenderPass(S32 pass) -{ - LL_RECORD_BLOCK_TIME(FTM_RENDER_FULLBRIGHT); - LLRenderPass::endRenderPass(pass); - - stop_glerror(); - - if (mShaderLevel > 0) - { - fullbright_shader->unbind(); - } - - stop_glerror(); + gGL.setSceneBlendType(LLRender::BT_ALPHA); + U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX; + + // render static + setup_fullbright_shader(shader); + pushBatches(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask, TRUE, TRUE); + + // render rigged + setup_fullbright_shader(shader->mRiggedVariant); + pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_RIGGED, fullbright_mask, TRUE, TRUE); } void LLDrawPoolFullbright::render(S32 pass) @@ -752,102 +468,75 @@ void LLDrawPoolFullbright::render(S32 pass) gGL.setSceneBlendType(LLRender::BT_ALPHA); stop_glerror(); + LLGLSLShader* shader = nullptr; + if (LLPipeline::sUnderWaterRender) + { + shader = &gObjectFullbrightWaterProgram; + } + else + { + shader = &gObjectFullbrightProgram; + } - if (mShaderLevel > 0) - { - fullbright_shader->bind(); - fullbright_shader->uniform1f(LLViewerShaderMgr::FULLBRIGHT, 1.f); - fullbright_shader->uniform1f(LLViewerShaderMgr::TEXTURE_GAMMA, 1.f); - if (LLPipeline::sRenderingHUDs) - { - fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, 1); - } - else - { - fullbright_shader->uniform1i(LLShaderMgr::NO_ATMO, 0); - } + U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX; - U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX; - - if (pass == 0) - { - pushBatches(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask, TRUE, TRUE); - pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, fullbright_mask, TRUE, TRUE); - pushBatches(LLRenderPass::PASS_SPECMAP_EMISSIVE, fullbright_mask, TRUE, TRUE); - pushBatches(LLRenderPass::PASS_NORMMAP_EMISSIVE, fullbright_mask, TRUE, TRUE); - pushBatches(LLRenderPass::PASS_NORMSPEC_EMISSIVE, fullbright_mask, TRUE, TRUE); - } - else - { - pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_RIGGED, fullbright_mask, TRUE, TRUE); - pushRiggedBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE_RIGGED, fullbright_mask, TRUE, TRUE); - pushRiggedBatches(LLRenderPass::PASS_SPECMAP_EMISSIVE_RIGGED, fullbright_mask, TRUE, TRUE); - pushRiggedBatches(LLRenderPass::PASS_NORMMAP_EMISSIVE_RIGGED, fullbright_mask, TRUE, TRUE); - pushRiggedBatches(LLRenderPass::PASS_NORMSPEC_EMISSIVE_RIGGED, fullbright_mask, TRUE, TRUE); - } - } - - stop_glerror(); + // render static + setup_fullbright_shader(shader); + pushBatches(LLRenderPass::PASS_FULLBRIGHT, mask, TRUE, TRUE); + pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, mask, TRUE, TRUE); + pushBatches(LLRenderPass::PASS_SPECMAP_EMISSIVE, mask, TRUE, TRUE); + pushBatches(LLRenderPass::PASS_NORMMAP_EMISSIVE, mask, TRUE, TRUE); + pushBatches(LLRenderPass::PASS_NORMSPEC_EMISSIVE, mask, TRUE, TRUE); + + // render rigged + setup_fullbright_shader(shader->mRiggedVariant); + pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_RIGGED, mask, TRUE, TRUE); + pushRiggedBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE_RIGGED, mask, TRUE, TRUE); + pushRiggedBatches(LLRenderPass::PASS_SPECMAP_EMISSIVE_RIGGED, mask, TRUE, TRUE); + pushRiggedBatches(LLRenderPass::PASS_NORMMAP_EMISSIVE_RIGGED, mask, TRUE, TRUE); + pushRiggedBatches(LLRenderPass::PASS_NORMSPEC_EMISSIVE_RIGGED, mask, TRUE, TRUE); } S32 LLDrawPoolFullbright::getNumPasses() { - return 2; -} - - -void LLDrawPoolFullbrightAlphaMask::beginPostDeferredPass(S32 pass) -{ - bool rigged = (pass == 1); - if (LLPipeline::sRenderingHUDs) - { - gObjectFullbrightAlphaMaskProgram.bind(rigged); - LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f); - LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::NO_ATMO, 1); - } - else if (LLPipeline::sRenderDeferred) - { - if (LLPipeline::sUnderWaterRender) - { - gDeferredFullbrightAlphaMaskWaterProgram.bind(rigged); - LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); - LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::NO_ATMO, 1); - } - else - { - gDeferredFullbrightAlphaMaskProgram.bind(rigged); - LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); - LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::NO_ATMO, 0); - } - } - else - { - gObjectFullbrightAlphaMaskProgram.bind(rigged); - LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f); - LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::NO_ATMO, 0); - } + return 1; } void LLDrawPoolFullbrightAlphaMask::renderPostDeferred(S32 pass) { LL_RECORD_BLOCK_TIME(FTM_RENDER_FULLBRIGHT); - LLGLDisable blend(GL_BLEND); - U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX; - if (pass == 0) + + LLGLSLShader* shader = nullptr; + if (LLPipeline::sRenderingHUDs) { - pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, fullbright_mask, TRUE, TRUE); + shader = &gObjectFullbrightAlphaMaskProgram; + } + else if (LLPipeline::sRenderDeferred) + { + if (LLPipeline::sUnderWaterRender) + { + shader = &gDeferredFullbrightAlphaMaskWaterProgram; + } + else + { + shader = &gDeferredFullbrightAlphaMaskProgram; + } } else { - pushRiggedMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK_RIGGED, fullbright_mask, TRUE, TRUE); + shader = &gObjectFullbrightAlphaMaskProgram; } + + LLGLDisable blend(GL_BLEND); + U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX; + + // render static + setup_fullbright_shader(shader); + pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, fullbright_mask, TRUE, TRUE); + + // render rigged + setup_fullbright_shader(shader->mRiggedVariant); + pushRiggedMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK_RIGGED, fullbright_mask, TRUE, TRUE); } -void LLDrawPoolFullbrightAlphaMask::endPostDeferredPass(S32 pass) -{ - LLGLSLShader::sCurBoundShaderPtr->unbind(); - LLRenderPass::endRenderPass(pass); -} - - diff --git a/indra/newview/lldrawpoolsimple.h b/indra/newview/lldrawpoolsimple.h index d6fecdd23c..cccbe5e495 100644 --- a/indra/newview/lldrawpoolsimple.h +++ b/indra/newview/lldrawpoolsimple.h @@ -46,18 +46,12 @@ public: LLDrawPoolSimple(); S32 getNumDeferredPasses() override; - void beginDeferredPass(S32 pass) override; - void endDeferredPass(S32 pass) override; void renderDeferred(S32 pass) override; - void beginRenderPass(S32 pass) override; - void endRenderPass(S32 pass) override; /// We need two passes so we can handle emissive materials separately. S32 getNumPasses() override; void render(S32 pass = 0) override; void prerender() override; - - LLGLSLShader* mShader = nullptr; }; class LLDrawPoolGrass : public LLRenderPass @@ -101,14 +95,10 @@ public: LLDrawPoolAlphaMask(); - /*virtual*/ S32 getNumDeferredPasses() { return 2; } - /*virtual*/ void beginDeferredPass(S32 pass); - /*virtual*/ void endDeferredPass(S32 pass); + /*virtual*/ S32 getNumDeferredPasses() { return 1; } /*virtual*/ void renderDeferred(S32 pass); - /*virtual*/ S32 getNumPasses() { return 2; } - /*virtual*/ void beginRenderPass(S32 pass); - /*virtual*/ void endRenderPass(S32 pass); + /*virtual*/ S32 getNumPasses() { return 1; } /*virtual*/ void render(S32 pass = 0); /*virtual*/ void prerender(); @@ -127,14 +117,10 @@ public: LLDrawPoolFullbrightAlphaMask(); - /*virtual*/ S32 getNumPostDeferredPasses() { return 2; } - /*virtual*/ void beginPostDeferredPass(S32 pass); - /*virtual*/ void endPostDeferredPass(S32 pass); + /*virtual*/ S32 getNumPostDeferredPasses() { return 1; } /*virtual*/ void renderPostDeferred(S32 pass); - /*virtual*/ S32 getNumPasses() { return 2; } - /*virtual*/ void beginRenderPass(S32 pass); - /*virtual*/ void endRenderPass(S32 pass); + /*virtual*/ S32 getNumPasses() { return 1; } /*virtual*/ void render(S32 pass = 0); /*virtual*/ void prerender(); }; @@ -153,13 +139,9 @@ public: LLDrawPoolFullbright(); - /*virtual*/ S32 getNumPostDeferredPasses() { return 2; } - /*virtual*/ void beginPostDeferredPass(S32 pass); - /*virtual*/ void endPostDeferredPass(S32 pass); + /*virtual*/ S32 getNumPostDeferredPasses() { return 1; } /*virtual*/ void renderPostDeferred(S32 pass); - /*virtual*/ void beginRenderPass(S32 pass); - /*virtual*/ void endRenderPass(S32 pass); /*virtual*/ S32 getNumPasses(); /*virtual*/ void render(S32 pass = 0); /*virtual*/ void prerender(); @@ -182,11 +164,11 @@ public: virtual void prerender() { } - /*virtual*/ S32 getNumPostDeferredPasses() { return 2; } - /*virtual*/ void beginPostDeferredPass(S32 pass); - /*virtual*/ void endPostDeferredPass(S32 pass); + /*virtual*/ S32 getNumPostDeferredPasses() { return 1; } /*virtual*/ void renderPostDeferred(S32 pass); + void render(LLGLSLShader* shader); + /*virtual*/ S32 getNumPasses(); void render(S32 pass = 0); From e7830b39f01d9f9c82e9e2029634dffb8386b24e Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 3 Dec 2021 15:07:31 +0000 Subject: [PATCH 6/6] SL-16436 and SL-16327 Fix for RenderDebugGL test failures and fix for grey textures --- indra/llrender/llgl.cpp | 44 +- indra/llrender/llimagegl.cpp | 34 +- indra/llrender/llimagegl.h | 10 +- indra/llrender/llrender.cpp | 6 +- indra/newview/CMakeLists.txt | 4 - .../class1/deferred/avatarAlphaShadowF.glsl | 4 +- .../class1/deferred/avatarAlphaShadowV.glsl | 3 - indra/newview/lldrawable.h | 5 +- indra/newview/lldrawpooltree.cpp | 10 +- indra/newview/llface.h | 1 - indra/newview/llglsandbox.cpp | 15 + indra/newview/llspatialpartition.cpp | 130 +----- indra/newview/llspatialpartition.h | 40 +- indra/newview/lltextureatlas.cpp | 416 ------------------ indra/newview/lltextureatlas.h | 90 ---- indra/newview/lltextureatlasmanager.cpp | 268 ----------- indra/newview/lltextureatlasmanager.h | 105 ----- indra/newview/llviewertexture.cpp | 71 +-- indra/newview/llvovolume.cpp | 11 +- indra/newview/pipeline.cpp | 28 +- indra/newview/pipeline.h | 3 + 21 files changed, 166 insertions(+), 1132 deletions(-) delete mode 100644 indra/newview/lltextureatlas.cpp delete mode 100644 indra/newview/lltextureatlas.h delete mode 100644 indra/newview/lltextureatlasmanager.cpp delete mode 100644 indra/newview/lltextureatlasmanager.h diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index 58183adfce..f24bf6ec78 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -88,24 +88,32 @@ void APIENTRY gl_debug_callback(GLenum source, { if (gGLDebugLoggingEnabled) { - if (severity == GL_DEBUG_SEVERITY_HIGH_ARB) - { - LL_WARNS() << "----- GL ERROR --------" << LL_ENDL; - } - else - { - LL_WARNS() << "----- GL WARNING -------" << LL_ENDL; - } - LL_WARNS() << "Type: " << std::hex << type << LL_ENDL; - LL_WARNS() << "ID: " << std::hex << id << LL_ENDL; - LL_WARNS() << "Severity: " << std::hex << severity << LL_ENDL; - LL_WARNS() << "Message: " << message << LL_ENDL; - LL_WARNS() << "-----------------------" << LL_ENDL; - if (severity == GL_DEBUG_SEVERITY_HIGH_ARB) - { - LL_ERRS() << "Halting on GL Error" << LL_ENDL; - } -} + + if (severity != GL_DEBUG_SEVERITY_HIGH_ARB && + severity != GL_DEBUG_SEVERITY_MEDIUM_ARB && + severity != GL_DEBUG_SEVERITY_LOW_ARB) + { //suppress out-of-spec messages sent by nvidia driver (mostly vertexbuffer hints) + return; + } + + if (severity == GL_DEBUG_SEVERITY_HIGH_ARB) + { + LL_WARNS() << "----- GL ERROR --------" << LL_ENDL; + } + else + { + LL_WARNS() << "----- GL WARNING -------" << LL_ENDL; + } + LL_WARNS() << "Type: " << std::hex << type << LL_ENDL; + LL_WARNS() << "ID: " << std::hex << id << LL_ENDL; + LL_WARNS() << "Severity: " << std::hex << severity << LL_ENDL; + LL_WARNS() << "Message: " << message << LL_ENDL; + LL_WARNS() << "-----------------------" << LL_ENDL; + if (severity == GL_DEBUG_SEVERITY_HIGH_ARB) + { + LL_ERRS() << "Halting on GL Error" << LL_ENDL; + } + } } #endif diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 894eb8c773..d3af27272b 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -41,6 +41,10 @@ #include "llrender.h" #include "llwindow.h" +#if !LL_IMAGEGL_THREAD_CHECK +#define checkActiveThread() +#endif + //---------------------------------------------------------------------------- const F32 MIN_TEXTURE_LIFETIME = 10.f; @@ -437,6 +441,10 @@ LLImageGL::~LLImageGL() void LLImageGL::init(BOOL usemipmaps) { +#if LL_IMAGEGL_THREAD_CHECK + mActiveThread = LLThread::currentID(); +#endif + // keep these members in the same order as declared in llimagehl.h // so that it is obvious by visual inspection if we forgot to // init a field. @@ -1317,6 +1325,8 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt BOOL LLImageGL::createGLTexture() { LL_PROFILE_ZONE_SCOPED; + checkActiveThread(); + if (gGLManager.mIsDisabled) { LL_WARNS() << "Trying to create a texture while GL is disabled!" << LL_ENDL; @@ -1349,6 +1359,8 @@ BOOL LLImageGL::createGLTexture() BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/, BOOL to_create, S32 category) { LL_PROFILE_ZONE_SCOPED; + checkActiveThread(); + if (gGLManager.mIsDisabled) { LL_WARNS() << "Trying to create a texture while GL is disabled!" << LL_ENDL; @@ -1462,6 +1474,8 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips, S32 usename) { LL_PROFILE_ZONE_SCOPED; + checkActiveThread(); + llassert(data_in); stop_glerror(); @@ -1576,6 +1590,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_ // mark this as bound at this point, so we don't throw it out immediately mLastBindTime = sLastFrameTime; + checkActiveThread(); return TRUE; } @@ -1690,18 +1705,10 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre return TRUE ; } -void LLImageGL::deleteDeadTextures() -{ - bool reset = false; - - if (reset) - { - gGL.getTexUnit(0)->activate(); - } -} - void LLImageGL::destroyGLTexture() { + checkActiveThread(); + if (mTexName != 0) { if(mTextureMemory != S32Bytes(0)) @@ -1720,6 +1727,7 @@ void LLImageGL::destroyGLTexture() //force to invalidate the gl texture, most likely a sculpty texture void LLImageGL::forceToInvalidateGLTexture() { + checkActiveThread(); if (mTexName != 0) { destroyGLTexture(); @@ -2196,6 +2204,12 @@ void LLImageGL::resetCurTexSizebar() sCurTexPickSize = -1 ; } //---------------------------------------------------------------------------- +#if LL_IMAGEGL_THREAD_CHECK +void LLImageGL::checkActiveThread() +{ + llassert(mActiveThread == LLThread::currentID()); +} +#endif //---------------------------------------------------------------------------- diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index ae773bb362..28996a554a 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -40,7 +40,8 @@ #include "threadpool.h" #include "workqueue.h" -class LLTextureAtlas ; +#define LL_IMAGEGL_THREAD_CHECK 0 //set to 1 to enable thread debugging for ImageGL + class LLWindow; #define BYTES_TO_MEGA_BYTES(x) ((x) >> 20) @@ -54,7 +55,6 @@ public: // These 2 functions replace glGenTextures() and glDeleteTextures() static void generateTextures(S32 numTextures, U32 *textures); static void deleteTextures(S32 numTextures, const U32 *textures); - static void deleteDeadTextures(); // Size calculation static S32 dataFormatBits(S32 dataformat); @@ -189,6 +189,12 @@ public: BOOL preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image); void postAddToAtlas() ; +#if LL_IMAGEGL_THREAD_CHECK + // thread debugging + std::thread::id mActiveThread; + void checkActiveThread(); +#endif + public: // Various GL/Rendering options S32Bytes mTextureMemory; diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 235f8a8eb0..8b4f250894 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -181,7 +181,11 @@ void LLTexUnit::bindFast(LLTexture* texture) mCurrTexture = gl_tex->getTexName(); if (!mCurrTexture) { - mCurrTexture = LLImageGL::sDefaultGLTexture->getTexName(); + LL_PROFILE_ZONE_NAMED("MISSING TEXTURE"); + //if deleted, will re-generate it immediately + texture->forceImmediateUpdate(); + gl_tex->forceUpdateBindStats(); + texture->bindDefaultImage(mIndex); } glBindTexture(sGLTextureType[gl_tex->getTarget()], mCurrTexture); mHasMipMaps = gl_tex->mHasMipMaps; diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 4a7f17f15b..8157d1566a 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -590,8 +590,6 @@ set(viewer_SOURCE_FILES llsyswellwindow.cpp llteleporthistory.cpp llteleporthistorystorage.cpp - lltextureatlas.cpp - lltextureatlasmanager.cpp lltexturecache.cpp lltexturectrl.cpp lltexturefetch.cpp @@ -1219,8 +1217,6 @@ set(viewer_HEADER_FILES lltable.h llteleporthistory.h llteleporthistorystorage.h - lltextureatlas.h - lltextureatlasmanager.h lltexturecache.h lltexturectrl.h lltexturefetch.h diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl index ef49b6f4e8..1b16e4eb09 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl @@ -40,11 +40,11 @@ VARYING vec4 post_pos; VARYING float pos_w; VARYING float target_pos_x; VARYING vec2 vary_texcoord0; -VARYING vec4 vertex_color; +uniform vec4 color; void main() { - float alpha = texture2D(diffuseMap, vary_texcoord0.xy).a * vertex_color.a; + float alpha = texture2D(diffuseMap, vary_texcoord0.xy).a * color.a; if (alpha < 0.05) // treat as totally transparent { diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl index d1d7ece6fe..1c5b142ebd 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl @@ -30,7 +30,6 @@ uniform float shadow_target_width; mat4 getSkinnedTransform(); void passTextureIndex(); -ATTRIBUTE vec4 diffuse_color; ATTRIBUTE vec3 position; ATTRIBUTE vec3 normal; ATTRIBUTE vec2 texcoord0; @@ -41,7 +40,6 @@ VARYING vec4 post_pos; VARYING float pos_w; VARYING float target_pos_x; VARYING vec2 vary_texcoord0; -VARYING vec4 vertex_color; void main() { @@ -68,7 +66,6 @@ void main() vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; - vertex_color = diffuse_color; #if !DEPTH_CLAMP post_pos = pos; diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index 6002e3e0dd..9a9f6cf7c2 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -64,6 +64,8 @@ class LLDrawable { LL_ALIGN_NEW; public: + typedef std::vector face_list_t; + LLDrawable(const LLDrawable& rhs) : LLViewerOctreeEntryData(rhs) { @@ -129,6 +131,7 @@ public: inline LLFace* getFace(const S32 i) const; inline S32 getNumFaces() const; + face_list_t& getFaces() { return mFaces; } //void removeFace(const S32 i); // SJB: Avoid using this, it's slow LLFace* addFace(LLFacePool *poolp, LLViewerTexture *texturep); @@ -297,8 +300,6 @@ public: static F32 sCurPixelAngle; //current pixels per radian private: - typedef std::vector face_list_t; - U32 mState; S32 mRenderType; LLPointer mVObjp; diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp index ac957f1cbd..facfb235c9 100644 --- a/indra/newview/lldrawpooltree.cpp +++ b/indra/newview/lldrawpooltree.cpp @@ -92,8 +92,9 @@ void LLDrawPoolTree::render(S32 pass) LLGLState test(GL_ALPHA_TEST, 0); - gGL.getTexUnit(sDiffTex)->bind(mTexturep); - + gGL.getTexUnit(sDiffTex)->bindFast(mTexturep); + gPipeline.touchTexture(mTexturep, 1024.f * 1024.f); // <=== keep Linden tree textures at full res + for (std::vector::iterator iter = mDrawFace.begin(); iter != mDrawFace.end(); iter++) { @@ -116,9 +117,8 @@ void LLDrawPoolTree::render(S32 pass) gPipeline.mMatrixOpCount++; } - buff->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK); - buff->drawRange(LLRender::TRIANGLES, 0, buff->getNumVerts()-1, buff->getNumIndices(), 0); - gPipeline.addTrianglesDrawn(buff->getNumIndices()); + buff->setBufferFast(LLDrawPoolTree::VERTEX_DATA_MASK); + buff->drawRangeFast(LLRender::TRIANGLES, 0, buff->getNumVerts()-1, buff->getNumIndices(), 0); } } } diff --git a/indra/newview/llface.h b/indra/newview/llface.h index c533edede4..79f50f2273 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -47,7 +47,6 @@ class LLTextureEntry; class LLVertexProgram; class LLViewerTexture; class LLGeometryManager; -class LLTextureAtlasSlot; class LLDrawInfo; class LLMeshSkinInfo; diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp index a135ef0814..0b5064c77d 100644 --- a/indra/newview/llglsandbox.cpp +++ b/indra/newview/llglsandbox.cpp @@ -1115,6 +1115,14 @@ F32 gpu_benchmark() // ensure matched pair of bind() and unbind() calls ShaderBinder binder(gBenchmarkProgram); + U32 glarray = 0; + + if (LLRender::sGLCoreProfile) + { + glGenVertexArrays(1, &glarray); + glBindVertexArray(glarray); + } + buff->setBuffer(LLVertexBuffer::MAP_VERTEX); glFinish(); @@ -1147,6 +1155,13 @@ F32 gpu_benchmark() } } + if (LLRender::sGLCoreProfile) + { + glBindVertexArray(0); + glDeleteVertexArrays(1, &glarray); + } + + std::sort(results.begin(), results.end()); F32 gbps = results[results.size()/2]; diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 25d6106361..48e9f3726f 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -51,7 +51,6 @@ #include "llphysicsshapebuilderutil.h" #include "llvoavatar.h" #include "llvolumemgr.h" -#include "lltextureatlas.h" #include "llviewershadermgr.h" #include "llcontrolavatar.h" @@ -128,129 +127,6 @@ LLSpatialGroup::~LLSpatialGroup() sNodeCount--; clearDrawMap(); - clearAtlasList() ; -} - -BOOL LLSpatialGroup::hasAtlas(LLTextureAtlas* atlasp) -{ - S8 type = atlasp->getComponents() - 1 ; - for(std::list::iterator iter = mAtlasList[type].begin(); iter != mAtlasList[type].end() ; ++iter) - { - if(atlasp == *iter) - { - return TRUE ; - } - } - return FALSE ; -} - -void LLSpatialGroup::addAtlas(LLTextureAtlas* atlasp, S8 recursive_level) -{ - if(!hasAtlas(atlasp)) - { - mAtlasList[atlasp->getComponents() - 1].push_back(atlasp) ; - atlasp->addSpatialGroup(this) ; - } - - --recursive_level; - if(recursive_level)//levels propagating up. - { - LLSpatialGroup* parent = getParent() ; - if(parent) - { - parent->addAtlas(atlasp, recursive_level) ; - } - } -} - -void LLSpatialGroup::removeAtlas(LLTextureAtlas* atlasp, BOOL remove_group, S8 recursive_level) -{ - mAtlasList[atlasp->getComponents() - 1].remove(atlasp) ; - if(remove_group) - { - atlasp->removeSpatialGroup(this) ; - } - - --recursive_level; - if(recursive_level)//levels propagating up. - { - LLSpatialGroup* parent = getParent() ; - if(parent) - { - parent->removeAtlas(atlasp, recursive_level) ; - } - } -} - -void LLSpatialGroup::clearAtlasList() -{ - std::list::iterator iter ; - for(S8 i = 0 ; i < 4 ; i++) - { - if(mAtlasList[i].size() > 0) - { - for(iter = mAtlasList[i].begin(); iter != mAtlasList[i].end() ; ++iter) - { - ((LLTextureAtlas*)*iter)->removeSpatialGroup(this) ; - } - mAtlasList[i].clear() ; - } - } -} - -LLTextureAtlas* LLSpatialGroup::getAtlas(S8 ncomponents, S8 to_be_reserved, S8 recursive_level) -{ - S8 type = ncomponents - 1 ; - if(mAtlasList[type].size() > 0) - { - for(std::list::iterator iter = mAtlasList[type].begin(); iter != mAtlasList[type].end() ; ++iter) - { - if(!((LLTextureAtlas*)*iter)->isFull(to_be_reserved)) - { - return *iter ; - } - } - } - - --recursive_level; - if(recursive_level) - { - LLSpatialGroup* parent = getParent() ; - if(parent) - { - return parent->getAtlas(ncomponents, to_be_reserved, recursive_level) ; - } - } - return NULL ; -} - -void LLSpatialGroup::setCurUpdatingSlot(LLTextureAtlasSlot* slotp) -{ - mCurUpdatingSlotp = slotp; - - //if(!hasAtlas(mCurUpdatingSlotp->getAtlas())) - //{ - // addAtlas(mCurUpdatingSlotp->getAtlas()) ; - //} -} - -LLTextureAtlasSlot* LLSpatialGroup::getCurUpdatingSlot(LLViewerTexture* imagep, S8 recursive_level) -{ - if(gFrameCount && mCurUpdatingTime == gFrameCount && mCurUpdatingTexture == imagep) - { - return mCurUpdatingSlotp ; - } - - //--recursive_level ; - //if(recursive_level) - //{ - // LLSpatialGroup* parent = getParent() ; - // if(parent) - // { - // return parent->getCurUpdatingSlot(imagep, recursive_level) ; - // } - //} - return NULL ; } void LLSpatialGroup::clearDrawMap() @@ -665,11 +541,7 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : LLO mDistance(0.f), mDepth(0.f), mLastUpdateDistance(-1.f), - mLastUpdateTime(gFrameTimeSeconds), - mAtlasList(4), - mCurUpdatingTime(0), - mCurUpdatingSlotp(NULL), - mCurUpdatingTexture (NULL) + mLastUpdateTime(gFrameTimeSeconds) { ll_assert_aligned(this,16); diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 5fca516f19..58d821353a 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -50,8 +50,6 @@ class LLViewerOctreePartition; class LLSpatialPartition; class LLSpatialBridge; class LLSpatialGroup; -class LLTextureAtlas; -class LLTextureAtlasSlot; class LLViewerRegion; void pushVerts(LLFace* face, U32 mask); @@ -91,6 +89,10 @@ public: LLPointer mTexture; std::vector > mTextureList; + // virtual size of mTexture and mTextureList textures + // used to update the decode priority of textures in this DrawInfo + std::vector mTextureListVSize; + S32 mDebugColor; const LLMatrix4* mTextureMatrix; const LLMatrix4* mModelMatrix; @@ -304,49 +306,15 @@ public: virtual void handleDestruction(const TreeNode* node); virtual void handleChildAddition(const OctreeNode* parent, OctreeNode* child); -//------------------- -//for atlas use -//------------------- - //atlas - void setCurUpdatingTime(U32 t) {mCurUpdatingTime = t ;} - U32 getCurUpdatingTime() const { return mCurUpdatingTime ;} - - void setCurUpdatingSlot(LLTextureAtlasSlot* slotp) ; - LLTextureAtlasSlot* getCurUpdatingSlot(LLViewerTexture* imagep, S8 recursive_level = 3) ; - - void setCurUpdatingTexture(LLViewerTexture* tex){ mCurUpdatingTexture = tex ;} - LLViewerTexture* getCurUpdatingTexture() const { return mCurUpdatingTexture ;} - - BOOL hasAtlas(LLTextureAtlas* atlasp) ; - LLTextureAtlas* getAtlas(S8 ncomponents, S8 to_be_reserved, S8 recursive_level = 3) ; - void addAtlas(LLTextureAtlas* atlasp, S8 recursive_level = 3) ; - void removeAtlas(LLTextureAtlas* atlasp, BOOL remove_group = TRUE, S8 recursive_level = 3) ; - void clearAtlasList() ; - public: - LL_ALIGN_16(LLVector4a mViewAngle); LL_ALIGN_16(LLVector4a mLastUpdateViewAngle); F32 mObjectBoxSize; //cached mObjectBounds[1].getLength3() - -private: - U32 mCurUpdatingTime ; - //do not make the below two to use LLPointer - //because mCurUpdatingTime invalidates them automatically. - LLTextureAtlasSlot* mCurUpdatingSlotp ; - LLViewerTexture* mCurUpdatingTexture ; - - std::vector< std::list > mAtlasList ; -//------------------- -//end for atlas use -//------------------- protected: virtual ~LLSpatialGroup(); - static S32 sLODSeed; - public: bridge_list_t mBridgeList; buffer_map_t mBufferMap; //used by volume buffers to attempt to reuse vertex buffers diff --git a/indra/newview/lltextureatlas.cpp b/indra/newview/lltextureatlas.cpp deleted file mode 100644 index 1c8e4f796e..0000000000 --- a/indra/newview/lltextureatlas.cpp +++ /dev/null @@ -1,416 +0,0 @@ -/** - * @file lltextureatlas.cpp - * @brief LLTextureAtlas class implementation. - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, 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$ - */ -#include "llviewerprecompiledheaders.h" -#include "linden_common.h" -#include "llerror.h" -#include "llimage.h" -#include "llmath.h" -#include "llgl.h" -#include "llrender.h" -#include "lltextureatlas.h" - -//------------------- -S16 LLTextureAtlas::sMaxSubTextureSize = 64 ; -S16 LLTextureAtlas::sSlotSize = 32 ; - -#ifndef DEBUG_ATLAS -#define DEBUG_ATLAS 0 -#endif - -#ifndef DEBUG_USAGE_BITS -#define DEBUG_USAGE_BITS 0 -#endif -//************************************************************************************************************** -LLTextureAtlas::LLTextureAtlas(U8 ncomponents, S16 atlas_dim) : - LLViewerTexture(atlas_dim * sSlotSize, atlas_dim * sSlotSize, ncomponents, TRUE), - mAtlasDim(atlas_dim), - mNumSlotsReserved(0), - mMaxSlotsInAtlas(atlas_dim * atlas_dim) -{ - generateEmptyUsageBits() ; - - //generate an empty texture - generateGLTexture() ; - LLPointer image_raw = new LLImageRaw(mFullWidth, mFullHeight, mComponents); - createGLTexture(0, image_raw, 0); - image_raw = NULL; -} - -LLTextureAtlas::~LLTextureAtlas() -{ - if(mSpatialGroupList.size() > 0) - { - LL_ERRS() << "Not clean up the spatial groups!" << LL_ENDL ; - } - releaseUsageBits() ; -} - -//virtual -S8 LLTextureAtlas::getType() const -{ - return 0; //LLViewerTexture::ATLAS_TEXTURE ; -} - -void LLTextureAtlas::getTexCoordOffset(S16 col, S16 row, F32& xoffset, F32& yoffset) -{ - xoffset = (F32)col / mAtlasDim ; - yoffset = (F32)row / mAtlasDim ; -} - -void LLTextureAtlas::getTexCoordScale(S32 w, S32 h, F32& xscale, F32& yscale) -{ - xscale = (F32)w / (mAtlasDim * sSlotSize) ; - yscale = (F32)h / (mAtlasDim * sSlotSize) ; -} - -//insert a texture piece into the atlas -LLGLuint LLTextureAtlas::insertSubTexture(LLImageGL* source_gl_tex, S32 discard_level, const LLImageRaw* raw_image, S16 slot_col, S16 slot_row) -{ - if(!getTexName()) - { - return 0 ; - } - - S32 w = raw_image->getWidth() ; - S32 h = raw_image->getHeight() ; - if(w < 8 || w > sMaxSubTextureSize || h < 8 || h > sMaxSubTextureSize) - { - //size overflow - return 0 ; - } - - BOOL res = gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, getTexName()); - if (!res) - { - LL_ERRS() << "bindTexture failed" << LL_ENDL; - } - - GLint xoffset = sSlotSize * slot_col ; - GLint yoffset = sSlotSize * slot_row ; - - if(!source_gl_tex->preAddToAtlas(discard_level, raw_image)) - { - return 0 ; - } - - glTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, w, h, - mGLTexturep->getPrimaryFormat(), mGLTexturep->getFormatType(), raw_image->getData()); - - source_gl_tex->postAddToAtlas() ; - return getTexName(); -} - -//release a sub-texture slot from the atlas -void LLTextureAtlas::releaseSlot(S16 slot_col, S16 slot_row, S8 slot_width) -{ - unmarkUsageBits(slot_width, slot_col, slot_row) ; - mNumSlotsReserved -= slot_width * slot_width ; -} - -BOOL LLTextureAtlas::isEmpty() const -{ - return !mNumSlotsReserved ; -} - -BOOL LLTextureAtlas::isFull(S8 to_be_reserved) const -{ - return mNumSlotsReserved + to_be_reserved > mMaxSlotsInAtlas ; -} -F32 LLTextureAtlas::getFullness() const -{ - return (F32)mNumSlotsReserved / mMaxSlotsInAtlas ; -} - -void LLTextureAtlas::addSpatialGroup(LLSpatialGroup* groupp) -{ - if(groupp && !hasSpatialGroup(groupp)) - { - mSpatialGroupList.push_back(groupp); - } -} - -void LLTextureAtlas::removeSpatialGroup(LLSpatialGroup* groupp) -{ - if(groupp) - { - mSpatialGroupList.remove(groupp); - } -} - -void LLTextureAtlas::clearSpatialGroup() -{ - mSpatialGroupList.clear(); -} -void LLTextureAtlas::removeLastSpatialGroup() -{ - mSpatialGroupList.pop_back() ; -} - -LLSpatialGroup* LLTextureAtlas::getLastSpatialGroup() -{ - if(mSpatialGroupList.size() > 0) - { - return mSpatialGroupList.back() ; - } - return NULL ; -} - -BOOL LLTextureAtlas::hasSpatialGroup(LLSpatialGroup* groupp) -{ - for(std::list::iterator iter = mSpatialGroupList.begin(); iter != mSpatialGroupList.end() ; ++iter) - { - if(*iter == groupp) - { - return TRUE ; - } - } - return FALSE ; -} - -//-------------------------------------------------------------------------------------- -//private -void LLTextureAtlas::generateEmptyUsageBits() -{ - S32 col_len = (mAtlasDim + 7) >> 3 ; - mUsageBits = new U8*[mAtlasDim] ; - *mUsageBits = new U8[mAtlasDim * col_len] ; - - mUsageBits[0] = *mUsageBits ; - for(S32 i = 1 ; i < mAtlasDim ; i++) - { - mUsageBits[i] = mUsageBits[i-1] + col_len ; - - for(S32 j = 0 ; j < col_len ; j++) - { - //init by 0 for all bits. - mUsageBits[i][j] = 0 ; - } - } - - //do not forget mUsageBits[0]! - for(S32 j = 0 ; j < col_len ; j++) - { - //init by 0 for all bits. - mUsageBits[0][j] = 0 ; - } - - mTestBits = NULL ; -#if DEBUG_USAGE_BITS - //------------ - //test - mTestBits = new U8*[mAtlasDim] ; - *mTestBits = new U8[mAtlasDim * mAtlasDim] ; - mTestBits[0] = *mTestBits ; - for(S32 i = 1 ; i < mAtlasDim ; i++) - { - mTestBits[i] = mTestBits[i-1] + mAtlasDim ; - - for(S32 j = 0 ; j < mAtlasDim ; j++) - { - //init by 0 for all bits. - mTestBits[i][j] = 0 ; - } - } - - for(S32 j = 0 ; j < mAtlasDim ; j++) - { - //init by 0 for all bits. - mTestBits[0][j] = 0 ; - } -#endif -} - -void LLTextureAtlas::releaseUsageBits() -{ - if(mUsageBits) - { - delete[] *mUsageBits ; - delete[] mUsageBits ; - } - mUsageBits = NULL ; - - //test - if( mTestBits) - { - delete[] *mTestBits; - delete[] mTestBits; - } - mTestBits = NULL ; -} - -void LLTextureAtlas::markUsageBits(S8 bits_len, U8 mask, S16 col, S16 row) -{ - S16 x = col >> 3 ; - - for(S8 i = 0 ; i < bits_len ; i++) - { - mUsageBits[row + i][x] |= mask ; - } - -#if DEBUG_USAGE_BITS - //test - for(S8 i = row ; i < row + bits_len ; i++) - { - for(S8 j = col ; j < col + bits_len ; j++) - { - mTestBits[i][j] = 1 ; - } - } -#endif -} - -void LLTextureAtlas::unmarkUsageBits(S8 bits_len, S16 col, S16 row) -{ - S16 x = col >> 3 ; - U8 mask = 1 ; - for(S8 i = 1 ; i < bits_len ; i++) - { - mask |= (1 << i) ; - } - mask <<= (col & 7) ; - mask = ~mask ; - - for(S8 i = 0 ; i < bits_len ; i++) - { - mUsageBits[row + i][x] &= mask ; - } - -#if DEBUG_USAGE_BITS - //test - for(S8 i = row ; i < row + bits_len ; i++) - { - for(S8 j = col ; j < col + bits_len ; j++) - { - mTestBits[i][j] = 0 ; - } - } -#endif -} - -//return true if any of bits in the range marked. -BOOL LLTextureAtlas::areUsageBitsMarked(S8 bits_len, U8 mask, S16 col, S16 row) -{ - BOOL ret = FALSE ; - S16 x = col >> 3 ; - - for(S8 i = 0 ; i < bits_len ; i++) - { - if(mUsageBits[row + i][x] & mask) - { - ret = TRUE ; - break ; - //return TRUE ; - } - } - -#if DEBUG_USAGE_BITS - //test - BOOL ret2 = FALSE ; - for(S8 i = row ; i < row + bits_len ; i++) - { - for(S8 j = col ; j < col + bits_len ; j++) - { - if(mTestBits[i][j]) - { - ret2 = TRUE ; - } - } - } - - if(ret != ret2) - { - LL_ERRS() << "bits map corrupted." << LL_ENDL ; - } -#endif - return ret ;//FALSE ; -} - -//---------------------------------------------------------------------- -// -//index order: Z order, i.e.: -// |-----|-----|-----|-----| -// | 10 | 11 | 14 | 15 | -// |-----|-----|-----|-----| -// | 8 | 9 | 12 | 13 | -// |-----|-----|-----|-----| -// | 2 | 3 | 6 | 7 | -// |-----|-----|-----|-----| -// | 0 | 1 | 4 | 5 | -// |-----|-----|-----|-----| -void LLTextureAtlas::getPositionFromIndex(S16 index, S16& col, S16& row) -{ - col = 0 ; - row = 0 ; - - S16 index_copy = index ; - for(S16 i = 0 ; index_copy && i < 16 ; i += 2) - { - col |= ((index & (1 << i)) >> i) << (i >> 1) ; - row |= ((index & (1 << (i + 1))) >> (i + 1)) << (i >> 1) ; - index_copy >>= 2 ; - } -} -void LLTextureAtlas::getIndexFromPosition(S16 col, S16 row, S16& index) -{ - index = 0 ; - S16 col_copy = col ; - S16 row_copy = row ; - for(S16 i = 0 ; (col_copy || row_copy) && i < 16 ; i++) - { - index |= ((col & 1 << i) << i) | ((row & 1 << i) << ( i + 1)) ; - col_copy >>= 1 ; - row_copy >>= 1 ; - } -} -//---------------------------------------------------------------------- -//return TRUE if succeeds. -BOOL LLTextureAtlas::getNextAvailableSlot(S8 bits_len, S16& col, S16& row) -{ - S16 index_step = bits_len * bits_len ; - - U8 mask = 1 ; - for(S8 i = 1 ; i < bits_len ; i++) - { - mask |= (1 << i) ; - } - - U8 cur_mask ; - for(S16 index = 0 ; index < mMaxSlotsInAtlas ; index += index_step) - { - getPositionFromIndex(index, col, row) ; - - cur_mask = mask << (col & 7) ; - if(!areUsageBitsMarked(bits_len, cur_mask, col, row)) - { - markUsageBits(bits_len, cur_mask, col, row) ; - mNumSlotsReserved += bits_len * bits_len ; - - return TRUE ; - } - } - - return FALSE ; -} diff --git a/indra/newview/lltextureatlas.h b/indra/newview/lltextureatlas.h deleted file mode 100644 index 6b36eb7fe4..0000000000 --- a/indra/newview/lltextureatlas.h +++ /dev/null @@ -1,90 +0,0 @@ -/** - * @file lltextureatlas.h - * @brief LLTextureAtlas base class. - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, 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$ - */ - - -#ifndef LL_TEXTUREATLAS_H -#define LL_TEXTUREATLAS_H - -#include "llviewertexture.h" -class LLSpatialGroup ; - -class LLTextureAtlas : public LLViewerTexture -{ -protected: - /*virtual*/ ~LLTextureAtlas() ; - -public: - LLTextureAtlas(U8 ncomponents, S16 atlas_dim = 16) ; - - /*virtual*/ S8 getType() const; - - LLGLuint insertSubTexture(LLImageGL* source_gl_tex, S32 discard_level, const LLImageRaw* raw_image, S16 slot_col, S16 slot_row) ; - void releaseSlot(S16 slot_col, S16 slot_row, S8 slot_width); - - BOOL getNextAvailableSlot(S8 bits_len, S16& col, S16& row) ; - void getTexCoordOffset(S16 col, S16 row, F32& xoffset, F32& yOffset) ; - void getTexCoordScale(S32 w, S32 h, F32& xscale, F32& yscale) ; - - BOOL isEmpty() const ; - BOOL isFull(S8 to_be_reserved = 1) const ; - F32 getFullness() const ; - - void addSpatialGroup(LLSpatialGroup* groupp) ; - void removeSpatialGroup(LLSpatialGroup* groupp) ; - LLSpatialGroup* getLastSpatialGroup() ; - void removeLastSpatialGroup() ; - BOOL hasSpatialGroup(LLSpatialGroup* groupp) ; - void clearSpatialGroup() ; - std::list* getSpatialGroupList() {return &mSpatialGroupList;} -private: - void generateEmptyUsageBits() ; - void releaseUsageBits() ; - - void markUsageBits(S8 bits_len, U8 mask, S16 col, S16 row) ; - void unmarkUsageBits(S8 bits_len, S16 col, S16 row) ; - - void getPositionFromIndex(S16 index, S16& col, S16& row) ; - void getIndexFromPosition(S16 col, S16 row, S16& index) ; - BOOL areUsageBitsMarked(S8 bits_len, U8 mask, S16 col, S16 row) ; - -private: - S16 mAtlasDim ; //number of slots per edge, i.e, there are "mAtlasDim * mAtlasDim" total slots in the atlas. - S16 mNumSlotsReserved ; - S16 mMaxSlotsInAtlas ; - U8 **mUsageBits ; - std::list mSpatialGroupList ; - -public: - //debug use only - U8 **mTestBits ; - -public: - static S16 sMaxSubTextureSize ; - static S16 sSlotSize ; -}; - -#endif - diff --git a/indra/newview/lltextureatlasmanager.cpp b/indra/newview/lltextureatlasmanager.cpp deleted file mode 100644 index ca9d6da4db..0000000000 --- a/indra/newview/lltextureatlasmanager.cpp +++ /dev/null @@ -1,268 +0,0 @@ -/** - * @file lltextureatlasmanager.cpp - * @brief LLTextureAtlasManager class implementation. - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, 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$ - */ -#include "llviewerprecompiledheaders.h" -#include "linden_common.h" -#include "llerror.h" -#include "llmath.h" -#include "lltextureatlas.h" -#include "lltextureatlasmanager.h" -#include "llspatialpartition.h" - -const S8 MAX_NUM_EMPTY_ATLAS = 2 ; -const F32 MIN_ATLAS_FULLNESS = 0.6f ; - -//********************************************************************************************* -//implementation of class LLTextureAtlasInfo -//********************************************************************************************* -LLTextureAtlasSlot::LLTextureAtlasSlot(LLTextureAtlas* atlasp, LLSpatialGroup* groupp, S16 col, S16 row, F32 xoffset, F32 yoffset, S8 slot_width) : - mAtlasp(atlasp), - mGroupp(groupp), - mCol(col), - mRow(row), - mReservedSlotWidth(slot_width), - mValid(FALSE), - mUpdatedTime(0), - mTexCoordOffset(xoffset, yoffset), - mTexCoordScale(1.f, 1.f) -{ - llassert_always(mAtlasp || mGroupp || mReservedSlotWidth) ; -} - -LLTextureAtlasSlot::~LLTextureAtlasSlot() -{ - if(mAtlasp) - { - mAtlasp->releaseSlot(mCol, mRow, mReservedSlotWidth) ; - if(mAtlasp->isEmpty()) - { - LLTextureAtlasManager::getInstance()->releaseAtlas(mAtlasp) ; - } - mAtlasp = NULL ; - } -} - -//void LLTextureAtlasSlot::setAtlas(LLTextureAtlas* atlasp) -//{ -// mAtlasp = atlasp ; -//} -//void LLTextureAtlasSlot::setSlotPos(S16 col, S16 row) -//{ -// mCol = col ; -// mRow = row ; -//} -//void LLTextureAtlasSlot::setSlotWidth(S8 width) -//{ -// //slot is a square with each edge length a power-of-two number -// mReservedSlotWidth = width ; -//} -//void LLTextureAtlasSlot::setTexCoordOffset(F32 xoffset, F32 yoffset) -//{ -// mTexCoordOffset.mV[0] = xoffset ; -// mTexCoordOffset.mV[1] = yoffset ; -//} - -void LLTextureAtlasSlot::setSpatialGroup(LLSpatialGroup* groupp) -{ - mGroupp = groupp ; -} -void LLTextureAtlasSlot::setTexCoordScale(F32 xscale, F32 yscale) -{ - mTexCoordScale.mV[0] = xscale ; - mTexCoordScale.mV[1] = yscale ; -} -//********************************************************************************************* -//END of implementation of class LLTextureAtlasInfo -//********************************************************************************************* - -//********************************************************************************************* -//implementation of class LLTextureAtlasManager -//********************************************************************************************* -LLTextureAtlasManager::LLTextureAtlasManager() : - mAtlasMap(4), - mEmptyAtlasMap(4) -{ -} - -LLTextureAtlasManager::~LLTextureAtlasManager() -{ - for(S32 i = 0 ; i < 4 ; i++) - { - for(ll_texture_atlas_list_t::iterator j = mAtlasMap[i].begin() ; j != mAtlasMap[i].end() ; ++j) - { - *j = NULL ; - } - for(ll_texture_atlas_list_t::iterator j = mEmptyAtlasMap[i].begin() ; j != mEmptyAtlasMap[i].end() ; ++j) - { - *j = NULL ; - } - - mAtlasMap[i].clear() ; - mEmptyAtlasMap[i].clear() ; - } - mAtlasMap.clear() ; - mEmptyAtlasMap.clear() ; -} - -//return TRUE if qualified -BOOL LLTextureAtlasManager::canAddToAtlas(S32 w, S32 h, S8 ncomponents, LLGLenum target) -{ - if(ncomponents < 1 || ncomponents > 4) - { - return FALSE ; - } - //only support GL_TEXTURE_2D - if(GL_TEXTURE_2D != target) - { - return FALSE ; - } - //real image size overflows - if(w < 8 || w > LLTextureAtlas::sMaxSubTextureSize || h < 8 || h > LLTextureAtlas::sMaxSubTextureSize) - { - return FALSE ; - } - - //if non-power-of-two number - if((w & (w - 1)) || (h & (h - 1))) - { - return FALSE ; - } - - return TRUE ; -} - -void LLTextureAtlasManager::releaseAtlas(LLTextureAtlas* atlasp) -{ - LLSpatialGroup* groupp = atlasp->getLastSpatialGroup() ; - while(groupp) - { - groupp->removeAtlas(atlasp, FALSE) ; - atlasp->removeLastSpatialGroup() ; - - groupp = atlasp->getLastSpatialGroup() ; - } - - S8 type = atlasp->getComponents() - 1 ; - //insert to the empty list - if(mEmptyAtlasMap[type].size() < MAX_NUM_EMPTY_ATLAS) - { - mEmptyAtlasMap[type].push_back(atlasp) ; - } - - //delete the atlasp - mAtlasMap[type].remove(atlasp) ; -} - -// -//this function reserves an appropriate slot from atlas pool for an image. -//return non-NULL if succeeds. -//Note: -//1, this function does not check if the image this slot assigned for qualifies for atlas or not, -// call LLTextureAtlasManager::canAddToAtlas(...) to do the check before calling this function. -//2, this function also dose not check if the image is already in atlas. It always assigns a new slot anyway. -//3, this function tries to group sub-textures from same spatial group into ONE atlas to improve render batching. -// -LLPointer LLTextureAtlasManager::reserveAtlasSlot(S32 sub_texture_size, S8 ncomponents, - LLSpatialGroup* groupp, LLViewerTexture* imagep) -{ - if(!groupp) - { - //do not insert to atlas if does not have a group. - return NULL ; - } - - //bits_len must <= 8 and is a power of two number, i.e.: must be one of these numbers: 1, 2, 4, 8. - if(sub_texture_size > LLTextureAtlas::sMaxSubTextureSize) - { - sub_texture_size = LLTextureAtlas::sMaxSubTextureSize ; - } - S8 bits_len = sub_texture_size / LLTextureAtlas::sSlotSize ; - if(bits_len < 1) - { - bits_len = 1 ; - } - - S16 col = -1, row = -1; - S8 total_bits = bits_len * bits_len ; - - //insert to the atlas reserved by the same spatial group - LLPointer atlasp = groupp->getAtlas(ncomponents, total_bits) ; - if(atlasp.notNull()) - { - if(!atlasp->getNextAvailableSlot(bits_len, col, row)) - { - //failed - atlasp = NULL ; - } - } - - //search an atlas to fit for 'size' - if(!atlasp) - { - S8 atlas_index = ncomponents - 1 ; - ll_texture_atlas_list_t::iterator iter = mAtlasMap[atlas_index].begin() ; - for(; iter != mAtlasMap[atlas_index].end(); ++iter) - { - LLTextureAtlas* cur = (LLTextureAtlas*)*iter ; - if(cur->getFullness() < MIN_ATLAS_FULLNESS)//this atlas is empty enough for this group to insert more sub-textures later if necessary. - { - if(cur->getNextAvailableSlot(bits_len, col, row)) - { - atlasp = cur ; - groupp->addAtlas(atlasp) ; - break ; - } - } - } - } - - //create a new atlas if necessary - if(!atlasp) - { - if(mEmptyAtlasMap[ncomponents - 1].size() > 0) - { - //there is an empty one - atlasp = mEmptyAtlasMap[ncomponents - 1].back() ; - mEmptyAtlasMap[ncomponents - 1].pop_back() ; - } - else - { - atlasp = new LLTextureAtlas(ncomponents, 16) ; - } - mAtlasMap[ncomponents - 1].push_back(atlasp) ; - atlasp->getNextAvailableSlot(bits_len, col, row) ; - groupp->addAtlas(atlasp) ; - } - - F32 xoffset, yoffset ; - atlasp->getTexCoordOffset(col, row, xoffset, yoffset) ; - LLPointer slot_infop = new LLTextureAtlasSlot(atlasp, groupp, col, row, xoffset, yoffset, bits_len) ; - - return slot_infop ; -} - -//********************************************************************************************* -//END of implementation of class LLTextureAtlasManager -//********************************************************************************************* diff --git a/indra/newview/lltextureatlasmanager.h b/indra/newview/lltextureatlasmanager.h deleted file mode 100644 index 1b8df708c6..0000000000 --- a/indra/newview/lltextureatlasmanager.h +++ /dev/null @@ -1,105 +0,0 @@ -/** - * @file lltextureatlasmanager.h - * @brief LLTextureAtlasManager base class. - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, 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$ - */ - - -#ifndef LL_TEXTUREATLASMANAGER_H -#define LL_TEXTUREATLASMANAGER_H - -#include "llmemory.h" - -class LLSpatialGroup ; -class LLViewerTexture ; - -//just use it as a structure. -class LLTextureAtlasSlot : public LLRefCount -{ -public: - LLTextureAtlasSlot(LLTextureAtlas* atlasp, LLSpatialGroup* groupp, S16 col, S16 row, F32 xoffset, F32 yoffset, S8 slot_width) ; - -protected: - virtual ~LLTextureAtlasSlot(); - -public: - - // - //do not allow to change those values - // - //void setAtlas(LLTextureAtlas* atlasp) ; - //void setSlotPos(S16 col, S16 row) ; - //void setSlotWidth(S8 width) ; - //void setTexCoordOffset(F32 xoffser, F32 yoffset) ; - // - - void setSpatialGroup(LLSpatialGroup* groupp) ; - void setTexCoordScale(F32 xscale, F32 yscale) ; - void setValid() {mValid = TRUE ;} - - LLTextureAtlas* getAtlas()const {return mAtlasp;} - LLSpatialGroup* getSpatialGroup() const {return mGroupp ;} - S16 getSlotCol()const {return mCol;} - S16 getSlotRow()const {return mRow;} - S8 getSlotWidth()const{return mReservedSlotWidth;} - BOOL isValid()const { return mValid;} - const LLVector2* getTexCoordOffset()const {return &mTexCoordOffset;} - const LLVector2* getTexCoordScale() const {return &mTexCoordScale;} - - void setUpdatedTime(U32 t) {mUpdatedTime = t;} - U32 getUpdatedTime()const {return mUpdatedTime;} - -private: - LLTextureAtlas* mAtlasp; - S16 mCol ;//col of the slot - S16 mRow ;//row of the slot - S8 mReservedSlotWidth ; //slot is a square with each edge length a power-of-two number - LLSpatialGroup* mGroupp ; - BOOL mValid ; - - LLVector2 mTexCoordOffset ; - LLVector2 mTexCoordScale ; - - U32 mUpdatedTime ; -} ; - -class LLTextureAtlasManager : public LLSingleton -{ - LLSINGLETON(LLTextureAtlasManager); - ~LLTextureAtlasManager(); - typedef std::list > ll_texture_atlas_list_t ; - -public: - - LLPointer reserveAtlasSlot(S32 sub_texture_size, S8 ncomponents, - LLSpatialGroup* groupp, LLViewerTexture* imagep) ; - void releaseAtlas(LLTextureAtlas* atlasp); - - BOOL canAddToAtlas(S32 w, S32 h, S8 ncomponents, LLGLenum target) ; - -private: - std::vector mAtlasMap ; - std::vector mEmptyAtlasMap ; //delay some empty atlases deletion to avoid possible creation of new atlas immediately. -}; - -#endif diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index f932acd48c..37ed2e9f20 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -1476,6 +1476,10 @@ void LLViewerFetchedTexture::addToCreateTexture() BOOL LLViewerFetchedTexture::preCreateTexture(S32 usename/*= 0*/) { LL_PROFILE_ZONE_SCOPED; +#if LL_IMAGEGL_THREAD_CHECK + mGLTexturep->checkActiveThread(); +#endif + if (!mNeedsCreateTexture) { destroyRawImage(); @@ -1603,6 +1607,9 @@ void LLViewerFetchedTexture::postCreateTexture() { return; } +#if LL_IMAGEGL_THREAD_CHECK + mGLTexturep->checkActiveThread(); +#endif notifyAboutCreatingTexture(); @@ -1619,36 +1626,45 @@ void LLViewerFetchedTexture::postCreateTexture() void LLViewerFetchedTexture::scheduleCreateTexture() { - ref(); - mNeedsCreateTexture = TRUE; - if (preCreateTexture()) + if (!mNeedsCreateTexture) { + ref(); mNeedsCreateTexture = TRUE; + if (preCreateTexture()) + { + mNeedsCreateTexture = TRUE; #if LL_WINDOWS //flip to 0 to revert to single-threaded OpenGL texture uploads - auto mainq = mMainQueue.lock(); - if (mainq) - { - mainq->postTo( - mImageQueue, - // work to be done on LLImageGL worker thread - [this]() - { - //actually create the texture on a background thread - createTexture(); - }, - // callback to be run on main thread - [this]() - { - //finalize on main thread - postCreateTexture(); - unref(); - }); - } - else + auto mainq = mMainQueue.lock(); + if (mainq) + { + mainq->postTo( + mImageQueue, + // work to be done on LLImageGL worker thread + [this]() + { +#if LL_IMAGEGL_THREAD_CHECK + mGLTexturep->mActiveThread = LLThread::currentID(); #endif - { - gTextureList.mCreateTextureList.insert(this); - unref(); + //actually create the texture on a background thread + createTexture(); + }, + // callback to be run on main thread + [this]() + { +#if LL_IMAGEGL_THREAD_CHECK + mGLTexturep->mActiveThread = LLThread::currentID(); +#endif + //finalize on main thread + postCreateTexture(); + unref(); + }); + } + else +#endif + { + gTextureList.mCreateTextureList.insert(this); + unref(); + } } } } @@ -2967,7 +2983,8 @@ void LLViewerFetchedTexture::destroyRawImage() void LLViewerFetchedTexture::switchToCachedImage() { LL_PROFILE_ZONE_SCOPED; - if(mCachedRawImage.notNull()) + if(mCachedRawImage.notNull() && + !mNeedsCreateTexture) // <--- texture creation is pending, don't step on it { mRawImage = mCachedRawImage; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 2f554bc9b8..4e7eb4df5d 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -5189,6 +5189,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, } } + F32 vsize = facep->getVirtualSize(); //TODO -- adjust by texture scale? if (index < FACE_DO_NOT_BATCH_TEXTURES && idx >= 0) { @@ -5202,10 +5203,12 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, { batchable = true; draw_vec[idx]->mTextureList[index] = tex; + draw_vec[idx]->mTextureListVSize[index] = vsize; } else if (draw_vec[idx]->mTextureList[index] == tex) { //this face's texture index can be used with this batch batchable = true; + draw_vec[idx]->mTextureListVSize[index] = llmax(vsize, draw_vec[idx]->mTextureListVSize[index]); } } else @@ -5236,12 +5239,14 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, { draw_vec[idx]->mCount += facep->getIndicesCount(); draw_vec[idx]->mEnd += facep->getGeomCount(); - draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, facep->getVirtualSize()); + draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, vsize); if (index < FACE_DO_NOT_BATCH_TEXTURES && index >= draw_vec[idx]->mTextureList.size()) { draw_vec[idx]->mTextureList.resize(index+1); draw_vec[idx]->mTextureList[index] = tex; + draw_vec[idx]->mTextureListVSize.resize(index + 1); + draw_vec[idx]->mTextureListVSize[index] = vsize; } draw_vec[idx]->validate(); update_min_max(draw_vec[idx]->mExtents[0], draw_vec[idx]->mExtents[1], facep->mExtents[0]); @@ -5256,7 +5261,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, LLPointer draw_info = new LLDrawInfo(start,end,count,offset, tex, facep->getVertexBuffer(), selected, fullbright, bump); draw_info->mGroup = group; - draw_info->mVSize = facep->getVirtualSize(); + draw_info->mVSize = vsize; draw_vec.push_back(draw_info); draw_info->mTextureMatrix = tex_mat; draw_info->mModelMatrix = model_mat; @@ -5331,6 +5336,8 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, { //initialize texture list for texture batching draw_info->mTextureList.resize(index+1); draw_info->mTextureList[index] = tex; + draw_info->mTextureListVSize.resize(index + 1); + draw_info->mTextureListVSize[index] = vsize; } draw_info->validate(); } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index c122b4f43e..df676b30fc 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -3711,25 +3711,31 @@ void renderSoundHighlights(LLDrawable* drawablep) } } -void LLPipeline::touchTextures(LLDrawInfo* info) +void LLPipeline::touchTexture(LLViewerTexture* tex, F32 vsize) { - LL_PROFILE_ZONE_SCOPED; - for (auto& tex : info->mTextureList) + if (tex) { - if (tex.notNull()) + LLImageGL* gl_tex = tex->getGLTexture(); + if (gl_tex && gl_tex->updateBindStats(gl_tex->mTextureMemory)) { - LLImageGL* gl_tex = tex->getGLTexture(); - if (gl_tex && gl_tex->updateBindStats(gl_tex->mTextureMemory)) - { - tex->setActive(); - } + tex->setActive(); + tex->addTextureStats(vsize); } } - if (info->mTexture.notNull()) + +} +void LLPipeline::touchTextures(LLDrawInfo* info) +{ + LL_PROFILE_ZONE_SCOPED; + for (int i = 0; i < info->mTextureList.size(); ++i) { - info->mTexture->addTextureStats(info->mVSize); + touchTexture(info->mTextureList[i], info->mTextureListVSize[i]); } + + touchTexture(info->mTexture, info->mVSize); + touchTexture(info->mSpecularMap, info->mVSize); + touchTexture(info->mNormalMap, info->mVSize); } void LLPipeline::postSort(LLCamera& camera) diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 3ac3e3ce01..794d806d0c 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -260,8 +260,11 @@ public: void stateSort(LLSpatialBridge* bridge, LLCamera& camera, BOOL fov_changed = FALSE); void stateSort(LLDrawable* drawablep, LLCamera& camera); void postSort(LLCamera& camera); + //update stats for textures in given DrawInfo void touchTextures(LLDrawInfo* info); + void touchTexture(LLViewerTexture* tex, F32 vsize); + void forAllVisibleDrawables(void (*func)(LLDrawable*)); void renderObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false, bool rigged = false);