From 0b4982ac897fcc1f38a18934a42836a4d2eecb29 Mon Sep 17 00:00:00 2001 From: Graham Linden Date: Mon, 4 Mar 2019 10:31:55 -0800 Subject: Roll back optimizations to lldrawpoolalpha causing emissive strangeness and alpha materials lighting errors. --- indra/newview/lldrawpoolalpha.cpp | 303 +++++++++++++++++++++++++++++++------- 1 file changed, 251 insertions(+), 52 deletions(-) (limited to 'indra') diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 82a95ac7a8..7945c950db 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -424,6 +424,7 @@ void LLDrawPoolAlpha::renderSimples(U32 mask, std::vector& simples) simple_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep); simple_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, 1.0f, 1.0f, 1.0f, 1.0f); simple_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, 0.0f); + simple_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 0.0f); for (LLDrawInfo* draw : simples) { @@ -438,7 +439,7 @@ void LLDrawPoolAlpha::renderFullbrights(U32 mask, std::vector& full { gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); fullbright_shader->bind(); - fullbright_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.0f); + fullbright_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 0.0f); for (LLDrawInfo* draw : fullbrights) { bool tex_setup = TexSetup(draw); @@ -453,6 +454,7 @@ void LLDrawPoolAlpha::renderMaterials(U32 mask, std::vector& materi LLGLSLShader::bindNoShader(); current_shader = NULL; + gPipeline.enableLightsDynamic(); for (LLDrawInfo* draw : materials) { U32 mask = draw->mShaderMask; @@ -504,6 +506,7 @@ void LLDrawPoolAlpha::renderMaterials(U32 mask, std::vector& materi void LLDrawPoolAlpha::renderEmissives(U32 mask, std::vector& emissives) { emissive_shader->bind(); + emissive_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.f); // install glow-accumulating blend mode // don't touch color, add to alpha (glow) @@ -524,36 +527,30 @@ void LLDrawPoolAlpha::renderEmissives(U32 mask, std::vector& emissi void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA); - - std::vector simples_3d; - std::vector fullbrights_3d; - std::vector materials_3d; - std::vector emissives_3d; - std::vector simples_hud; - std::vector fullbrights_hud; - std::vector materials_hud; - std::vector emissives_hud; - - for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i) + BOOL initialized_lighting = FALSE; + BOOL light_enabled = TRUE; + + BOOL use_shaders = gPipeline.canUseVertexShaders(); + + for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_GROUP_LOOP); - LLSpatialGroup* group = *i; llassert(group); + llassert(group->getSpatialPartition()); - LLSpatialPartition* partition = group->getSpatialPartition(); - llassert(partition); - - if (partition->mRenderByGroup && !group->isDead()) + if (group->getSpatialPartition()->mRenderByGroup && + !group->isDead()) { - bool is_particle_or_hud_particle = partition->mPartitionType == LLViewerRegion::PARTITION_PARTICLE - || partition->mPartitionType == LLViewerRegion::PARTITION_HUD_PARTICLE; + bool is_particle_or_hud_particle = group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_PARTICLE + || group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_HUD_PARTICLE; + + bool draw_glow_for_this_partition = mShaderLevel > 0; // no shaders = no glow. - std::vector* fullbrights = is_particle_or_hud_particle ? &fullbrights_hud : &fullbrights_3d; - std::vector* materials = is_particle_or_hud_particle ? &materials_hud : &materials_3d; - std::vector* simples = is_particle_or_hud_particle ? &simples_hud : &simples_3d; - std::vector* emissives = is_particle_or_hud_particle ? &emissives_hud : &emissives_3d; + + LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_GROUP_LOOP); + + bool disable_cull = is_particle_or_hud_particle; + LLGLDisable cull(disable_cull ? GL_CULL_FACE : 0); LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA]; @@ -561,44 +558,246 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) { LLDrawInfo& params = **k; - if (params.mGroup) + if ((params.mVertexBuffer->getTypeMask() & mask) != mask) + { //FIXME! + LL_WARNS_ONCE() << "Missing required components, expected mask: " << mask + << " present: " << (params.mVertexBuffer->getTypeMask() & mask) + << ". Skipping render batch." << LL_ENDL; + 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) + { + LLFace* face = params.mFace; + if(face) + { + const LLTextureEntry* tep = face->getTextureEntry(); + if(tep) + { + if(tep->getColor().mV[3] < 0.1f) + continue; + } + } + } + + LLRenderPass::applyModelMatrix(params); + + LLMaterial* mat = NULL; + + if (deferred_render) + { + mat = params.mMaterial; + } + + if (params.mFullbright) + { + // Turn off lighting if it hasn't already been so. + if (light_enabled || !initialized_lighting) + { + initialized_lighting = TRUE; + if (use_shaders) + { + target_shader = fullbright_shader; + } + else + { + gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); + } + light_enabled = FALSE; + } + } + // Turn on lighting if it isn't already. + else if (!light_enabled || !initialized_lighting) + { + initialized_lighting = TRUE; + if (use_shaders) + { + target_shader = simple_shader; + } + else + { + gPipeline.enableLightsDynamic(); + } + light_enabled = TRUE; + } + + if (deferred_render && mat) + { + U32 mask = params.mShaderMask; + + llassert(mask < LLMaterial::SHADER_COUNT); + target_shader = &(gDeferredMaterialProgram[mask]); + + if (LLPipeline::sUnderWaterRender) + { + target_shader = &(gDeferredMaterialWaterProgram[mask]); + } + + if (current_shader != target_shader) + { + gPipeline.bindDeferredShader(*target_shader); + } + } + else if (!params.mFullbright) + { + target_shader = simple_shader; + } + else + { + target_shader = fullbright_shader; + } + + if(use_shaders && (current_shader != target_shader)) + {// If we need shaders, and we're not ALREADY using the proper shader, then bind it + // (this way we won't rebind shaders unnecessarily). + current_shader = target_shader; + current_shader->bind(); + } + else if (!use_shaders && current_shader != NULL) + { + LLGLSLShader::bindNoShader(); + current_shader = NULL; + } + + if (use_shaders && mat) + { + // We have a material. Supply the appropriate data here. + if (LLPipeline::sRenderDeferred) + { + current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, params.mSpecColor.mV[0], params.mSpecColor.mV[1], params.mSpecColor.mV[2], params.mSpecColor.mV[3]); + current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, params.mEnvIntensity); + current_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, params.mFullbright ? 1.f : 0.f); + + if (params.mNormalMap) + { + params.mNormalMap->addTextureStats(params.mVSize); + current_shader->bindTexture(LLShaderMgr::BUMP_MAP, params.mNormalMap); + } + + if (params.mSpecularMap) + { + params.mSpecularMap->addTextureStats(params.mVSize); + current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, params.mSpecularMap); + } + } + + } else if (LLPipeline::sRenderDeferred && current_shader && (current_shader == simple_shader)) + { + current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, 1.0f, 1.0f, 1.0f, 1.0f); + current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, 0.0f); + LLViewerFetchedTexture::sFlatNormalImagep->addTextureStats(params.mVSize); + current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep); + LLViewerFetchedTexture::sWhiteImagep->addTextureStats(params.mVSize); + current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep); + } + + if (params.mGroup) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MESH_REBUILD); params.mGroup->rebuildMesh(); } - (IsMaterial(params) ? materials : - IsFullbright(params) ? fullbrights : - simples)->push_back(¶ms); + bool tex_setup = false; - if (IsEmissive(params)) - { - emissives->push_back(¶ms); - } - } - } - } + if (use_shaders && params.mTextureList.size() > 1) + { + for (U32 i = 0; i < params.mTextureList.size(); ++i) + { + if (params.mTextureList[i].notNull()) + { + gGL.getTexUnit(i)->bind(params.mTextureList[i], TRUE); + } + } + } + else + { //not batching textures or batch has only 1 texture -- might need a texture matrix + if (params.mTexture.notNull()) + { + params.mTexture->addTextureStats(params.mVSize); + if (use_shaders && mat) + { + current_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, params.mTexture); + } + else + { + gGL.getTexUnit(0)->bind(params.mTexture, TRUE) ; + } + + if (params.mTextureMatrix) + { + tex_setup = true; + gGL.getTexUnit(0)->activate(); + gGL.matrixMode(LLRender::MM_TEXTURE); + gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix); + gPipeline.mTextureMatrixOps++; + } + } + else + { + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + } + } - renderSimples(mask, simples_3d); - renderFullbrights(mask, fullbrights_3d); - renderMaterials(mask, materials_3d); - renderEmissives(mask, emissives_3d); + { + LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_PUSH); - LLGLDisable cull(GL_CULL_FACE); + LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test); - renderSimples(mask, simples_hud); - renderFullbrights(mask, fullbrights_hud); - renderMaterials(mask, materials_hud); - renderEmissives(mask, emissives_hud); - - simple_shader->bind(); - current_shader = simple_shader; + gGL.blendFunc((LLRender::eBlendFactor) params.mBlendFuncSrc, (LLRender::eBlendFactor) params.mBlendFuncDst, mAlphaSFactor, mAlphaDFactor); + params.mVertexBuffer->setBuffer(mask & ~(params.mFullbright ? (LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2) : 0)); - gGL.setSceneBlendType(LLRender::BT_ALPHA); + params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); + gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); + } + + // If this alpha mesh has glow, then draw it a second time to add the destination-alpha (=glow). Interleaving these state-changing calls could be expensive, but glow must be drawn Z-sorted with alpha. + if (current_shader && + draw_glow_for_this_partition && + params.mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE)) + { + // install glow-accumulating blend mode + gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, // don't touch color + LLRender::BF_ONE, LLRender::BF_ONE); // add to alpha (glow) + + emissive_shader->bind(); + if (LLPipeline::sRenderingHUDs) + { + emissive_shader->uniform1i(LLShaderMgr::NO_ATMO, 1); + } + else + { + emissive_shader->uniform1i(LLShaderMgr::NO_ATMO, 0); + } + params.mVertexBuffer->setBuffer((mask & ~LLVertexBuffer::MAP_COLOR) | LLVertexBuffer::MAP_EMISSIVE); + + // do the actual drawing, again + params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); + gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); + + // restore our alpha blend mode + gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor); + + current_shader->bind(); + } + + if (tex_setup) + { + gGL.getTexUnit(0)->activate(); + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + } + } + } + } - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gGL.setSceneBlendType(LLRender::BT_ALPHA); LLVertexBuffer::unbind(); - gPipeline.enableLightsDynamic(); + if (!light_enabled) + { + gPipeline.enableLightsDynamic(); + } } -- cgit v1.2.3