summaryrefslogtreecommitdiff
path: root/indra/llrender/llglslshader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llrender/llglslshader.cpp')
-rw-r--r--[-rwxr-xr-x]indra/llrender/llglslshader.cpp159
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);