Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • alchemy/viewer
  • Miezhiko/alchemy-next
  • JennaHuntsman/xdg-integration
  • logue/alchemy-next
  • FelixWolf/alchemy-viewer
  • XenHat/xdg-integration
6 results
Show changes
Commits on Source (2)
......@@ -447,29 +447,6 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
return createShader(attributes,uniforms);
}
}
else if (mFeatures.mIndexedTextureChannels > 0)
{ //override texture channels for indexed texture rendering
bind();
S32 channel_count = mFeatures.mIndexedTextureChannels;
for (S32 i = 0; i < channel_count; i++)
{
LLStaticHashedString uniName(llformat("tex%d", i));
uniform1i(uniName, i);
}
S32 cur_tex = channel_count; //adjust any texture channels that might have been overwritten
for (U32 i = 0; i < mTexture.size(); i++)
{
if (mTexture[i] > -1 && mTexture[i] < channel_count)
{
llassert(cur_tex < gGLManager.mNumTextureImageUnits);
uniform1i(i, cur_tex);
mTexture[i] = cur_tex++;
}
}
unbind();
}
return success;
}
......@@ -588,25 +565,14 @@ BOOL LLGLSLShader::mapAttributes(const std::vector<LLStaticHashedString> * attri
return FALSE;
}
void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString> * uniforms)
void LLGLSLShader::mapUniform(const gl_uniform_data_t& gl_uniform, const std::vector<LLStaticHashedString> * uniforms)
{
if (index == -1)
{
return;
}
GLenum type;
GLsizei length;
GLint size = -1;
char name[1024]; /* Flawfinder: ignore */
name[0] = 0;
glGetActiveUniform(mProgramObject, index, 1024, &length, &size, &type, (GLchar *)name);
char* name = (char*)gl_uniform.name.c_str(); //blegh
#if !LL_DARWIN
GLint size = gl_uniform.size;
if (size > 0)
{
switch(type)
switch(gl_uniform.type)
{
case GL_FLOAT_VEC2: size *= 2; break;
case GL_FLOAT_VEC3: size *= 3; break;
......@@ -664,29 +630,39 @@ void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString> *
LL_DEBUGS("ShaderUniform") << "Uniform " << name << " is at location " << location << LL_ENDL;
// Indexed textures are referenced by hardcoded tex unit index. This is where that mapping happens.
if (gl_uniform.texunit_priority < (U32)mFeatures.mIndexedTextureChannels)
{
// mUniform and mTexture are irrelivant for indexed textures, since there's no enum to look them up through.
// Thus, only call mapUniformTextureChannel to create the texunit => uniform location mapping in opengl.
mapUniformTextureChannel(location, gl_uniform.type);
return;
}
//find the index of this uniform
for (S32 i = 0; i < (S32) LLShaderMgr::instance()->mReservedUniforms.size(); i++)
for (U32 i = 0; i < LLShaderMgr::instance()->mReservedUniforms.size(); i++)
{
if ( (mUniform[i] == -1)
&& (LLShaderMgr::instance()->mReservedUniforms[i] == name))
{
//found it
mUniform[i] = location;
mTexture[i] = mapUniformTextureChannel(location, type);
mTexture[i] = mapUniformTextureChannel(location, gl_uniform.type);
return;
}
}
if (uniforms != NULL)
{
for (U32 i = 0; i < uniforms->size(); i++)
U32 j = LLShaderMgr::instance()->mReservedUniforms.size();
for (U32 i = 0; i < uniforms->size(); i++, j++)
{
if ( (mUniform[i+LLShaderMgr::instance()->mReservedUniforms.size()] == -1)
if ( (mUniform[j] == -1)
&& ((*uniforms)[i].String() == name))
{
//found it
mUniform[i+LLShaderMgr::instance()->mReservedUniforms.size()] = location;
mTexture[i+LLShaderMgr::instance()->mReservedUniforms.size()] = mapUniformTextureChannel(location, type);
mUniform[j] = location;
mTexture[j] = mapUniformTextureChannel(location, gl_uniform.type);
return;
}
}
......@@ -715,7 +691,7 @@ GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type)
type == GL_SAMPLER_2D_MULTISAMPLE)
{ //this here is a texture
glUniform1i(location, mActiveTextureChannels);
LL_DEBUGS("ShaderUniform") << "Assigned to texture channel " << mActiveTextureChannels << LL_ENDL;
LL_DEBUGS("ShaderUniform") << "Assigned " << mUniformNameMap[location] << " to texture channel " << mActiveTextureChannels << " in shader " << mName << LL_ENDL;
return mActiveTextureChannels++;
}
return -1;
......@@ -725,6 +701,8 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
{
BOOL res = TRUE;
const auto& reservedUniforms = LLShaderMgr::instance()->mReservedUniforms;
mTotalUniformSize = 0;
mActiveTextureChannels = 0;
mUniform.clear();
......@@ -734,8 +712,8 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
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);
mUniform.resize(numUniforms + reservedUniforms.size(), -1);
mTexture.resize(numUniforms + reservedUniforms.size(), -1);
bind();
......@@ -743,119 +721,63 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
GLint activeCount;
glGetProgramiv(mProgramObject, GL_ACTIVE_UNIFORMS, &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, MAINT-6437
*/
S32 diffuseMap = glGetUniformLocation(mProgramObject, "diffuseMap");
S32 specularMap = glGetUniformLocation(mProgramObject, "specularMap");
S32 bumpMap = glGetUniformLocation(mProgramObject, "bumpMap");
S32 altDiffuseMap = glGetUniformLocation(mProgramObject, "altDiffuseMap");
S32 environmentMap = glGetUniformLocation(mProgramObject, "environmentMap");
std::set<S32> skip_index;
if (-1 != diffuseMap && (-1 != specularMap || -1 != bumpMap || -1 != environmentMap || -1 != altDiffuseMap))
std::vector< gl_uniform_data_t > gl_uniforms;
bool has_diffuse = false;
U32 max_index = mFeatures.mIndexedTextureChannels;
// Gather active uniforms.
for (S32 i = 0; i < activeCount; i++)
{
GLenum type;
GLsizei length;
GLint size = -1;
// Fetch name and size from opengl
char name[1024];
diffuseMap = altDiffuseMap = specularMap = bumpMap = environmentMap = -1;
for (S32 i = 0; i < activeCount; i++)
gl_uniform_data_t gl_uniform;
GLsizei length;
glGetActiveUniform(mProgramObject, i, 1024, &length, &gl_uniform.size, &gl_uniform.type, (GLcharARB *)name);
if (length && name[length - 1] == '\0')
{
name[0] = '\0';
glGetActiveUniform(mProgramObject, i, 1024, &length, &size, &type, (GLchar *)name);
if (-1 == diffuseMap && std::string(name) == "diffuseMap")
{
diffuseMap = i;
continue;
}
if (-1 == specularMap && std::string(name) == "specularMap")
{
specularMap = i;
continue;
}
if (-1 == bumpMap && std::string(name) == "bumpMap")
{
bumpMap = i;
continue;
}
if (-1 == environmentMap && std::string(name) == "environmentMap")
{
environmentMap = i;
continue;
}
if (-1 == altDiffuseMap && std::string(name) == "altDiffuseMap")
{
altDiffuseMap = i;
continue;
}
--length; // Some drivers can't be trusted...
}
if (gl_uniform.size < 0 || length <= 0)
continue;
gl_uniform.name = std::string(name, length);
bool specularDiff = specularMap < diffuseMap && -1 != specularMap;
bool bumpLessDiff = bumpMap < diffuseMap && -1 != bumpMap;
bool envLessDiff = environmentMap < diffuseMap && -1 != environmentMap;
if (specularDiff || bumpLessDiff || envLessDiff)
{
mapUniform(diffuseMap, uniforms);
skip_index.insert(diffuseMap);
if (-1 != specularMap) {
mapUniform(specularMap, uniforms);
skip_index.insert(specularMap);
}
// Track if diffuseMap uniform was detected. If so, flag as such to assert indexed textures aren't also used in this shader.
has_diffuse |= gl_uniform.name == "diffuseMap";
if (-1 != bumpMap) {
mapUniform(bumpMap, uniforms);
skip_index.insert(bumpMap);
}
// Use mReservedUniforms to calculate texunit ordering. Reserve priority [0,max_index) for indexed textures if applicable.
auto it = std::find(reservedUniforms.cbegin(), reservedUniforms.cend(), gl_uniform.name);
gl_uniform.texunit_priority = it != reservedUniforms.cend() ? max_index + std::distance(reservedUniforms.cbegin(), it) : UINT_MAX;
if (-1 != environmentMap) {
mapUniform(environmentMap, uniforms);
skip_index.insert(environmentMap);
// Indexed texture uniforms must ALWAYS have highest texunit priority. Ensures [texunit[0],texunit[max_index]) map to [tex[0],tex[max_index]) uniforms.
// Note that this logic will break if a tex# index is skipped over in the shader.
if (gl_uniform.texunit_priority == UINT_MAX)
{
S32 idx;
if (sscanf(gl_uniform.name.c_str(), "tex%d", &idx) && idx < (S32)max_index)
{
gl_uniform.texunit_priority = idx;
}
}
gl_uniforms.push_back(gl_uniform);
}
//........................................................................................
// Sort uniforms by texunit_priority
std::sort(gl_uniforms.begin(), gl_uniforms.end(), [](gl_uniform_data_t& lhs, gl_uniform_data_t& rhs)
{
return lhs.texunit_priority < rhs.texunit_priority;
});
for (S32 i = 0; i < activeCount; i++)
// Sanity check
if (!gl_uniforms.empty() && gl_uniforms[0].name == "tex0")
{
//........................................................................................
if (skip_index.end() != skip_index.find(i)) continue;
//........................................................................................
llassert_always_msg(!has_diffuse, "Indexed textures and diffuseMap are incompatible!");
}
mapUniform(i, uniforms);
for (auto& gl_uniform : gl_uniforms)
{
mapUniform(gl_uniform, uniforms);
}
//........................................................................................................................................
unbind();
......
......@@ -76,6 +76,13 @@ class LLGLSLShader
SG_SKY,
SG_WATER
};
struct gl_uniform_data_t {
std::string name;
GLenum type = (GLenum)-1;
GLint size = -1;
U32 texunit_priority = UINT_MAX; // Lower gets earlier texunits indices.
};
static std::set<LLGLSLShader*> sInstances;
static bool sProfileEnabled;
......@@ -110,7 +117,7 @@ class LLGLSLShader
void attachObjects(GLuint* objects = NULL, S32 count = 0);
BOOL mapAttributes(const std::vector<LLStaticHashedString> * attributes);
BOOL mapUniforms(const std::vector<LLStaticHashedString> *);
void mapUniform(GLint index, const std::vector<LLStaticHashedString> *);
void mapUniform(const gl_uniform_data_t& gl_uniform, const std::vector<LLStaticHashedString> *);
void uniform1i(U32 index, GLint i);
void uniform1f(U32 index, GLfloat v);
void uniform2f(U32 index, GLfloat x, GLfloat y);
......
......@@ -354,6 +354,7 @@ void LLDrawPoolTerrain::renderFullShader()
((LLSettingsVOWater*)pwater.get())->updateShader(shader);
// TERRAIN TEXTURE COORDS 0:
gGL.matrixMode(LLRender::MM_TEXTURE);
gGL.loadIdentity();
gGL.matrixMode(LLRender::MM_MODELVIEW);
......@@ -366,7 +367,7 @@ void LLDrawPoolTerrain::renderFullShader()
gGL.getTexUnit(detail1)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
gGL.getTexUnit(detail1)->activate();
/// ALPHA TEXTURE COORDS 0:
// TERRAIN TEXTURE COORDS 1:
gGL.matrixMode(LLRender::MM_TEXTURE);
gGL.loadIdentity();
gGL.matrixMode(LLRender::MM_MODELVIEW);
......@@ -377,8 +378,8 @@ void LLDrawPoolTerrain::renderFullShader()
gGL.getTexUnit(detail2)->bind(detail_texture2p);
gGL.getTexUnit(detail2)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
gGL.getTexUnit(detail2)->activate();
/// ALPHA TEXTURE COORDS 1:
// TERRAIN TEXTURE COORDS 2:
gGL.matrixMode(LLRender::MM_TEXTURE);
gGL.loadIdentity();
gGL.translatef(-2.f, 0.f, 0.f);
......@@ -391,7 +392,7 @@ void LLDrawPoolTerrain::renderFullShader()
gGL.getTexUnit(detail3)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
gGL.getTexUnit(detail3)->activate();
/// ALPHA TEXTURE COORDS 2:
// TERRAIN TEXTURE COORDS 3:
gGL.matrixMode(LLRender::MM_TEXTURE);
gGL.loadIdentity();
gGL.translatef(-1.f, 0.f, 0.f);
......