diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index ed8497536..5190f91ab 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -194,7 +194,7 @@ void LLTexUnit::enable(eTextureType type) mCurrTexType = type; gGL.flush(); - if (!LLGLSLShader::sNoFixedFunction && + if (!LLGLSLShader::sNoFixedFunction && //type != LLTexUnit::TT_MULTISAMPLE_TEXTURE && mIndex < gGLManager.mNumTextureUnits) { diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 99e8c20ef..00baee43d 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -216,8 +216,7 @@ void LLDrawPoolAlpha::render(S32 pass) gGL.setColorMask(true, true); } - bool write_depth = LLDrawPoolWater::sSkipScreenCopy - || (deferred_render && pass == 1) + bool write_depth = (deferred_render && pass == 1) // we want depth written so that rendered alpha will // contribute to the alpha mask used for impostors || LLPipeline::sImpostorRenderAlphaDepthPass; @@ -271,8 +270,7 @@ void LLDrawPoolAlpha::render(S32 pass) if (sShowDebugAlpha) { - BOOL shaders = gPipeline.canUseVertexShaders(); - if(shaders) + if (LLGLSLShader::sNoFixedFunction) { gHighlightProgram.bind(); } @@ -292,7 +290,7 @@ void LLDrawPoolAlpha::render(S32 pass) pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); pushBatches(LLRenderPass::PASS_ALPHA_INVISIBLE, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); - if(shaders) + if (LLGLSLShader::sNoFixedFunction) { gHighlightProgram.unbind(); } @@ -337,7 +335,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) BOOL initialized_lighting = FALSE; BOOL light_enabled = TRUE; - BOOL use_shaders = gPipeline.canUseVertexShaders(); + BOOL use_shaders = LLGLSLShader::sNoFixedFunction; BOOL depth_only = (pass == 1 && !LLPipeline::sImpostorRender); diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 5e16499c5..7c2f36524 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -644,7 +644,7 @@ void LLDrawPoolAvatar::endImpostor() void LLDrawPoolAvatar::beginRigid() { - if (gPipeline.canUseVertexShaders()) + if (LLGLSLShader::sNoFixedFunction) { if (LLPipeline::sUnderWaterRender) { @@ -724,18 +724,18 @@ void LLDrawPoolAvatar::endDeferredRigid() void LLDrawPoolAvatar::beginSkinned() { - if(!gPipeline.canUseVertexShaders()) + if (!LLGLSLShader::sNoFixedFunction) { sVertexProgram = NULL; return; } - if (sShaderLevel > 0) + if (sShaderLevel > 0) // for hardware blending { if (LLPipeline::sUnderWaterRender) { sVertexProgram = &gAvatarWaterProgram; - sShaderLevel = llmin((U32) 1, sShaderLevel); + sShaderLevel = 1; } else { @@ -797,7 +797,7 @@ void LLDrawPoolAvatar::endSkinned() void LLDrawPoolAvatar::beginRiggedSimple() { sDiffuseChannel = 0; - if(!gPipeline.canUseVertexShaders()) + if (!LLGLSLShader::sNoFixedFunction) { sVertexProgram = NULL; return; @@ -845,7 +845,7 @@ void LLDrawPoolAvatar::endRiggedFullbrightAlpha() void LLDrawPoolAvatar::beginRiggedGlow() { sDiffuseChannel = 0; - if(!gPipeline.canUseVertexShaders()) + if (!LLGLSLShader::sNoFixedFunction) { sVertexProgram = NULL; return; @@ -867,7 +867,7 @@ void LLDrawPoolAvatar::endRiggedGlow() void LLDrawPoolAvatar::beginRiggedFullbright() { sDiffuseChannel = 0; - if(!gPipeline.canUseVertexShaders()) + if (!LLGLSLShader::sNoFixedFunction) { sVertexProgram = NULL; return; @@ -908,7 +908,7 @@ void LLDrawPoolAvatar::endRiggedFullbright() void LLDrawPoolAvatar::beginRiggedShinySimple() { - if(!gPipeline.canUseVertexShaders()) + if (!LLGLSLShader::sNoFixedFunction) { sVertexProgram = NULL; return; @@ -935,7 +935,7 @@ void LLDrawPoolAvatar::endRiggedShinySimple() void LLDrawPoolAvatar::beginRiggedFullbrightShiny() { - if(!gPipeline.canUseVertexShaders()) + if (!LLGLSLShader::sNoFixedFunction) { sVertexProgram = NULL; return; @@ -1322,7 +1322,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) return; } - if ((sShaderLevel >= SHADER_LEVEL_CLOTH)) + if (sShaderLevel >= SHADER_LEVEL_CLOTH) { LLMatrix4 rot_mat; LLViewerCamera::getInstance()->getMatrixToLocal(rot_mat); diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index fcebf26e7..280f6e914 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -1550,7 +1550,7 @@ void LLDrawPoolInvisible::render(S32 pass) { //render invisiprims LLFastTimer t(FTM_RENDER_INVISIBLE); - if (gPipeline.canUseVertexShaders()) + if (LLGLSLShader::sNoFixedFunction) { gOcclusionProgram.bind(); } @@ -1562,7 +1562,7 @@ void LLDrawPoolInvisible::render(S32 pass) gGL.setColorMask(true, false); glStencilMask(0xFFFFFFFF); - if (gPipeline.canUseVertexShaders()) + if (LLGLSLShader::sNoFixedFunction) { gOcclusionProgram.unbind(); } diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp index 392522913..8ef66aa24 100644 --- a/indra/newview/lldrawpooltree.cpp +++ b/indra/newview/lldrawpooltree.cpp @@ -79,7 +79,7 @@ void LLDrawPoolTree::beginRenderPass(S32 pass) shader = &gTreeProgram; } - if (gPipeline.canUseVertexShaders()) + if (LLGLSLShader::sNoFixedFunction) { shader->bind(); shader->setMinimumAlpha(0.5f); diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index daebb322b..91cad1577 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -63,7 +63,6 @@ static float sTime; BOOL deferred_render = FALSE; -BOOL LLDrawPoolWater::sSkipScreenCopy = FALSE; BOOL LLDrawPoolWater::sNeedsReflectionUpdate = TRUE; BOOL LLDrawPoolWater::sNeedsDistortionUpdate = TRUE; LLColor4 LLDrawPoolWater::sWaterFogColor = LLColor4(0.2f, 0.5f, 0.5f, 0.f); @@ -185,7 +184,7 @@ void LLDrawPoolWater::render(S32 pass) LLGLEnable blend(GL_BLEND); - if ((mVertexShaderLevel > 0) && !sSkipScreenCopy) + if (mVertexShaderLevel > 0) { shade(); return; diff --git a/indra/newview/lldrawpoolwater.h b/indra/newview/lldrawpoolwater.h index 4d12605f5..1e93c2752 100644 --- a/indra/newview/lldrawpoolwater.h +++ b/indra/newview/lldrawpoolwater.h @@ -49,7 +49,6 @@ protected: LLPointer mWaterNormp; public: - static BOOL sSkipScreenCopy; static BOOL sNeedsReflectionUpdate; static BOOL sNeedsDistortionUpdate; static LLVector3 sLightDir; diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index 83047aa81..dbe7b2911 100644 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -219,7 +219,7 @@ void LLDrawPoolWLSky::renderStars(void) const //New gGL.getTexUnit(0)->bind(gSky.mVOSkyp->getBloomTex()); - if (gPipeline.canUseVertexShaders()) + if (LLGLSLShader::sNoFixedFunction) { static LLStaticHashedString sCustomAlpha("custom_alpha"); star_shader->uniform1f(sCustomAlpha, star_alpha.mV[3]); @@ -235,7 +235,7 @@ void LLDrawPoolWLSky::renderStars(void) const gGL.popMatrix(); - if (!gPipeline.canUseVertexShaders()) + if (!LLGLSLShader::sNoFixedFunction) { // and disable the combiner states gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); @@ -294,7 +294,7 @@ void LLDrawPoolWLSky::renderHeavenlyBodies() // since LLImageGL::bind detects that it's a noop, and optimizes it out. gGL.getTexUnit(0)->bind(face->getTexture()); - if (gPipeline.canUseVertexShaders()) + if (LLGLSLShader::sNoFixedFunction) { // Okay, so the moon isn't a star, but it's close enough. static LLStaticHashedString sCustomAlpha("custom_alpha"); @@ -310,7 +310,7 @@ void LLDrawPoolWLSky::renderHeavenlyBodies() face->getVertexBuffer()->setBuffer(LLDrawPoolWLSky::STAR_VERTEX_DATA_MASK); face->getVertexBuffer()->draw(LLRender::TRIANGLES, face->getVertexBuffer()->getNumIndices(), 0); - if (!gPipeline.canUseVertexShaders()) + if (!LLGLSLShader::sNoFixedFunction) { gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); } @@ -387,7 +387,7 @@ void LLDrawPoolWLSky::render(S32 pass) gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]); - if(gPipeline.canUseVertexShaders()) + if (LLGLSLShader::sNoFixedFunction) star_shader->bind(); // *NOTE: have to bind a texture here since register combiners blending in // renderStars() requires something to be bound and we might as well only @@ -398,7 +398,7 @@ void LLDrawPoolWLSky::render(S32 pass) renderStars(); - if(gPipeline.canUseVertexShaders()) + if (LLGLSLShader::sNoFixedFunction) star_shader->unbind(); diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index cf8e2d501..04158230b 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -559,7 +559,6 @@ void LLFeatureManager::setGraphicsLevel(S32 level, bool skipFeatures) LLViewerShaderMgr::sSkipReload = false; LLViewerShaderMgr::instance()->setShaders(); - gPipeline.refreshCachedSettings(); } void LLFeatureManager::applyBaseMasks() diff --git a/indra/newview/llfloaterenvsettings.cpp b/indra/newview/llfloaterenvsettings.cpp index c54a62545..d6b053f97 100644 --- a/indra/newview/llfloaterenvsettings.cpp +++ b/indra/newview/llfloaterenvsettings.cpp @@ -141,7 +141,7 @@ void LLFloaterEnvSettings::syncMenu() childEnable("EnvUseEstateTimeButton"); } - if(!gPipeline.canUseVertexShaders()) + if (!LLGLSLShader::sNoFixedFunction) { childDisable("EnvWaterColor"); childDisable("EnvWaterColorText"); diff --git a/indra/newview/llframestatview.cpp b/indra/newview/llframestatview.cpp index 9eb295794..1db6c296c 100644 --- a/indra/newview/llframestatview.cpp +++ b/indra/newview/llframestatview.cpp @@ -133,7 +133,7 @@ void LLFrameStatView::draw() for (i = 0; i < mNumStats; i++) { - if (mStats[i]->getLastTime() >= min_last_time) + if (mStats[i]->getCurrentTime() >= min_last_time) { is_active[i] = TRUE; } diff --git a/indra/newview/llpaneldisplay.cpp b/indra/newview/llpaneldisplay.cpp index 70e98a663..9ba12e570 100644 --- a/indra/newview/llpaneldisplay.cpp +++ b/indra/newview/llpaneldisplay.cpp @@ -507,11 +507,9 @@ void LLPanelDisplay::refreshEnabledState() //I actually recommend RenderUseFBO:FALSE for ati users when not using deferred, so RenderUseFBO shouldn't control visibility of the element. // Instead, gGLManager.mHasFramebufferObject seems better as it is determined by hardware and not current user settings. -Shyotl //Enabling deferred will force RenderUseFBO to TRUE. - BOOL can_defer = gGLManager.mHasFramebufferObject && - LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && //Ensure it's enabled in the gpu feature table - LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarVP") && //Hardware Skinning. Deferred forces RenderAvatarVP to true - LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable") && gSavedSettings.getBOOL("VertexShaderEnable") && //Basic Shaders - LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders") && wlatmos; //Atmospheric Shaders + BOOL can_defer = LLPipeline::isRenderDeferredCapable() && + gSavedSettings.getBOOL("VertexShaderEnable") && //Basic Shaders + wlatmos; //Atmospheric Shaders mCtrlDeferred->setEnabled(can_defer); diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 021844f0e..c34069e94 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -205,7 +205,6 @@ bool handleRenderAvatarComplexityLimitChanged(const LLSD& newvalue) bool handleRenderTransparentWaterChanged(const LLSD& newvalue) { - LLPipeline::sWaterReflections = gGLManager.mHasCubeMap && gSavedSettings.getBOOL("VertexShaderEnable"); if (gPipeline.isInit()) //If water is opaque then distortion/reflection fbos will not be needed. { gPipeline.releaseGLBuffers(); @@ -466,17 +465,9 @@ static bool handleRenderLocalLightsChanged(const LLSD& newvalue) static bool handleRenderDeferredChanged(const LLSD& newvalue) { - bool can_defer = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred"); - bool old_deferred = !newvalue.asBoolean() && can_defer; - LLRenderTarget::sUseFBO = (newvalue.asBoolean() && can_defer) || gSavedSettings.getBOOL("RenderUseFBO"); if (gPipeline.isInit()) { - LLPipeline::refreshCachedSettings(); - gPipeline.updateRenderDeferred(); - gPipeline.releaseGLBuffers(); - gPipeline.createGLBuffers(); - gPipeline.resetVertexBuffers(); - if (old_deferred != newvalue.asBoolean()) + if (LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred")) { LLViewerShaderMgr::instance()->setShaders(); } @@ -486,13 +477,11 @@ static bool handleRenderDeferredChanged(const LLSD& newvalue) static bool handleRenderUseFBOChanged(const LLSD& newvalue) { - bool can_defer = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred"); - LLRenderTarget::sUseFBO = newvalue.asBoolean() || (gSavedSettings.getBOOL("RenderDeferred") && can_defer); + LLRenderTarget::sUseFBO = newvalue.asBoolean() || LLPipeline::sRenderDeferred; if (gPipeline.isInit()) { gPipeline.releaseGLBuffers(); gPipeline.createGLBuffers(); - gPipeline.resetVertexBuffers(); } return true; } diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 6fe2d4d9d..681838d21 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -733,7 +733,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot, boo LLGLState::checkTextureChannels(); LLGLState::checkClientArrays(); - BOOL to_texture = gPipeline.canUseVertexShaders() && + BOOL to_texture = LLGLSLShader::sNoFixedFunction && LLPipeline::sRenderGlow; LLAppViewer::instance()->pingMainloopTimeout("Display:Swap"); @@ -959,7 +959,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot, boo else { gPipeline.mScreen.bindTarget(); - if (LLPipeline::sUnderWaterRender && !gPipeline.canUseWindLightShaders()) + if (LLPipeline::sUnderWaterRender) { const LLColor4 &col = LLDrawPoolWater::sWaterFogColor; glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f); @@ -1343,7 +1343,7 @@ void render_ui(F32 zoom_factor, int subfield, bool tiling) } { - BOOL to_texture = gPipeline.canUseVertexShaders() && + BOOL to_texture = LLGLSLShader::sNoFixedFunction && LLPipeline::sRenderGlow; if (to_texture) @@ -1351,7 +1351,7 @@ void render_ui(F32 zoom_factor, int subfield, bool tiling) gPipeline.renderBloom(gSnapshot, zoom_factor, subfield, tiling); } - if(gPipeline.canUseVertexShaders()) + if (LLGLSLShader::sNoFixedFunction) { LLPostProcess::getInstance()->renderEffects(gViewerWindow->getWindowDisplayWidth(), gViewerWindow->getWindowDisplayHeight()); } diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index a072431fa..bb581801b 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -1686,7 +1686,6 @@ class LLAdvancedToggleWireframe : public view_listener_t // [/RLVa:KB] // gUseWireframe = !(gUseWireframe); // gWindowResized = TRUE; // Singu Note: We don't use this (yet?) - LLPipeline::updateRenderDeferred(); gPipeline.resetVertexBuffers(); // return true; } diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index d29dc6cef..70c19837d 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -133,8 +133,6 @@ LLGLSLShader gHighlightSpecularProgram(LLViewerShaderMgr::SHADER_INTERFACE); //avatar shader handles LLGLSLShader gAvatarProgram(LLViewerShaderMgr::SHADER_AVATAR); LLGLSLShader gAvatarWaterProgram(LLViewerShaderMgr::SHADER_AVATAR); -LLGLSLShader gAvatarEyeballProgram(LLViewerShaderMgr::SHADER_AVATAR); -LLGLSLShader gAvatarPickProgram(LLViewerShaderMgr::SHADER_AVATAR); //Not in mShaderList LLGLSLShader gImpostorProgram(LLViewerShaderMgr::SHADER_OBJECT); // Effects Shaders @@ -207,8 +205,7 @@ LLGLSLShaderArray gDeferredMaterialProgram[L LLGLSLShaderArray gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2]; LLViewerShaderMgr::LLViewerShaderMgr() : - mVertexShaderLevel(SHADER_COUNT, 0), - mMaxAvatarShaderLevel(0) + mVertexShaderLevel(SHADER_COUNT, 0) {} LLViewerShaderMgr::~LLViewerShaderMgr() @@ -241,7 +238,7 @@ void LLViewerShaderMgr::initAttribsAndUniforms(void) S32 LLViewerShaderMgr::getVertexShaderLevel(S32 type) { - return LLPipeline::sDisableShaders ? 0 : mVertexShaderLevel[type]; + return mVertexShaderLevel[type]; } //============================================================================ @@ -257,6 +254,10 @@ void LLViewerShaderMgr::setShaders() return; } + //Since setShaders can be reentrant, be sure to clear out stale shader objects that may be left over from parent call. + unloadShaderObjects(); + unloadShaders(); + LLGLSLShader::sIndexedTextureChannels = llmax(llmin(gGLManager.mNumTextureImageUnits, (S32) gSavedSettings.getU32("RenderMaxTextureIndex")), 1); static const LLCachedControl no_texture_indexing("ShyotlUseLegacyTextureBatching",false); if(no_texture_indexing) @@ -284,16 +285,16 @@ void LLViewerShaderMgr::setShaders() initAttribsAndUniforms(); gPipeline.releaseGLBuffers(); - if (gSavedSettings.getBOOL("VertexShaderEnable")) + bool want_shaders = LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable") && + gSavedSettings.getBOOL("VertexShaderEnable") && + (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 10); + + bool want_deferred = want_shaders && LLPipeline::isRenderDeferredDesired(); + + if (want_shaders) { - LLPipeline::sWaterReflections = gGLManager.mHasCubeMap; - LLPipeline::sRenderGlow = gSavedSettings.getBOOL("RenderGlow"); - LLPipeline::updateRenderDeferred(); - } - else - { - LLPipeline::sRenderGlow = FALSE; - LLPipeline::sWaterReflections = FALSE; + //sRenderGlow needs set as it's referenced in the shader load process. + LLPipeline::sRenderGlow = want_deferred || gSavedSettings.getBOOL("RenderGlow"); } //hack to reset buffers that change behavior with shaders @@ -311,21 +312,10 @@ void LLViewerShaderMgr::setShaders() LL_INFOS("ShaderLoading") << "\n~~~~~~~~~~~~~~~~~~\n Loading Shaders:\n~~~~~~~~~~~~~~~~~~" << LL_ENDL; LL_INFOS("ShaderLoading") << llformat("Using GLSL %d.%d", gGLManager.mGLSLVersionMajor, gGLManager.mGLSLVersionMinor) << llendl; - for (S32 i = 0; i < SHADER_COUNT; i++) - { - mVertexShaderLevel[i] = 0; - } - mMaxAvatarShaderLevel = 0; - - LLGLSLShader::sNoFixedFunction = false; LLVertexBuffer::unbind(); - if (LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable") - && (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 10) - && gSavedSettings.getBOOL("VertexShaderEnable")) + + if (want_shaders) { - //using shaders, disable fixed function - LLGLSLShader::sNoFixedFunction = true; - S32 light_class = 2; S32 env_class = 2; S32 obj_class = 2; @@ -340,11 +330,8 @@ void LLViewerShaderMgr::setShaders() { transform_class = 0; } - - if (LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && - gSavedSettings.getBOOL("RenderDeferred") && - gSavedSettings.getBOOL("RenderAvatarVP") && - gSavedSettings.getBOOL("WindLightUseAtmosShaders")) + + if (want_deferred) { if (gSavedSettings.getS32("RenderShadowDetail") > 0) { //shadows @@ -393,9 +380,6 @@ void LLViewerShaderMgr::setShaders() if (loaded) { - gPipeline.mVertexShadersEnabled = TRUE; - gPipeline.mVertexShadersLoaded = 1; - // Load all shaders to set max levels loaded = loadShadersEnvironment(); @@ -421,75 +405,58 @@ void LLViewerShaderMgr::setShaders() if (loaded) { - loaded = loadTransformShaders(); - if(!loaded) //Failed to load. Just wipe all transformfeedback shaders and continue like nothing happened. - { - mVertexShaderLevel[SHADER_TRANSFORM] = 0; - unloadShaderClass(SHADER_TRANSFORM); - loaded = true; - } + loadTransformShaders(); } if (loaded) { // Load max avatar shaders to set the max level - mVertexShaderLevel[SHADER_AVATAR] = 3; - mMaxAvatarShaderLevel = 3; + bool can_skin = want_deferred || (LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarVP") && gSavedSettings.getBOOL("RenderAvatarVP")); - if (LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarVP") && gSavedSettings.getBOOL("RenderAvatarVP") && loadShadersObject()) + if (can_skin) { //hardware skinning is enabled and rigged attachment shaders loaded correctly - BOOL avatar_cloth = gSavedSettings.getBOOL("RenderAvatarCloth"); - S32 avatar_class = 1; - - // cloth is a class3 shader - if(avatar_cloth) - { - avatar_class = 3; - } // Set the actual level - mVertexShaderLevel[SHADER_AVATAR] = avatar_class; - loadShadersAvatar(); - if (mVertexShaderLevel[SHADER_AVATAR] != avatar_class) + mVertexShaderLevel[SHADER_AVATAR] = gSavedSettings.getBOOL("RenderAvatarCloth") ? 3 : 1; + + if(!loadShadersAvatar() || !loadShadersObject()) { - if (mVertexShaderLevel[SHADER_AVATAR] == 0) - { - gSavedSettings.setBOOL("RenderAvatarVP", FALSE); - } - if(llmax(mVertexShaderLevel[SHADER_AVATAR]-1,0) >= 3) - { - avatar_cloth = true; - } - else - { - avatar_cloth = false; - } - gSavedSettings.setBOOL("RenderAvatarCloth", avatar_cloth); + can_skin = false; + } + else if (mVertexShaderLevel[SHADER_AVATAR] < 3) + { + gSavedSettings.setBOOL("RenderAvatarCloth", false); } } - else + + if (!can_skin) { //hardware skinning not possible, neither is deferred rendering - mVertexShaderLevel[SHADER_AVATAR] = 0; mVertexShaderLevel[SHADER_DEFERRED] = 0; + mVertexShaderLevel[SHADER_AVATAR] = 0; + unloadShaderClass(SHADER_AVATAR); + unloadShaderClass(SHADER_OBJECT); - if (gSavedSettings.getBOOL("RenderAvatarVP")) - { - gSavedSettings.setBOOL("RenderDeferred", FALSE); - gSavedSettings.setBOOL("RenderAvatarCloth", FALSE); - gSavedSettings.setBOOL("RenderAvatarVP", FALSE); - } + want_deferred = false; //Deferred requires skinned shaders. - loadShadersAvatar(); // unloads + gSavedSettings.setBOOL("RenderDeferred", FALSE); + gSavedSettings.setBOOL("RenderAvatarCloth", FALSE); + gSavedSettings.setBOOL("RenderAvatarVP", FALSE); loaded = loadShadersObject(); } } + if (loaded) + { + loaded = loadShadersInterface(); + } + if (!loaded) { //some shader absolutely could not load, try to fall back to a simpler setting if (gSavedSettings.getBOOL("WindLightUseAtmosShaders")) { //disable windlight and try again gSavedSettings.setBOOL("WindLightUseAtmosShaders", FALSE); + gSavedSettings.setBOOL("RenderDeferred", FALSE); reentrance = false; setShaders(); return; @@ -498,48 +465,38 @@ void LLViewerShaderMgr::setShaders() if (gSavedSettings.getBOOL("VertexShaderEnable")) { //disable shaders outright and try again gSavedSettings.setBOOL("VertexShaderEnable", FALSE); + gSavedSettings.setBOOL("RenderDeferred", FALSE); reentrance = false; setShaders(); return; } - } - - if (loaded && !loadShadersDeferred()) - { //everything else succeeded but deferred failed, disable deferred and try again + } + else if (!loadShadersDeferred()) + { gSavedSettings.setBOOL("RenderDeferred", FALSE); reentrance = false; setShaders(); return; } } - else + if (!loaded) { - LLGLSLShader::sNoFixedFunction = false; - LLGLSLShader::sIndexedTextureChannels = 1; - gPipeline.mVertexShadersEnabled = FALSE; - gPipeline.mVertexShadersLoaded = 0; - for (S32 i = 0; i < SHADER_COUNT; i++) - mVertexShaderLevel[i] = 0; + llassert_always(!LLRender::sGLCoreProfile); //This is bad... + unloadShaders(); + } + else //Shaders loaded + { + //using shaders, disable fixed function + LLGLSLShader::sNoFixedFunction = true; + LLPipeline::sWaterReflections = gGLManager.mHasCubeMap; + LLPipeline::sRenderDeferred = want_deferred; } //Flag base shader objects for deletion //Don't worry-- they won't be deleted until no programs refrence them. - std::multimap::iterator it = mShaderObjects.begin(); - for(; it!=mShaderObjects.end();++it) - if(it->second.mHandle) - glDeleteObjectARB(it->second.mHandle); - mShaderObjects.clear(); + unloadShaderObjects(); } - else - { - LLGLSLShader::sNoFixedFunction = false; - LLGLSLShader::sIndexedTextureChannels = 1; - gPipeline.mVertexShadersEnabled = FALSE; - gPipeline.mVertexShadersLoaded = 0; - for (S32 i = 0; i < SHADER_COUNT; i++) - mVertexShaderLevel[i] = 0; - } - + if (gViewerWindow) { gViewerWindow->setCursor(UI_CURSOR_ARROW); @@ -565,7 +522,21 @@ void LLViewerShaderMgr::unloadShaders() for (S32 i = 0; i < SHADER_COUNT; i++) mVertexShaderLevel[i] = 0; - gPipeline.mVertexShadersLoaded = 0; + //Unset all shader-dependent static variables. + LLGLSLShader::sNoFixedFunction = false; + LLGLSLShader::sIndexedTextureChannels = 1; + LLPipeline::sRenderDeferred = false; + LLPipeline::sWaterReflections = FALSE; + LLPipeline::sRenderGlow = FALSE; +} + +void LLViewerShaderMgr::unloadShaderObjects() +{ + std::multimap::iterator it = mShaderObjects.begin(); + for (; it != mShaderObjects.end(); ++it) + if (it->second.mHandle) + glDeleteObjectARB(it->second.mHandle); + mShaderObjects.clear(); } BOOL LLViewerShaderMgr::loadBasicShaders() @@ -713,18 +684,19 @@ BOOL LLViewerShaderMgr::loadShadersEnvironment() if (!success) { mVertexShaderLevel[SHADER_ENVIRONMENT] = 0; - return FALSE; + unloadShaderClass(SHADER_ENVIRONMENT); + } + else + { + LLWorld::getInstance()->updateWaterObjects(); } - LLWorld::getInstance()->updateWaterObjects(); - - return TRUE; + return success; } BOOL LLViewerShaderMgr::loadShadersWater() { BOOL success = TRUE; - BOOL terrainWaterSuccess = TRUE; if (mVertexShaderLevel[SHADER_WATER] == 0) { @@ -775,33 +747,20 @@ BOOL LLViewerShaderMgr::loadShadersWater() gTerrainWaterProgram.mShaderFiles.push_back(make_pair("environment/terrainWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); gTerrainWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_ENVIRONMENT]; gTerrainWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - terrainWaterSuccess = gTerrainWaterProgram.createShader(NULL, NULL); - } - - /// Keep track of water shader levels - if (gWaterProgram.mShaderLevel != mVertexShaderLevel[SHADER_WATER] - || gUnderWaterProgram.mShaderLevel != mVertexShaderLevel[SHADER_WATER]) - { - mVertexShaderLevel[SHADER_WATER] = llmin(gWaterProgram.mShaderLevel, gUnderWaterProgram.mShaderLevel); + success = gTerrainWaterProgram.createShader(NULL, NULL); } if (!success) { mVertexShaderLevel[SHADER_WATER] = 0; - return FALSE; + unloadShaderClass(SHADER_WATER); } - - // if we failed to load the terrain water shaders and we need them (using class2 water), - // then drop down to class1 water. - if (mVertexShaderLevel[SHADER_WATER] > 1 && !terrainWaterSuccess) + else { - mVertexShaderLevel[SHADER_WATER]--; - return loadShadersWater(); + LLWorld::getInstance()->updateWaterObjects(); } - - LLWorld::getInstance()->updateWaterObjects(); - return TRUE; + return success; } BOOL LLViewerShaderMgr::loadShadersEffects() @@ -980,6 +939,12 @@ BOOL LLViewerShaderMgr::loadShadersEffects() #endif + if (!success) + { + mVertexShaderLevel[SHADER_EFFECT] = 0; + unloadShaderClass(SHADER_EFFECT); + } + return success; } @@ -1426,20 +1391,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAlphaWaterProgram.mFeatures.calculatesLighting = true; gDeferredAlphaWaterProgram.mFeatures.hasLighting = true; } - - /*if (success) - { - gDeferredAvatarEyesProgram.mName = "Deferred Avatar Eyes Shader"; - gDeferredAvatarEyesProgram.mFeatures.calculatesAtmospherics = true; - gDeferredAvatarEyesProgram.mFeatures.hasGamma = true; - gDeferredAvatarEyesProgram.mFeatures.hasTransport = true; - gDeferredAvatarEyesProgram.mFeatures.disableTextureIndex = true; - gDeferredAvatarEyesProgram.mShaderFiles.clear(); - gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/avatarEyesV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredAvatarEyesProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; - success = gDeferredAvatarEyesProgram.createShader(NULL, NULL); - }*/ if (success) { @@ -1831,6 +1782,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() success = gNormalMapGenProgram.createShader(NULL, NULL); } + if (!success) + { + mVertexShaderLevel[SHADER_DEFERRED] = 0; + unloadShaderClass(SHADER_DEFERRED); + } + return success; } @@ -2138,13 +2095,13 @@ BOOL LLViewerShaderMgr::loadShadersObject() } } - if( !success ) + if (!success) { mVertexShaderLevel[SHADER_OBJECT] = 0; - return FALSE; + unloadShaderClass(SHADER_OBJECT); } - return TRUE; + return success; } BOOL LLViewerShaderMgr::loadShadersAvatar() @@ -2193,52 +2150,15 @@ BOOL LLViewerShaderMgr::loadShadersAvatar() gAvatarWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; success = gAvatarWaterProgram.createShader(NULL, NULL); } - - /// Keep track of avatar levels - if (gAvatarProgram.mShaderLevel != mVertexShaderLevel[SHADER_AVATAR]) - { - mMaxAvatarShaderLevel = mVertexShaderLevel[SHADER_AVATAR] = gAvatarProgram.mShaderLevel; - } - } - - if (success) - { - gAvatarPickProgram.mName = "Avatar Pick Shader"; - gAvatarPickProgram.mFeatures.hasSkinning = true; - gAvatarPickProgram.mFeatures.disableTextureIndex = true; - gAvatarPickProgram.mShaderFiles.clear(); - gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarV.glsl", GL_VERTEX_SHADER_ARB)); - gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarF.glsl", GL_FRAGMENT_SHADER_ARB)); - gAvatarPickProgram.mShaderLevel = mVertexShaderLevel[SHADER_AVATAR]; - success = gAvatarPickProgram.createShader(NULL, NULL); - } - - if (success) - { - /*gAvatarEyeballProgram.mName = "Avatar Eyeball Program"; - gAvatarEyeballProgram.mFeatures.calculatesLighting = true; - gAvatarEyeballProgram.mFeatures.isSpecular = true; - gAvatarEyeballProgram.mFeatures.calculatesAtmospherics = true; - gAvatarEyeballProgram.mFeatures.hasGamma = true; - gAvatarEyeballProgram.mFeatures.hasAtmospherics = true; - gAvatarEyeballProgram.mFeatures.hasLighting = true; - gAvatarEyeballProgram.mFeatures.hasAlphaMask = true; - gAvatarEyeballProgram.mFeatures.disableTextureIndex = true; - gAvatarEyeballProgram.mShaderFiles.clear(); - gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballV.glsl", GL_VERTEX_SHADER_ARB)); - gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballF.glsl", GL_FRAGMENT_SHADER_ARB)); - gAvatarEyeballProgram.mShaderLevel = mVertexShaderLevel[SHADER_AVATAR]; - success = gAvatarEyeballProgram.createShader(NULL, NULL);*/ } if( !success ) { mVertexShaderLevel[SHADER_AVATAR] = 0; - mMaxAvatarShaderLevel = 0; - return FALSE; + unloadShaderClass(SHADER_AVATAR); } - return TRUE; + return success; } BOOL LLViewerShaderMgr::loadShadersInterface() @@ -2474,13 +2394,13 @@ BOOL LLViewerShaderMgr::loadShadersInterface() success = gAlphaMaskProgram.createShader(NULL, NULL); } - if( !success ) + if (!success) { mVertexShaderLevel[SHADER_INTERFACE] = 0; - return FALSE; + unloadShaderClass(SHADER_INTERFACE); } - - return TRUE; + + return success; } BOOL LLViewerShaderMgr::loadShadersWindLight() @@ -2517,6 +2437,12 @@ BOOL LLViewerShaderMgr::loadShadersWindLight() success = gWLCloudProgram.createShader(NULL, NULL); } + if (!success) + { + mVertexShaderLevel[SHADER_WINDLIGHT] = 0; + unloadShaderClass(SHADER_WINDLIGHT); + } + return success; } @@ -2601,6 +2527,12 @@ BOOL LLViewerShaderMgr::loadTransformShaders() success = gTransformTangentProgram.createShader(NULL, NULL, 1, varyings); } + + if (!success) + { + mVertexShaderLevel[SHADER_TRANSFORM] = 0; + unloadShaderClass(SHADER_TRANSFORM); + } return success; } diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 8ee913d06..fe7d4d64c 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -57,6 +57,7 @@ public: void initAttribsAndUniforms(void); void setShaders(); void unloadShaders(); + void unloadShaderObjects(); S32 getVertexShaderLevel(S32 type); BOOL loadBasicShaders(); BOOL loadShadersEffects(); @@ -70,7 +71,6 @@ public: BOOL loadTransformShaders(); std::vector mVertexShaderLevel; - S32 mMaxAvatarShaderLevel; enum EShaderClass { @@ -252,8 +252,6 @@ extern LLGLSLShader gHighlightSpecularProgram; // avatar shader handles extern LLGLSLShader gAvatarProgram; extern LLGLSLShader gAvatarWaterProgram; -extern LLGLSLShader gAvatarEyeballProgram; -extern LLGLSLShader gAvatarPickProgram; extern LLGLSLShader gImpostorProgram; // WindLight shader handles diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index ebc25abab..4a0e79b97 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -472,7 +472,7 @@ public: static const LLCachedControl debug_show_render_info("DebugShowRenderInfo"); if (debug_show_render_info) { - if (gPipeline.getUseVertexShaders() == 0) + if (!LLGLSLShader::sNoFixedFunction) { addText(xpos, ypos, "Shaders Disabled"); ypos += y_inc; diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index 837d0aea2..045713b03 100644 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -49,6 +49,7 @@ #include "llviewerregion.h" #include "pipeline.h" #include "llspatialpartition.h" +#include "llglslshader.h" const F32 MAX_PART_LIFETIME = 120.f; @@ -715,7 +716,7 @@ void LLVOPartGroup::getGeometry(S32 idx, *colorsp++ = color; //Only add emissive attributes if glowing (doing it for all particles is INCREDIBLY inefficient as it leads to a second, slower, render pass.) - if (gPipeline.canUseVertexShaders() && (pglow.mV[3] > 0 || part.mGlow.mV[3] > 0)) + if (LLGLSLShader::sNoFixedFunction && (pglow.mV[3] > 0 || part.mGlow.mV[3] > 0)) { //only write glow if it is not zero *emissivep++ = pglow; *emissivep++ = pglow; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 751c93ef2..a8a9ec104 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4670,7 +4670,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA : LLDrawPoolAvatar::RIGGED_ALPHA); } } - else if (gPipeline.canUseVertexShaders() + else if (LLGLSLShader::sNoFixedFunction && LLPipeline::sRenderBump && te->getShiny() && can_be_shiny) @@ -5227,7 +5227,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) spec_mask = spec_mask | LLVertexBuffer::MAP_EMISSIVE; } - BOOL batch_textures = gPipeline.getUseVertexShaders(); + BOOL batch_textures = LLGLSLShader::sNoFixedFunction; U32 additional_flags = 0x0; if(batch_textures) @@ -6004,7 +6004,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac { registerFace(group, facep, LLRenderPass::PASS_ALPHA); } - else if (gPipeline.canUseVertexShaders() + else if (LLGLSLShader::sNoFixedFunction && LLPipeline::sRenderBump && te->getShiny() && can_be_shiny) @@ -6039,7 +6039,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac registerFace(group, facep, LLRenderPass::PASS_ALPHA); } } - else if (gPipeline.canUseVertexShaders() + else if (LLGLSLShader::sNoFixedFunction && LLPipeline::sRenderBump && te->getShiny() && can_be_shiny) @@ -6120,7 +6120,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac } - if (!gPipeline.canUseVertexShaders() && + if (!LLGLSLShader::sNoFixedFunction && !is_alpha && te->getShiny() && LLPipeline::sRenderBump) @@ -6151,8 +6151,8 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac tex = facep->getTexture(); bool is_alpha = facep->getPoolType() == LLDrawPool::POOL_ALPHA; - bool is_shiny_shader = facep->getPoolType() == LLDrawPool::POOL_BUMP && gPipeline.canUseVertexShaders() && te->getShiny(); - bool is_shiny_fixed = facep->getPoolType() == LLDrawPool::POOL_BUMP && !gPipeline.canUseVertexShaders() && te->getShiny(); + bool is_shiny_shader = facep->getPoolType() == LLDrawPool::POOL_BUMP && LLGLSLShader::sNoFixedFunction && te->getShiny(); + bool is_shiny_fixed = facep->getPoolType() == LLDrawPool::POOL_BUMP && !LLGLSLShader::sNoFixedFunction && te->getShiny(); bool is_fullbright = facep->isState(LLFace::FULLBRIGHT); if (facep->getPoolType() == LLDrawPool::POOL_MATERIALS) diff --git a/indra/newview/llwaterparammanager.cpp b/indra/newview/llwaterparammanager.cpp index 6ba6a5ef9..1dd9610a7 100644 --- a/indra/newview/llwaterparammanager.cpp +++ b/indra/newview/llwaterparammanager.cpp @@ -298,7 +298,7 @@ bool LLWaterParamManager::savePresetToNotecard(const std::string & name) void LLWaterParamManager::propagateParameters(void) { // bind the variables only if we're using shaders - if(gPipeline.canUseVertexShaders()) + if(LLGLSLShader::sNoFixedFunction) { std::vector::iterator shaders_iter=mShaderList.begin(); for(; shaders_iter != mShaderList.end(); ++shaders_iter) @@ -387,7 +387,7 @@ void LLWaterParamManager::update(LLViewerCamera * cam) stop_glerror(); // only do this if we're dealing with shaders - if(gPipeline.canUseVertexShaders()) + if(LLGLSLShader::sNoFixedFunction) { //transform water plane to eye space LLVector4a enorm(0.f, 0.f, 1.f); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 3c41658b9..f58a7faf7 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -212,7 +212,6 @@ static LLFastTimer::DeclareTimer FTM_STATESORT_POSTSORT("Post Sort"); //static LLStaticHashedString sAlphaScale("alpha_scale"); static LLStaticHashedString sNormMat("norm_mat"); //static LLStaticHashedString sOffset("offset"); -static LLStaticHashedString sScreenRes("screenRes"); static LLStaticHashedString sDelta("delta"); static LLStaticHashedString sDistFactor("dist_factor"); static LLStaticHashedString sKern("kern"); @@ -309,7 +308,6 @@ S32 LLPipeline::sUseOcclusion = 0; BOOL LLPipeline::sDelayVBUpdate = FALSE; BOOL LLPipeline::sAutoMaskAlphaDeferred = TRUE; BOOL LLPipeline::sAutoMaskAlphaNonDeferred = FALSE; -BOOL LLPipeline::sDisableShaders = FALSE; BOOL LLPipeline::sRenderBump = TRUE; BOOL LLPipeline::sNoAlpha = FALSE; BOOL LLPipeline::sUseFarClip = TRUE; @@ -364,10 +362,7 @@ LLPipeline::LLPipeline() : mMeanBatchSize(0), mTrianglesDrawn(0), mNumVisibleNodes(0), - mInitialized(FALSE), - mVertexShadersEnabled(FALSE), - mVertexShadersLoaded(0), mTransformFeedbackPrimitives(0), mRenderDebugFeatureMask(0), mRenderDebugMask(0), @@ -405,9 +400,6 @@ void LLPipeline::init() { refreshCachedSettings(); - bool can_defer = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred"); - LLRenderTarget::sUseFBO = gSavedSettings.getBOOL("RenderUseFBO") || (gSavedSettings.getBOOL("RenderDeferred") && can_defer); - gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity"); gOctreeReserveCapacity = llmin(gSavedSettings.getU32("OctreeReserveNodeCapacity"),U32(512)); sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD"); @@ -494,11 +486,11 @@ void LLPipeline::init() gSavedSettings.getControl("RenderAvatarMaxVisible")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); //gSavedSettings.getControl("RenderDelayVBUpdate")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); gSavedSettings.getControl("UseOcclusion")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("VertexShaderEnable")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderDeferred")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + //gSavedSettings.getControl("VertexShaderEnable")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); //Already registered to handleSetShaderChanged + //gSavedSettings.getControl("RenderDeferred")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); //Already registered to handleSetShaderChanged gSavedSettings.getControl("RenderFSAASamples")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("RenderAvatarVP")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); - gSavedSettings.getControl("WindLightUseAtmosShaders")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + //gSavedSettings.getControl("RenderAvatarVP")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); //Already registered to handleSetShaderChanged + //gSavedSettings.getControl("WindLightUseAtmosShaders")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); //Already registered to handleSetShaderChanged } LLPipeline::~LLPipeline() @@ -635,7 +627,7 @@ void LLPipeline::throttleNewMemoryAllocation(BOOL disable) void LLPipeline::resizeScreenTexture() { LLFastTimer ft(FTM_RESIZE_SCREEN_TEXTURE); - if (gPipeline.canUseVertexShaders() && assertInitialized()) + if (LLGLSLShader::sNoFixedFunction && assertInitialized()) { GLuint resX = gViewerWindow->getWorldViewWidthRaw(); GLuint resY = gViewerWindow->getWorldViewHeightRaw(); @@ -937,25 +929,28 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) return true; } -//static -void LLPipeline::updateRenderDeferred() +bool LLPipeline::isRenderDeferredCapable() { - sRenderDeferred = (gSavedSettings.getBOOL("RenderDeferred") && - LLRenderTarget::sUseFBO && + return gGLManager.mHasFramebufferObject && LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && - gSavedSettings.getBOOL("RenderObjectBump") && - gSavedSettings.getBOOL("VertexShaderEnable") && - gSavedSettings.getBOOL("RenderAvatarVP") && - gSavedSettings.getBOOL("WindLightUseAtmosShaders") && - !gUseWireframe); - if (sRenderDeferred) - { //must render glow when rendering deferred since post effect pass is needed to present any lighting at all - sRenderGlow = TRUE; - } + LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarVP") && //Hardware Skinning. Deferred forces RenderAvatarVP to true + LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable") && //Basic Shaders + LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders") && //Atmospheric Shaders + LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable"); } + +bool LLPipeline::isRenderDeferredDesired() +{ + return isRenderDeferredCapable() && + gSavedSettings.getBOOL("RenderDeferred") && + gSavedSettings.getBOOL("VertexShaderEnable") && + gSavedSettings.getBOOL("WindLightUseAtmosShaders"); +} + //static void LLPipeline::refreshCachedSettings() { + LLRenderTarget::sUseFBO = gSavedSettings.getBOOL("RenderUseFBO") || LLPipeline::sRenderDeferred; LLPipeline::sAutoMaskAlphaDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaDeferred"); LLPipeline::sAutoMaskAlphaNonDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaNonDeferred"); LLPipeline::sUseFarClip = gSavedSettings.getBOOL("RenderUseFarClip"); @@ -968,8 +963,6 @@ void LLPipeline::refreshCachedSettings() && LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") && gSavedSettings.getBOOL("UseOcclusion") && gGLManager.mHasOcclusionQuery) ? 2 : 0; - - updateRenderDeferred(); } void LLPipeline::releaseGLBuffers() @@ -1044,8 +1037,6 @@ void LLPipeline::createGLBuffers() stop_glerror(); assertInitialized(); - updateRenderDeferred(); - bool materials_in_water = false; #if MATERIALS_IN_REFLECTIONS @@ -1215,7 +1206,7 @@ void LLPipeline::restoreGL() { assertInitialized(); - if (mVertexShadersEnabled) + if (LLGLSLShader::sNoFixedFunction) { LLViewerShaderMgr::instance()->setShaders(); } @@ -1237,29 +1228,9 @@ void LLPipeline::restoreGL() resetLocalLights(); //Default all gl light parameters. Fixes light brightness problems on fullscren toggle } - -BOOL LLPipeline::canUseVertexShaders() -{ - static const std::string vertex_shader_enable_feature_string = "VertexShaderEnable"; - - if (sDisableShaders || - !gGLManager.mHasVertexShader || - !gGLManager.mHasFragmentShader || - !LLFeatureManager::getInstance()->isFeatureAvailable(vertex_shader_enable_feature_string) || - (assertInitialized() && mVertexShadersLoaded != 1) ) - { - return FALSE; - } - else - { - return TRUE; - } -} - BOOL LLPipeline::canUseWindLightShaders() const { - return (!LLPipeline::sDisableShaders && - gWLSkyProgram.mProgramObject != 0 && + return (gWLSkyProgram.mProgramObject != 0 && LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1); } @@ -1277,8 +1248,6 @@ BOOL LLPipeline::canUseAntiAliasing() const void LLPipeline::unloadShaders() { LLViewerShaderMgr::instance()->unloadShaders(); - - mVertexShadersLoaded = 0; } void LLPipeline::assertInitializedDoError() @@ -1322,7 +1291,7 @@ S32 LLPipeline::setLightingDetail(S32 level) } level = llclamp(level, 0, getMaxLightingDetail()); //Bugfix: If setshaders was called with RenderLocalLights off then enabling RenderLocalLights later will not work. Reloading shaders fixes this. - if (level != mLightingDetail && mVertexShadersLoaded) + if (level != mLightingDetail && LLGLSLShader::sNoFixedFunction) { LLViewerShaderMgr::instance()->setShaders(); } @@ -2291,7 +2260,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl BOOL to_texture = LLPipeline::sUseOcclusion > 1 && !hasRenderType(LLPipeline::RENDER_TYPE_HUD) && LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && - gPipeline.canUseVertexShaders() && + LLGLSLShader::sNoFixedFunction && sRenderGlow; if (to_texture) @@ -2359,7 +2328,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl LLGLDepthTest depth(GL_TRUE, GL_FALSE); bool bound_shader = false; - if (gPipeline.canUseVertexShaders() && LLGLSLShader::sCurBoundShader == 0) + if (LLGLSLShader::sNoFixedFunction && LLGLSLShader::sCurBoundShader == 0) { //if no shader is currently bound, use the occlusion shader instead of fixed function if we can // (shadow render uses a special shader that clamps to clip planes) bound_shader = true; @@ -6783,7 +6752,7 @@ void LLPipeline::doResetVertexBuffers() sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("ShyotlRenderUseStreamVBO"); - LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO") && gPipeline.canUseVertexShaders(); //Temporary workaround for vaos being broken when shaders are off + LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO") && LLGLSLShader::sNoFixedFunction; //Temporary workaround for vaos being broken when shaders are off LLVertexBuffer::sPreferStreamDraw = gSavedSettings.getBOOL("RenderPreferStreamDraw"); LLVertexBuffer::sEnableVBOs = gSavedSettings.getBOOL("RenderVBOEnable"); LLVertexBuffer::sDisableVBOMapping = LLVertexBuffer::sEnableVBOs;// && gSavedSettings.getBOOL("RenderVBOMappingDisable") ; //Temporary workaround for vbo mapping being straight up broken @@ -6893,7 +6862,7 @@ void LLPipeline::bindScreenToTexture() static LLFastTimer::DeclareTimer FTM_RENDER_BLOOM("Bloom"); void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, bool tiling) { - if (!(gPipeline.canUseVertexShaders() && + if (!(LLGLSLShader::sNoFixedFunction && sRenderGlow)) { return; diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 589c2a3e4..1c2d13baf 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -236,9 +236,6 @@ public: S32 getLightingDetail() const { return mLightingDetail; } S32 getMaxLightingDetail() const; - void setUseVertexShaders(BOOL use_shaders); - BOOL getUseVertexShaders() const { return mVertexShadersEnabled; } - BOOL canUseVertexShaders(); BOOL canUseWindLightShaders() const; BOOL canUseWindLightShadersOnObjects() const; BOOL canUseAntiAliasing() const; @@ -412,7 +409,8 @@ public: static BOOL getRenderHighlights(void* data); static void setRenderHighlightTextureChannel(LLRender::eTexIndex channel); // sets which UV setup to display in highlight overlay - static void updateRenderDeferred(); + static bool isRenderDeferredCapable(); + static bool isRenderDeferredDesired(); static void refreshCachedSettings(); static void throttleNewMemoryAllocation(BOOL disable); @@ -567,7 +565,6 @@ public: static BOOL sDelayVBUpdate; static BOOL sAutoMaskAlphaDeferred; static BOOL sAutoMaskAlphaNonDeferred; - static BOOL sDisableShaders; // if TRUE, rendering will be done without shaders static BOOL sRenderBump; static BOOL sNoAlpha; static BOOL sUseFarClip; @@ -657,7 +654,6 @@ private: public: BOOL mInitialized; BOOL mVertexShadersEnabled; - S32 mVertexShadersLoaded; // 0 = no, 1 = yes, -1 = failed U32 mTransformFeedbackPrimitives; //number of primitives expected to be generated by transform feedback private: