summaryrefslogtreecommitdiff
path: root/indra/llrender/llglslshader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llrender/llglslshader.cpp')
-rw-r--r--indra/llrender/llglslshader.cpp1294
1 files changed, 783 insertions, 511 deletions
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index da24d999b0..ccfb8f69be 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llglslshader.cpp
* @brief GLSL helper functions and state.
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -32,13 +32,17 @@
#include "llfile.h"
#include "llrender.h"
#include "llvertexbuffer.h"
+#include "llrendertarget.h"
+
+#include "hbxxh.h"
+#include "llsdserialize.h"
#if LL_DARWIN
#include "OpenGL/OpenGL.h"
#endif
-// Print-print list of shader included source files that are linked together via glAttachObjectARB()
-// i.e. On macOS / OSX the AMD GLSL linker will display an error if a varying is left in an undefined state.
+ // Print-print list of shader included source files that are linked together via glAttachShader()
+ // i.e. On macOS / OSX the AMD GLSL linker will display an error if a varying is left in an undefined state.
#define DEBUG_SHADER_INCLUDES 0
// Lots of STL stuff in here, using namespace std to keep things more readable
@@ -47,51 +51,39 @@ using std::pair;
using std::make_pair;
using std::string;
-GLhandleARB LLGLSLShader::sCurBoundShader = 0;
+GLuint LLGLSLShader::sCurBoundShader = 0;
LLGLSLShader* LLGLSLShader::sCurBoundShaderPtr = NULL;
S32 LLGLSLShader::sIndexedTextureChannels = 0;
bool LLGLSLShader::sProfileEnabled = false;
std::set<LLGLSLShader*> LLGLSLShader::sInstances;
+LLGLSLShader::defines_map_t LLGLSLShader::sGlobalDefines;
U64 LLGLSLShader::sTotalTimeElapsed = 0;
U32 LLGLSLShader::sTotalTrianglesDrawn = 0;
U64 LLGLSLShader::sTotalSamplesDrawn = 0;
-U32 LLGLSLShader::sTotalDrawCalls = 0;
+U32 LLGLSLShader::sTotalBinds = 0;
//UI shader -- declared here so llui_libtest will link properly
LLGLSLShader gUIProgram;
LLGLSLShader gSolidColorProgram;
-BOOL shouldChange(const LLVector4& v1, const LLVector4& v2)
+// NOTE: Keep gShaderConsts* and LLGLSLShader::ShaderConsts_e in sync!
+const std::string gShaderConstsKey[LLGLSLShader::NUM_SHADER_CONSTS] =
{
- return v1 != v2;
-}
+ "LL_SHADER_CONST_CLOUD_MOON_DEPTH"
+ , "LL_SHADER_CONST_STAR_DEPTH"
+};
-LLShaderFeatures::LLShaderFeatures()
- : atmosphericHelpers(false)
- , calculatesLighting(false)
- , calculatesAtmospherics(false)
- , hasLighting(false)
- , isAlphaLighting(false)
- , isShiny(false)
- , isFullbright(false)
- , isSpecular(false)
- , hasWaterFog(false)
- , hasTransport(false)
- , hasSkinning(false)
- , hasObjectSkinning(false)
- , hasAtmospherics(false)
- , hasGamma(false)
- , hasSrgb(false)
- , encodesNormal(false)
- , isDeferred(false)
- , hasIndirect(false)
- , hasShadows(false)
- , hasAmbientOcclusion(false)
- , mIndexedTextureChannels(0)
- , disableTextureIndex(false)
- , hasAlphaMask(false)
- , attachNothing(false)
+// NOTE: Keep gShaderConsts* and LLGLSLShader::ShaderConsts_e in sync!
+const std::string gShaderConstsVal[LLGLSLShader::NUM_SHADER_CONSTS] =
{
+ "0.99998" // SHADER_CONST_CLOUD_MOON_DEPTH // SL-14113
+ , "0.99999" // SHADER_CONST_STAR_DEPTH // SL-14113
+};
+
+
+BOOL shouldChange(const LLVector4& v1, const LLVector4& v2)
+{
+ return v1 != v2;
}
//===============================
@@ -105,7 +97,7 @@ void LLGLSLShader::initProfile()
sTotalTimeElapsed = 0;
sTotalTrianglesDrawn = 0;
sTotalSamplesDrawn = 0;
- sTotalDrawCalls = 0;
+ sTotalBinds = 0;
for (std::set<LLGLSLShader*>::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter)
{
@@ -116,10 +108,10 @@ void LLGLSLShader::initProfile()
struct LLGLSLShaderCompareTimeElapsed
{
- bool operator()(const LLGLSLShader* const& lhs, const LLGLSLShader* const& rhs)
- {
- return lhs->mTimeElapsed < rhs->mTimeElapsed;
- }
+ bool operator()(const LLGLSLShader* const& lhs, const LLGLSLShader* const& rhs)
+ {
+ return lhs->mTimeElapsed < rhs->mTimeElapsed;
+ }
};
//static
@@ -138,15 +130,33 @@ void LLGLSLShader::finishProfile(bool emit_report)
std::sort(sorted.begin(), sorted.end(), LLGLSLShaderCompareTimeElapsed());
+ bool unbound = false;
for (std::vector<LLGLSLShader*>::iterator iter = sorted.begin(); iter != sorted.end(); ++iter)
{
(*iter)->dumpStats();
+ if ((*iter)->mBinds == 0)
+ {
+ unbound = true;
+ }
+ }
+
+ LL_INFOS() << "-----------------------------------" << LL_ENDL;
+ LL_INFOS() << "Total rendering time: " << llformat("%.4f ms", sTotalTimeElapsed / 1000000.f) << LL_ENDL;
+ LL_INFOS() << "Total samples drawn: " << llformat("%.4f million", sTotalSamplesDrawn / 1000000.f) << LL_ENDL;
+ LL_INFOS() << "Total triangles drawn: " << llformat("%.3f million", sTotalTrianglesDrawn / 1000000.f) << LL_ENDL;
+ LL_INFOS() << "-----------------------------------" << LL_ENDL;
+
+ if (unbound)
+ {
+ LL_INFOS() << "The following shaders were unused: " << LL_ENDL;
+ for (std::vector<LLGLSLShader*>::iterator iter = sorted.begin(); iter != sorted.end(); ++iter)
+ {
+ if ((*iter)->mBinds == 0)
+ {
+ LL_INFOS() << (*iter)->mName << LL_ENDL;
+ }
+ }
}
-
- LL_INFOS() << "-----------------------------------" << LL_ENDL;
- LL_INFOS() << "Total rendering time: " << llformat("%.4f ms", sTotalTimeElapsed/1000000.f) << LL_ENDL;
- LL_INFOS() << "Total samples drawn: " << llformat("%.4f million", sTotalSamplesDrawn/1000000.f) << LL_ENDL;
- LL_INFOS() << "Total triangles drawn: " << llformat("%.3f million", sTotalTrianglesDrawn/1000000.f) << LL_ENDL;
}
}
@@ -155,15 +165,12 @@ void LLGLSLShader::clearStats()
mTrianglesDrawn = 0;
mTimeElapsed = 0;
mSamplesDrawn = 0;
- mDrawCalls = 0;
- mTextureStateFetched = false;
- mTextureMagFilter.clear();
- mTextureMinFilter.clear();
+ mBinds = 0;
}
void LLGLSLShader::dumpStats()
{
- if (mDrawCalls > 0)
+ if (mBinds > 0)
{
LL_INFOS() << "=============================================" << LL_ENDL;
LL_INFOS() << mName << LL_ENDL;
@@ -171,36 +178,25 @@ void LLGLSLShader::dumpStats()
{
LL_INFOS() << mShaderFiles[i].first << LL_ENDL;
}
- for (U32 i = 0; i < mTexture.size(); ++i)
- {
- GLint idx = mTexture[i];
-
- if (idx >= 0)
- {
- GLint uniform_idx = getUniformLocation(i);
- LL_INFOS() << mUniformNameMap[uniform_idx] << " - " << std::hex << mTextureMagFilter[i] << "/" << mTextureMinFilter[i] << std::dec << LL_ENDL;
- }
- }
LL_INFOS() << "=============================================" << LL_ENDL;
-
- F32 ms = mTimeElapsed/1000000.f;
- F32 seconds = ms/1000.f;
- F32 pct_tris = (F32) mTrianglesDrawn/(F32)sTotalTrianglesDrawn*100.f;
- F32 tris_sec = (F32) (mTrianglesDrawn/1000000.0);
+ F32 ms = mTimeElapsed / 1000000.f;
+ F32 seconds = ms / 1000.f;
+
+ F32 pct_tris = (F32)mTrianglesDrawn / (F32)sTotalTrianglesDrawn * 100.f;
+ F32 tris_sec = (F32)(mTrianglesDrawn / 1000000.0);
tris_sec /= seconds;
- F32 pct_samples = (F32) ((F64)mSamplesDrawn/(F64)sTotalSamplesDrawn)*100.f;
- F32 samples_sec = (F32) mSamplesDrawn/1000000000.0;
+ F32 pct_samples = (F32)((F64)mSamplesDrawn / (F64)sTotalSamplesDrawn) * 100.f;
+ F32 samples_sec = (F32)mSamplesDrawn / 1000000000.0;
samples_sec /= seconds;
- F32 pct_calls = (F32) mDrawCalls/(F32)sTotalDrawCalls*100.f;
- U32 avg_batch = mTrianglesDrawn/mDrawCalls;
+ F32 pct_binds = (F32)mBinds / (F32)sTotalBinds * 100.f;
- LL_INFOS() << "Triangles Drawn: " << mTrianglesDrawn << " " << llformat("(%.2f pct of total, %.3f million/sec)", pct_tris, tris_sec ) << LL_ENDL;
- LL_INFOS() << "Draw Calls: " << mDrawCalls << " " << llformat("(%.2f pct of total, avg %d tris/call)", pct_calls, avg_batch) << LL_ENDL;
+ LL_INFOS() << "Triangles Drawn: " << mTrianglesDrawn << " " << llformat("(%.2f pct of total, %.3f million/sec)", pct_tris, tris_sec) << LL_ENDL;
+ LL_INFOS() << "Binds: " << mBinds << " " << llformat("(%.2f pct of total)", pct_binds) << LL_ENDL;
LL_INFOS() << "SamplesDrawn: " << mSamplesDrawn << " " << llformat("(%.2f pct of total, %.3f billion/sec)", pct_samples, samples_sec) << LL_ENDL;
- LL_INFOS() << "Time Elapsed: " << mTimeElapsed << " " << llformat("(%.2f pct of total, %.5f ms)\n", (F32) ((F64)mTimeElapsed/(F64)sTotalTimeElapsed)*100.f, ms) << LL_ENDL;
+ LL_INFOS() << "Time Elapsed: " << mTimeElapsed << " " << llformat("(%.2f pct of total, %.5f ms)\n", (F32)((F64)mTimeElapsed / (F64)sTotalTimeElapsed) * 100.f, ms) << LL_ENDL;
}
}
@@ -216,112 +212,109 @@ void LLGLSLShader::startProfile()
}
//static
-void LLGLSLShader::stopProfile(U32 count, U32 mode)
+void LLGLSLShader::stopProfile()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
+
if (sProfileEnabled && sCurBoundShaderPtr)
{
- sCurBoundShaderPtr->readProfileQuery(count, mode);
+ sCurBoundShaderPtr->unbind();
}
}
-void LLGLSLShader::placeProfileQuery()
+void LLGLSLShader::placeProfileQuery(bool for_runtime)
{
-#if !LL_DARWIN
- if (mTimerQuery == 0)
- {
- glGenQueriesARB(1, &mSamplesQuery);
- glGenQueriesARB(1, &mTimerQuery);
- }
-
- if (!mTextureStateFetched)
+ if (sProfileEnabled || for_runtime)
{
- mTextureStateFetched = true;
- mTextureMagFilter.resize(mTexture.size());
- mTextureMinFilter.resize(mTexture.size());
+ if (mTimerQuery == 0)
+ {
+ glGenQueries(1, &mSamplesQuery);
+ glGenQueries(1, &mTimerQuery);
+ glGenQueries(1, &mPrimitivesQuery);
+ }
- U32 cur_active = gGL.getCurrentTexUnitIndex();
+ glBeginQuery(GL_TIME_ELAPSED, mTimerQuery);
- for (U32 i = 0; i < mTexture.size(); ++i)
+ if (!for_runtime)
{
- GLint idx = mTexture[i];
+ glBeginQuery(GL_SAMPLES_PASSED, mSamplesQuery);
+ glBeginQuery(GL_PRIMITIVES_GENERATED, mPrimitivesQuery);
+ }
+ }
+}
- if (idx >= 0)
+bool LLGLSLShader::readProfileQuery(bool for_runtime, bool force_read)
+{
+ if (sProfileEnabled || for_runtime)
+ {
+ if (!mProfilePending)
+ {
+ glEndQuery(GL_TIME_ELAPSED);
+ if (!for_runtime)
{
- gGL.getTexUnit(idx)->activate();
-
- U32 mag = 0xFFFFFFFF;
- U32 min = 0xFFFFFFFF;
-
- U32 type = LLTexUnit::getInternalType(gGL.getTexUnit(idx)->getCurrType());
+ glEndQuery(GL_SAMPLES_PASSED);
+ glEndQuery(GL_PRIMITIVES_GENERATED);
+ }
+ mProfilePending = for_runtime;
+ }
- glGetTexParameteriv(type, GL_TEXTURE_MAG_FILTER, (GLint*) &mag);
- glGetTexParameteriv(type, GL_TEXTURE_MIN_FILTER, (GLint*) &min);
+ if (mProfilePending && for_runtime && !force_read)
+ {
+ GLuint64 result = 0;
+ glGetQueryObjectui64v(mTimerQuery, GL_QUERY_RESULT_AVAILABLE, &result);
- mTextureMagFilter[i] = mag;
- mTextureMinFilter[i] = min;
+ if (result != GL_TRUE)
+ {
+ return false;
}
}
- gGL.getTexUnit(cur_active)->activate();
- }
-
+ GLuint64 time_elapsed = 0;
+ glGetQueryObjectui64v(mTimerQuery, GL_QUERY_RESULT, &time_elapsed);
+ mTimeElapsed += time_elapsed;
+ mProfilePending = false;
- glBeginQueryARB(GL_SAMPLES_PASSED, mSamplesQuery);
- glBeginQueryARB(GL_TIME_ELAPSED, mTimerQuery);
-#endif
-}
+ if (!for_runtime)
+ {
+ GLuint64 samples_passed = 0;
+ glGetQueryObjectui64v(mSamplesQuery, GL_QUERY_RESULT, &samples_passed);
-void LLGLSLShader::readProfileQuery(U32 count, U32 mode)
-{
-#if !LL_DARWIN
- glEndQueryARB(GL_TIME_ELAPSED);
- glEndQueryARB(GL_SAMPLES_PASSED);
-
- GLuint64 time_elapsed = 0;
- glGetQueryObjectui64v(mTimerQuery, GL_QUERY_RESULT, &time_elapsed);
+ U64 primitives_generated = 0;
+ glGetQueryObjectui64v(mPrimitivesQuery, GL_QUERY_RESULT, &primitives_generated);
+ sTotalTimeElapsed += time_elapsed;
- GLuint64 samples_passed = 0;
- glGetQueryObjectui64v(mSamplesQuery, GL_QUERY_RESULT, &samples_passed);
+ sTotalSamplesDrawn += samples_passed;
+ mSamplesDrawn += samples_passed;
- sTotalTimeElapsed += time_elapsed;
- mTimeElapsed += time_elapsed;
+ U32 tri_count = (U32)primitives_generated / 3;
- sTotalSamplesDrawn += samples_passed;
- mSamplesDrawn += samples_passed;
+ mTrianglesDrawn += tri_count;
+ sTotalTrianglesDrawn += tri_count;
- U32 tri_count = 0;
- switch (mode)
- {
- case LLRender::TRIANGLES: tri_count = count/3; break;
- case LLRender::TRIANGLE_FAN: tri_count = count-2; break;
- case LLRender::TRIANGLE_STRIP: tri_count = count-2; break;
- default: tri_count = count; break; //points lines etc just use primitive count
+ sTotalBinds++;
+ mBinds++;
+ }
}
- mTrianglesDrawn += tri_count;
- sTotalTrianglesDrawn += tri_count;
-
- sTotalDrawCalls++;
- mDrawCalls++;
-#endif
+ return true;
}
LLGLSLShader::LLGLSLShader()
- : mProgramObject(0),
- mAttributeMask(0),
- mTotalUniformSize(0),
- mActiveTextureChannels(0),
- mShaderLevel(0),
- mShaderGroup(SG_DEFAULT),
- mUniformsDirty(FALSE),
- mTimerQuery(0),
- mSamplesQuery(0)
-
+ : mProgramObject(0),
+ mAttributeMask(0),
+ mTotalUniformSize(0),
+ mActiveTextureChannels(0),
+ mShaderLevel(0),
+ mShaderGroup(SG_DEFAULT),
+ mFeatures(),
+ mUniformsDirty(FALSE),
+ mTimerQuery(0),
+ mSamplesQuery(0),
+ mPrimitivesQuery(0)
{
-
+
}
LLGLSLShader::~LLGLSLShader()
@@ -332,6 +325,7 @@ void LLGLSLShader::unload()
{
mShaderFiles.clear();
mDefines.clear();
+ mFeatures = LLShaderFeatures();
unloadInternal();
}
@@ -347,30 +341,37 @@ void LLGLSLShader::unloadInternal()
if (mProgramObject)
{
- GLhandleARB obj[1024];
- GLsizei count;
- glGetAttachedObjectsARB(mProgramObject, 1024, &count, obj);
+ GLuint obj[1024];
+ GLsizei count = 0;
+ glGetAttachedShaders(mProgramObject, 1024, &count, obj);
+
+ for (GLsizei i = 0; i < count; i++)
+ {
+ glDetachShader(mProgramObject, obj[i]);
+ }
for (GLsizei i = 0; i < count; i++)
{
- glDetachObjectARB(mProgramObject, obj[i]);
- glDeleteObjectARB(obj[i]);
+ if (glIsShader(obj[i]))
+ {
+ glDeleteShader(obj[i]);
+ }
}
- glDeleteObjectARB(mProgramObject);
+ glDeleteProgram(mProgramObject);
mProgramObject = 0;
}
if (mTimerQuery)
{
- glDeleteQueriesARB(1, &mTimerQuery);
+ glDeleteQueries(1, &mTimerQuery);
mTimerQuery = 0;
}
if (mSamplesQuery)
{
- glDeleteQueriesARB(1, &mSamplesQuery);
+ glDeleteQueries(1, &mSamplesQuery);
mSamplesQuery = 0;
}
@@ -380,10 +381,10 @@ void LLGLSLShader::unloadInternal()
stop_glerror();
}
-BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
- std::vector<LLStaticHashedString> * uniforms,
- U32 varying_count,
- const char** varyings)
+BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString>* attributes,
+ std::vector<LLStaticHashedString>* uniforms,
+ U32 varying_count,
+ const char** varyings)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
@@ -400,8 +401,15 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
llassert_always(!mShaderFiles.empty());
+#if LL_DARWIN
+ // work-around missing mix(vec3,vec3,bvec3)
+ mDefines["OLD_SELECT"] = "1";
+#endif
+
+ mShaderHash = hash();
+
// Create program
- mProgramObject = glCreateProgramObjectARB();
+ mProgramObject = glCreateProgram();
if (mProgramObject == 0)
{
// Shouldn't happen if shader related extensions, like ARB_vertex_shader, exist.
@@ -411,51 +419,38 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
}
BOOL success = TRUE;
-
-#if LL_DARWIN
- // work-around missing mix(vec3,vec3,bvec3)
- mDefines["OLD_SELECT"] = "1";
-#endif
-
+
+ mUsingBinaryProgram = LLShaderMgr::instance()->loadCachedProgramBinary(this);
+
+ if (!mUsingBinaryProgram)
+ {
#if DEBUG_SHADER_INCLUDES
- fprintf(stderr, "--- %s ---\n", mName.c_str());
+ fprintf(stderr, "--- %s ---\n", mName.c_str());
#endif // DEBUG_SHADER_INCLUDES
- //compile new source
- vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin();
- for ( ; fileIter != mShaderFiles.end(); fileIter++ )
- {
- GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second, &mDefines, mFeatures.mIndexedTextureChannels);
- LL_DEBUGS("ShaderLoading") << "SHADER FILE: " << (*fileIter).first << " mShaderLevel=" << mShaderLevel << LL_ENDL;
- if (shaderhandle)
- {
- attachObject(shaderhandle);
- }
- else
- {
- success = FALSE;
- }
+ //compile new source
+ vector< pair<string, GLenum> >::iterator fileIter = mShaderFiles.begin();
+ for (; fileIter != mShaderFiles.end(); fileIter++)
+ {
+ GLuint shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second, &mDefines, mFeatures.mIndexedTextureChannels);
+ LL_DEBUGS("ShaderLoading") << "SHADER FILE: " << (*fileIter).first << " mShaderLevel=" << mShaderLevel << LL_ENDL;
+ if (shaderhandle)
+ {
+ attachObject(shaderhandle);
+ }
+ else
+ {
+ success = FALSE;
+ }
+ }
}
// Attach existing objects
if (!LLShaderMgr::instance()->attachShaderFeatures(this))
{
+ unloadInternal();
return FALSE;
}
-
- if (gGLManager.mGLSLVersionMajor < 2 && gGLManager.mGLSLVersionMinor < 3)
- { //indexed texture rendering requires GLSL 1.3 or later
- //attachShaderFeatures may have set the number of indexed texture channels, so set to 1 again
- mFeatures.mIndexedTextureChannels = llmin(mFeatures.mIndexedTextureChannels, 1);
- }
-
-#ifdef GL_INTERLEAVED_ATTRIBS
- if (varying_count > 0 && varyings)
- {
- glTransformFeedbackVaryings(mProgramObject, varying_count, varyings, GL_INTERLEAVED_ATTRIBS);
- }
-#endif
-
// Map attributes and uniforms
if (success)
{
@@ -465,7 +460,7 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
{
success = mapUniforms(uniforms);
}
- if( !success )
+ if (!success)
{
LL_SHADER_LOADING_WARNS() << "Failed to link shader: " << mName << LL_ENDL;
@@ -474,7 +469,12 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
{
LL_SHADER_LOADING_WARNS() << "Failed to link using shader level " << mShaderLevel << " trying again using shader level " << (mShaderLevel - 1) << LL_ENDL;
mShaderLevel--;
- return createShader(attributes,uniforms);
+ return createShader(attributes, uniforms);
+ }
+ else
+ {
+ // Give up and unload shader.
+ unloadInternal();
}
}
else if (mFeatures.mIndexedTextureChannels > 0)
@@ -501,26 +501,30 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
unbind();
}
+#ifdef LL_PROFILER_ENABLE_RENDER_DOC
+ setLabel(mName.c_str());
+#endif
+
return success;
}
#if DEBUG_SHADER_INCLUDES
-void dumpAttachObject( const char *func_name, GLhandleARB program_object, const std::string &object_path )
+void dumpAttachObject(const char* func_name, GLuint program_object, const std::string& object_path)
{
- GLcharARB* info_log;
+ GLchar* info_log;
GLint info_len_expect = 0;
GLint info_len_actual = 0;
- glGetObjectParameterivARB(program_object, GL_OBJECT_INFO_LOG_LENGTH_ARB, &info_len_expect);
+ glGetShaderiv(program_object, GL_INFO_LOG_LENGTH, , &info_len_expect);
fprintf(stderr, " * %-20s(), log size: %d, %s\n", func_name, info_len_expect, object_path.c_str());
if (info_len_expect > 0)
{
fprintf(stderr, " ========== %s() ========== \n", func_name);
- info_log = new GLcharARB [ info_len_expect ];
- glGetInfoLogARB(program_object, info_len_expect, &info_len_actual, info_log);
- fprintf(stderr, "%s\n", info_log);
- delete [] info_log;
+ info_log = new GLchar[info_len_expect];
+ glGetProgramInfoLog(program_object, info_len_expect, &info_len_actual, info_log);
+ fprintf(stderr, "%s\n", info_log);
+ delete[] info_log;
}
}
#endif // DEBUG_SHADER_INCLUDES
@@ -530,7 +534,7 @@ BOOL LLGLSLShader::attachVertexObject(std::string object_path)
if (LLShaderMgr::instance()->mVertexShaderObjects.count(object_path) > 0)
{
stop_glerror();
- glAttachObjectARB(mProgramObject, LLShaderMgr::instance()->mVertexShaderObjects[object_path]);
+ glAttachShader(mProgramObject, LLShaderMgr::instance()->mVertexShaderObjects[object_path]);
#if DEBUG_SHADER_INCLUDES
dumpAttachObject("attachVertexObject", mProgramObject, object_path);
#endif // DEBUG_SHADER_INCLUDES
@@ -546,10 +550,13 @@ BOOL LLGLSLShader::attachVertexObject(std::string object_path)
BOOL LLGLSLShader::attachFragmentObject(std::string object_path)
{
+ if(mUsingBinaryProgram)
+ return TRUE;
+
if (LLShaderMgr::instance()->mFragmentShaderObjects.count(object_path) > 0)
{
stop_glerror();
- glAttachObjectARB(mProgramObject, LLShaderMgr::instance()->mFragmentShaderObjects[object_path]);
+ glAttachShader(mProgramObject, LLShaderMgr::instance()->mFragmentShaderObjects[object_path]);
#if DEBUG_SHADER_INCLUDES
dumpAttachObject("attachFragmentObject", mProgramObject, object_path);
#endif // DEBUG_SHADER_INCLUDES
@@ -563,12 +570,15 @@ BOOL LLGLSLShader::attachFragmentObject(std::string object_path)
}
}
-void LLGLSLShader::attachObject(GLhandleARB object)
+void LLGLSLShader::attachObject(GLuint object)
{
+ if(mUsingBinaryProgram)
+ return;
+
if (object != 0)
{
stop_glerror();
- glAttachObjectARB(mProgramObject, object);
+ glAttachShader(mProgramObject, object);
#if DEBUG_SHADER_INCLUDES
std::string object_path("???");
dumpAttachObject("attachObject", mProgramObject, object_path);
@@ -581,27 +591,34 @@ void LLGLSLShader::attachObject(GLhandleARB object)
}
}
-void LLGLSLShader::attachObjects(GLhandleARB* objects, S32 count)
+void LLGLSLShader::attachObjects(GLuint* objects, S32 count)
{
+ if(mUsingBinaryProgram)
+ return;
+
for (S32 i = 0; i < count; i++)
{
attachObject(objects[i]);
}
}
-BOOL LLGLSLShader::mapAttributes(const std::vector<LLStaticHashedString> * attributes)
+BOOL LLGLSLShader::mapAttributes(const std::vector<LLStaticHashedString>* attributes)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
- //before linking, make sure reserved attributes always have consistent locations
- for (U32 i = 0; i < LLShaderMgr::instance()->mReservedAttribs.size(); i++)
- {
- const char* name = LLShaderMgr::instance()->mReservedAttribs[i].c_str();
- glBindAttribLocationARB(mProgramObject, i, (const GLcharARB *) name);
- }
-
- //link the program
- BOOL res = link();
+ BOOL res = TRUE;
+ if (!mUsingBinaryProgram)
+ {
+ //before linking, make sure reserved attributes always have consistent locations
+ for (U32 i = 0; i < LLShaderMgr::instance()->mReservedAttribs.size(); i++)
+ {
+ const char* name = LLShaderMgr::instance()->mReservedAttribs[i].c_str();
+ glBindAttribLocation(mProgramObject, i, (const GLchar*)name);
+ }
+
+ //link the program
+ res = link();
+ }
mAttribute.clear();
U32 numAttributes = (attributes == NULL) ? 0 : attributes->size();
@@ -610,7 +627,7 @@ BOOL LLGLSLShader::mapAttributes(const std::vector<LLStaticHashedString> * attri
#else
mAttribute.resize(LLShaderMgr::instance()->mReservedAttribs.size() + numAttributes, -1);
#endif
-
+
if (res)
{ //read back channel locations
@@ -620,7 +637,7 @@ BOOL LLGLSLShader::mapAttributes(const std::vector<LLStaticHashedString> * attri
for (U32 i = 0; i < LLShaderMgr::instance()->mReservedAttribs.size(); i++)
{
const char* name = LLShaderMgr::instance()->mReservedAttribs[i].c_str();
- S32 index = glGetAttribLocationARB(mProgramObject, (const GLcharARB *)name);
+ S32 index = glGetAttribLocation(mProgramObject, (const GLchar*)name);
if (index != -1)
{
#if LL_RELEASE_WITH_DEBUG_INFO
@@ -637,7 +654,7 @@ BOOL LLGLSLShader::mapAttributes(const std::vector<LLStaticHashedString> * attri
for (U32 i = 0; i < numAttributes; i++)
{
const char* name = (*attributes)[i].String().c_str();
- S32 index = glGetAttribLocationARB(mProgramObject, name);
+ S32 index = glGetAttribLocation(mProgramObject, name);
if (index != -1)
{
mAttribute[LLShaderMgr::instance()->mReservedAttribs.size() + i] = index;
@@ -648,11 +665,11 @@ BOOL LLGLSLShader::mapAttributes(const std::vector<LLStaticHashedString> * attri
return TRUE;
}
-
+
return FALSE;
}
-void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString> * uniforms)
+void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString>* uniforms)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
@@ -668,52 +685,50 @@ void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString> *
name[0] = 0;
- glGetActiveUniformARB(mProgramObject, index, 1024, &length, &size, &type, (GLcharARB *)name);
-#if !LL_DARWIN
+ glGetActiveUniform(mProgramObject, index, 1024, &length, &size, &type, (GLchar*)name);
if (size > 0)
{
- switch(type)
- {
- case GL_FLOAT_VEC2: size *= 2; break;
- case GL_FLOAT_VEC3: size *= 3; break;
- case GL_FLOAT_VEC4: size *= 4; break;
- case GL_DOUBLE: size *= 2; break;
- case GL_DOUBLE_VEC2: size *= 2; break;
- case GL_DOUBLE_VEC3: size *= 6; break;
- case GL_DOUBLE_VEC4: size *= 8; break;
- case GL_INT_VEC2: size *= 2; break;
- case GL_INT_VEC3: size *= 3; break;
- case GL_INT_VEC4: size *= 4; break;
- case GL_UNSIGNED_INT_VEC2: size *= 2; break;
- case GL_UNSIGNED_INT_VEC3: size *= 3; break;
- case GL_UNSIGNED_INT_VEC4: size *= 4; break;
- case GL_BOOL_VEC2: size *= 2; break;
- case GL_BOOL_VEC3: size *= 3; break;
- case GL_BOOL_VEC4: size *= 4; break;
- case GL_FLOAT_MAT2: size *= 4; break;
- case GL_FLOAT_MAT3: size *= 9; break;
- case GL_FLOAT_MAT4: size *= 16; break;
- case GL_FLOAT_MAT2x3: size *= 6; break;
- case GL_FLOAT_MAT2x4: size *= 8; break;
- case GL_FLOAT_MAT3x2: size *= 6; break;
- case GL_FLOAT_MAT3x4: size *= 12; break;
- case GL_FLOAT_MAT4x2: size *= 8; break;
- case GL_FLOAT_MAT4x3: size *= 12; break;
- case GL_DOUBLE_MAT2: size *= 8; break;
- case GL_DOUBLE_MAT3: size *= 18; break;
- case GL_DOUBLE_MAT4: size *= 32; break;
- case GL_DOUBLE_MAT2x3: size *= 12; break;
- case GL_DOUBLE_MAT2x4: size *= 16; break;
- case GL_DOUBLE_MAT3x2: size *= 12; break;
- case GL_DOUBLE_MAT3x4: size *= 24; break;
- case GL_DOUBLE_MAT4x2: size *= 16; break;
- case GL_DOUBLE_MAT4x3: size *= 24; break;
+ switch (type)
+ {
+ case GL_FLOAT_VEC2: size *= 2; break;
+ case GL_FLOAT_VEC3: size *= 3; break;
+ case GL_FLOAT_VEC4: size *= 4; break;
+ case GL_DOUBLE: size *= 2; break;
+ case GL_DOUBLE_VEC2: size *= 2; break;
+ case GL_DOUBLE_VEC3: size *= 6; break;
+ case GL_DOUBLE_VEC4: size *= 8; break;
+ case GL_INT_VEC2: size *= 2; break;
+ case GL_INT_VEC3: size *= 3; break;
+ case GL_INT_VEC4: size *= 4; break;
+ case GL_UNSIGNED_INT_VEC2: size *= 2; break;
+ case GL_UNSIGNED_INT_VEC3: size *= 3; break;
+ case GL_UNSIGNED_INT_VEC4: size *= 4; break;
+ case GL_BOOL_VEC2: size *= 2; break;
+ case GL_BOOL_VEC3: size *= 3; break;
+ case GL_BOOL_VEC4: size *= 4; break;
+ case GL_FLOAT_MAT2: size *= 4; break;
+ case GL_FLOAT_MAT3: size *= 9; break;
+ case GL_FLOAT_MAT4: size *= 16; break;
+ case GL_FLOAT_MAT2x3: size *= 6; break;
+ case GL_FLOAT_MAT2x4: size *= 8; break;
+ case GL_FLOAT_MAT3x2: size *= 6; break;
+ case GL_FLOAT_MAT3x4: size *= 12; break;
+ case GL_FLOAT_MAT4x2: size *= 8; break;
+ case GL_FLOAT_MAT4x3: size *= 12; break;
+ case GL_DOUBLE_MAT2: size *= 8; break;
+ case GL_DOUBLE_MAT3: size *= 18; break;
+ case GL_DOUBLE_MAT4: size *= 32; break;
+ case GL_DOUBLE_MAT2x3: size *= 12; break;
+ case GL_DOUBLE_MAT2x4: size *= 16; break;
+ case GL_DOUBLE_MAT3x2: size *= 12; break;
+ case GL_DOUBLE_MAT3x4: size *= 24; break;
+ case GL_DOUBLE_MAT4x2: size *= 16; break;
+ case GL_DOUBLE_MAT4x3: size *= 24; break;
}
mTotalUniformSize += size;
}
-#endif
- S32 location = glGetUniformLocationARB(mProgramObject, name);
+ S32 location = glGetUniformLocation(mProgramObject, name);
if (location != -1)
{
//chop off "[0]" so we can always access the first element
@@ -725,20 +740,19 @@ void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString> *
}
LLStaticHashedString hashedName(name);
- mUniformNameMap[location] = name;
mUniformMap[hashedName] = location;
LL_DEBUGS("ShaderUniform") << "Uniform " << name << " is at location " << location << LL_ENDL;
-
+
//find the index of this uniform
- for (S32 i = 0; i < (S32) LLShaderMgr::instance()->mReservedUniforms.size(); i++)
+ for (S32 i = 0; i < (S32)LLShaderMgr::instance()->mReservedUniforms.size(); i++)
{
- if ( (mUniform[i] == -1)
+ if ((mUniform[i] == -1)
&& (LLShaderMgr::instance()->mReservedUniforms[i] == name))
{
//found it
mUniform[i] = location;
- mTexture[i] = mapUniformTextureChannel(location, type);
+ mTexture[i] = mapUniformTextureChannel(location, type, size);
return;
}
}
@@ -747,12 +761,12 @@ void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString> *
{
for (U32 i = 0; i < uniforms->size(); i++)
{
- if ( (mUniform[i+LLShaderMgr::instance()->mReservedUniforms.size()] == -1)
+ if ((mUniform[i + LLShaderMgr::instance()->mReservedUniforms.size()] == -1)
&& ((*uniforms)[i].String() == name))
{
//found it
- mUniform[i+LLShaderMgr::instance()->mReservedUniforms.size()] = location;
- mTexture[i+LLShaderMgr::instance()->mReservedUniforms.size()] = mapUniformTextureChannel(location, type);
+ mUniform[i + LLShaderMgr::instance()->mReservedUniforms.size()] = location;
+ mTexture[i + LLShaderMgr::instance()->mReservedUniforms.size()] = mapUniformTextureChannel(location, type, size);
return;
}
}
@@ -770,167 +784,220 @@ void LLGLSLShader::addPermutation(std::string name, std::string value)
mDefines[name] = value;
}
+void LLGLSLShader::addConstant(const LLGLSLShader::eShaderConsts shader_const)
+{
+ addPermutation(gShaderConstsKey[shader_const], gShaderConstsVal[shader_const]);
+}
+
void LLGLSLShader::removePermutation(std::string name)
{
- mDefines[name].erase();
+ mDefines.erase(name);
}
-GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type)
+GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type, GLint size)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
- if ((type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB) ||
- type == GL_SAMPLER_2D_MULTISAMPLE)
+ if ((type >= GL_SAMPLER_1D && type <= GL_SAMPLER_2D_RECT_SHADOW) ||
+ type == GL_SAMPLER_2D_MULTISAMPLE ||
+ type == GL_SAMPLER_CUBE_MAP_ARRAY)
{ //this here is a texture
- glUniform1iARB(location, mActiveTextureChannels);
- LL_DEBUGS("ShaderUniform") << "Assigned to texture channel " << mActiveTextureChannels << LL_ENDL;
- return mActiveTextureChannels++;
+ GLint ret = mActiveTextureChannels;
+ if (size == 1)
+ {
+ glUniform1i(location, mActiveTextureChannels);
+ LL_DEBUGS("ShaderUniform") << "Assigned to texture channel " << mActiveTextureChannels << LL_ENDL;
+ mActiveTextureChannels++;
+ }
+ else
+ {
+ //is array of textures, make sequential after this texture
+ GLint channel[32]; // <=== only support up to 32 texture channels
+ llassert(size <= 32);
+ size = llmin(size, 32);
+ for (int i = 0; i < size; ++i)
+ {
+ channel[i] = mActiveTextureChannels++;
+ }
+ glUniform1iv(location, size, channel);
+ LL_DEBUGS("ShaderUniform") << "Assigned to texture channel " <<
+ (mActiveTextureChannels - size) << " through " << (mActiveTextureChannels - 1) << LL_ENDL;
+ }
+
+ llassert(mActiveTextureChannels <= 32); // too many textures (probably)
+ return ret;
}
return -1;
}
-BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
+BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString>* uniforms)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
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);
+ mTotalUniformSize = 0;
+ mActiveTextureChannels = 0;
+ mUniform.clear();
+ mUniformMap.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();
+ bind();
- //get the number of active uniforms
- GLint activeCount;
- glGetObjectParameterivARB(mProgramObject, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &activeCount);
+ //get the number of active 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).
+ /*
+ 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.
+ 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.
+ 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
- */
+ As example where this situation appear see: "Deferred Material Shader 28/29/30/31"
+ And tickets: MAINT-4165, MAINT-4839, MAINT-3568, MAINT-6437
+ --- davep TODO -- pretty sure the entire block here is superstitious and that the uniform index has nothing to do with the texture channel
+ texture channel should follow the uniform VALUE
+ */
- S32 diffuseMap = glGetUniformLocationARB(mProgramObject, "diffuseMap");
- S32 specularMap = glGetUniformLocationARB(mProgramObject, "specularMap");
- S32 bumpMap = glGetUniformLocationARB(mProgramObject, "bumpMap");
- S32 altDiffuseMap = glGetUniformLocationARB(mProgramObject, "altDiffuseMap");
- S32 environmentMap = glGetUniformLocationARB(mProgramObject, "environmentMap");
- std::set<S32> skip_index;
+ 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");
+ S32 reflectionMap = glGetUniformLocation(mProgramObject, "reflectionMap");
- if (-1 != diffuseMap && (-1 != specularMap || -1 != bumpMap || -1 != environmentMap || -1 != altDiffuseMap))
- {
- GLenum type;
- GLsizei length;
- GLint size = -1;
- char name[1024];
+ std::set<S32> skip_index;
- diffuseMap = altDiffuseMap = specularMap = bumpMap = environmentMap = -1;
+ if (-1 != diffuseMap && (-1 != specularMap || -1 != bumpMap || -1 != environmentMap || -1 != altDiffuseMap))
+ {
+ GLenum type;
+ GLsizei length;
+ GLint size = -1;
+ char name[1024];
- for (S32 i = 0; i < activeCount; i++)
- {
- name[0] = '\0';
+ diffuseMap = altDiffuseMap = specularMap = bumpMap = environmentMap = -1;
- glGetActiveUniformARB(mProgramObject, i, 1024, &length, &size, &type, (GLcharARB *)name);
+ for (S32 i = 0; i < activeCount; i++)
+ {
+ name[0] = '\0';
- if (-1 == diffuseMap && std::string(name) == "diffuseMap")
- {
- diffuseMap = i;
- continue;
- }
+ glGetActiveUniform(mProgramObject, i, 1024, &length, &size, &type, (GLchar*)name);
- if (-1 == specularMap && std::string(name) == "specularMap")
- {
- specularMap = i;
- continue;
- }
+ if (-1 == diffuseMap && std::string(name) == "diffuseMap")
+ {
+ diffuseMap = i;
+ continue;
+ }
- if (-1 == bumpMap && std::string(name) == "bumpMap")
- {
- bumpMap = i;
- continue;
- }
+ if (-1 == specularMap && std::string(name) == "specularMap")
+ {
+ specularMap = i;
+ continue;
+ }
- if (-1 == environmentMap && std::string(name) == "environmentMap")
- {
- environmentMap = i;
- continue;
- }
+ if (-1 == bumpMap && std::string(name) == "bumpMap")
+ {
+ bumpMap = i;
+ continue;
+ }
+
+ if (-1 == environmentMap && std::string(name) == "environmentMap")
+ {
+ environmentMap = i;
+ continue;
+ }
+
+ if (-1 == reflectionMap && std::string(name) == "reflectionMap")
+ {
+ reflectionMap = i;
+ continue;
+ }
if (-1 == altDiffuseMap && std::string(name) == "altDiffuseMap")
- {
- altDiffuseMap = i;
- continue;
- }
- }
+ {
+ altDiffuseMap = i;
+ continue;
+ }
+ }
- bool specularDiff = specularMap < diffuseMap && -1 != specularMap;
- bool bumpLessDiff = bumpMap < diffuseMap && -1 != bumpMap;
- bool envLessDiff = environmentMap < diffuseMap && -1 != environmentMap;
+ bool specularDiff = specularMap < diffuseMap && -1 != specularMap;
+ bool bumpLessDiff = bumpMap < diffuseMap && -1 != bumpMap;
+ bool envLessDiff = environmentMap < diffuseMap && -1 != environmentMap;
+ bool refLessDiff = reflectionMap < diffuseMap && -1 != reflectionMap;
- if (specularDiff || bumpLessDiff || envLessDiff)
- {
- mapUniform(diffuseMap, uniforms);
- skip_index.insert(diffuseMap);
+ if (specularDiff || bumpLessDiff || envLessDiff || refLessDiff)
+ {
+ mapUniform(diffuseMap, uniforms);
+ skip_index.insert(diffuseMap);
- if (-1 != specularMap) {
- mapUniform(specularMap, uniforms);
- skip_index.insert(specularMap);
- }
+ if (-1 != specularMap) {
+ mapUniform(specularMap, uniforms);
+ skip_index.insert(specularMap);
+ }
- if (-1 != bumpMap) {
- mapUniform(bumpMap, uniforms);
- skip_index.insert(bumpMap);
- }
+ if (-1 != bumpMap) {
+ mapUniform(bumpMap, uniforms);
+ skip_index.insert(bumpMap);
+ }
- if (-1 != environmentMap) {
- mapUniform(environmentMap, uniforms);
- skip_index.insert(environmentMap);
- }
- }
- }
+ if (-1 != environmentMap) {
+ mapUniform(environmentMap, uniforms);
+ skip_index.insert(environmentMap);
+ }
+
+ if (-1 != reflectionMap) {
+ mapUniform(reflectionMap, uniforms);
+ skip_index.insert(reflectionMap);
+ }
+ }
+ }
- //........................................................................................
+ //........................................................................................
- for (S32 i = 0; i < activeCount; i++)
- {
- //........................................................................................
- if (skip_index.end() != skip_index.find(i)) continue;
- //........................................................................................
+ for (S32 i = 0; i < activeCount; i++)
+ {
+ //........................................................................................
+ if (skip_index.end() != skip_index.find(i)) continue;
+ //........................................................................................
- mapUniform(i, uniforms);
- }
- //........................................................................................................................................
+ mapUniform(i, uniforms);
+ }
+ //........................................................................................................................................
- unbind();
+ if (mFeatures.hasReflectionProbes) // Set up block binding, in a way supported by Apple (rather than binding = 1 in .glsl).
+ { // See slide 35 and more of https://docs.huihoo.com/apple/wwdc/2011/session_420__advances_in_opengl_for_mac_os_x_lion.pdf
+ static const GLuint BLOCKBINDING = 1; //picked by us
+ //Get the index, similar to a uniform location
+ GLuint UBOBlockIndex = glGetUniformBlockIndex(mProgramObject, "ReflectionProbes");
+ if (UBOBlockIndex != GL_INVALID_INDEX)
+ {
+ //Set this index to a binding index
+ glUniformBlockBinding(mProgramObject, UBOBlockIndex, BLOCKBINDING);
+ }
+ }
+ unbind();
- LL_DEBUGS("ShaderUniform") << "Total Uniform Size: " << mTotalUniformSize << LL_ENDL;
- return res;
+ LL_DEBUGS("ShaderUniform") << "Total Uniform Size: " << mTotalUniformSize << LL_ENDL;
+ return res;
}
@@ -945,6 +1012,11 @@ BOOL LLGLSLShader::link(BOOL suppress_errors)
LLShaderMgr::instance()->dumpObjectLog(mProgramObject, !success, mName);
}
+ if (success)
+ {
+ LLShaderMgr::instance()->saveCachedProgramBinary(this);
+ }
+
return success;
}
@@ -952,14 +1024,22 @@ void LLGLSLShader::bind()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
+ llassert(mProgramObject != 0);
+
gGL.flush();
if (sCurBoundShader != mProgramObject) // Don't re-bind current shader
{
+ if (sCurBoundShaderPtr)
+ {
+ sCurBoundShaderPtr->readProfileQuery();
+ }
LLVertexBuffer::unbind();
- glUseProgramObjectARB(mProgramObject);
+ glUseProgram(mProgramObject);
sCurBoundShader = mProgramObject;
sCurBoundShaderPtr = this;
+ placeProfileQuery();
+ LLVertexBuffer::setupClientArrays(mAttributeMask);
}
if (mUniformsDirty)
@@ -982,40 +1062,33 @@ void LLGLSLShader::bind(bool rigged)
}
}
-void LLGLSLShader::unbind()
+void LLGLSLShader::unbind(void)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
-
gGL.flush();
- stop_glerror();
LLVertexBuffer::unbind();
- glUseProgramObjectARB(0);
- sCurBoundShader = 0;
- sCurBoundShaderPtr = NULL;
- stop_glerror();
-}
-void LLGLSLShader::bindNoShader(void)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
+ if (sCurBoundShaderPtr)
+ {
+ sCurBoundShaderPtr->readProfileQuery();
+ }
- LLVertexBuffer::unbind();
- glUseProgramObjectARB(0);
+ glUseProgram(0);
sCurBoundShader = 0;
sCurBoundShaderPtr = NULL;
}
-S32 LLGLSLShader::bindTexture(const std::string &uniform, LLTexture *texture, LLTexUnit::eTextureType mode, LLTexUnit::eTextureColorSpace colorspace)
+S32 LLGLSLShader::bindTexture(const std::string& uniform, LLTexture* texture, LLTexUnit::eTextureType mode, LLTexUnit::eTextureColorSpace colorspace)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
S32 channel = 0;
channel = getUniformLocation(uniform);
-
+
return bindTexture(channel, texture, mode, colorspace);
}
-S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextureType mode, LLTexUnit::eTextureColorSpace colorspace)
+S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture* texture, LLTexUnit::eTextureType mode, LLTexUnit::eTextureColorSpace colorspace)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
@@ -1024,25 +1097,62 @@ S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextu
LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL;
return -1;
}
-
+
uniform = mTexture[uniform];
-
+
if (uniform > -1)
{
gGL.getTexUnit(uniform)->bindFast(texture);
gGL.getTexUnit(uniform)->setTextureColorSpace(colorspace);
}
-
+
return uniform;
}
-S32 LLGLSLShader::unbindTexture(const std::string &uniform, LLTexUnit::eTextureType mode)
+S32 LLGLSLShader::bindTexture(S32 uniform, LLRenderTarget* texture, bool depth, LLTexUnit::eTextureFilterOptions mode, U32 index)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
+
+ if (uniform < 0 || uniform >= (S32)mTexture.size())
+ {
+ return -1;
+ }
+
+ uniform = getTextureChannel(uniform);
+
+ if (uniform > -1)
+ {
+ if (depth) {
+ gGL.getTexUnit(uniform)->bind(texture, true);
+ }
+ else {
+ bool has_mips = mode == LLTexUnit::TFO_TRILINEAR || mode == LLTexUnit::TFO_ANISOTROPIC;
+ gGL.getTexUnit(uniform)->bindManual(texture->getUsage(), texture->getTexture(index), has_mips);
+ }
+
+ gGL.getTexUnit(uniform)->setTextureFilteringOption(mode);
+ }
+
+ return uniform;
+}
+
+S32 LLGLSLShader::bindTexture(const std::string& uniform, LLRenderTarget* texture, bool depth, LLTexUnit::eTextureFilterOptions mode)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
S32 channel = 0;
channel = getUniformLocation(uniform);
-
+
+ return bindTexture(channel, texture, depth, mode);
+}
+
+S32 LLGLSLShader::unbindTexture(const std::string& uniform, LLTexUnit::eTextureType mode)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
+
+ S32 channel = 0;
+ channel = getUniformLocation(uniform);
+
return unbindTexture(channel);
}
@@ -1055,17 +1165,22 @@ S32 LLGLSLShader::unbindTexture(S32 uniform, LLTexUnit::eTextureType mode)
LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL;
return -1;
}
-
+
uniform = mTexture[uniform];
-
+
if (uniform > -1)
{
gGL.getTexUnit(uniform)->unbindFast(mode);
}
-
+
return uniform;
}
+S32 LLGLSLShader::getTextureChannel(S32 uniform) const
+{
+ return mTexture[uniform];
+}
+
S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode, LLTexUnit::eTextureColorSpace space)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
@@ -1116,9 +1231,10 @@ S32 LLGLSLShader::disableTexture(S32 uniform, LLTexUnit::eTextureType mode, LLTe
void LLGLSLShader::uniform1i(U32 index, GLint x)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
+ llassert(sCurBoundShaderPtr == this);
if (mProgramObject)
- {
+ {
if (mUniform.size() <= index)
{
LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
@@ -1130,8 +1246,8 @@ void LLGLSLShader::uniform1i(U32 index, GLint x)
const auto& iter = mValue.find(mUniform[index]);
if (iter == mValue.end() || iter->second.mV[0] != x)
{
- glUniform1iARB(mUniform[index], x);
- mValue[mUniform[index]] = LLVector4(x,0.f,0.f,0.f);
+ glUniform1i(mUniform[index], x);
+ mValue[mUniform[index]] = LLVector4(x, 0.f, 0.f, 0.f);
}
}
}
@@ -1139,9 +1255,11 @@ void LLGLSLShader::uniform1i(U32 index, GLint x)
void LLGLSLShader::uniform1f(U32 index, GLfloat x)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
+ llassert(sCurBoundShaderPtr == this);
+
if (mProgramObject)
- {
+ {
if (mUniform.size() <= index)
{
LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
@@ -1153,17 +1271,30 @@ void LLGLSLShader::uniform1f(U32 index, GLfloat x)
const auto& iter = mValue.find(mUniform[index]);
if (iter == mValue.end() || iter->second.mV[0] != x)
{
- glUniform1fARB(mUniform[index], x);
- mValue[mUniform[index]] = LLVector4(x,0.f,0.f,0.f);
+ glUniform1f(mUniform[index], x);
+ mValue[mUniform[index]] = LLVector4(x, 0.f, 0.f, 0.f);
}
}
}
}
+void LLGLSLShader::fastUniform1f(U32 index, GLfloat x)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
+ llassert(sCurBoundShaderPtr == this);
+ llassert(mProgramObject);
+ llassert(mUniform.size() <= index);
+ llassert(mUniform[index] >= 0);
+ glUniform1f(mUniform[index], x);
+}
+
void LLGLSLShader::uniform2f(U32 index, GLfloat x, GLfloat y)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
+ llassert(sCurBoundShaderPtr == this);
+
if (mProgramObject)
- {
+ {
if (mUniform.size() <= index)
{
LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
@@ -1173,10 +1304,10 @@ void LLGLSLShader::uniform2f(U32 index, GLfloat x, GLfloat y)
if (mUniform[index] >= 0)
{
const auto& iter = mValue.find(mUniform[index]);
- LLVector4 vec(x,y,0.f,0.f);
- if (iter == mValue.end() || shouldChange(iter->second,vec))
+ LLVector4 vec(x, y, 0.f, 0.f);
+ if (iter == mValue.end() || shouldChange(iter->second, vec))
{
- glUniform2fARB(mUniform[index], x, y);
+ glUniform2f(mUniform[index], x, y);
mValue[mUniform[index]] = vec;
}
}
@@ -1185,8 +1316,11 @@ void LLGLSLShader::uniform2f(U32 index, GLfloat x, GLfloat y)
void LLGLSLShader::uniform3f(U32 index, GLfloat x, GLfloat y, GLfloat z)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
+ llassert(sCurBoundShaderPtr == this);
+
if (mProgramObject)
- {
+ {
if (mUniform.size() <= index)
{
LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
@@ -1196,10 +1330,10 @@ void LLGLSLShader::uniform3f(U32 index, GLfloat x, GLfloat y, GLfloat z)
if (mUniform[index] >= 0)
{
const auto& iter = mValue.find(mUniform[index]);
- LLVector4 vec(x,y,z,0.f);
- if (iter == mValue.end() || shouldChange(iter->second,vec))
+ LLVector4 vec(x, y, z, 0.f);
+ if (iter == mValue.end() || shouldChange(iter->second, vec))
{
- glUniform3fARB(mUniform[index], x, y, z);
+ glUniform3f(mUniform[index], x, y, z);
mValue[mUniform[index]] = vec;
}
}
@@ -1208,8 +1342,11 @@ void LLGLSLShader::uniform3f(U32 index, GLfloat x, GLfloat y, GLfloat z)
void LLGLSLShader::uniform4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
+ llassert(sCurBoundShaderPtr == this);
+
if (mProgramObject)
- {
+ {
if (mUniform.size() <= index)
{
LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
@@ -1219,10 +1356,10 @@ void LLGLSLShader::uniform4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat
if (mUniform[index] >= 0)
{
const auto& iter = mValue.find(mUniform[index]);
- LLVector4 vec(x,y,z,w);
- if (iter == mValue.end() || shouldChange(iter->second,vec))
+ LLVector4 vec(x, y, z, w);
+ if (iter == mValue.end() || shouldChange(iter->second, vec))
{
- glUniform4fARB(mUniform[index], x, y, z, w);
+ glUniform4f(mUniform[index], x, y, z, w);
mValue[mUniform[index]] = vec;
}
}
@@ -1231,8 +1368,37 @@ void LLGLSLShader::uniform4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat
void LLGLSLShader::uniform1iv(U32 index, U32 count, const GLint* v)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
+ llassert(sCurBoundShaderPtr == this);
+
+ if (mProgramObject)
+ {
+ if (mUniform.size() <= index)
+ {
+ LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
+ return;
+ }
+
+ if (mUniform[index] >= 0)
+ {
+ const auto& iter = mValue.find(mUniform[index]);
+ LLVector4 vec(v[0], 0.f, 0.f, 0.f);
+ if (iter == mValue.end() || shouldChange(iter->second, vec) || count != 1)
+ {
+ glUniform1iv(mUniform[index], count, v);
+ mValue[mUniform[index]] = vec;
+ }
+ }
+ }
+}
+
+void LLGLSLShader::uniform4iv(U32 index, U32 count, const GLint* v)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
+ llassert(sCurBoundShaderPtr == this);
+
if (mProgramObject)
- {
+ {
if (mUniform.size() <= index)
{
LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
@@ -1242,20 +1408,24 @@ void LLGLSLShader::uniform1iv(U32 index, U32 count, const GLint* v)
if (mUniform[index] >= 0)
{
const auto& iter = mValue.find(mUniform[index]);
- LLVector4 vec(v[0],0.f,0.f,0.f);
- if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
+ LLVector4 vec(v[0], v[1], v[2], v[3]);
+ if (iter == mValue.end() || shouldChange(iter->second, vec) || count != 1)
{
- glUniform1ivARB(mUniform[index], count, v);
+ glUniform1iv(mUniform[index], count, v);
mValue[mUniform[index]] = vec;
}
}
}
}
+
void LLGLSLShader::uniform1fv(U32 index, U32 count, const GLfloat* v)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
+ llassert(sCurBoundShaderPtr == this);
+
if (mProgramObject)
- {
+ {
if (mUniform.size() <= index)
{
LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
@@ -1265,10 +1435,10 @@ void LLGLSLShader::uniform1fv(U32 index, U32 count, const GLfloat* v)
if (mUniform[index] >= 0)
{
const auto& iter = mValue.find(mUniform[index]);
- LLVector4 vec(v[0],0.f,0.f,0.f);
- if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
+ LLVector4 vec(v[0], 0.f, 0.f, 0.f);
+ if (iter == mValue.end() || shouldChange(iter->second, vec) || count != 1)
{
- glUniform1fvARB(mUniform[index], count, v);
+ glUniform1fv(mUniform[index], count, v);
mValue[mUniform[index]] = vec;
}
}
@@ -1277,8 +1447,11 @@ void LLGLSLShader::uniform1fv(U32 index, U32 count, const GLfloat* v)
void LLGLSLShader::uniform2fv(U32 index, U32 count, const GLfloat* v)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
+ llassert(sCurBoundShaderPtr == this);
+
if (mProgramObject)
- {
+ {
if (mUniform.size() <= index)
{
LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
@@ -1288,10 +1461,10 @@ void LLGLSLShader::uniform2fv(U32 index, U32 count, const GLfloat* v)
if (mUniform[index] >= 0)
{
const auto& iter = mValue.find(mUniform[index]);
- LLVector4 vec(v[0],v[1],0.f,0.f);
- if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
+ LLVector4 vec(v[0], v[1], 0.f, 0.f);
+ if (iter == mValue.end() || shouldChange(iter->second, vec) || count != 1)
{
- glUniform2fvARB(mUniform[index], count, v);
+ glUniform2fv(mUniform[index], count, v);
mValue[mUniform[index]] = vec;
}
}
@@ -1300,8 +1473,11 @@ void LLGLSLShader::uniform2fv(U32 index, U32 count, const GLfloat* v)
void LLGLSLShader::uniform3fv(U32 index, U32 count, const GLfloat* v)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
+ llassert(sCurBoundShaderPtr == this);
+
if (mProgramObject)
- {
+ {
if (mUniform.size() <= index)
{
LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
@@ -1311,10 +1487,10 @@ void LLGLSLShader::uniform3fv(U32 index, U32 count, const GLfloat* v)
if (mUniform[index] >= 0)
{
const auto& iter = mValue.find(mUniform[index]);
- LLVector4 vec(v[0],v[1],v[2],0.f);
- if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
+ LLVector4 vec(v[0], v[1], v[2], 0.f);
+ if (iter == mValue.end() || shouldChange(iter->second, vec) || count != 1)
{
- glUniform3fvARB(mUniform[index], count, v);
+ glUniform3fv(mUniform[index], count, v);
mValue[mUniform[index]] = vec;
}
}
@@ -1323,8 +1499,11 @@ void LLGLSLShader::uniform3fv(U32 index, U32 count, const GLfloat* v)
void LLGLSLShader::uniform4fv(U32 index, U32 count, const GLfloat* v)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
+ llassert(sCurBoundShaderPtr == this);
+
if (mProgramObject)
- {
+ {
if (mUniform.size() <= index)
{
LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
@@ -1334,21 +1513,24 @@ void LLGLSLShader::uniform4fv(U32 index, U32 count, const GLfloat* v)
if (mUniform[index] >= 0)
{
const auto& iter = mValue.find(mUniform[index]);
- LLVector4 vec(v[0],v[1],v[2],v[3]);
- if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
+ LLVector4 vec(v[0], v[1], v[2], v[3]);
+ if (iter == mValue.end() || shouldChange(iter->second, vec) || count != 1)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
- glUniform4fvARB(mUniform[index], count, v);
+ glUniform4fv(mUniform[index], count, v);
mValue[mUniform[index]] = vec;
}
}
}
}
-void LLGLSLShader::uniformMatrix2fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v)
+void LLGLSLShader::uniformMatrix2fv(U32 index, U32 count, GLboolean transpose, const GLfloat* v)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
+ llassert(sCurBoundShaderPtr == this);
+
if (mProgramObject)
- {
+ {
if (mUniform.size() <= index)
{
LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
@@ -1357,15 +1539,18 @@ void LLGLSLShader::uniformMatrix2fv(U32 index, U32 count, GLboolean transpose, c
if (mUniform[index] >= 0)
{
- glUniformMatrix2fvARB(mUniform[index], count, transpose, v);
+ glUniformMatrix2fv(mUniform[index], count, transpose, v);
}
}
}
-void LLGLSLShader::uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v)
+void LLGLSLShader::uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, const GLfloat* v)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
+ llassert(sCurBoundShaderPtr == this);
+
if (mProgramObject)
- {
+ {
if (mUniform.size() <= index)
{
LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
@@ -1374,34 +1559,38 @@ void LLGLSLShader::uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, c
if (mUniform[index] >= 0)
{
- glUniformMatrix3fvARB(mUniform[index], count, transpose, v);
+ glUniformMatrix3fv(mUniform[index], count, transpose, v);
}
}
}
-void LLGLSLShader::uniformMatrix3x4fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v)
+void LLGLSLShader::uniformMatrix3x4fv(U32 index, U32 count, GLboolean transpose, const GLfloat* v)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
+ llassert(sCurBoundShaderPtr == this);
- if (mProgramObject)
- {
- if (mUniform.size() <= index)
- {
- LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
- return;
- }
+ if (mProgramObject)
+ {
+ if (mUniform.size() <= index)
+ {
+ LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
+ return;
+ }
- if (mUniform[index] >= 0)
- {
- glUniformMatrix3x4fv(mUniform[index], count, transpose, v);
- }
- }
+ if (mUniform[index] >= 0)
+ {
+ glUniformMatrix3x4fv(mUniform[index], count, transpose, v);
+ }
+ }
}
-void LLGLSLShader::uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v)
+void LLGLSLShader::uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, const GLfloat* v)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
+ llassert(sCurBoundShaderPtr == this);
+
if (mProgramObject)
- {
+ {
if (mUniform.size() <= index)
{
LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
@@ -1410,7 +1599,7 @@ void LLGLSLShader::uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, c
if (mUniform[index] >= 0)
{
- glUniformMatrix4fvARB(mUniform[index], count, transpose, v);
+ glUniformMatrix4fv(mUniform[index], count, transpose, v);
}
}
}
@@ -1428,7 +1617,7 @@ GLint LLGLSLShader::getUniformLocation(const LLStaticHashedString& uniform)
if (gDebugGL)
{
stop_glerror();
- if (iter->second != glGetUniformLocationARB(mProgramObject, uniform.String().c_str()))
+ if (iter->second != glGetUniformLocation(mProgramObject, uniform.String().c_str()))
{
LL_ERRS() << "Uniform does not match." << LL_ENDL;
}
@@ -1475,15 +1664,52 @@ GLint LLGLSLShader::getAttribLocation(U32 attrib)
void LLGLSLShader::uniform1i(const LLStaticHashedString& uniform, GLint v)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
+ GLint location = getUniformLocation(uniform);
+
+ if (location >= 0)
+ {
+ const auto& iter = mValue.find(location);
+ LLVector4 vec(v, 0.f, 0.f, 0.f);
+ if (iter == mValue.end() || shouldChange(iter->second, vec))
+ {
+ glUniform1i(location, v);
+ mValue[location] = vec;
+ }
+ }
+}
+
+void LLGLSLShader::uniform1iv(const LLStaticHashedString& uniform, U32 count, const GLint* v)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
+ GLint location = getUniformLocation(uniform);
+
+ if (location >= 0)
+ {
+ LLVector4 vec(v[0], 0, 0, 0);
+ const auto& iter = mValue.find(location);
+ if (iter == mValue.end() || shouldChange(iter->second, vec) || count != 1)
+ {
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
+ glUniform1iv(location, count, v);
+ mValue[location] = vec;
+ }
+ }
+}
+
+void LLGLSLShader::uniform4iv(const LLStaticHashedString& uniform, U32 count, const GLint* v)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
GLint location = getUniformLocation(uniform);
-
+
if (location >= 0)
{
+ LLVector4 vec(v[0], v[1], v[2], v[3]);
const auto& iter = mValue.find(location);
- LLVector4 vec(v,0.f,0.f,0.f);
- if (iter == mValue.end() || shouldChange(iter->second,vec))
+ if (iter == mValue.end() || shouldChange(iter->second, vec) || count != 1)
{
- glUniform1iARB(location, v);
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
+ glUniform4iv(location, count, v);
mValue[location] = vec;
}
}
@@ -1491,15 +1717,16 @@ void LLGLSLShader::uniform1i(const LLStaticHashedString& uniform, GLint v)
void LLGLSLShader::uniform2i(const LLStaticHashedString& uniform, GLint i, GLint j)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
GLint location = getUniformLocation(uniform);
-
+
if (location >= 0)
{
const auto& iter = mValue.find(location);
- LLVector4 vec(i,j,0.f,0.f);
- if (iter == mValue.end() || shouldChange(iter->second,vec))
+ LLVector4 vec(i, j, 0.f, 0.f);
+ if (iter == mValue.end() || shouldChange(iter->second, vec))
{
- glUniform2iARB(location, i, j);
+ glUniform2i(location, i, j);
mValue[location] = vec;
}
}
@@ -1508,15 +1735,16 @@ void LLGLSLShader::uniform2i(const LLStaticHashedString& uniform, GLint i, GLint
void LLGLSLShader::uniform1f(const LLStaticHashedString& uniform, GLfloat v)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
GLint location = getUniformLocation(uniform);
-
+
if (location >= 0)
{
const auto& iter = mValue.find(location);
- LLVector4 vec(v,0.f,0.f,0.f);
- if (iter == mValue.end() || shouldChange(iter->second,vec))
+ LLVector4 vec(v, 0.f, 0.f, 0.f);
+ if (iter == mValue.end() || shouldChange(iter->second, vec))
{
- glUniform1fARB(location, v);
+ glUniform1f(location, v);
mValue[location] = vec;
}
}
@@ -1524,15 +1752,16 @@ void LLGLSLShader::uniform1f(const LLStaticHashedString& uniform, GLfloat v)
void LLGLSLShader::uniform2f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
GLint location = getUniformLocation(uniform);
-
+
if (location >= 0)
{
const auto& iter = mValue.find(location);
- LLVector4 vec(x,y,0.f,0.f);
- if (iter == mValue.end() || shouldChange(iter->second,vec))
+ LLVector4 vec(x, y, 0.f, 0.f);
+ if (iter == mValue.end() || shouldChange(iter->second, vec))
{
- glUniform2fARB(location, x,y);
+ glUniform2f(location, x, y);
mValue[location] = vec;
}
}
@@ -1541,15 +1770,16 @@ void LLGLSLShader::uniform2f(const LLStaticHashedString& uniform, GLfloat x, GLf
void LLGLSLShader::uniform3f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y, GLfloat z)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
GLint location = getUniformLocation(uniform);
-
+
if (location >= 0)
{
const auto& iter = mValue.find(location);
- LLVector4 vec(x,y,z,0.f);
- if (iter == mValue.end() || shouldChange(iter->second,vec))
+ LLVector4 vec(x, y, z, 0.f);
+ if (iter == mValue.end() || shouldChange(iter->second, vec))
{
- glUniform3fARB(location, x,y,z);
+ glUniform3f(location, x, y, z);
mValue[location] = vec;
}
}
@@ -1557,15 +1787,16 @@ void LLGLSLShader::uniform3f(const LLStaticHashedString& uniform, GLfloat x, GLf
void LLGLSLShader::uniform1fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
GLint location = getUniformLocation(uniform);
if (location >= 0)
{
const auto& iter = mValue.find(location);
- LLVector4 vec(v[0],0.f,0.f,0.f);
- if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
+ LLVector4 vec(v[0], 0.f, 0.f, 0.f);
+ if (iter == mValue.end() || shouldChange(iter->second, vec) || count != 1)
{
- glUniform1fvARB(location, count, v);
+ glUniform1fv(location, count, v);
mValue[location] = vec;
}
}
@@ -1573,15 +1804,16 @@ void LLGLSLShader::uniform1fv(const LLStaticHashedString& uniform, U32 count, co
void LLGLSLShader::uniform2fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
GLint location = getUniformLocation(uniform);
-
+
if (location >= 0)
{
const auto& iter = mValue.find(location);
- LLVector4 vec(v[0],v[1],0.f,0.f);
- if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
+ LLVector4 vec(v[0], v[1], 0.f, 0.f);
+ if (iter == mValue.end() || shouldChange(iter->second, vec) || count != 1)
{
- glUniform2fvARB(location, count, v);
+ glUniform2fv(location, count, v);
mValue[location] = vec;
}
}
@@ -1589,15 +1821,16 @@ void LLGLSLShader::uniform2fv(const LLStaticHashedString& uniform, U32 count, co
void LLGLSLShader::uniform3fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
GLint location = getUniformLocation(uniform);
-
+
if (location >= 0)
{
const auto& iter = mValue.find(location);
- LLVector4 vec(v[0],v[1],v[2],0.f);
- if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
+ LLVector4 vec(v[0], v[1], v[2], 0.f);
+ if (iter == mValue.end() || shouldChange(iter->second, vec) || count != 1)
{
- glUniform3fvARB(location, count, v);
+ glUniform3fv(location, count, v);
mValue[location] = vec;
}
}
@@ -1605,16 +1838,17 @@ void LLGLSLShader::uniform3fv(const LLStaticHashedString& uniform, U32 count, co
void LLGLSLShader::uniform4fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
GLint location = getUniformLocation(uniform);
if (location >= 0)
{
LLVector4 vec(v);
const auto& iter = mValue.find(location);
- if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
+ if (iter == mValue.end() || shouldChange(iter->second, vec) || count != 1)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
- glUniform4fvARB(location, count, v);
+ glUniform4fv(location, count, v);
mValue[location] = vec;
}
}
@@ -1622,12 +1856,13 @@ void LLGLSLShader::uniform4fv(const LLStaticHashedString& uniform, U32 count, co
void LLGLSLShader::uniformMatrix4fv(const LLStaticHashedString& uniform, U32 count, GLboolean transpose, const GLfloat* v)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
GLint location = getUniformLocation(uniform);
-
+
if (location >= 0)
{
stop_glerror();
- glUniformMatrix4fvARB(location, count, transpose, v);
+ glUniformMatrix4fv(location, count, transpose, v);
stop_glerror();
}
}
@@ -1637,7 +1872,7 @@ void LLGLSLShader::vertexAttrib4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GL
{
if (mAttribute[index] > 0)
{
- glVertexAttrib4fARB(mAttribute[index], x, y, z, w);
+ glVertexAttrib4f(mAttribute[index], x, y, z, w);
}
}
@@ -1645,12 +1880,13 @@ void LLGLSLShader::vertexAttrib4fv(U32 index, GLfloat* v)
{
if (mAttribute[index] > 0)
{
- glVertexAttrib4fvARB(mAttribute[index], v);
+ glVertexAttrib4fv(mAttribute[index], v);
}
}
void LLGLSLShader::setMinimumAlpha(F32 minimum)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
gGL.flush();
uniform1f(LLShaderMgr::MINIMUM_ALPHA, minimum);
}
@@ -1678,3 +1914,39 @@ void LLShaderUniforms::apply(LLGLSLShader* shader)
shader->uniform3fv(uniform.mUniform, 1, uniform.mValue.mV);
}
}
+
+LLUUID LLGLSLShader::hash()
+{
+ HBXXH128 hash_obj;
+ hash_obj.update(mName);
+ hash_obj.update(&mShaderGroup, sizeof(mShaderGroup));
+ hash_obj.update(&mShaderLevel, sizeof(mShaderLevel));
+ for (const auto& shdr_pair : mShaderFiles)
+ {
+ hash_obj.update(shdr_pair.first);
+ hash_obj.update(&shdr_pair.second, sizeof(GLenum));
+ }
+ for (const auto& define_pair : mDefines)
+ {
+ hash_obj.update(define_pair.first);
+ hash_obj.update(define_pair.second);
+
+ }
+ for (const auto& define_pair : LLGLSLShader::sGlobalDefines)
+ {
+ hash_obj.update(define_pair.first);
+ hash_obj.update(define_pair.second);
+
+ }
+ hash_obj.update(&mFeatures, sizeof(LLShaderFeatures));
+ hash_obj.update(gGLManager.mGLVendor);
+ hash_obj.update(gGLManager.mGLRenderer);
+ hash_obj.update(gGLManager.mGLVersionString);
+ return hash_obj.digest();
+}
+
+#ifdef LL_PROFILER_ENABLE_RENDER_DOC
+void LLGLSLShader::setLabel(const char* label) {
+ LL_LABEL_OBJECT_GL(GL_PROGRAM, mProgramObject, strlen(label), label);
+}
+#endif