diff options
Diffstat (limited to 'indra/llrender/llglslshader.cpp')
-rw-r--r--[-rwxr-xr-x] | indra/llrender/llglslshader.cpp | 159 |
1 files changed, 130 insertions, 29 deletions
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 3ceed95248..0f260674ed 100755..100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -702,37 +702,138 @@ GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type) BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms) { - BOOL res = TRUE; - - mTotalUniformSize = 0; - mActiveTextureChannels = 0; - mUniform.clear(); - mUniformMap.clear(); - mUniformNameMap.clear(); - mTexture.clear(); - mValue.clear(); - //initialize arrays - U32 numUniforms = (uniforms == NULL) ? 0 : uniforms->size(); - mUniform.resize(numUniforms + LLShaderMgr::instance()->mReservedUniforms.size(), -1); - mTexture.resize(numUniforms + LLShaderMgr::instance()->mReservedUniforms.size(), -1); - - bind(); - - //get the number of active uniforms - GLint activeCount; - glGetObjectParameterivARB(mProgramObject, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &activeCount); - - for (S32 i = 0; i < activeCount; i++) - { - mapUniform(i, uniforms); - } - - unbind(); - - LL_DEBUGS("ShaderLoading") << "Total Uniform Size: " << mTotalUniformSize << LL_ENDL; - return res; + BOOL res = TRUE; + + mTotalUniformSize = 0; + mActiveTextureChannels = 0; + mUniform.clear(); + mUniformMap.clear(); + mUniformNameMap.clear(); + mTexture.clear(); + mValue.clear(); + //initialize arrays + U32 numUniforms = (uniforms == NULL) ? 0 : uniforms->size(); + mUniform.resize(numUniforms + LLShaderMgr::instance()->mReservedUniforms.size(), -1); + mTexture.resize(numUniforms + LLShaderMgr::instance()->mReservedUniforms.size(), -1); + + bind(); + + //get the number of active uniforms + GLint activeCount; + glGetObjectParameterivARB(mProgramObject, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &activeCount); + + //........................................................................................................................................ + //........................................................................................ + + /* + EXPLANATION: + This is part of code is temporary because as the final result the mapUniform() should be rewrited. + But it's a huge a volume of work which is need to be a more carefully performed for avoid possible + regression's (i.e. it should be formalized a separate ticket in JIRA). + + RESON: + The reason of this code is that SL engine is very sensitive to fact that "diffuseMap" should be appear + first as uniform parameter which is should get 0-"texture channel" index (see mapUniformTextureChannel() and mActiveTextureChannels) + it influence to which is texture matrix will be updated during rendering. + + But, order of indexe's of uniform variables is not defined and GLSL compiler can change it as want + , even if the "diffuseMap" will be appear and use first in shader code. + + As example where this situation appear see: "Deferred Material Shader 28/29/30/31" + And tickets: MAINT-4165, MAINT-4839, MAINT-3568 + */ + + + S32 diffuseMap = glGetUniformLocationARB(mProgramObject, "diffuseMap"); + S32 bumpMap = glGetUniformLocationARB(mProgramObject, "bumpMap"); + S32 environmentMap = glGetUniformLocationARB(mProgramObject, "environmentMap"); + + std::set<S32> skip_index; + + if (-1 != diffuseMap && (-1 != bumpMap || -1 != environmentMap)) + { + GLenum type; + GLsizei length; + GLint size = -1; + char name[1024]; + + diffuseMap = bumpMap = environmentMap = -1; + + for (S32 i = 0; i < activeCount; i++) + { + name[0] = '\0'; + + glGetActiveUniformARB(mProgramObject, i, 1024, &length, &size, &type, (GLcharARB *)name); + + if (-1 == diffuseMap && std::string(name) == "diffuseMap") + { + diffuseMap = i; + continue; + } + + if (-1 == bumpMap && std::string(name) == "bumpMap") + { + bumpMap = i; + continue; + } + + if (-1 == environmentMap && std::string(name) == "environmentMap") + { + environmentMap = i; + continue; + } + } + + bool bumpLessDiff = bumpMap < diffuseMap && -1 != bumpMap; + bool envLessDiff = environmentMap < diffuseMap && -1 != environmentMap; + + if (bumpLessDiff && envLessDiff) + { + mapUniform(diffuseMap, uniforms); + mapUniform(bumpMap, uniforms); + mapUniform(environmentMap, uniforms); + + skip_index.insert(diffuseMap); + skip_index.insert(bumpMap); + skip_index.insert(environmentMap); + } + else if (bumpLessDiff) + { + mapUniform(diffuseMap, uniforms); + mapUniform(bumpMap, uniforms); + + skip_index.insert(diffuseMap); + skip_index.insert(bumpMap); + } + else if (envLessDiff) + { + mapUniform(diffuseMap, uniforms); + mapUniform(environmentMap, uniforms); + + skip_index.insert(diffuseMap); + skip_index.insert(environmentMap); + } + } + + //........................................................................................ + + for (S32 i = 0; i < activeCount; i++) + { + //........................................................................................ + if (skip_index.end() != skip_index.find(i)) continue; + //........................................................................................ + + mapUniform(i, uniforms); + } + //........................................................................................................................................ + + unbind(); + + LL_DEBUGS("ShaderLoading") << "Total Uniform Size: " << mTotalUniformSize << LL_ENDL; + return res; } + BOOL LLGLSLShader::link(BOOL suppress_errors) { BOOL success = LLShaderMgr::instance()->linkProgramObject(mProgramObject, suppress_errors); |