summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llrender/llgl.cpp4
-rw-r--r--indra/llrender/llglslshader.cpp752
-rw-r--r--indra/llrender/llglslshader.h342
-rw-r--r--indra/llrender/llrender.cpp113
-rw-r--r--indra/llrender/llrendertarget.cpp128
-rw-r--r--indra/llrender/llrendertarget.h16
-rw-r--r--indra/llrender/llvertexbuffer.cpp874
-rw-r--r--indra/llrender/llvertexbuffer.h73
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaMaskShadowF.glsl64
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowF.glsl68
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowV.glsl74
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarAlphaMaskShadowF.glsl8
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl9
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl9
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl12
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskSkinnedV.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl11
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/shadowSkinnedV.glsl9
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl15
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/treeShadowF.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/treeShadowSkinnedV.glsl9
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/treeShadowV.glsl13
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/copyF.glsl (renamed from indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl)23
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/copyV.glsl (renamed from indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl)34
-rw-r--r--indra/newview/lldrawpoolalpha.cpp29
-rw-r--r--indra/newview/lldrawpoolwater.cpp17
-rw-r--r--indra/newview/llgltfmateriallist.cpp4
-rw-r--r--indra/newview/llselectmgr.cpp1
-rw-r--r--indra/newview/lltooldraganddrop.cpp77
-rw-r--r--indra/newview/llviewerdisplay.cpp23
-rw-r--r--indra/newview/llviewershadermgr.cpp67
-rw-r--r--indra/newview/llviewershadermgr.h5
-rw-r--r--indra/newview/llviewerwindow.cpp8
-rw-r--r--indra/newview/pipeline.cpp262
-rw-r--r--indra/newview/pipeline.h8
39 files changed, 1377 insertions, 1826 deletions
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index e15157af05..67bd9e277e 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -2413,7 +2413,7 @@ void LLGLState::checkStates(const std::string& msg)
BOOL error = FALSE;
- if (src != GL_SRC_ALPHA || dst != GL_ONE_MINUS_SRC_ALPHA)
+ /*if (src != GL_SRC_ALPHA || dst != GL_ONE_MINUS_SRC_ALPHA)
{
if (gDebugSession)
{
@@ -2424,7 +2424,7 @@ void LLGLState::checkStates(const std::string& msg)
{
LL_GL_ERRS << "Blend function corrupted: " << std::hex << src << " " << std::hex << dst << " " << msg << std::dec << LL_ENDL;
}
- }
+ }*/
for (boost::unordered_map<LLGLenum, LLGLboolean>::iterator iter = sStateMap.begin();
iter != sStateMap.end(); ++iter)
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index e3b29dc812..c5f4efd2c0 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$
*/
@@ -37,8 +37,8 @@
#include "OpenGL/OpenGL.h"
#endif
-// 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.
+ // 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
@@ -55,24 +55,24 @@ std::set<LLGLSLShader*> LLGLSLShader::sInstances;
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;
// NOTE: Keep gShaderConsts* and LLGLSLShader::ShaderConsts_e in sync!
-const std::string gShaderConstsKey[ LLGLSLShader::NUM_SHADER_CONSTS ] =
+const std::string gShaderConstsKey[LLGLSLShader::NUM_SHADER_CONSTS] =
{
- "LL_SHADER_CONST_CLOUD_MOON_DEPTH"
- , "LL_SHADER_CONST_STAR_DEPTH"
+ "LL_SHADER_CONST_CLOUD_MOON_DEPTH"
+ , "LL_SHADER_CONST_STAR_DEPTH"
};
// NOTE: Keep gShaderConsts* and LLGLSLShader::ShaderConsts_e in sync!
-const std::string gShaderConstsVal[ LLGLSLShader::NUM_SHADER_CONSTS ] =
+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
+ "0.99998" // SHADER_CONST_CLOUD_MOON_DEPTH // SL-14113
+ , "0.99999" // SHADER_CONST_STAR_DEPTH // SL-14113
};
@@ -121,7 +121,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)
{
@@ -132,10 +132,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
@@ -158,11 +158,11 @@ void LLGLSLShader::finishProfile(bool emit_report)
{
(*iter)->dumpStats();
}
-
- 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;
+ 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;
}
}
@@ -171,15 +171,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;
@@ -187,36 +184,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;
}
}
@@ -232,108 +218,80 @@ 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()
{
- if (mTimerQuery == 0)
+ if (sProfileEnabled)
{
- glGenQueries(1, &mSamplesQuery);
- glGenQueries(1, &mTimerQuery);
- }
-
- if (!mTextureStateFetched)
- {
- mTextureStateFetched = true;
- mTextureMagFilter.resize(mTexture.size());
- mTextureMinFilter.resize(mTexture.size());
-
- U32 cur_active = gGL.getCurrentTexUnitIndex();
-
- for (U32 i = 0; i < mTexture.size(); ++i)
+ if (mTimerQuery == 0)
{
- GLint idx = mTexture[i];
-
- if (idx >= 0)
- {
- gGL.getTexUnit(idx)->activate();
-
- U32 mag = 0xFFFFFFFF;
- U32 min = 0xFFFFFFFF;
-
- U32 type = LLTexUnit::getInternalType(gGL.getTexUnit(idx)->getCurrType());
-
- glGetTexParameteriv(type, GL_TEXTURE_MAG_FILTER, (GLint*) &mag);
- glGetTexParameteriv(type, GL_TEXTURE_MIN_FILTER, (GLint*) &min);
-
- mTextureMagFilter[i] = mag;
- mTextureMinFilter[i] = min;
- }
+ glGenQueries(1, &mSamplesQuery);
+ glGenQueries(1, &mTimerQuery);
+ glGenQueries(1, &mPrimitivesQuery);
}
- gGL.getTexUnit(cur_active)->activate();
+ glBeginQuery(GL_SAMPLES_PASSED, mSamplesQuery);
+ glBeginQuery(GL_TIME_ELAPSED, mTimerQuery);
+ glBeginQuery(GL_PRIMITIVES_GENERATED, mPrimitivesQuery);
}
-
-
- glBeginQuery(GL_SAMPLES_PASSED, mSamplesQuery);
- glBeginQuery(GL_TIME_ELAPSED, mTimerQuery);
}
-void LLGLSLShader::readProfileQuery(U32 count, U32 mode)
+void LLGLSLShader::readProfileQuery()
{
- glEndQuery(GL_TIME_ELAPSED);
- glEndQuery(GL_SAMPLES_PASSED);
-
- U64 time_elapsed = 0;
- glGetQueryObjectui64v(mTimerQuery, GL_QUERY_RESULT, &time_elapsed);
+ if (sProfileEnabled)
+ {
+ glEndQuery(GL_TIME_ELAPSED);
+ glEndQuery(GL_SAMPLES_PASSED);
+ glEndQuery(GL_PRIMITIVES_GENERATED);
- U64 samples_passed = 0;
- glGetQueryObjectui64v(mSamplesQuery, GL_QUERY_RESULT, &samples_passed);
+ U64 time_elapsed = 0;
+ glGetQueryObjectui64v(mTimerQuery, GL_QUERY_RESULT, &time_elapsed);
- sTotalTimeElapsed += time_elapsed;
- mTimeElapsed += time_elapsed;
+ U64 samples_passed = 0;
+ glGetQueryObjectui64v(mSamplesQuery, GL_QUERY_RESULT, &samples_passed);
- sTotalSamplesDrawn += samples_passed;
- mSamplesDrawn += samples_passed;
+ U64 primitives_generated = 0;
+ glGetQueryObjectui64v(mPrimitivesQuery, GL_QUERY_RESULT, &primitives_generated);
+ sTotalTimeElapsed += time_elapsed;
+ mTimeElapsed += time_elapsed;
- 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
- }
+ sTotalSamplesDrawn += samples_passed;
+ mSamplesDrawn += samples_passed;
+
+ U32 tri_count = (U32)primitives_generated / 3;
- mTrianglesDrawn += tri_count;
- sTotalTrianglesDrawn += tri_count;
+ mTrianglesDrawn += tri_count;
+ sTotalTrianglesDrawn += tri_count;
- sTotalDrawCalls++;
- mDrawCalls++;
+ sTotalBinds++;
+ mBinds++;
+ }
}
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),
+ mUniformsDirty(FALSE),
+ mTimerQuery(0),
+ mSamplesQuery(0),
+ mPrimitivesQuery(0)
{
-
+
}
LLGLSLShader::~LLGLSLShader()
@@ -399,10 +357,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;
@@ -430,19 +388,19 @@ 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
-
+
#if DEBUG_SHADER_INCLUDES
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++ )
+ 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;
@@ -471,7 +429,7 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
#ifdef GL_INTERLEAVED_ATTRIBS
if (varying_count > 0 && varyings)
{
- glTransformFeedbackVaryings((GLuint64) mProgramObject, varying_count, varyings, GL_INTERLEAVED_ATTRIBS);
+ glTransformFeedbackVaryings((GLuint64)mProgramObject, varying_count, varyings, GL_INTERLEAVED_ATTRIBS);
}
#endif
@@ -484,7 +442,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;
@@ -493,7 +451,7 @@ 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 if (mFeatures.mIndexedTextureChannels > 0)
@@ -528,22 +486,22 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
}
#if DEBUG_SHADER_INCLUDES
-void dumpAttachObject( const char *func_name, GLuint program_object, const std::string &object_path )
+void dumpAttachObject(const char* func_name, GLuint program_object, const std::string& object_path)
{
GLchar* info_log;
GLint info_len_expect = 0;
GLint info_len_actual = 0;
- glGetShaderiv(program_object, GL_INFO_LOG_LENGTH,, &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 GLchar [ info_len_expect ];
- glGetProgramInfoLog(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
@@ -612,7 +570,7 @@ void LLGLSLShader::attachObjects(GLuint* objects, S32 count)
}
}
-BOOL LLGLSLShader::mapAttributes(const std::vector<LLStaticHashedString> * attributes)
+BOOL LLGLSLShader::mapAttributes(const std::vector<LLStaticHashedString>* attributes)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
@@ -620,9 +578,9 @@ 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();
- glBindAttribLocation(mProgramObject, i, (const GLchar *) name);
+ glBindAttribLocation(mProgramObject, i, (const GLchar*)name);
}
-
+
//link the program
BOOL res = link();
@@ -633,7 +591,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
@@ -643,7 +601,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 = glGetAttribLocation(mProgramObject, (const GLchar *)name);
+ S32 index = glGetAttribLocation(mProgramObject, (const GLchar*)name);
if (index != -1)
{
#if LL_RELEASE_WITH_DEBUG_INFO
@@ -671,11 +629,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;
@@ -691,45 +649,45 @@ void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString> *
name[0] = 0;
- glGetActiveUniform(mProgramObject, index, 1024, &length, &size, &type, (GLchar *)name);
+ 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;
}
@@ -750,11 +708,11 @@ void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString> *
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
@@ -768,12 +726,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, size);
+ mUniform[i + LLShaderMgr::instance()->mReservedUniforms.size()] = location;
+ mTexture[i + LLShaderMgr::instance()->mReservedUniforms.size()] = mapUniformTextureChannel(location, type, size);
return;
}
}
@@ -791,9 +749,9 @@ void LLGLSLShader::addPermutation(std::string name, std::string value)
mDefines[name] = value;
}
-void LLGLSLShader::addConstant( const LLGLSLShader::eShaderConsts shader_const )
+void LLGLSLShader::addConstant(const LLGLSLShader::eShaderConsts shader_const)
{
- addPermutation( gShaderConstsKey[ shader_const ], gShaderConstsVal[ shader_const ] );
+ addPermutation(gShaderConstsKey[shader_const], gShaderConstsVal[shader_const]);
}
void LLGLSLShader::removePermutation(std::string name)
@@ -805,7 +763,7 @@ GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type, GLint
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
- if ((type >= GL_SAMPLER_1D && type <= GL_SAMPLER_2D_RECT_SHADOW) ||
+ 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
@@ -827,8 +785,8 @@ GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type, GLint
channel[i] = mActiveTextureChannels++;
}
glUniform1iv(location, size, channel);
- LL_DEBUGS("ShaderUniform") << "Assigned to texture channel " <<
- (mActiveTextureChannels-size) << " through " << (mActiveTextureChannels-1) << LL_ENDL;
+ LL_DEBUGS("ShaderUniform") << "Assigned to texture channel " <<
+ (mActiveTextureChannels - size) << " through " << (mActiveTextureChannels - 1) << LL_ENDL;
}
llassert(mActiveTextureChannels <= 32); // too many textures (probably)
@@ -837,102 +795,102 @@ GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type, GLint
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);
-
- bind();
-
- //get the number of active uniforms
- GLint activeCount;
+ 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;
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 = glGetUniformLocation(mProgramObject, "diffuseMap");
- S32 specularMap = glGetUniformLocation(mProgramObject, "specularMap");
- S32 bumpMap = glGetUniformLocation(mProgramObject, "bumpMap");
+ 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 environmentMap = glGetUniformLocation(mProgramObject, "environmentMap");
S32 reflectionMap = glGetUniformLocation(mProgramObject, "reflectionMap");
- std::set<S32> skip_index;
+ std::set<S32> skip_index;
- if (-1 != diffuseMap && (-1 != specularMap || -1 != bumpMap || -1 != environmentMap || -1 != altDiffuseMap))
- {
- GLenum type;
- GLsizei length;
- GLint size = -1;
- char name[1024];
+ if (-1 != diffuseMap && (-1 != specularMap || -1 != bumpMap || -1 != environmentMap || -1 != altDiffuseMap))
+ {
+ GLenum type;
+ GLsizei length;
+ GLint size = -1;
+ char name[1024];
- diffuseMap = altDiffuseMap = specularMap = bumpMap = environmentMap = -1;
+ diffuseMap = altDiffuseMap = specularMap = bumpMap = environmentMap = -1;
- for (S32 i = 0; i < activeCount; i++)
- {
- name[0] = '\0';
+ for (S32 i = 0; i < activeCount; i++)
+ {
+ name[0] = '\0';
- glGetActiveUniform(mProgramObject, i, 1024, &length, &size, &type, (GLchar *)name);
+ glGetActiveUniform(mProgramObject, i, 1024, &length, &size, &type, (GLchar*)name);
- if (-1 == diffuseMap && std::string(name) == "diffuseMap")
- {
- diffuseMap = i;
- continue;
- }
+ if (-1 == diffuseMap && std::string(name) == "diffuseMap")
+ {
+ diffuseMap = i;
+ continue;
+ }
- if (-1 == specularMap && std::string(name) == "specularMap")
- {
- specularMap = i;
- continue;
- }
+ if (-1 == specularMap && std::string(name) == "specularMap")
+ {
+ specularMap = i;
+ continue;
+ }
- if (-1 == bumpMap && std::string(name) == "bumpMap")
- {
- bumpMap = i;
- continue;
- }
+ if (-1 == bumpMap && std::string(name) == "bumpMap")
+ {
+ bumpMap = i;
+ continue;
+ }
- if (-1 == environmentMap && std::string(name) == "environmentMap")
- {
- environmentMap = i;
- continue;
- }
+ if (-1 == environmentMap && std::string(name) == "environmentMap")
+ {
+ environmentMap = i;
+ continue;
+ }
if (-1 == reflectionMap && std::string(name) == "reflectionMap")
{
@@ -941,55 +899,55 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
}
if (-1 == altDiffuseMap && std::string(name) == "altDiffuseMap")
- {
- altDiffuseMap = i;
- continue;
- }
- }
-
- bool specularDiff = specularMap < diffuseMap && -1 != specularMap;
- bool bumpLessDiff = bumpMap < diffuseMap && -1 != bumpMap;
- bool envLessDiff = environmentMap < diffuseMap && -1 != environmentMap;
+ {
+ altDiffuseMap = i;
+ continue;
+ }
+ }
+
+ 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 || refLessDiff)
- {
- 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);
+ }
+ //........................................................................................................................................
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
@@ -1002,10 +960,10 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
glUniformBlockBinding(mProgramObject, UBOBlockIndex, BLOCKBINDING);
}
}
- unbind();
+ unbind();
- LL_DEBUGS("ShaderUniform") << "Total Uniform Size: " << mTotalUniformSize << LL_ENDL;
- return res;
+ LL_DEBUGS("ShaderUniform") << "Total Uniform Size: " << mTotalUniformSize << LL_ENDL;
+ return res;
}
@@ -1031,10 +989,15 @@ void LLGLSLShader::bind()
if (sCurBoundShader != mProgramObject) // Don't re-bind current shader
{
+ if (sCurBoundShaderPtr)
+ {
+ sCurBoundShaderPtr->readProfileQuery();
+ }
LLVertexBuffer::unbind();
glUseProgram(mProgramObject);
sCurBoundShader = mProgramObject;
sCurBoundShaderPtr = this;
+ placeProfileQuery();
}
if (mUniformsDirty)
@@ -1060,8 +1023,11 @@ void LLGLSLShader::bind(bool rigged)
void LLGLSLShader::unbind()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
-
gGL.flush();
+ if (sCurBoundShaderPtr)
+ {
+ sCurBoundShaderPtr->readProfileQuery();
+ }
stop_glerror();
LLVertexBuffer::unbind();
glUseProgram(0);
@@ -1075,22 +1041,28 @@ void LLGLSLShader::bindNoShader(void)
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
LLVertexBuffer::unbind();
+
+ if (sCurBoundShaderPtr)
+ {
+ sCurBoundShaderPtr->readProfileQuery();
+ }
+
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;
@@ -1099,25 +1071,25 @@ 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::unbindTexture(const std::string& uniform, LLTexUnit::eTextureType mode)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
S32 channel = 0;
channel = getUniformLocation(uniform);
-
+
return unbindTexture(channel);
}
@@ -1130,14 +1102,14 @@ 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;
}
@@ -1194,7 +1166,7 @@ void LLGLSLShader::uniform1i(U32 index, GLint x)
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;
@@ -1207,7 +1179,7 @@ void LLGLSLShader::uniform1i(U32 index, GLint x)
if (iter == mValue.end() || iter->second.mV[0] != x)
{
glUniform1i(mUniform[index], x);
- mValue[mUniform[index]] = LLVector4(x,0.f,0.f,0.f);
+ mValue[mUniform[index]] = LLVector4(x, 0.f, 0.f, 0.f);
}
}
}
@@ -1219,7 +1191,7 @@ void LLGLSLShader::uniform1f(U32 index, GLfloat x)
llassert(sCurBoundShaderPtr == this);
if (mProgramObject)
- {
+ {
if (mUniform.size() <= index)
{
LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
@@ -1232,7 +1204,7 @@ void LLGLSLShader::uniform1f(U32 index, GLfloat x)
if (iter == mValue.end() || iter->second.mV[0] != x)
{
glUniform1f(mUniform[index], x);
- mValue[mUniform[index]] = LLVector4(x,0.f,0.f,0.f);
+ mValue[mUniform[index]] = LLVector4(x, 0.f, 0.f, 0.f);
}
}
}
@@ -1254,7 +1226,7 @@ void LLGLSLShader::uniform2f(U32 index, GLfloat x, GLfloat y)
llassert(sCurBoundShaderPtr == this);
if (mProgramObject)
- {
+ {
if (mUniform.size() <= index)
{
LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
@@ -1264,8 +1236,8 @@ 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))
{
glUniform2f(mUniform[index], x, y);
mValue[mUniform[index]] = vec;
@@ -1280,7 +1252,7 @@ void LLGLSLShader::uniform3f(U32 index, GLfloat x, GLfloat y, GLfloat z)
llassert(sCurBoundShaderPtr == this);
if (mProgramObject)
- {
+ {
if (mUniform.size() <= index)
{
LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
@@ -1290,8 +1262,8 @@ 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))
{
glUniform3f(mUniform[index], x, y, z);
mValue[mUniform[index]] = vec;
@@ -1306,7 +1278,7 @@ void LLGLSLShader::uniform4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat
llassert(sCurBoundShaderPtr == this);
if (mProgramObject)
- {
+ {
if (mUniform.size() <= index)
{
LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
@@ -1316,8 +1288,8 @@ 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))
{
glUniform4f(mUniform[index], x, y, z, w);
mValue[mUniform[index]] = vec;
@@ -1332,7 +1304,7 @@ void LLGLSLShader::uniform1iv(U32 index, U32 count, const GLint* v)
llassert(sCurBoundShaderPtr == this);
if (mProgramObject)
- {
+ {
if (mUniform.size() <= index)
{
LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
@@ -1342,8 +1314,8 @@ 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], 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;
@@ -1385,7 +1357,7 @@ void LLGLSLShader::uniform1fv(U32 index, U32 count, const GLfloat* v)
llassert(sCurBoundShaderPtr == this);
if (mProgramObject)
- {
+ {
if (mUniform.size() <= index)
{
LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
@@ -1395,8 +1367,8 @@ 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)
{
glUniform1fv(mUniform[index], count, v);
mValue[mUniform[index]] = vec;
@@ -1411,7 +1383,7 @@ void LLGLSLShader::uniform2fv(U32 index, U32 count, const GLfloat* v)
llassert(sCurBoundShaderPtr == this);
if (mProgramObject)
- {
+ {
if (mUniform.size() <= index)
{
LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
@@ -1421,8 +1393,8 @@ 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)
{
glUniform2fv(mUniform[index], count, v);
mValue[mUniform[index]] = vec;
@@ -1437,7 +1409,7 @@ void LLGLSLShader::uniform3fv(U32 index, U32 count, const GLfloat* v)
llassert(sCurBoundShaderPtr == this);
if (mProgramObject)
- {
+ {
if (mUniform.size() <= index)
{
LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
@@ -1447,8 +1419,8 @@ 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)
{
glUniform3fv(mUniform[index], count, v);
mValue[mUniform[index]] = vec;
@@ -1463,7 +1435,7 @@ void LLGLSLShader::uniform4fv(U32 index, U32 count, const GLfloat* v)
llassert(sCurBoundShaderPtr == this);
if (mProgramObject)
- {
+ {
if (mUniform.size() <= index)
{
LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
@@ -1473,8 +1445,8 @@ 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;
glUniform4fv(mUniform[index], count, v);
@@ -1484,13 +1456,13 @@ void LLGLSLShader::uniform4fv(U32 index, U32 count, const GLfloat* v)
}
}
-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;
@@ -1504,13 +1476,13 @@ void LLGLSLShader::uniformMatrix2fv(U32 index, U32 count, GLboolean transpose, c
}
}
-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;
@@ -1524,33 +1496,33 @@ void LLGLSLShader::uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, c
}
}
-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;
@@ -1626,12 +1598,12 @@ 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))
+ LLVector4 vec(v, 0.f, 0.f, 0.f);
+ if (iter == mValue.end() || shouldChange(iter->second, vec))
{
glUniform1i(location, v);
mValue[location] = vec;
@@ -1679,12 +1651,12 @@ void LLGLSLShader::uniform2i(const LLStaticHashedString& uniform, GLint i, GLint
{
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))
{
glUniform2i(location, i, j);
mValue[location] = vec;
@@ -1697,12 +1669,12 @@ 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))
{
glUniform1f(location, v);
mValue[location] = vec;
@@ -1714,14 +1686,14 @@ void LLGLSLShader::uniform2f(const LLStaticHashedString& uniform, GLfloat x, GLf
{
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))
{
- glUniform2f(location, x,y);
+ glUniform2f(location, x, y);
mValue[location] = vec;
}
}
@@ -1732,14 +1704,14 @@ void LLGLSLShader::uniform3f(const LLStaticHashedString& uniform, GLfloat x, GLf
{
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))
{
- glUniform3f(location, x,y,z);
+ glUniform3f(location, x, y, z);
mValue[location] = vec;
}
}
@@ -1753,8 +1725,8 @@ void LLGLSLShader::uniform1fv(const LLStaticHashedString& uniform, U32 count, co
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)
{
glUniform1fv(location, count, v);
mValue[location] = vec;
@@ -1766,12 +1738,12 @@ void LLGLSLShader::uniform2fv(const LLStaticHashedString& uniform, U32 count, co
{
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)
{
glUniform2fv(location, count, v);
mValue[location] = vec;
@@ -1783,12 +1755,12 @@ void LLGLSLShader::uniform3fv(const LLStaticHashedString& uniform, U32 count, co
{
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)
{
glUniform3fv(location, count, v);
mValue[location] = vec;
@@ -1805,7 +1777,7 @@ void LLGLSLShader::uniform4fv(const LLStaticHashedString& uniform, U32 count, co
{
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;
glUniform4fv(location, count, v);
@@ -1818,7 +1790,7 @@ void LLGLSLShader::uniformMatrix4fv(const LLStaticHashedString& uniform, U32 cou
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
GLint location = getUniformLocation(uniform);
-
+
if (location >= 0)
{
stop_glerror();
diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index 23db1a8549..0522f78614 100644
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llglslshader.h
* @brief GLSL shader wrappers
*
* $LicenseInfo:firstyear=2001&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$
*/
@@ -35,36 +35,36 @@
class LLShaderFeatures
{
public:
- bool atmosphericHelpers;
- bool calculatesLighting;
- bool calculatesAtmospherics;
- bool hasLighting; // implies no transport (it's possible to have neither though)
- bool isAlphaLighting; // indicates lighting shaders need not be linked in (lighting performed directly in alpha shader to match deferred lighting functions)
- bool isShiny;
- bool isFullbright; // implies no lighting
- bool isSpecular;
- bool hasWaterFog; // implies no gamma
- bool hasTransport; // implies no lighting (it's possible to have neither though)
- bool hasSkinning;
- bool hasObjectSkinning;
- bool hasAtmospherics;
- bool hasGamma;
+ bool atmosphericHelpers;
+ bool calculatesLighting;
+ bool calculatesAtmospherics;
+ bool hasLighting; // implies no transport (it's possible to have neither though)
+ bool isAlphaLighting; // indicates lighting shaders need not be linked in (lighting performed directly in alpha shader to match deferred lighting functions)
+ bool isShiny;
+ bool isFullbright; // implies no lighting
+ bool isSpecular;
+ bool hasWaterFog; // implies no gamma
+ bool hasTransport; // implies no lighting (it's possible to have neither though)
+ bool hasSkinning;
+ bool hasObjectSkinning;
+ bool hasAtmospherics;
+ bool hasGamma;
bool hasShadows;
bool hasAmbientOcclusion;
- bool hasSrgb;
+ bool hasSrgb;
bool encodesNormal; // include: shaders\class1\environment\encodeNormF.glsl
bool isDeferred;
bool hasScreenSpaceReflections;
bool hasIndirect;
- S32 mIndexedTextureChannels;
- bool disableTextureIndex;
- bool hasAlphaMask;
+ S32 mIndexedTextureChannels;
+ bool disableTextureIndex;
+ bool hasAlphaMask;
bool hasReflectionProbes = false;
- bool attachNothing;
+ bool attachNothing;
- // char numLights;
-
- LLShaderFeatures();
+ // char numLights;
+
+ LLShaderFeatures();
};
// ============= Structure for caching shader uniforms ===============
@@ -108,7 +108,7 @@ public:
{
mVectors.push_back({ index, value });
}
-
+
void uniform4fv(S32 index, const F32* value)
{
mVectors.push_back({ index, LLVector4(value) });
@@ -125,7 +125,7 @@ public:
}
void apply(LLGLSLShader* shader);
-
+
std::vector<IntSetting> mIntegers;
std::vector<FloatSetting> mFloats;
@@ -138,184 +138,182 @@ public:
// NOTE: Keep gShaderConsts and LLGLSLShader::ShaderConsts_e in sync!
enum eShaderConsts
{
- SHADER_CONST_CLOUD_MOON_DEPTH
+ SHADER_CONST_CLOUD_MOON_DEPTH
, SHADER_CONST_STAR_DEPTH
, NUM_SHADER_CONSTS
};
// enum primarily used to control application sky settings uniforms
- typedef enum
- {
- SG_DEFAULT = 0, // not sky or water specific
- SG_SKY, //
- SG_WATER,
+ typedef enum
+ {
+ SG_DEFAULT = 0, // not sky or water specific
+ SG_SKY, //
+ SG_WATER,
SG_ANY,
SG_COUNT
- } eGroup;
-
- static std::set<LLGLSLShader*> sInstances;
- static bool sProfileEnabled;
-
- LLGLSLShader();
- ~LLGLSLShader();
-
- static GLuint sCurBoundShader;
- static LLGLSLShader* sCurBoundShaderPtr;
- static S32 sIndexedTextureChannels;
-
- static void initProfile();
- static void finishProfile(bool emit_report = true);
-
- static void startProfile();
- static void stopProfile(U32 count, U32 mode);
-
- void unload();
- void clearStats();
- void dumpStats();
- void placeProfileQuery();
- void readProfileQuery(U32 count, U32 mode);
-
- BOOL createShader(std::vector<LLStaticHashedString> * attributes,
- std::vector<LLStaticHashedString> * uniforms,
- U32 varying_count = 0,
- const char** varyings = NULL);
+ } eGroup;
+
+ static std::set<LLGLSLShader*> sInstances;
+ static bool sProfileEnabled;
+
+ LLGLSLShader();
+ ~LLGLSLShader();
+
+ static GLuint sCurBoundShader;
+ static LLGLSLShader* sCurBoundShaderPtr;
+ static S32 sIndexedTextureChannels;
+
+ static void initProfile();
+ static void finishProfile(bool emit_report = true);
+
+ static void startProfile();
+ static void stopProfile();
+
+ void unload();
+ void clearStats();
+ void dumpStats();
+ void placeProfileQuery();
+ void readProfileQuery();
+
+ BOOL createShader(std::vector<LLStaticHashedString>* attributes,
+ std::vector<LLStaticHashedString>* uniforms,
+ U32 varying_count = 0,
+ const char** varyings = NULL);
BOOL attachFragmentObject(std::string object);
BOOL attachVertexObject(std::string object);
- void attachObject(GLuint object);
- 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 uniform1i(U32 index, GLint i);
- void uniform1f(U32 index, GLfloat v);
+ void attachObject(GLuint object);
+ 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 uniform1i(U32 index, GLint i);
+ void uniform1f(U32 index, GLfloat v);
void fastUniform1f(U32 index, GLfloat v);
- void uniform2f(U32 index, GLfloat x, GLfloat y);
- void uniform3f(U32 index, GLfloat x, GLfloat y, GLfloat z);
- void uniform4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
- void uniform1iv(U32 index, U32 count, const GLint* i);
+ void uniform2f(U32 index, GLfloat x, GLfloat y);
+ void uniform3f(U32 index, GLfloat x, GLfloat y, GLfloat z);
+ void uniform4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ void uniform1iv(U32 index, U32 count, const GLint* i);
void uniform4iv(U32 index, U32 count, const GLint* i);
- void uniform1fv(U32 index, U32 count, const GLfloat* v);
- void uniform2fv(U32 index, U32 count, const GLfloat* v);
- void uniform3fv(U32 index, U32 count, const GLfloat* v);
- void uniform4fv(U32 index, U32 count, const GLfloat* v);
- void uniform2i(const LLStaticHashedString& uniform, GLint i, GLint j);
- void uniformMatrix2fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v);
- void uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v);
- void uniformMatrix3x4fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v);
- void uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v);
- void uniform1i(const LLStaticHashedString& uniform, GLint i);
+ void uniform1fv(U32 index, U32 count, const GLfloat* v);
+ void uniform2fv(U32 index, U32 count, const GLfloat* v);
+ void uniform3fv(U32 index, U32 count, const GLfloat* v);
+ void uniform4fv(U32 index, U32 count, const GLfloat* v);
+ void uniform2i(const LLStaticHashedString& uniform, GLint i, GLint j);
+ void uniformMatrix2fv(U32 index, U32 count, GLboolean transpose, const GLfloat* v);
+ void uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, const GLfloat* v);
+ void uniformMatrix3x4fv(U32 index, U32 count, GLboolean transpose, const GLfloat* v);
+ void uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, const GLfloat* v);
+ void uniform1i(const LLStaticHashedString& uniform, GLint i);
void uniform1iv(const LLStaticHashedString& uniform, U32 count, const GLint* v);
void uniform4iv(const LLStaticHashedString& uniform, U32 count, const GLint* v);
- void uniform1f(const LLStaticHashedString& uniform, GLfloat v);
- void uniform2f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y);
- void uniform3f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y, GLfloat z);
- void uniform1fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v);
- void uniform2fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v);
- void uniform3fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v);
- void uniform4fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v);
- void uniformMatrix4fv(const LLStaticHashedString& uniform, U32 count, GLboolean transpose, const GLfloat *v);
-
- void setMinimumAlpha(F32 minimum);
-
- void vertexAttrib4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
- void vertexAttrib4fv(U32 index, GLfloat* v);
-
- //GLint getUniformLocation(const std::string& uniform);
- GLint getUniformLocation(const LLStaticHashedString& uniform);
- GLint getUniformLocation(U32 index);
-
- GLint getAttribLocation(U32 attrib);
- GLint mapUniformTextureChannel(GLint location, GLenum type, GLint size);
-
+ void uniform1f(const LLStaticHashedString& uniform, GLfloat v);
+ void uniform2f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y);
+ void uniform3f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y, GLfloat z);
+ void uniform1fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v);
+ void uniform2fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v);
+ void uniform3fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v);
+ void uniform4fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v);
+ void uniformMatrix4fv(const LLStaticHashedString& uniform, U32 count, GLboolean transpose, const GLfloat* v);
+
+ void setMinimumAlpha(F32 minimum);
+
+ void vertexAttrib4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ void vertexAttrib4fv(U32 index, GLfloat* v);
+
+ //GLint getUniformLocation(const std::string& uniform);
+ GLint getUniformLocation(const LLStaticHashedString& uniform);
+ GLint getUniformLocation(U32 index);
+
+ GLint getAttribLocation(U32 attrib);
+ GLint mapUniformTextureChannel(GLint location, GLenum type, GLint size);
+
void clearPermutations();
- void addPermutation(std::string name, std::string value);
- void removePermutation(std::string name);
-
- void addConstant( const LLGLSLShader::eShaderConsts shader_const );
-
- //enable/disable texture channel for specified uniform
- //if given texture uniform is active in the shader,
- //the corresponding channel will be active upon return
- //returns channel texture is enabled in from [0-MAX)
- S32 enableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE, LLTexUnit::eTextureColorSpace space = LLTexUnit::TCS_LINEAR);
+ void addPermutation(std::string name, std::string value);
+ void removePermutation(std::string name);
+
+ void addConstant(const LLGLSLShader::eShaderConsts shader_const);
+
+ //enable/disable texture channel for specified uniform
+ //if given texture uniform is active in the shader,
+ //the corresponding channel will be active upon return
+ //returns channel texture is enabled in from [0-MAX)
+ S32 enableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE, LLTexUnit::eTextureColorSpace space = LLTexUnit::TCS_LINEAR);
S32 disableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE, LLTexUnit::eTextureColorSpace space = LLTexUnit::TCS_LINEAR);
-
- // bindTexture returns the texture unit we've bound the texture to.
- // You can reuse the return value to unbind a texture when required.
- S32 bindTexture(const std::string& uniform, LLTexture *texture, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE, LLTexUnit::eTextureColorSpace space = LLTexUnit::TCS_LINEAR);
- S32 bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE, LLTexUnit::eTextureColorSpace space = LLTexUnit::TCS_LINEAR);
- S32 unbindTexture(const std::string& uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
- S32 unbindTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
-
+
+ // bindTexture returns the texture unit we've bound the texture to.
+ // You can reuse the return value to unbind a texture when required.
+ S32 bindTexture(const std::string& uniform, LLTexture* texture, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE, LLTexUnit::eTextureColorSpace space = LLTexUnit::TCS_LINEAR);
+ S32 bindTexture(S32 uniform, LLTexture* texture, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE, LLTexUnit::eTextureColorSpace space = LLTexUnit::TCS_LINEAR);
+ S32 unbindTexture(const std::string& uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
+ S32 unbindTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
+
BOOL link(BOOL suppress_errors = FALSE);
- void bind();
+ void bind();
//helper to conditionally bind mRiggedVariant instead of this
void bind(bool rigged);
- void unbind();
+ void unbind();
- // Unbinds any previously bound shader by explicitly binding no shader.
- static void bindNoShader(void);
+ // Unbinds any previously bound shader by explicitly binding no shader.
+ static void bindNoShader(void);
- U32 mMatHash[LLRender::NUM_MATRIX_MODES];
- U32 mLightHash;
+ U32 mMatHash[LLRender::NUM_MATRIX_MODES];
+ U32 mLightHash;
- GLuint mProgramObject;
+ GLuint mProgramObject;
#if LL_RELEASE_WITH_DEBUG_INFO
- struct attr_name
- {
- GLint loc;
- const char *name;
- void operator = (GLint _loc) { loc = _loc; }
- operator GLint () { return loc; }
- };
- std::vector<attr_name> mAttribute; //lookup table of attribute enum to attribute channel
+ struct attr_name
+ {
+ GLint loc;
+ const char* name;
+ void operator = (GLint _loc) { loc = _loc; }
+ operator GLint () { return loc; }
+ };
+ std::vector<attr_name> mAttribute; //lookup table of attribute enum to attribute channel
#else
- std::vector<GLint> mAttribute; //lookup table of attribute enum to attribute channel
+ std::vector<GLint> mAttribute; //lookup table of attribute enum to attribute channel
#endif
- U32 mAttributeMask; //mask of which reserved attributes are set (lines up with LLVertexBuffer::getTypeMask())
- std::vector<GLint> mUniform; //lookup table of uniform enum to uniform location
- LLStaticStringTable<GLint> mUniformMap; //lookup map of uniform name to uniform location
+ U32 mAttributeMask; //mask of which reserved attributes are set (lines up with LLVertexBuffer::getTypeMask())
+ std::vector<GLint> mUniform; //lookup table of uniform enum to uniform location
+ LLStaticStringTable<GLint> mUniformMap; //lookup map of uniform name to uniform location
typedef std::unordered_map<GLint, std::string> uniform_name_map_t;
typedef std::unordered_map<GLint, LLVector4> uniform_value_map_t;
uniform_name_map_t mUniformNameMap; //lookup map of uniform location to uniform name
- uniform_value_map_t mValue; //lookup map of uniform location to last known value
- std::vector<GLint> mTexture;
- S32 mTotalUniformSize;
- S32 mActiveTextureChannels;
- S32 mShaderLevel;
- S32 mShaderGroup; // see LLGLSLShader::eGroup
- BOOL mUniformsDirty;
- LLShaderFeatures mFeatures;
- std::vector< std::pair< std::string, GLenum > > mShaderFiles;
- std::string mName;
+ uniform_value_map_t mValue; //lookup map of uniform location to last known value
+ std::vector<GLint> mTexture;
+ S32 mTotalUniformSize;
+ S32 mActiveTextureChannels;
+ S32 mShaderLevel;
+ S32 mShaderGroup; // see LLGLSLShader::eGroup
+ BOOL mUniformsDirty;
+ LLShaderFeatures mFeatures;
+ std::vector< std::pair< std::string, GLenum > > mShaderFiles;
+ std::string mName;
typedef std::unordered_map<std::string, std::string> defines_map_t;
- defines_map_t mDefines;
-
- //statistcis for profiling shader performance
- U32 mTimerQuery;
- U32 mSamplesQuery;
- U64 mTimeElapsed;
- static U64 sTotalTimeElapsed;
- U32 mTrianglesDrawn;
- static U32 sTotalTrianglesDrawn;
- U64 mSamplesDrawn;
- static U64 sTotalSamplesDrawn;
- U32 mDrawCalls;
- static U32 sTotalDrawCalls;
-
- bool mTextureStateFetched;
- std::vector<U32> mTextureMagFilter;
- std::vector<U32> mTextureMinFilter;
+ defines_map_t mDefines;
+
+ //statistics for profiling shader performance
+ U32 mTimerQuery;
+ U32 mSamplesQuery;
+ U32 mPrimitivesQuery;
+
+ U64 mTimeElapsed;
+ static U64 sTotalTimeElapsed;
+ U32 mTrianglesDrawn;
+ static U32 sTotalTrianglesDrawn;
+ U64 mSamplesDrawn;
+ static U64 sTotalSamplesDrawn;
+ U32 mBinds;
+ static U32 sTotalBinds;
// this pointer should be set to whichever shader represents this shader's rigged variant
LLGLSLShader* mRiggedVariant = nullptr;
- #ifdef LL_PROFILER_ENABLE_RENDER_DOC
+#ifdef LL_PROFILER_ENABLE_RENDER_DOC
void setLabel(const char* label);
- #endif
+#endif
private:
- void unloadInternal();
+ void unloadInternal();
};
//UI shader (declared here so llui_libtest will link properly)
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index c58fbe6c8e..02942eb292 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -35,6 +35,7 @@
#include "llrendertarget.h"
#include "lltexture.h"
#include "llshadermgr.h"
+#include "llmd5.h"
#if LL_WINDOWS
extern void APIENTRY gl_debug_callback(GLenum source,
@@ -66,6 +67,14 @@ LLVector2 LLRender::sUIGLScaleFactor = LLVector2(1.f, 1.f);
static const U32 LL_NUM_TEXTURE_LAYERS = 32;
static const U32 LL_NUM_LIGHT_UNITS = 8;
+struct LLVBCache
+{
+ LLPointer<LLVertexBuffer> vb;
+ std::chrono::steady_clock::time_point touched;
+};
+
+static std::unordered_map<std::size_t, LLVBCache> sVBCache;
+
static const GLenum sGLTextureType[] =
{
GL_TEXTURE_2D,
@@ -370,9 +379,10 @@ bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth)
if (bindDepth)
{
- if (renderTarget->hasStencil())
+
+ if (renderTarget->getDepth() && !renderTarget->canSampleDepth())
{
- LL_ERRS() << "Cannot bind a render buffer for sampling. Allocate render target without a stencil buffer if sampling of depth buffer is required." << LL_ENDL;
+ LL_ERRS() << "Cannot bind a render buffer for sampling. Allocate render target with depth buffer sampling enabled." << LL_ENDL;
}
bindManual(renderTarget->getUsage(), renderTarget->getDepth());
@@ -1634,24 +1644,105 @@ void LLRender::flush()
if (mBuffer)
{
- if (mBuffer->useVBOs() && !mBuffer->isLocked())
- { //hack to only flush the part of the buffer that was updated (relies on stream draw using buffersubdata)
- mBuffer->getVertexStrider(mVerticesp, 0, count);
- mBuffer->getTexCoord0Strider(mTexcoordsp, 0, count);
- mBuffer->getColorStrider(mColorsp, 0, count);
+
+ LLMD5 hash;
+ U32 attribute_mask = LLGLSLShader::sCurBoundShaderPtr->mAttributeMask;
+
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vb cache hash");
+
+ hash.update((U8*)mVerticesp.get(), count * sizeof(LLVector4a));
+ if (attribute_mask & LLVertexBuffer::MAP_TEXCOORD0)
+ {
+ hash.update((U8*)mTexcoordsp.get(), count * sizeof(LLVector2));
+ }
+
+ if (attribute_mask & LLVertexBuffer::MAP_COLOR)
+ {
+ hash.update((U8*)mColorsp.get(), count * sizeof(LLColor4U));
+ }
+
+ hash.finalize();
+ }
+
+ size_t vhash[2];
+ hash.raw_digest((unsigned char*) vhash);
+
+ // check the VB cache before making a new vertex buffer
+ // This is a giant hack to deal with (mostly) our terrible UI rendering code
+ // that was built on top of OpenGL immediate mode. Huge performance wins
+ // can be had by not uploading geometry to VRAM unless absolutely necessary.
+ // Most of our usage of the "immediate mode" style draw calls is actually
+ // sending the same geometry over and over again.
+ // To leverage this, we maintain a running hash of the vertex stream being
+ // built up before a flush, and then check that hash against a VB
+ // cache just before creating a vertex buffer in VRAM
+ auto& cache = sVBCache.find(vhash[0]);
+
+ LLPointer<LLVertexBuffer> vb;
+
+ if (cache != sVBCache.end())
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vb cache hit");
+ // cache hit, just use the cached buffer
+ vb = cache->second.vb;
+ cache->second.touched = std::chrono::steady_clock::now();
+ }
+ else
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vb cache miss");
+ vb = new LLVertexBuffer(attribute_mask, GL_STATIC_DRAW);
+ vb->allocateBuffer(count, 0, true);
+ vb->setPositionData((LLVector4a*) mVerticesp.get());
+
+ if (attribute_mask & LLVertexBuffer::MAP_TEXCOORD0)
+ {
+ vb->setTexCoordData(mTexcoordsp.get());
+ }
+
+ if (attribute_mask & LLVertexBuffer::MAP_COLOR)
+ {
+ vb->setColorData(mColorsp.get());
+ }
+
+ vb->unbind();
+
+ sVBCache[vhash[0]] = { vb , std::chrono::steady_clock::now() };
+
+ static U32 miss_count = 0;
+ miss_count++;
+ if (miss_count > 1024)
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vb cache clean");
+ miss_count = 0;
+ auto now = std::chrono::steady_clock::now();
+
+ using namespace std::chrono_literals;
+ // every 1024 misses, clean the cache of any VBs that haven't been touched in the last second
+ for (auto& iter = sVBCache.begin(); iter != sVBCache.end(); )
+ {
+ if (now - iter->second.touched > 1s)
+ {
+ iter = sVBCache.erase(iter);
+ }
+ else
+ {
+ ++iter;
+ }
+ }
+ }
}
- mBuffer->flush();
- mBuffer->setBuffer(immediate_mask);
+ vb->setBuffer(attribute_mask);
if (mMode == LLRender::QUADS && sGLCoreProfile)
{
- mBuffer->drawArrays(LLRender::TRIANGLES, 0, count);
+ vb->drawArrays(LLRender::TRIANGLES, 0, count);
mQuadCycle = 1;
}
else
{
- mBuffer->drawArrays(mMode, 0, count);
+ vb->drawArrays(mMode, 0, count);
}
}
else
diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
index 01ccf3d314..9827db8084 100644
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -67,9 +67,8 @@ LLRenderTarget::LLRenderTarget() :
mPreviousResX(0),
mPreviousResY(0),
mDepth(0),
- mStencil(0),
mUseDepth(false),
- mRenderDepth(false),
+ mSampleDepth(false),
mUsage(LLTexUnit::TT_TEXTURE)
{
}
@@ -98,11 +97,11 @@ void LLRenderTarget::resize(U32 resx, U32 resy)
if (mDepth)
{ //resize depth attachment
- if (mStencil)
+ if (!mSampleDepth)
{
//use render buffers where stencil buffers are in play
glBindRenderbuffer(GL_RENDERBUFFER, mDepth);
- glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, mResX, mResY);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, mResX, mResY);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
}
else
@@ -117,7 +116,7 @@ void LLRenderTarget::resize(U32 resx, U32 resy)
}
-bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, S32 samples)
+bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool sample_depth, LLTexUnit::eTextureType usage, bool use_fbo, S32 samples)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
resx = llmin(resx, (U32) gGLManager.mGLMaxTextureSize);
@@ -130,9 +129,9 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, boo
mResX = resx;
mResY = resy;
- mStencil = stencil;
mUsage = usage;
- mUseDepth = depth;
+ mUseDepth = depth;
+ mSampleDepth = sample_depth;
if ((sUseFBO || use_fbo))
{
@@ -150,13 +149,10 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, boo
if (mDepth)
{
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
- llassert(!mStencil); // use of stencil buffer is deprecated (performance penalty)
- if (mStencil)
+
+ if (!canSampleDepth())
{
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepth);
- stop_glerror();
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mDepth);
- stop_glerror();
}
else
{
@@ -315,14 +311,12 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
bool LLRenderTarget::allocateDepth()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
- if (mStencil)
+ if (!mSampleDepth)
{
- //use render buffers where stencil buffers are in play
+ //use render buffers if depth buffer won't be sampled
glGenRenderbuffers(1, (GLuint *) &mDepth);
glBindRenderbuffer(GL_RENDERBUFFER, mDepth);
- stop_glerror();
- clear_glerror();
- glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, mResX, mResY);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, mResX, mResY);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
}
else
@@ -367,23 +361,15 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target)
if (mDepth)
{
- stop_glerror();
glBindFramebuffer(GL_FRAMEBUFFER, target.mFBO);
- stop_glerror();
-
- llassert(!mStencil); // deprecated -- performance penalty
- if (mStencil)
+
+ if (!mSampleDepth)
{
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepth);
- stop_glerror();
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mDepth);
- stop_glerror();
- target.mStencil = true;
}
else
{
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), mDepth, 0);
- stop_glerror();
}
check_framebuffer_status();
@@ -399,15 +385,13 @@ void LLRenderTarget::release()
LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
if (mDepth)
{
- if (mStencil)
+ if (!mSampleDepth)
{
glDeleteRenderbuffers(1, (GLuint*) &mDepth);
- stop_glerror();
}
else
{
LLImageGL::deleteTextures(1, &mDepth);
- stop_glerror();
}
mDepth = 0;
@@ -419,12 +403,10 @@ void LLRenderTarget::release()
if (mUseDepth)
{ //detach shared depth buffer
- llassert(!mStencil); //deprecated, performance penalty
- if (mStencil)
+ if (!mSampleDepth)
{ //attached as a renderbuffer
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
- mStencil = false;
+ mSampleDepth = false;
}
else
{ //attached as a texture
@@ -624,84 +606,6 @@ void LLRenderTarget::flush(bool fetch_depth)
}
}
-void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0, S32 srcX1, S32 srcY1,
- S32 dstX0, S32 dstY0, S32 dstX1, S32 dstY1, U32 mask, U32 filter)
-{
- LL_PROFILE_GPU_ZONE("LLRenderTarget::copyContents");
-
- GLboolean write_depth = mask & GL_DEPTH_BUFFER_BIT ? TRUE : FALSE;
-
- LLGLDepthTest depth(write_depth, write_depth);
-
- gGL.flush();
- if (!source.mFBO || !mFBO)
- {
- LL_WARNS() << "Cannot copy framebuffer contents for non FBO render targets." << LL_ENDL;
- return;
- }
-
-
- if (mask == GL_DEPTH_BUFFER_BIT && source.mStencil != mStencil)
- {
- stop_glerror();
-
- glBindFramebuffer(GL_FRAMEBUFFER, source.mFBO);
- check_framebuffer_status();
- gGL.getTexUnit(0)->bind(this, true);
- stop_glerror();
- glCopyTexSubImage2D(LLTexUnit::getInternalType(mUsage), 0, srcX0, srcY0, dstX0, dstY0, dstX1, dstY1);
- stop_glerror();
- glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
- stop_glerror();
- }
- else
- {
- glBindFramebuffer(GL_READ_FRAMEBUFFER, source.mFBO);
- stop_glerror();
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFBO);
- stop_glerror();
- check_framebuffer_status();
- stop_glerror();
- glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
- stop_glerror();
- glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
- stop_glerror();
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
- stop_glerror();
- glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
- stop_glerror();
- }
-}
-
-//static
-void LLRenderTarget::copyContentsToFramebuffer(LLRenderTarget& source, S32 srcX0, S32 srcY0, S32 srcX1, S32 srcY1,
- S32 dstX0, S32 dstY0, S32 dstX1, S32 dstY1, U32 mask, U32 filter)
-{
- if (!source.mFBO)
- {
- LL_WARNS() << "Cannot copy framebuffer contents for non FBO render targets." << LL_ENDL;
- return;
- }
-
- {
- LL_PROFILE_GPU_ZONE("copyContentsToFramebuffer");
- GLboolean write_depth = mask & GL_DEPTH_BUFFER_BIT ? TRUE : FALSE;
-
- LLGLDepthTest depth(write_depth, write_depth);
-
- glBindFramebuffer(GL_READ_FRAMEBUFFER, source.mFBO);
- stop_glerror();
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
- stop_glerror();
- check_framebuffer_status();
- stop_glerror();
- glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
- stop_glerror();
- glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
- stop_glerror();
- }
-}
-
bool LLRenderTarget::isComplete() const
{
return (!mTex.empty() || mDepth) ? true : false;
diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h
index 584f224dca..5f3214add3 100644
--- a/indra/llrender/llrendertarget.h
+++ b/indra/llrender/llrendertarget.h
@@ -73,7 +73,7 @@ public:
//allocate resources for rendering
//must be called before use
//multiple calls will release previously allocated resources
- bool allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, bool use_fbo = false, S32 samples = 0);
+ bool allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool sample_depth, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, bool use_fbo = false, S32 samples = 0);
//resize existing attachments to use new resolution and color format
// CAUTION: if the GL runs out of memory attempting to resize, this render target will be undefined
@@ -136,7 +136,7 @@ public:
U32 getNumTextures() const;
U32 getDepth(void) const { return mDepth; }
- bool hasStencil() const { return mStencil; }
+ bool canSampleDepth() const { return mSampleDepth; }
void bindTexture(U32 index, S32 channel, LLTexUnit::eTextureFilterOptions filter_options = LLTexUnit::TFO_BILINEAR);
@@ -148,12 +148,6 @@ public:
// the current depth texture. A depth texture will be allocated if needed.
void flush(bool fetch_depth = FALSE);
- void copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0, S32 srcX1, S32 srcY1,
- S32 dstX0, S32 dstY0, S32 dstX1, S32 dstY1, U32 mask, U32 filter);
-
- static void copyContentsToFramebuffer(LLRenderTarget& source, S32 srcX0, S32 srcY0, S32 srcX1, S32 srcY1,
- S32 dstX0, S32 dstY0, S32 dstX1, S32 dstY1, U32 mask, U32 filter);
-
//Returns TRUE if target is ready to be rendered into.
//That is, if the target has been allocated with at least
//one renderable attachment (i.e. color buffer, depth buffer).
@@ -172,9 +166,9 @@ protected:
U32 mPreviousResY;
U32 mDepth;
- bool mStencil;
- bool mUseDepth;
- bool mRenderDepth;
+ bool mUseDepth;
+ bool mSampleDepth;
+
LLTexUnit::eTextureType mUsage;
static LLRenderTarget* sBoundTarget;
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 7b8f85acba..e1352691d4 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -62,6 +62,14 @@ U32 wpo2(U32 i)
return r;
}
+struct CompareMappedRegion
+{
+ bool operator()(const LLVertexBuffer::MappedRegion& lhs, const LLVertexBuffer::MappedRegion& rhs)
+ {
+ return lhs.mStart < rhs.mStart;
+ }
+};
+
const U32 LL_VBO_BLOCK_SIZE = 2048;
const U32 LL_VBO_POOL_MAX_SEED_SIZE = 256*1024;
@@ -81,266 +89,217 @@ U32 vbo_block_index(U32 size)
const U32 LL_VBO_POOL_SEED_COUNT = vbo_block_index(LL_VBO_POOL_MAX_SEED_SIZE) + 1;
+#define ENABLE_GL_WORK_QUEUE 0
+
+#if ENABLE_GL_WORK_QUEUE
+
+#define THREAD_COUNT 1
//============================================================================
-//static
-LLVBOPool LLVertexBuffer::sStreamVBOPool(GL_STREAM_DRAW, GL_ARRAY_BUFFER);
-LLVBOPool LLVertexBuffer::sDynamicVBOPool(GL_DYNAMIC_DRAW, GL_ARRAY_BUFFER);
-LLVBOPool LLVertexBuffer::sDynamicCopyVBOPool(GL_DYNAMIC_COPY, GL_ARRAY_BUFFER);
-LLVBOPool LLVertexBuffer::sStreamIBOPool(GL_STREAM_DRAW, GL_ELEMENT_ARRAY_BUFFER);
-LLVBOPool LLVertexBuffer::sDynamicIBOPool(GL_DYNAMIC_DRAW, GL_ELEMENT_ARRAY_BUFFER);
+// High performance WorkQueue for usage in real-time rendering work
+class GLWorkQueue
+{
+public:
+ using Work = std::function<void()>;
-U32 LLVBOPool::sBytesPooled = 0;
-U32 LLVBOPool::sIndexBytesPooled = 0;
-U32 LLVBOPool::sNameIdx = 0;
-U32 LLVBOPool::sNamePool[1024];
+ GLWorkQueue();
-std::list<U32> LLVertexBuffer::sAvailableVAOName;
-U32 LLVertexBuffer::sCurVAOName = 1;
+ void post(const Work& value);
-U32 LLVertexBuffer::sAllocatedIndexBytes = 0;
-U32 LLVertexBuffer::sIndexCount = 0;
+ size_t size();
-U32 LLVertexBuffer::sBindCount = 0;
-U32 LLVertexBuffer::sSetCount = 0;
-S32 LLVertexBuffer::sCount = 0;
-S32 LLVertexBuffer::sGLCount = 0;
-S32 LLVertexBuffer::sMappedCount = 0;
-bool LLVertexBuffer::sDisableVBOMapping = false;
-bool LLVertexBuffer::sEnableVBOs = true;
-U32 LLVertexBuffer::sGLRenderBuffer = 0;
-U32 LLVertexBuffer::sGLRenderArray = 0;
-U32 LLVertexBuffer::sGLRenderIndices = 0;
-U32 LLVertexBuffer::sLastMask = 0;
-bool LLVertexBuffer::sVBOActive = false;
-bool LLVertexBuffer::sIBOActive = false;
-U32 LLVertexBuffer::sAllocatedBytes = 0;
-U32 LLVertexBuffer::sVertexCount = 0;
-bool LLVertexBuffer::sMapped = false;
-bool LLVertexBuffer::sUseStreamDraw = true;
-bool LLVertexBuffer::sUseVAO = false;
-bool LLVertexBuffer::sPreferStreamDraw = false;
+ bool done();
-U32 LLVBOPool::genBuffer()
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX
+ // Get the next element from the queue
+ Work pop();
- if (sNameIdx == 0)
- {
- glGenBuffers(1024, sNamePool);
- sNameIdx = 1024;
- }
+ void runOne();
- return sNamePool[--sNameIdx];
-}
+ bool runPending();
-void LLVBOPool::deleteBuffer(U32 name)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX
- if (gGLManager.mInited)
- {
- LLVertexBuffer::unbind();
+ void runUntilClose();
- glBindBuffer(mType, name);
- glBufferData(mType, 0, NULL, mUsage);
- glBindBuffer(mType, 0);
+ void close();
- glDeleteBuffers(1, &name);
- }
-}
+ bool isClosed();
+ void syncGL();
-LLVBOPool::LLVBOPool(U32 vboUsage, U32 vboType)
-: mUsage(vboUsage), mType(vboType), mMissCountDirty(true)
-{
- mFreeList.resize(LL_VBO_POOL_SEED_COUNT);
- mMissCount.resize(LL_VBO_POOL_SEED_COUNT);
- std::fill(mMissCount.begin(), mMissCount.end(), 0);
-}
+private:
+ std::mutex mMutex;
+ std::condition_variable mCondition;
+ std::queue<Work> mQueue;
+ bool mClosed = false;
+};
-U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
+GLWorkQueue::GLWorkQueue()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX
- llassert(vbo_block_size(size) == size);
-
- U8* ret = NULL;
- U32 i = vbo_block_index(size);
+}
- if (mFreeList.size() <= i)
- {
- mFreeList.resize(i+1);
- }
+void GLWorkQueue::syncGL()
+{
+ /*if (mSync)
+ {
+ std::lock_guard<std::mutex> lock(mMutex);
+ glWaitSync(mSync, 0, GL_TIMEOUT_IGNORED);
+ mSync = 0;
+ }*/
+}
- if (mFreeList[i].empty() || for_seed)
- {
- //make a new buffer
- name = genBuffer();
+size_t GLWorkQueue::size()
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
+ std::lock_guard<std::mutex> lock(mMutex);
+ return mQueue.size();
+}
- glBindBuffer(mType, name);
+bool GLWorkQueue::done()
+{
+ return size() == 0 && isClosed();
+}
- if (!for_seed && i < LL_VBO_POOL_SEED_COUNT)
- { //record this miss
- mMissCount[i]++;
- mMissCountDirty = true; // signal to ::seedPool()
- }
+void GLWorkQueue::post(const GLWorkQueue::Work& value)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
+ {
+ std::lock_guard<std::mutex> lock(mMutex);
+ mQueue.push(std::move(value));
+ }
- if (mType == GL_ARRAY_BUFFER)
- {
- LLVertexBuffer::sAllocatedBytes += size;
- }
- else
- {
- LLVertexBuffer::sAllocatedIndexBytes += size;
- }
+ mCondition.notify_one();
+}
- if (LLVertexBuffer::sDisableVBOMapping || mUsage != GL_DYNAMIC_DRAW)
- {
- glBufferData(mType, size, 0, mUsage);
- if (mUsage != GL_DYNAMIC_COPY)
- { //data will be provided by application
- ret = (U8*) ll_aligned_malloc<64>(size);
- if (!ret)
- {
- LL_ERRS()
- << "Failed to allocate " << size << " bytes for LLVBOPool buffer " << name << "." << LL_NEWLINE
- << "Free list size: "
- << mFreeList.size() // this happens if we are out of memory so a solution might be to clear some from freelist
- << " Allocated Bytes: " << LLVertexBuffer::sAllocatedBytes
- << " Allocated Index Bytes: " << LLVertexBuffer::sAllocatedIndexBytes << " Pooled Bytes: " << sBytesPooled
- << " Pooled Index Bytes: " << sIndexBytesPooled << LL_ENDL;
- }
- }
- }
- else
- { //always use a true hint of static draw when allocating non-client-backed buffers
- glBufferData(mType, size, 0, GL_STATIC_DRAW);
- }
+// Get the next element from the queue
+GLWorkQueue::Work GLWorkQueue::pop()
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
+ // Lock the mutex
+ {
+ std::unique_lock<std::mutex> lock(mMutex);
- glBindBuffer(mType, 0);
+ // Wait for a new element to become available or for the queue to close
+ {
+ mCondition.wait(lock, [=] { return !mQueue.empty() || mClosed; });
+ }
+ }
- if (for_seed)
- { //put into pool for future use
- llassert(mFreeList.size() > i);
+ Work ret;
- Record rec;
- rec.mGLName = name;
- rec.mClientData = ret;
-
- if (mType == GL_ARRAY_BUFFER)
- {
- sBytesPooled += size;
- }
- else
- {
- sIndexBytesPooled += size;
- }
- mFreeList[i].push_back(rec);
- mMissCountDirty = true; // signal to ::seedPool()
- }
- }
- else
- {
- name = mFreeList[i].front().mGLName;
- ret = mFreeList[i].front().mClientData;
+ {
+ std::lock_guard<std::mutex> lock(mMutex);
- if (mType == GL_ARRAY_BUFFER)
- {
- sBytesPooled -= size;
- }
- else
- {
- sIndexBytesPooled -= size;
- }
+ // Get the next element from the queue
+ if (mQueue.size() > 0)
+ {
+ ret = mQueue.front();
+ mQueue.pop();
+ }
+ else
+ {
+ ret = []() {};
+ }
+ }
- mFreeList[i].pop_front();
- mMissCountDirty = true; // signal to ::seedPool()
- }
+ return ret;
+}
- return ret;
+void GLWorkQueue::runOne()
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
+ Work w = pop();
+ w();
+ //mSync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
}
-void LLVBOPool::release(U32 name, U8* buffer, U32 size)
+void GLWorkQueue::runUntilClose()
{
- llassert(vbo_block_size(size) == size);
+ while (!isClosed())
+ {
+ runOne();
+ }
+}
- deleteBuffer(name);
- ll_aligned_free_fallback((U8*) buffer);
+void GLWorkQueue::close()
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
+ {
+ std::lock_guard<std::mutex> lock(mMutex);
+ mClosed = true;
+ }
- if (mType == GL_ARRAY_BUFFER)
- {
- LLVertexBuffer::sAllocatedBytes -= size;
- }
- else
- {
- LLVertexBuffer::sAllocatedIndexBytes -= size;
- }
+ mCondition.notify_all();
}
-void LLVBOPool::seedPool()
+bool GLWorkQueue::isClosed()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX
- if (mMissCountDirty)
- {
- U32 dummy_name = 0;
- U32 size = LL_VBO_BLOCK_SIZE;
-
- for (U32 i = 0; i < LL_VBO_POOL_SEED_COUNT; i++)
- {
- if (mMissCount[i] > mFreeList[i].size())
- {
- S32 count = mMissCount[i] - mFreeList[i].size();
- for (U32 j = 0; j < count; ++j)
- {
- allocate(dummy_name, size, true);
- }
- }
- size += LL_VBO_BLOCK_SIZE;
- }
- mMissCountDirty = false;
- }
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
+ std::lock_guard<std::mutex> lock(mMutex);
+ return mClosed;
}
-void LLVBOPool::cleanup()
+#include "llwindow.h"
+
+class LLGLWorkerThread : public LLThread
{
- U32 size = LL_VBO_BLOCK_SIZE;
+public:
+ LLGLWorkerThread(const std::string& name, GLWorkQueue* queue, LLWindow* window)
+ : LLThread(name)
+ {
+ mWindow = window;
+ mContext = mWindow->createSharedContext();
+ mQueue = queue;
+ }
- for (U32 i = 0; i < mFreeList.size(); ++i)
- {
- record_list_t& l = mFreeList[i];
+ void run() override
+ {
+ mWindow->makeContextCurrent(mContext);
+ gGL.init(false);
+ mQueue->runUntilClose();
+ gGL.shutdown();
+ mWindow->destroySharedContext(mContext);
+ }
- while (!l.empty())
- {
- Record& r = l.front();
+ GLWorkQueue* mQueue;
+ LLWindow* mWindow;
+ void* mContext = nullptr;
+};
- deleteBuffer(r.mGLName);
-
- if (r.mClientData)
- {
- ll_aligned_free<64>((void*) r.mClientData);
- }
- l.pop_front();
+static LLGLWorkerThread* sVBOThread[THREAD_COUNT];
+static GLWorkQueue* sQueue = nullptr;
- if (mType == GL_ARRAY_BUFFER)
- {
- sBytesPooled -= size;
- LLVertexBuffer::sAllocatedBytes -= size;
- }
- else
- {
- sIndexBytesPooled -= size;
- LLVertexBuffer::sAllocatedIndexBytes -= size;
- }
- }
+#endif
- size += LL_VBO_BLOCK_SIZE;
- }
+//============================================================================
- //reset miss counts
- std::fill(mMissCount.begin(), mMissCount.end(), 0);
-}
+//static
+std::list<U32> LLVertexBuffer::sAvailableVAOName;
+U32 LLVertexBuffer::sCurVAOName = 1;
+
+U32 LLVertexBuffer::sAllocatedIndexBytes = 0;
+U32 LLVertexBuffer::sIndexCount = 0;
+
+U32 LLVertexBuffer::sBindCount = 0;
+U32 LLVertexBuffer::sSetCount = 0;
+S32 LLVertexBuffer::sCount = 0;
+S32 LLVertexBuffer::sGLCount = 0;
+S32 LLVertexBuffer::sMappedCount = 0;
+bool LLVertexBuffer::sDisableVBOMapping = false;
+bool LLVertexBuffer::sEnableVBOs = true;
+U32 LLVertexBuffer::sGLRenderBuffer = 0;
+U32 LLVertexBuffer::sGLRenderArray = 0;
+U32 LLVertexBuffer::sGLRenderIndices = 0;
+U32 LLVertexBuffer::sLastMask = 0;
+bool LLVertexBuffer::sVBOActive = false;
+bool LLVertexBuffer::sIBOActive = false;
+U32 LLVertexBuffer::sAllocatedBytes = 0;
+U32 LLVertexBuffer::sVertexCount = 0;
+bool LLVertexBuffer::sMapped = false;
+bool LLVertexBuffer::sUseStreamDraw = true;
+bool LLVertexBuffer::sUseVAO = false;
+bool LLVertexBuffer::sPreferStreamDraw = false;
//NOTE: each component must be AT LEAST 4 bytes in size to avoid a performance penalty on AMD hardware
@@ -420,17 +379,6 @@ void LLVertexBuffer::releaseVAOName(U32 name)
//static
-void LLVertexBuffer::seedPools()
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX
- sStreamVBOPool.seedPool();
- sDynamicVBOPool.seedPool();
- sDynamicCopyVBOPool.seedPool();
- sStreamIBOPool.seedPool();
- sDynamicIBOPool.seedPool();
-}
-
-//static
void LLVertexBuffer::setupClientArrays(U32 data_mask)
{
if (sLastMask != data_mask)
@@ -473,7 +421,7 @@ void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos)
}
gGL.end();
gGL.flush();
- }
+}
//static
void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVector2* tc, S32 num_indices, const U16* indicesp)
@@ -612,12 +560,8 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
U16* idx = ((U16*) getIndicesPointer())+indices_offset;
- stop_glerror();
- LLGLSLShader::startProfile();
glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT,
idx);
- LLGLSLShader::stopProfile(count, mode);
- stop_glerror();
}
void LLVertexBuffer::drawRangeFast(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const
@@ -659,12 +603,8 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
return;
}
- stop_glerror();
- LLGLSLShader::startProfile();
glDrawElements(sGLMode[mode], count, GL_UNSIGNED_SHORT,
((U16*) getIndicesPointer()) + indices_offset);
- LLGLSLShader::stopProfile(count, mode);
- stop_glerror();
}
@@ -694,20 +634,24 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
}
#endif
- LLGLSLShader::startProfile();
- {
- glDrawArrays(sGLMode[mode], first, count);
- }
- LLGLSLShader::stopProfile(count, mode);
-
- stop_glerror();
+ glDrawArrays(sGLMode[mode], first, count);
}
//static
-void LLVertexBuffer::initClass(bool use_vbo, bool no_vbo_mapping)
+void LLVertexBuffer::initClass(LLWindow* window)
{
- sEnableVBOs = use_vbo;
- sDisableVBOMapping = sEnableVBOs && no_vbo_mapping;
+ sEnableVBOs = true;
+ sDisableVBOMapping = true;
+
+#if ENABLE_GL_WORK_QUEUE
+ sQueue = new GLWorkQueue();
+
+ for (int i = 0; i < THREAD_COUNT; ++i)
+ {
+ sVBOThread[i] = new LLGLWorkerThread("VBO Worker", sQueue, window);
+ sVBOThread[i]->start();
+ }
+#endif
}
//static
@@ -743,14 +687,19 @@ void LLVertexBuffer::cleanupClass()
{
unbind();
- sStreamIBOPool.cleanup();
- sDynamicIBOPool.cleanup();
- sStreamVBOPool.cleanup();
- sDynamicVBOPool.cleanup();
- sDynamicCopyVBOPool.cleanup();
-
- llassert(0 == LLVBOPool::sBytesPooled);
- llassert(0 == LLVBOPool::sIndexBytesPooled);
+#if ENABLE_GL_WORK_QUEUE
+ sQueue->close();
+ for (int i = 0; i < THREAD_COUNT; ++i)
+ {
+ sVBOThread[i]->shutdown();
+ delete sVBOThread[i];
+ sVBOThread[i] = nullptr;
+ }
+
+ delete sQueue;
+ sQueue = nullptr;
+#endif
+
//llassert(0 == sAllocatedBytes);
//llassert(0 == sAllocatedIndexBytes);
}
@@ -781,21 +730,6 @@ S32 LLVertexBuffer::determineUsage(S32 usage)
ret_usage = GL_STREAM_DRAW;
}
- if (ret_usage && ret_usage != GL_STREAM_DRAW)
- { //only stream_draw and dynamic_draw are supported when using VBOs, dynamic draw is the default
- if (ret_usage != GL_DYNAMIC_COPY)
- {
- if (sDisableVBOMapping)
- { //always use stream draw if VBO mapping is disabled
- ret_usage = GL_STREAM_DRAW;
- }
- else
- {
- ret_usage = GL_DYNAMIC_DRAW;
- }
- }
- }
-
return ret_usage;
}
@@ -848,7 +782,7 @@ S32 LLVertexBuffer::calcOffsets(const U32& typemask, S32* offsets, S32 num_verti
offsets[TYPE_TEXTURE_INDEX] = offsets[TYPE_VERTEX] + 12;
- return offset+16;
+ return offset;
}
//static
@@ -896,74 +830,103 @@ LLVertexBuffer::~LLVertexBuffer()
//----------------------------------------------------------------------------
+// batch glGenBuffers
+static GLuint gen_buffer()
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX;
+ constexpr U32 pool_size = 4096;
+
+ thread_local static GLuint sNamePool[pool_size];
+ thread_local static U32 sIndex = 0;
+
+ if (sIndex == 0)
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("gen ibo");
+ sIndex = pool_size;
+ glGenBuffers(pool_size, sNamePool);
+ }
+
+ return sNamePool[--sIndex];
+}
+
+// batch glDeleteBuffers
+static void release_buffer(U32 buff)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX;
+#if 0
+
+ constexpr U32 pool_size = 4096;
+
+ thread_local static GLuint sNamePool[pool_size];
+ thread_local static U32 sIndex = 0;
+
+ if (sIndex == pool_size)
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("gen ibo");
+ sIndex = 0;
+ glDeleteBuffers(pool_size, sNamePool);
+ }
+
+ sNamePool[sIndex++] = buff;
+#else
+ glDeleteBuffers(1, &buff);
+#endif
+}
+
void LLVertexBuffer::genBuffer(U32 size)
{
- mSize = vbo_block_size(size);
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX;
- if (mUsage == GL_STREAM_DRAW)
- {
- mMappedData = sStreamVBOPool.allocate(mGLBuffer, mSize);
- }
- else if (mUsage == GL_DYNAMIC_DRAW)
- {
- mMappedData = sDynamicVBOPool.allocate(mGLBuffer, mSize);
- }
- else
- {
- mMappedData = sDynamicCopyVBOPool.allocate(mGLBuffer, mSize);
- }
-
-
- sGLCount++;
+ mSize = size;
+ mMappedData = (U8*) ll_aligned_malloc_16(size);
+ mGLBuffer = gen_buffer();
+
+ glBindBuffer(GL_ARRAY_BUFFER, mGLBuffer);
+ glBufferData(GL_ARRAY_BUFFER, mSize, nullptr, mUsage);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ sGLRenderBuffer = 0;
+
+ sGLCount++;
}
void LLVertexBuffer::genIndices(U32 size)
{
- mIndicesSize = vbo_block_size(size);
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX;
+
+ mIndicesSize = size;
+ mMappedIndexData = (U8*) ll_aligned_malloc_16(size);
+
+ mGLIndices = gen_buffer();
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mGLIndices);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, mIndicesSize, nullptr, mUsage);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ sGLRenderIndices = 0;
- if (mUsage == GL_STREAM_DRAW)
- {
- mMappedIndexData = sStreamIBOPool.allocate(mGLIndices, mIndicesSize);
- }
- else
- {
- mMappedIndexData = sDynamicIBOPool.allocate(mGLIndices, mIndicesSize);
- }
-
sGLCount++;
}
void LLVertexBuffer::releaseBuffer()
{
- if (mUsage == GL_STREAM_DRAW)
- {
- sStreamVBOPool.release(mGLBuffer, mMappedData, mSize);
- }
- else
- {
- sDynamicVBOPool.release(mGLBuffer, mMappedData, mSize);
- }
-
- mGLBuffer = 0;
- mMappedData = NULL;
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX;
+ release_buffer(mGLBuffer);
+ mGLBuffer = 0;
+ ll_aligned_free_16(mMappedData);
+ mMappedData = nullptr;
+
sGLCount--;
}
void LLVertexBuffer::releaseIndices()
{
- if (mUsage == GL_STREAM_DRAW)
- {
- sStreamIBOPool.release(mGLIndices, mMappedIndexData, mIndicesSize);
- }
- else
- {
- sDynamicIBOPool.release(mGLIndices, mMappedIndexData, mIndicesSize);
- }
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX;
+ release_buffer(mGLIndices);
+ mGLIndices = 0;
+
+ ll_aligned_free_16(mMappedIndexData);
+ mMappedIndexData = nullptr;
- mGLIndices = 0;
- mMappedIndexData = NULL;
-
sGLCount--;
}
@@ -1183,21 +1146,20 @@ bool LLVertexBuffer::useVBOs() const
//----------------------------------------------------------------------------
-bool expand_region(LLVertexBuffer::MappedRegion& region, S32 index, S32 count)
+// if no gap between region and given range exists, expand region to cover given range and return true
+// otherwise return false
+bool expand_region(LLVertexBuffer::MappedRegion& region, S32 start, S32 end)
{
- S32 end = index+count;
- S32 region_end = region.mIndex+region.mCount;
- if (end < region.mIndex ||
- index > region_end)
+ if (end < region.mStart ||
+ start > region.mEnd)
{ //gap exists, do not merge
return false;
}
- S32 new_end = llmax(end, region_end);
- S32 new_index = llmin(index, region.mIndex);
- region.mIndex = new_index;
- region.mCount = new_end-new_index;
+ region.mStart = llmin(region.mStart, start);
+ region.mEnd = llmax(region.mEnd, end);
+
return true;
}
@@ -1206,7 +1168,6 @@ bool expand_region(LLVertexBuffer::MappedRegion& region, S32 index, S32 count)
U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX;
- bindGLBuffer(true);
if (mFinal)
{
LL_ERRS() << "LLVertexBuffer::mapVeretxBuffer() called on a finalized buffer." << LL_ENDL;
@@ -1215,34 +1176,34 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
{
LL_ERRS() << "LLVertexBuffer::mapVertexBuffer() called on unallocated buffer." << LL_ENDL;
}
-
- if (useVBOs())
- {
- if (count == -1)
- {
- count = mNumVerts-index;
- }
- bool mapped = false;
- //see if range is already mapped
+
+ if (useVBOs())
+ {
+ if (count == -1)
+ {
+ count = mNumVerts - index;
+ }
+
+ S32 start = mOffsets[type] + sTypeSize[type] * index;
+ S32 end = start + sTypeSize[type] * count;
+
+ bool flagged = false;
+ // flag region as mapped
for (U32 i = 0; i < mMappedVertexRegions.size(); ++i)
{
MappedRegion& region = mMappedVertexRegions[i];
- if (region.mType == type)
- {
- if (expand_region(region, index, count))
- {
- mapped = true;
- break;
- }
- }
+ if (expand_region(region, start, end))
+ {
+ flagged = true;
+ break;
+ }
}
- if (!mapped)
+ if (!flagged)
{
- //not already mapped, map new region
- MappedRegion region(type, index, count);
- mMappedVertexRegions.push_back(region);
+ //didn't expand an existing region, make a new one
+ mMappedVertexRegions.push_back({ start, end });
}
if (mVertexLocked && map_range)
@@ -1282,7 +1243,6 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX;
- bindGLIndices(true);
if (mFinal)
{
LL_ERRS() << "LLVertexBuffer::mapIndexBuffer() called on a finalized buffer." << LL_ENDL;
@@ -1299,25 +1259,26 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
count = mNumIndices-index;
}
- bool mapped = false;
- //see if range is already mapped
- for (U32 i = 0; i < mMappedIndexRegions.size(); ++i)
- {
- MappedRegion& region = mMappedIndexRegions[i];
- if (expand_region(region, index, count))
- {
- mapped = true;
- break;
- }
- }
+ S32 start = sizeof(U16) * index;
+ S32 end = start + sizeof(U16) * count;
- if (!mapped)
- {
- //not already mapped, map new region
- MappedRegion region(TYPE_INDEX, index, count);
- mMappedIndexRegions.push_back(region);
- }
-
+ bool flagged = false;
+ // flag region as mapped
+ for (U32 i = 0; i < mMappedIndexRegions.size(); ++i)
+ {
+ MappedRegion& region = mMappedIndexRegions[i];
+ if (expand_region(region, start, end))
+ {
+ flagged = true;
+ break;
+ }
+ }
+
+ if (!flagged)
+ {
+ //didn't expand an existing region, make a new one
+ mMappedIndexRegions.push_back({ start, end });
+ }
if (mIndexLocked && map_range)
{
@@ -1330,17 +1291,6 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
sMappedCount++;
stop_glerror();
- if (gDebugGL && useVBOs())
- {
- GLint elem = 0;
- glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &elem);
-
- if (elem != mGLIndices)
- {
- LL_ERRS() << "Wrong index buffer bound!" << LL_ENDL;
- }
- }
-
map_range = false;
}
@@ -1360,6 +1310,27 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
return mMappedIndexData + sizeof(U16)*index;
}
+static void flush_vbo(GLenum target, S32 start, S32 end, void* data)
+{
+ if (end != 0)
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("glBufferSubData");
+ LL_PROFILE_ZONE_NUM(start);
+ LL_PROFILE_ZONE_NUM(end);
+ LL_PROFILE_ZONE_NUM(end-start);
+
+ constexpr S32 block_size = 65536;
+
+ for (S32 i = start; i < end; i += block_size)
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("glBufferSubData block");
+ LL_PROFILE_GPU_ZONE("glBufferSubData");
+ S32 tend = llmin(i + block_size, end);
+ glBufferSubData(target, i, tend - i, (U8*) data + (i-start));
+ }
+ }
+}
+
void LLVertexBuffer::unmapBuffer()
{
if (!useVBOs())
@@ -1377,37 +1348,31 @@ void LLVertexBuffer::unmapBuffer()
if (!mMappedVertexRegions.empty())
{
- stop_glerror();
+ S32 start = 0;
+ S32 end = 0;
+
for (U32 i = 0; i < mMappedVertexRegions.size(); ++i)
{
const MappedRegion& region = mMappedVertexRegions[i];
- S32 offset = region.mIndex >= 0 ? mOffsets[region.mType]+sTypeSize[region.mType]*region.mIndex : 0;
- S32 length = sTypeSize[region.mType]*region.mCount;
- if (mSize >= length + offset)
- {
- glBufferSubData(GL_ARRAY_BUFFER, offset, length, (U8*)mMappedData + offset);
- }
- else
- {
- GLint size = 0;
- glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);
- LL_WARNS() << "Attempted to map regions to a buffer that is too small, "
- << "mapped size: " << mSize
- << ", gl buffer size: " << size
- << ", length: " << length
- << ", offset: " << offset
- << LL_ENDL;
- }
- stop_glerror();
+ if (region.mStart == end + 1)
+ {
+ end = region.mEnd;
+ }
+ else
+ {
+ flush_vbo(GL_ARRAY_BUFFER, start, end, (U8*)mMappedData + start);
+ start = region.mStart;
+ end = region.mEnd;
+ }
}
+ flush_vbo(GL_ARRAY_BUFFER, start, end, (U8*)mMappedData + start);
+
mMappedVertexRegions.clear();
}
else
{
- stop_glerror();
- glBufferSubData(GL_ARRAY_BUFFER, 0, getSize(), (U8*) mMappedData);
- stop_glerror();
+ llassert(false); // this shouldn't happen -- a buffer must always be explicitly mapped
}
mVertexLocked = false;
@@ -1421,36 +1386,31 @@ void LLVertexBuffer::unmapBuffer()
if (!mMappedIndexRegions.empty())
{
- for (U32 i = 0; i < mMappedIndexRegions.size(); ++i)
- {
- const MappedRegion& region = mMappedIndexRegions[i];
- S32 offset = region.mIndex >= 0 ? sizeof(U16)*region.mIndex : 0;
- S32 length = sizeof(U16)*region.mCount;
- if (mIndicesSize >= length + offset)
- {
- glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, offset, length, (U8*) mMappedIndexData+offset);
- }
- else
- {
- GLint size = 0;
- glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);
- LL_WARNS() << "Attempted to map regions to a buffer that is too small, "
- << "mapped size: " << mIndicesSize
- << ", gl buffer size: " << size
- << ", length: " << length
- << ", offset: " << offset
- << LL_ENDL;
- }
- stop_glerror();
- }
+ S32 start = 0;
+ S32 end = 0;
+
+ for (U32 i = 0; i < mMappedIndexRegions.size(); ++i)
+ {
+ const MappedRegion& region = mMappedIndexRegions[i];
+ if (region.mStart == end + 1)
+ {
+ end = region.mEnd;
+ }
+ else
+ {
+ flush_vbo(GL_ELEMENT_ARRAY_BUFFER, start, end, (U8*)mMappedIndexData + start);
+ start = region.mStart;
+ end = region.mEnd;
+ }
+ }
+
+ flush_vbo(GL_ELEMENT_ARRAY_BUFFER, start, end, (U8*)mMappedIndexData + start);
mMappedIndexRegions.clear();
}
else
{
- stop_glerror();
- glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, getIndicesSize(), (U8*) mMappedIndexData);
- stop_glerror();
+ llassert(false); // this shouldn't happen -- a buffer must always be explicitly mapped
}
mIndexLocked = false;
@@ -1640,11 +1600,53 @@ bool LLVertexBuffer::bindGLIndicesFast()
return false;
}
-void LLVertexBuffer::flush()
+void LLVertexBuffer::flush(bool discard)
{
if (useVBOs())
{
- unmapBuffer();
+ if (discard)
+ { // discard existing VBO data if the buffer must be updated
+
+ if (!mMappedVertexRegions.empty())
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("flush discard vbo");
+ LL_PROFILE_ZONE_NUM(mSize);
+ release_buffer(mGLBuffer);
+ mGLBuffer = gen_buffer();
+ bindGLBuffer();
+ {
+ LL_PROFILE_GPU_ZONE("glBufferData");
+ glBufferData(GL_ARRAY_BUFFER, mSize, nullptr, mUsage);
+
+ for (int i = 0; i < mSize; i += 65536)
+ {
+ LL_PROFILE_GPU_ZONE("glBufferSubData");
+ S32 end = llmin(i + 65536, mSize);
+ S32 count = end - i;
+ glBufferSubData(GL_ARRAY_BUFFER, i, count, mMappedData + i);
+ }
+ }
+ mMappedVertexRegions.clear();
+ }
+ if (!mMappedIndexRegions.empty())
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("flush discard ibo");
+ LL_PROFILE_ZONE_NUM(mIndicesSize);
+ release_buffer(mGLIndices);
+ mGLIndices = gen_buffer();
+ bindGLIndices();
+ {
+ LL_PROFILE_GPU_ZONE("glBufferData (ibo)");
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, mIndicesSize, mMappedIndexData, mUsage);
+ }
+ mMappedIndexRegions.clear();
+ }
+ }
+ else
+ {
+ unmapBuffer();
+ }
+
}
}
@@ -2043,12 +2045,24 @@ void LLVertexBuffer::setupVertexBufferFast(U32 data_mask)
void* ptr = (void*)(base + mOffsets[TYPE_VERTEX]);
glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
}
- }
+}
+
+void LLVertexBuffer::setPositionData(const LLVector4a* data)
+{
+ bindGLBuffer();
+ flush_vbo(GL_ARRAY_BUFFER, 0, sizeof(LLVector4a) * getNumVerts(), (U8*) data);
+}
-LLVertexBuffer::MappedRegion::MappedRegion(S32 type, S32 index, S32 count)
-: mType(type), mIndex(index), mCount(count)
-{
- mEnd = mIndex+mCount;
-}
+void LLVertexBuffer::setTexCoordData(const LLVector2* data)
+{
+ bindGLBuffer();
+ flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_TEXCOORD0], mOffsets[TYPE_TEXCOORD0] + sTypeSize[TYPE_TEXCOORD0] * getNumVerts(), (U8*)data);
+}
+
+void LLVertexBuffer::setColorData(const LLColor4U* data)
+{
+ bindGLBuffer();
+ flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_COLOR], mOffsets[TYPE_COLOR] + sTypeSize[TYPE_COLOR] * getNumVerts(), (U8*) data);
+}
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index bb7460fb2a..926d37b052 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -51,66 +51,15 @@
//============================================================================
-// gl name pools for dynamic and streaming buffers
-class LLVBOPool
-{
-public:
- static U32 sBytesPooled;
- static U32 sIndexBytesPooled;
-
- LLVBOPool(U32 vboUsage, U32 vboType);
-
- const U32 mUsage;
- const U32 mType;
-
- //size MUST be a power of 2
- U8* allocate(U32& name, U32 size, bool for_seed = false);
-
- //size MUST be the size provided to allocate that returned the given name
- void release(U32 name, U8* buffer, U32 size);
-
- //batch allocate buffers to be provided to the application on demand
- void seedPool();
-
- //destroy all records in mFreeList
- void cleanup();
-
- U32 genBuffer();
- void deleteBuffer(U32 name);
-
- class Record
- {
- public:
- U32 mGLName;
- U8* mClientData;
- };
-
- typedef std::list<Record> record_list_t;
- std::vector<record_list_t> mFreeList;
- std::vector<U32> mMissCount;
- bool mMissCountDirty; // flag any changes to mFreeList or mMissCount
-
- //used to avoid calling glGenBuffers for every VBO creation
- static U32 sNamePool[1024];
- static U32 sNameIdx;
-};
-
-
-//============================================================================
// base class
class LLPrivateMemoryPool;
class LLVertexBuffer : public LLRefCount
{
public:
- class MappedRegion
+ struct MappedRegion
{
- public:
- S32 mType;
- S32 mIndex;
- S32 mCount;
- S32 mEnd;
-
- MappedRegion(S32 type, S32 index, S32 count);
+ S32 mStart;
+ S32 mEnd;
};
LLVertexBuffer(const LLVertexBuffer& rhs)
@@ -125,12 +74,6 @@ public:
return *this;
}
- static LLVBOPool sStreamVBOPool;
- static LLVBOPool sDynamicVBOPool;
- static LLVBOPool sDynamicCopyVBOPool;
- static LLVBOPool sStreamIBOPool;
- static LLVBOPool sDynamicIBOPool;
-
static std::list<U32> sAvailableVAOName;
static U32 sCurVAOName;
@@ -138,12 +81,10 @@ public:
static bool sUseVAO;
static bool sPreferStreamDraw;
- static void seedPools();
-
static U32 getVAOName();
static void releaseVAOName(U32 name);
- static void initClass(bool use_vbo, bool no_vbo_mapping);
+ static void initClass(LLWindow* window);
static void cleanupClass();
static void setupClientArrays(U32 data_mask);
static void drawArrays(U32 mode, const std::vector<LLVector3>& pos);
@@ -240,7 +181,7 @@ public:
virtual void setBuffer(U32 data_mask); // calls setupVertexBuffer() if data_mask is not 0
void setBufferFast(U32 data_mask); // calls setupVertexBufferFast(), assumes data_mask is not 0 among other assumptions
- void flush(); //flush pending data to GL memory
+ void flush(bool discard = false); //flush pending data to GL memory, if discard is true, discard previous VBO
// allocate buffer
bool allocateBuffer(S32 nverts, S32 nindices, bool create);
virtual bool resizeBuffer(S32 newnverts, S32 newnindices);
@@ -271,6 +212,10 @@ public:
bool getMetallicRoughnessTexcoordStrider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getEmissiveTexcoordStrider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);
+ void setPositionData(const LLVector4a* data);
+ void setTexCoordData(const LLVector2* data);
+ void setColorData(const LLColor4U* data);
+
bool useVBOs() const;
bool isEmpty() const { return mEmpty; }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaMaskShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaMaskShadowF.glsl
deleted file mode 100644
index c2372fcbc0..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaMaskShadowF.glsl
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- * @file attachmentAlphaMaskShadowF.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, 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$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform float minimum_alpha;
-
-uniform sampler2D diffuseMap;
-
-VARYING vec4 post_pos;
-VARYING vec2 vary_texcoord0;
-VARYING float pos_w;
-VARYING float target_pos_x;
-VARYING vec4 vertex_color;
-
-void main()
-{
- float alpha = texture2D(diffuseMap, vary_texcoord0.xy).a;
-
- if (alpha < 0.05) // treat as totally transparent
- {
- discard;
- }
-
- if (alpha < minimum_alpha) // treat as semi-transparent
- {
- //if (fract(0.5*floor(target_pos_x / pos_w )) < 0.25)
- {
- discard;
- }
- }
-
- frag_color = vec4(1,1,1,1);
-
-#if !defined(DEPTH_CLAMP)
- gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
-#endif
-}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowF.glsl
deleted file mode 100644
index d0a049d372..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowF.glsl
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * @file attachmentAlphaShadowF.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, 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$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform float minimum_alpha;
-uniform sampler2D diffuseMap;
-
-VARYING float pos_w;
-VARYING float target_pos_x;
-
-#if !defined(DEPTH_CLAMP)
-VARYING vec4 post_pos;
-#endif
-
-VARYING vec2 vary_texcoord0;
-VARYING vec4 vertex_color;
-
-void main()
-{
- float alpha = texture2D(diffuseMap, vary_texcoord0.xy).a * vertex_color.a;
-
- if (alpha < 0.05) // treat as totally transparent
- {
- discard;
- }
-
- if (alpha < minimum_alpha)
- {
- if (fract(0.5*floor(target_pos_x / pos_w )) < 0.25)
- {
- discard;
- }
- }
-
- frag_color = vec4(1,1,1,1);
-
-#if !defined(DEPTH_CLAMP)
- gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
-#endif
-
-}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowV.glsl
deleted file mode 100644
index a7bf4d7780..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowV.glsl
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * @file attachmentAlphaShadowV.glsl
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, 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$
- */
-
-uniform mat4 projection_matrix;
-uniform mat4 modelview_matrix;
-uniform mat4 texture_matrix0;
-uniform float shadow_target_width;
-
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec2 texcoord0;
-
-mat4 getObjectSkinnedTransform();
-void passTextureIndex();
-
-#if !defined(DEPTH_CLAMP)
-VARYING vec4 post_pos;
-#endif
-VARYING vec2 vary_texcoord0;
-VARYING float pos_w;
-VARYING float target_pos_x;
-VARYING vec4 vertex_color;
-
-void main()
-{
- //transform vertex
- mat4 mat = getObjectSkinnedTransform();
-
- mat = modelview_matrix * mat;
- vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz;
-
- vec4 p = projection_matrix * vec4(pos, 1.0);
-
- pos_w = p.w;
-
- target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
-
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-
- vertex_color = diffuse_color;
-
-#if !defined(DEPTH_CLAMP)
- p.z = max(p.z, -p.w+0.01);
- post_pos = p;
- gl_Position = p;
-#else
- gl_Position = p;
-#endif
-
- passTextureIndex();
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaMaskShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaMaskShadowF.glsl
index f231213ac8..44f67899e4 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaMaskShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaMaskShadowF.glsl
@@ -32,10 +32,6 @@ out vec4 frag_color;
uniform float minimum_alpha;
uniform sampler2D diffuseMap;
-#if !defined(DEPTH_CLAMP)
-VARYING vec4 post_pos;
-#endif
-
VARYING float target_pos_x;
VARYING float pos_w;
VARYING vec2 vary_texcoord0;
@@ -58,8 +54,4 @@ void main()
}
frag_color = vec4(1,1,1,1);
-
-#if !defined(DEPTH_CLAMP)
- gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
-#endif
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl
index 0e66c722b6..9a0024ede9 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl
@@ -33,10 +33,6 @@ uniform float minimum_alpha;
uniform sampler2D diffuseMap;
-#if !defined(DEPTH_CLAMP)
-VARYING vec4 post_pos;
-#endif
-
VARYING float pos_w;
VARYING float target_pos_x;
VARYING vec2 vary_texcoord0;
@@ -60,9 +56,4 @@ void main()
}
frag_color = vec4(1,1,1,1);
-
-#if !defined(DEPTH_CLAMP)
- gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
-#endif
-
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl
index 40ac7b1f95..dfe7077db5 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl
@@ -34,9 +34,6 @@ ATTRIBUTE vec3 position;
ATTRIBUTE vec3 normal;
ATTRIBUTE vec2 texcoord0;
-#if !defined(DEPTH_CLAMP)
-VARYING vec4 post_pos;
-#endif
VARYING float pos_w;
VARYING float target_pos_x;
VARYING vec2 vary_texcoord0;
@@ -66,13 +63,7 @@ void main()
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-#if !defined(DEPTH_CLAMP)
- post_pos = pos;
-
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
gl_Position = pos;
-#endif
passTextureIndex();
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl
index 50020a50d8..0c386ade6c 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl
@@ -25,24 +25,12 @@
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
uniform sampler2D diffuseMap;
-#if !defined(DEPTH_CLAMP)
-VARYING vec4 post_pos;
-#endif
-
void main()
{
frag_color = vec4(1,1,1,1);
-
-#if !defined(DEPTH_CLAMP)
- gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
-#endif
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl
index 91b25613e0..ac8a483a6a 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl
@@ -31,10 +31,6 @@ ATTRIBUTE vec3 position;
ATTRIBUTE vec3 normal;
ATTRIBUTE vec2 texcoord0;
-#if !defined(DEPTH_CLAMP)
-VARYING vec4 post_pos;
-#endif
-
void main()
{
vec4 pos;
@@ -53,13 +49,7 @@ void main()
norm = normalize(norm);
pos = projection_matrix * pos;
-#if !defined(DEPTH_CLAMP)
- post_pos = pos;
-
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
gl_Position = pos;
-#endif
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl
index 06ebeb8281..68e9addc1b 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl
@@ -69,8 +69,4 @@ void main()
#endif
frag_color = vec4(1,1,1,1);
-
-#if !defined(DEPTH_CLAMP)
- gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
-#endif
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskSkinnedV.glsl
index 2b17aea75a..61c9e60744 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskSkinnedV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskSkinnedV.glsl
@@ -57,11 +57,7 @@ void main()
post_pos = pos;
-#if !defined(DEPTH_CLAMP)
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
gl_Position = pos;
-#endif
passTextureIndex();
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl
index b6a0f0b165..40f8fc9894 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl
@@ -47,11 +47,7 @@ void main()
post_pos = pos;
-#if !defined(DEPTH_CLAMP)
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
gl_Position = pos;
-#endif
passTextureIndex();
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl
index 0e74d2eb8a..9608e89169 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl
@@ -27,10 +27,6 @@ uniform mat4 modelview_projection_matrix;
ATTRIBUTE vec3 position;
-#if !defined(DEPTH_CLAMP)
-VARYING vec4 post_pos;
-#endif
-
uniform vec3 box_center;
uniform vec3 box_size;
@@ -40,11 +36,5 @@ void main()
vec3 p = position*box_size+box_center;
vec4 pos = modelview_projection_matrix*vec4(p.xyz, 1.0);
-#if !defined(DEPTH_CLAMP)
- post_pos = pos;
-
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
gl_Position = pos;
-#endif
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl
index 1ea96918bb..406a7ef3b3 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl
@@ -25,20 +25,9 @@
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-VARYING vec4 post_pos;
void main()
{
frag_color = vec4(1,1,1,1);
-
-#if !defined(DEPTH_CLAMP)
- gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
-#endif
-
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowSkinnedV.glsl
index bdf8e0854d..186ba49969 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowSkinnedV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowSkinnedV.glsl
@@ -28,8 +28,6 @@ uniform mat4 projection_matrix;
ATTRIBUTE vec3 position;
-VARYING vec4 post_pos;
-
mat4 getObjectSkinnedTransform();
void main()
@@ -41,12 +39,5 @@ void main()
vec4 pos = (mat*vec4(position.xyz, 1.0));
pos = projection_matrix*pos;
- post_pos = pos;
-
-#if !defined(DEPTH_CLAMP)
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
gl_Position = pos;
-#endif
-
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl
index 72bd0f0f34..bd62954ff8 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl
@@ -25,21 +25,10 @@
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
-
-VARYING vec4 post_pos;
+in vec3 position;
void main()
{
//transform vertex
- vec4 pos = modelview_projection_matrix*vec4(position.xyz, 1.0);
-
- post_pos = pos;
-
-#if !defined(DEPTH_CLAMP)
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
- gl_Position = pos;
-#endif
-
+ gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeShadowF.glsl
index e34d75ba1d..c850a39d6f 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/treeShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/treeShadowF.glsl
@@ -25,18 +25,14 @@
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
+
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
uniform float minimum_alpha;
uniform sampler2D diffuseMap;
-VARYING vec4 post_pos;
-VARYING vec2 vary_texcoord0;
+in vec2 vary_texcoord0;
void main()
{
@@ -48,6 +44,4 @@ void main()
}
frag_color = vec4(1,1,1,1);
-
- gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeShadowSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeShadowSkinnedV.glsl
index d9ca6d3a46..5a7cf369b5 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/treeShadowSkinnedV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/treeShadowSkinnedV.glsl
@@ -30,8 +30,7 @@ uniform mat4 projection_matrix;
ATTRIBUTE vec3 position;
ATTRIBUTE vec2 texcoord0;
-VARYING vec4 post_pos;
-VARYING vec2 vary_texcoord0;
+out vec2 vary_texcoord0;
mat4 getObjectSkinnedTransform();
@@ -43,11 +42,7 @@ void main()
mat = modelview_matrix * mat;
vec4 pos = mat * vec4(position.xyz, 1.0);
- pos = projection_matrix * pos;
-
- post_pos = pos;
-
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
+ gl_Position = projection_matrix * pos;
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeShadowV.glsl
index e472a75304..3102c870fc 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/treeShadowV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/treeShadowV.glsl
@@ -26,20 +26,15 @@
uniform mat4 texture_matrix0;
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
+in vec3 position;
+in vec2 texcoord0;
-VARYING vec4 post_pos;
-VARYING vec2 vary_texcoord0;
+out vec2 vary_texcoord0;
void main()
{
//transform vertex
- vec4 pos = modelview_projection_matrix*vec4(position.xyz, 1.0);
-
- post_pos = pos;
-
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
+ gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl b/indra/newview/app_settings/shaders/class1/interface/copyF.glsl
index 8e9a5fcd41..65d3c20091 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/copyF.glsl
@@ -1,8 +1,9 @@
/**
- * @file avatarShadowF.glsl
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * @file copyF.glsl
+ *
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * Copyright (C) 2023, 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
@@ -22,20 +23,18 @@
* $/LicenseInfo$
*/
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
+in vec2 tc;
+uniform sampler2D depthMap;
uniform sampler2D diffuseMap;
-VARYING vec2 vary_texcoord0;
+out vec4 frag_color;
void main()
{
- frag_color = vec4(1,1,1,1);
+ frag_color = texture(diffuseMap, tc);
+#if defined(COPY_DEPTH)
+ gl_FragDepth = texture(depthMap, tc).r;
+#endif
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl b/indra/newview/app_settings/shaders/class1/interface/copyV.glsl
index 0fa0edfd67..ace5da6578 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/copyV.glsl
@@ -1,8 +1,9 @@
/**
- * @file attachmentShadowV.glsl
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * @file copyV.glsl
+ *
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * Copyright (C) 2023, 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
@@ -22,29 +23,12 @@
* $/LicenseInfo$
*/
-uniform mat4 projection_matrix;
-uniform mat4 modelview_matrix;
-uniform mat4 texture_matrix0;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
+in vec3 position;
+out vec2 tc;
-mat4 getObjectSkinnedTransform();
-
-void main()
+void main()
{
- //transform vertex
- mat4 mat = getObjectSkinnedTransform();
-
- mat = modelview_matrix * mat;
- vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz;
-
-
- vec4 p = projection_matrix * vec4(pos, 1.0);
-#if !defined(DEPTH_CLAMP)
- p.z = max(p.z, -p.w+0.01);
- gl_Position = p;
-#else
- gl_Position = p;
-#endif
+ tc = position.xy * 0.5 + 0.5;
+ gl_Position = vec4(position, 1.0);
}
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index 3ce2ced255..07381acd25 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -600,6 +600,16 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
begin = gPipeline.beginAlphaGroups();
end = gPipeline.endAlphaGroups();
}
+
+ LLEnvironment& env = LLEnvironment::instance();
+ F32 water_height = env.getWaterHeight();
+
+ bool above_water = getType() == LLDrawPool::POOL_ALPHA_POST_WATER;
+ if (LLPipeline::sUnderWaterRender)
+ {
+ above_water = !above_water;
+ }
+
for (LLCullResult::sg_iterator i = begin; i != end; ++i)
{
@@ -611,6 +621,25 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
if (group->getSpatialPartition()->mRenderByGroup &&
!group->isDead())
{
+
+ LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge();
+ const LLVector4a* ext = bridge ? bridge->getSpatialExtents() : group->getExtents();
+
+ if (above_water)
+ { // reject any spatial groups that have no part above water
+ if (ext[1].getF32ptr()[2] < water_height)
+ {
+ continue;
+ }
+ }
+ else
+ { // reject any spatial groups that he no part below water
+ if (ext[0].getF32ptr()[2] > water_height)
+ {
+ continue;
+ }
+ }
+
static std::vector<LLDrawInfo*> emissives;
static std::vector<LLDrawInfo*> rigged_emissives;
emissives.resize(0);
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index 77da29061d..c2fe52683b 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -133,11 +133,28 @@ void LLDrawPoolWater::beginPostDeferredPass(S32 pass)
// reflections and refractions
LLRenderTarget& src = gPipeline.mRT->screen;
LLRenderTarget& dst = gPipeline.mWaterDis;
+
+#if 0
dst.copyContents(src,
0, 0, src.getWidth(), src.getHeight(),
0, 0, dst.getWidth(), dst.getHeight(),
GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
GL_NEAREST);
+#else
+ dst.bindTarget();
+ gCopyDepthProgram.bind();
+
+ S32 diff_map = gCopyDepthProgram.enableTexture(LLShaderMgr::DIFFUSE_MAP);
+ S32 depth_map = gCopyDepthProgram.enableTexture(LLShaderMgr::DEFERRED_DEPTH);
+
+ gGL.getTexUnit(diff_map)->bind(&src);
+ gGL.getTexUnit(depth_map)->bind(&src, true);
+
+ gPipeline.mScreenTriangleVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+ dst.flush();
+#endif
}
}
diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp
index 9539ffc700..9399342a61 100644
--- a/indra/newview/llgltfmateriallist.cpp
+++ b/indra/newview/llgltfmateriallist.cpp
@@ -297,7 +297,7 @@ public:
// object not ready to receive override data, queue for later
gGLTFMaterialList.queueOverrideUpdate(object_override.mObjectId, results[i].mSide, results[i].mMaterial);
}
- else if (obj && obj->getTE(i) && obj->getTE(i)->isSelected())
+ else if (obj && obj->getTE(results[i].mSide) && obj->getTE(results[i].mSide)->isSelected())
{
doSelectionCallbacks(object_override.mObjectId, results[i].mSide);
}
@@ -305,7 +305,7 @@ public:
else
{
// unblock material editor
- if (obj && obj->getTE(i) && obj->getTE(i)->isSelected())
+ if (obj && obj->getTE(results[i].mSide) && obj->getTE(results[i].mSide)->isSelected())
{
doSelectionCallbacks(object_override.mObjectId, results[i].mSide);
}
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index cb1e46068e..2b6578c272 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -5853,7 +5853,6 @@ void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data
if (can_copy && can_transfer)
{
- // this should be the only place that saved textures is called
node->saveTextures(texture_ids);
}
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index cde33a5f96..53bc77daa9 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -2080,24 +2080,101 @@ EAcceptance LLToolDragAndDrop::dad3dApplyToObject(
{
if (cargo_type == DAD_TEXTURE)
{
+ LLSelectNode *nodep = nullptr;
+ if (obj->isSelected())
+ {
+ // update object's saved textures
+ nodep = LLSelectMgr::getInstance()->getSelection()->findNode(obj);
+ }
+
if((mask & MASK_SHIFT))
{
dropTextureAllFaces(obj, item, mSource, mSourceID);
+
+ // If user dropped a texture onto face it implies
+ // applying texture now without cancel, save to selection
+ if (nodep)
+ {
+ uuid_vec_t texture_ids;
+ S32 num_faces = obj->getNumTEs();
+ for (S32 face = 0; face < num_faces; face++)
+ {
+ LLViewerTexture *tex = obj->getTEImage(face);
+ if (tex != nullptr)
+ {
+ texture_ids.push_back(tex->getID());
+ }
+ else
+ {
+ texture_ids.push_back(LLUUID::null);
+ }
+ }
+ nodep->saveTextures(texture_ids);
+ }
}
else
{
dropTextureOneFace(obj, face, item, mSource, mSourceID);
+
+ // If user dropped a texture onto face it implies
+ // applying texture now without cancel, save to selection
+ LLPanelFace* panel_face = gFloaterTools->getPanelFace();
+ if (nodep
+ && gFloaterTools->getVisible()
+ && panel_face
+ && panel_face->getTextureDropChannel() == 0 /*texture*/
+ && nodep->mSavedGLTFMaterialIds.size() > face)
+ {
+ LLViewerTexture *tex = obj->getTEImage(face);
+ if (tex != nullptr)
+ {
+ nodep->mSavedTextures[face] = tex->getID();
+ }
+ else
+ {
+ nodep->mSavedTextures[face] = LLUUID::null;
+ }
+ }
}
}
else if (cargo_type == DAD_MATERIAL)
{
+ LLSelectNode *nodep = nullptr;
+ if (obj->isSelected())
+ {
+ // update object's saved materials
+ nodep = LLSelectMgr::getInstance()->getSelection()->findNode(obj);
+ }
+
+ // If user dropped a material onto face it implies
+ // applying texture now without cancel, save to selection
if ((mask & MASK_SHIFT))
{
dropMaterialAllFaces(obj, item, mSource, mSourceID);
+
+ if (nodep)
+ {
+ uuid_vec_t material_ids;
+ S32 num_faces = obj->getNumTEs();
+ for (S32 face = 0; face < num_faces; face++)
+ {
+ material_ids.push_back(obj->getRenderMaterialID(face));
+ }
+ nodep->saveGLTFMaterialIds(material_ids);
+ }
}
else
{
dropMaterialOneFace(obj, face, item, mSource, mSourceID);
+
+ // If user dropped a material onto face it implies
+ // applying texture now without cancel, save to selection
+ if (nodep
+ && gFloaterTools->getVisible()
+ && nodep->mSavedGLTFMaterialIds.size() > face)
+ {
+ nodep->mSavedGLTFMaterialIds[face] = obj->getRenderMaterialID(face);
+ }
}
}
else if (cargo_type == DAD_MESH)
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 58b1716caa..d1a89a5846 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -710,11 +710,11 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
if (!for_snapshot)
{
- if (gFrameCount > 1)
- { //for some reason, ATI 4800 series will error out if you
- //try to generate a shadow before the first frame is through
- gPipeline.generateSunShadow(*LLViewerCamera::getInstance());
- }
+ if (gFrameCount > 1 && !for_snapshot)
+ { //for some reason, ATI 4800 series will error out if you
+ //try to generate a shadow before the first frame is through
+ gPipeline.generateSunShadow(*LLViewerCamera::getInstance());
+ }
LLVertexBuffer::unbind();
@@ -936,8 +936,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
else
{
gPipeline.renderGeom(*LLViewerCamera::getInstance(), TRUE);
- }
-
+ }
gGL.setColorMask(true, true);
//store this frame's modelview matrix for use
@@ -967,13 +966,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLRenderTarget &rt = (gPipeline.sRenderDeferred ? gPipeline.mRT->deferredScreen : gPipeline.mRT->screen);
rt.flush();
- /*if (rt.sUseFBO)
- {
- LLRenderTarget::copyContentsToFramebuffer(rt, 0, 0, rt.getWidth(), rt.getHeight(), 0, 0, rt.getWidth(),
- rt.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,
- GL_NEAREST);
- }*/
-
if (LLPipeline::sRenderDeferred)
{
gPipeline.renderDeferredLighting();
@@ -1364,6 +1356,8 @@ void render_ui(F32 zoom_factor, int subfield)
render_hud_elements();
render_hud_attachments();
+ LLGLState::checkStates();
+
LLGLSDefault gls_default;
LLGLSUIDefault gls_ui;
{
@@ -1378,6 +1372,7 @@ void render_ui(F32 zoom_factor, int subfield)
if (!gDisconnected)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_UI("UI 3D"); //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_3D);
+ LLGLState::checkStates();
render_ui_3d();
LLGLState::checkStates();
}
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 757a946fda..5d79c8e6b2 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -93,6 +93,8 @@ LLGLSLShader gDownsampleDepthRectProgram;
LLGLSLShader gAlphaMaskProgram;
LLGLSLShader gBenchmarkProgram;
LLGLSLShader gReflectionProbeDisplayProgram;
+LLGLSLShader gCopyProgram;
+LLGLSLShader gCopyDepthProgram;
//object shaders
LLGLSLShader gObjectSimpleProgram;
@@ -222,9 +224,6 @@ LLGLSLShader gDeferredSkinnedShadowFullbrightAlphaMaskProgram;
LLGLSLShader gDeferredAvatarShadowProgram;
LLGLSLShader gDeferredAvatarAlphaShadowProgram;
LLGLSLShader gDeferredAvatarAlphaMaskShadowProgram;
-LLGLSLShader gDeferredAttachmentShadowProgram;
-LLGLSLShader gDeferredAttachmentAlphaShadowProgram;
-LLGLSLShader gDeferredAttachmentAlphaMaskShadowProgram;
LLGLSLShader gDeferredAlphaProgram;
LLGLSLShader gDeferredSkinnedAlphaProgram;
LLGLSLShader gDeferredAlphaImpostorProgram;
@@ -1271,9 +1270,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAvatarShadowProgram.unload();
gDeferredAvatarAlphaShadowProgram.unload();
gDeferredAvatarAlphaMaskShadowProgram.unload();
- gDeferredAttachmentShadowProgram.unload();
- gDeferredAttachmentAlphaShadowProgram.unload();
- gDeferredAttachmentAlphaMaskShadowProgram.unload();
gDeferredAvatarProgram.unload();
gDeferredAvatarAlphaProgram.unload();
gDeferredAlphaProgram.unload();
@@ -2640,7 +2636,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
success = gDeferredAvatarAlphaShadowProgram.createShader(NULL, NULL);
llassert(success);
}
-
if (success)
{
gDeferredAvatarAlphaMaskShadowProgram.mName = "Deferred Avatar Alpha Mask Shadow Shader";
@@ -2655,43 +2650,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
- gDeferredAttachmentShadowProgram.mName = "Deferred Attachment Shadow Shader";
- gDeferredAttachmentShadowProgram.mFeatures.hasObjectSkinning = true;
-
- gDeferredAttachmentShadowProgram.mShaderFiles.clear();
- gDeferredAttachmentShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentShadowV.glsl", GL_VERTEX_SHADER));
- gDeferredAttachmentShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentShadowF.glsl", GL_FRAGMENT_SHADER));
- gDeferredAttachmentShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredAttachmentShadowProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredAttachmentAlphaShadowProgram.mName = "Deferred Attachment Alpha Shadow Shader";
- gDeferredAttachmentAlphaShadowProgram.mFeatures.hasObjectSkinning = true;
- gDeferredAttachmentAlphaShadowProgram.mShaderFiles.clear();
- gDeferredAttachmentAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaShadowV.glsl", GL_VERTEX_SHADER));
- gDeferredAttachmentAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaShadowF.glsl", GL_FRAGMENT_SHADER));
- gDeferredAttachmentAlphaShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredAttachmentAlphaShadowProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredAttachmentAlphaMaskShadowProgram.mName = "Deferred Attachment Alpha Mask Shadow Shader";
- gDeferredAttachmentAlphaMaskShadowProgram.mFeatures.hasObjectSkinning = true;
- gDeferredAttachmentAlphaMaskShadowProgram.mShaderFiles.clear();
- gDeferredAttachmentAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaShadowV.glsl", GL_VERTEX_SHADER));
- gDeferredAttachmentAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaMaskShadowF.glsl", GL_FRAGMENT_SHADER));
- gDeferredAttachmentAlphaMaskShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredAttachmentAlphaMaskShadowProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
gDeferredTerrainProgram.mName = "Deferred Terrain Shader";
gDeferredTerrainProgram.mFeatures.encodesNormal = true;
gDeferredTerrainProgram.mFeatures.hasSrgb = true;
@@ -3916,6 +3874,27 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
success = gReflectionProbeDisplayProgram.createShader(NULL, NULL);
}
+ if (success)
+ {
+ gCopyProgram.mName = "Copy Shader";
+ gCopyProgram.mShaderFiles.clear();
+ gCopyProgram.mShaderFiles.push_back(make_pair("interface/copyV.glsl", GL_VERTEX_SHADER));
+ gCopyProgram.mShaderFiles.push_back(make_pair("interface/copyF.glsl", GL_FRAGMENT_SHADER));
+ gCopyProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gCopyProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gCopyDepthProgram.mName = "Copy Depth Shader";
+ gCopyDepthProgram.mShaderFiles.clear();
+ gCopyDepthProgram.mShaderFiles.push_back(make_pair("interface/copyV.glsl", GL_VERTEX_SHADER));
+ gCopyDepthProgram.mShaderFiles.push_back(make_pair("interface/copyF.glsl", GL_FRAGMENT_SHADER));
+ gCopyDepthProgram.clearPermutations();
+ gCopyDepthProgram.addPermutation("COPY_DEPTH", "1");
+ gCopyDepthProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gCopyDepthProgram.createShader(NULL, NULL);
+ }
if (success)
{
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index 9ded72c6a7..593a8c14f3 100644
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -164,6 +164,8 @@ extern LLGLSLShader gDownsampleDepthProgram;
extern LLGLSLShader gDownsampleDepthRectProgram;
extern LLGLSLShader gBenchmarkProgram;
extern LLGLSLShader gReflectionProbeDisplayProgram;
+extern LLGLSLShader gCopyProgram;
+extern LLGLSLShader gCopyDepthProgram;
//output tex0[tc0] + tex1[tc1]
extern LLGLSLShader gTwoTextureAddProgram;
@@ -287,9 +289,6 @@ extern LLGLSLShader gFXAAProgram;
extern LLGLSLShader gDeferredPostNoDoFProgram;
extern LLGLSLShader gDeferredPostGammaCorrectProgram;
extern LLGLSLShader gDeferredAvatarShadowProgram;
-extern LLGLSLShader gDeferredAttachmentShadowProgram;
-extern LLGLSLShader gDeferredAttachmentAlphaShadowProgram;
-extern LLGLSLShader gDeferredAttachmentAlphaMaskShadowProgram;
extern LLGLSLShader gDeferredAvatarAlphaShadowProgram;
extern LLGLSLShader gDeferredAvatarAlphaMaskShadowProgram;
extern LLGLSLShader gDeferredAlphaProgram;
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index bc4f00bd3f..5848cbfd9d 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -658,12 +658,6 @@ public:
}
- addText(xpos, ypos, llformat("%d MB Index Data (%d MB Pooled, %d KIndices)", LLVertexBuffer::sAllocatedIndexBytes/(1024*1024), LLVBOPool::sIndexBytesPooled/(1024*1024), LLVertexBuffer::sIndexCount/1024));
- ypos += y_inc;
-
- addText(xpos, ypos, llformat("%d MB Vertex Data (%d MB Pooled, %d KVerts)", LLVertexBuffer::sAllocatedBytes/(1024*1024), LLVBOPool::sBytesPooled/(1024*1024), LLVertexBuffer::sVertexCount/1024));
- ypos += y_inc;
-
addText(xpos, ypos, llformat("%d Vertex Buffers", LLVertexBuffer::sGLCount));
ypos += y_inc;
@@ -1974,7 +1968,7 @@ LLViewerWindow::LLViewerWindow(const Params& p)
LL_DEBUGS("Window") << "Loading feature tables." << LL_ENDL;
// Initialize OpenGL Renderer
- LLVertexBuffer::initClass(gSavedSettings.getBOOL("RenderVBOEnable"), gSavedSettings.getBOOL("RenderVBOMappingDisable"));
+ LLVertexBuffer::initClass(mWindow);
LL_INFOS("RenderInit") << "LLVertexBuffer initialization done." << LL_ENDL ;
gGL.init(true);
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 9851d4bc6a..66083470e2 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -855,17 +855,13 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
S32 shadow_detail = RenderShadowDetail;
bool ssao = RenderDeferredSSAO;
- const U32 occlusion_divisor = 3;
-
//allocate deferred rendering color buffers
- if (!mRT->deferredScreen.allocate(resX, resY, GL_RGBA, TRUE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false;
- //if (!mRT->deferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false;
- if (!mRT->occlusionDepth.allocate(resX/occlusion_divisor, resY/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false;
+ if (!mRT->deferredScreen.allocate(resX, resY, GL_RGBA, true, true, LLTexUnit::TT_TEXTURE, false, samples)) return false;
if (!addDeferredAttachments(mRT->deferredScreen)) return false;
GLuint screenFormat = GL_RGBA16;
- if (!mRT->screen.allocate(resX, resY, screenFormat, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false;
+ if (!mRT->screen.allocate(resX, resY, screenFormat, FALSE, true, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false;
mRT->deferredScreen.shareDepthBuffer(mRT->screen);
@@ -905,9 +901,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
mRT->fxaaBuffer.release();
mRT->screen.release();
mRT->deferredScreen.release(); //make sure to release any render targets that share a depth buffer with mRT->deferredScreen first
- //mRT->deferredDepth.release();
- mRT->occlusionDepth.release();
-
+
if (!mRT->screen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_TEXTURE, FALSE)) return false;
}
@@ -926,8 +920,6 @@ bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY)
LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
S32 shadow_detail = RenderShadowDetail;
- const U32 occlusion_divisor = 3;
-
F32 scale = llmax(0.f, RenderShadowResolutionScale);
U32 sun_shadow_map_width = BlurHappySize(resX, scale);
U32 sun_shadow_map_height = BlurHappySize(resY, scale);
@@ -936,12 +928,7 @@ bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY)
{ //allocate 4 sun shadow maps
for (U32 i = 0; i < 4; i++)
{
- if (!mRT->shadow[i].allocate(sun_shadow_map_width, sun_shadow_map_height, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE))
- {
- return false;
- }
-
- if (!mRT->shadowOcclusion[i].allocate(sun_shadow_map_width / occlusion_divisor, sun_shadow_map_height / occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE))
+ if (!mRT->shadow[i].allocate(sun_shadow_map_width, sun_shadow_map_height, 0, true, true, LLTexUnit::TT_TEXTURE))
{
return false;
}
@@ -966,11 +953,7 @@ bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY)
U32 spot_shadow_map_height = height;
for (U32 i = 0; i < 2; i++)
{
- if (!mSpotShadow[i].allocate(spot_shadow_map_width, spot_shadow_map_height, 0, TRUE, FALSE))
- {
- return false;
- }
- if (!mSpotShadowOcclusion[i].allocate(spot_shadow_map_width / occlusion_divisor, height / occlusion_divisor, 0, TRUE, FALSE))
+ if (!mSpotShadow[i].allocate(spot_shadow_map_width, spot_shadow_map_height, 0, true, true))
{
return false;
}
@@ -1001,7 +984,7 @@ bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY)
}
}
- if (shadow_detail > 1)
+ if (shadow_detail > 1 && !gCubeSnapshot)
{
for (U32 i = 0; i < 2; i++)
{
@@ -1198,7 +1181,6 @@ void LLPipeline::releaseScreenBuffers()
mRT->deferredScreen.release();
mRT->deferredDepth.release();
mRT->deferredLight.release();
- mRT->occlusionDepth.release();
}
@@ -1206,7 +1188,6 @@ void LLPipeline::releaseSunShadowTarget(U32 index)
{
llassert(index < 4);
mRT->shadow[index].release();
- mRT->shadowOcclusion[index].release();
}
void LLPipeline::releaseSunShadowTargets()
@@ -1224,7 +1205,6 @@ void LLPipeline::releaseSpotShadowTargets()
for (U32 i = 0; i < 2; i++)
{
mSpotShadow[i].release();
- mSpotShadowOcclusion[i].release();
}
}
}
@@ -1239,7 +1219,7 @@ void LLPipeline::createGLBuffers()
if (LLPipeline::sRenderTransparentWater)
{ //water reflection texture
U32 res = (U32) llmax(gSavedSettings.getS32("RenderWaterRefResolution"), 512);
- mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE,LLTexUnit::TT_TEXTURE);
+ mWaterDis.allocate(res,res,GL_RGBA,true,true,LLTexUnit::TT_TEXTURE);
}
// Use FBO for bake tex
@@ -2353,16 +2333,35 @@ bool LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3&
static LLTrace::BlockTimerStatHandle FTM_CULL("Object Culling");
-void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* planep)
+void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result)
{
- static LLCachedControl<bool> use_occlusion(gSavedSettings,"UseOcclusion");
- static bool can_use_occlusion = LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion");
-
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_CULL);
+ LL_PROFILE_GPU_ZONE("updateCull"); // should always be zero GPU time, but drop a timer to flush stuff out
- if (planep != nullptr)
+ bool water_clip = !sRenderTransparentWater;
+
+ if (water_clip)
{
- camera.setUserClipPlane(*planep);
+
+ LLVector3 pnorm;
+
+ F32 water_height = LLEnvironment::instance().getWaterHeight();
+
+ if (sUnderWaterRender)
+ {
+ //camera is below water, cull above water
+ pnorm.setVec(0, 0, 1);
+ }
+ else
+ {
+ //camera is above water, cull below water
+ pnorm = LLVector3(0, 0, -1);
+ }
+
+ LLPlane plane;
+ plane.setVec(LLVector3(0, 0, water_height), pnorm);
+
+ camera.setUserClipPlane(plane);
}
else
{
@@ -2373,56 +2372,6 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* pla
sCull->clear();
- bool to_texture = LLPipeline::sUseOcclusion > 1 && gPipeline.shadersLoaded();
-
- if (to_texture)
- {
- if (LLPipeline::sRenderDeferred && can_use_occlusion)
- {
- mRT->occlusionDepth.bindTarget();
- }
- else
- {
- mRT->screen.bindTarget();
- }
- }
-
- if (sUseOcclusion > 1)
- {
- gGL.setColorMask(false, false);
- }
-
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.pushMatrix();
- gGL.loadMatrix(gGLLastProjection);
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
- gGLLastMatrix = NULL;
- gGL.loadMatrix(gGLLastModelView);
-
- LLGLDisable blend(GL_BLEND);
- LLGLDisable test(GL_ALPHA_TEST);
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- LLGLDepthTest depth(GL_TRUE, GL_FALSE);
-
- bool bound_shader = false;
- if (gPipeline.shadersLoaded() && 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;
- gOcclusionCubeProgram.bind();
- }
-
- if (sUseOcclusion > 1)
- {
- if (mCubeVB.isNull())
- { //cube VB will be used for issuing occlusion queries
- mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW);
- }
- mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
- }
-
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
{
@@ -2444,16 +2393,10 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* pla
LLVOCachePartition* vo_part = region->getVOCachePartition();
if(vo_part)
{
- bool do_occlusion_cull = can_use_occlusion && use_occlusion && !gUseWireframe;
- vo_part->cull(camera, do_occlusion_cull);
+ vo_part->cull(camera, sUseOcclusion > 0);
}
}
- if (bound_shader)
- {
- gOcclusionCubeProgram.unbind();
- }
-
if (hasRenderType(LLPipeline::RENDER_TYPE_SKY) &&
gSky.mVOSkyp.notNull() &&
gSky.mVOSkyp->mDrawable.notNull())
@@ -2479,28 +2422,6 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* pla
{
LLWorld::getInstance()->precullWaterObjects(camera, sCull, render_water);
}
-
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.popMatrix();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.popMatrix();
-
- if (sUseOcclusion > 1)
- {
- gGL.setColorMask(true, false);
- }
-
- if (to_texture)
- {
- if (LLPipeline::sRenderDeferred && can_use_occlusion)
- {
- mRT->occlusionDepth.flush();
- }
- else
- {
- mRT->screen.flush();
- }
- }
}
void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera)
@@ -2563,19 +2484,22 @@ void LLPipeline::markOccluder(LLSpatialGroup* group)
void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
+ LL_PROFILE_GPU_ZONE("downsampleDepthBuffer");
+
LLGLSLShader* last_shader = LLGLSLShader::sCurBoundShaderPtr;
LLGLSLShader* shader = NULL;
if (scratch_space)
{
+#if 0 // TODO -- restore occlusion culling functionality
GLint bits = 0;
- llassert(!source.hasStencil()); // stencil buffer usage is deprecated
- bits |= (source.hasStencil() && dest.hasStencil()) ? GL_STENCIL_BUFFER_BIT : 0;
- bits |= GL_DEPTH_BUFFER_BIT;
- scratch_space->copyContents(source,
+ bits = GL_DEPTH_BUFFER_BIT;
+ scratch_space->copyContents(source,
0, 0, source.getWidth(), source.getHeight(),
0, 0, scratch_space->getWidth(), scratch_space->getHeight(), bits, GL_NEAREST);
+#endif
}
dest.bindTarget();
@@ -2624,23 +2548,6 @@ void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& d
}
}
-void LLPipeline::doOcclusion(LLCamera& camera, LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
- llassert(!gCubeSnapshot);
-#if 0
- downsampleDepthBuffer(source, dest, scratch_space);
- dest.bindTarget();
- doOcclusion(camera);
- dest.flush();
-#else
- // none of the above shenanigans should matter (enough) because we've preserved hierarchical Z before issuing occlusion queries
- //source.bindTarget();
- doOcclusion(camera);
- //source.flush();
-#endif
-}
-
void LLPipeline::doOcclusion(LLCamera& camera)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
@@ -2741,10 +2648,6 @@ void LLPipeline::updateGL()
LLGLUpdate::sGLQ.pop_front();
}
}
-
- { //seed VBO Pools
- LLVertexBuffer::seedPools();
- }
}
void LLPipeline::clearRebuildGroups()
@@ -3321,6 +3224,7 @@ void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags f
void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
+ LL_PROFILE_GPU_ZONE("stateSort");
if (hasAnyRenderType(LLPipeline::RENDER_TYPE_AVATAR,
LLPipeline::RENDER_TYPE_CONTROL_AV,
@@ -3929,6 +3833,7 @@ void LLPipeline::postSort(LLCamera &camera)
// flush particle VB
if (LLVOPartGroup::sVB)
{
+ LL_PROFILE_GPU_ZONE("flush particle vb");
LLVOPartGroup::sVB->flush();
}
else
@@ -3952,9 +3857,12 @@ void LLPipeline::postSort(LLCamera &camera)
}*/
// pack vertex buffers for groups that chose to delay their updates
- for (LLSpatialGroup::sg_vector_t::iterator iter = mMeshDirtyGroup.begin(); iter != mMeshDirtyGroup.end(); ++iter)
{
- (*iter)->rebuildMesh();
+ LL_PROFILE_GPU_ZONE("rebuildMesh");
+ for (LLSpatialGroup::sg_vector_t::iterator iter = mMeshDirtyGroup.begin(); iter != mMeshDirtyGroup.end(); ++iter)
+ {
+ (*iter)->rebuildMesh();
+ }
}
/*if (use_transform_feedback)
@@ -7351,8 +7259,6 @@ void LLPipeline::doResetVertexBuffers(bool forced)
LLVOPartGroup::destroyGL();
gGL.resetVertexBuffer();
- SUBSYSTEM_CLEANUP(LLVertexBuffer);
-
if (LLVertexBuffer::sGLCount != 0)
{
LL_WARNS() << "VBO wipe failed -- " << LLVertexBuffer::sGLCount << " buffers remaining." << LL_ENDL;
@@ -7372,7 +7278,6 @@ void LLPipeline::doResetVertexBuffers(bool forced)
sNoAlpha = gSavedSettings.getBOOL("RenderNoAlpha");
LLPipeline::sTextureBindTest = gSavedSettings.getBOOL("RenderDebugTextureBind");
- LLVertexBuffer::initClass(LLVertexBuffer::sEnableVBOs, LLVertexBuffer::sDisableVBOMapping);
gGL.initVertexBuffer();
mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK, 0);
@@ -7445,30 +7350,28 @@ void LLPipeline::renderAlphaObjects(U32 mask, bool texture, bool batch_texture,
for (LLCullResult::drawinfo_iterator i = begin; i != end; )
{
LLDrawInfo* pparams = *i;
- if (pparams)
- {
- LLCullResult::increment_iterator(i, end);
+ LLCullResult::increment_iterator(i, end);
- if (rigged)
+ if (rigged)
+ {
+ if (pparams->mAvatar != nullptr)
{
- if (pparams->mAvatar != nullptr)
+ if (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash)
{
- if (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash)
- {
- mSimplePool->uploadMatrixPalette(*pparams);
- lastAvatar = pparams->mAvatar;
- lastMeshId = pparams->mSkinInfo->mHash;
- }
-
- mSimplePool->pushBatch(*pparams, mask | LLVertexBuffer::MAP_WEIGHT4, texture, batch_texture);
+ mSimplePool->uploadMatrixPalette(*pparams);
+ lastAvatar = pparams->mAvatar;
+ lastMeshId = pparams->mSkinInfo->mHash;
}
+
+ mSimplePool->pushBatch(*pparams, mask | LLVertexBuffer::MAP_WEIGHT4, texture, batch_texture);
}
- else if (pparams->mAvatar == nullptr)
- {
- mSimplePool->pushBatch(*pparams, mask, texture, batch_texture);
- }
+ }
+ else if (pparams->mAvatar == nullptr)
+ {
+ mSimplePool->pushBatch(*pparams, mask, texture, batch_texture);
}
}
+
gGL.loadMatrix(gGLModelView);
gGLLastMatrix = NULL;
}
@@ -9565,20 +9468,17 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
LLGLEnable cull(GL_CULL_FACE);
//enable depth clamping if available
- //LLGLEnable depth_clamp(GL_DEPTH_CLAMP);
+ LLGLEnable depth_clamp(GL_DEPTH_CLAMP);
+
+ LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_LESS);
if (use_shader)
{
gDeferredShadowCubeProgram.bind();
}
- LLRenderTarget& occlusion_target = LLViewerCamera::sCurCameraID >= LLViewerCamera::CAMERA_SPOT_SHADOW0 ?
- mSpotShadowOcclusion[LLViewerCamera::sCurCameraID - LLViewerCamera::CAMERA_SPOT_SHADOW0] :
- mRT->shadowOcclusion[LLViewerCamera::sCurCameraID - LLViewerCamera::CAMERA_SUN_SHADOW0];
-
- occlusion_target.bindTarget();
+
updateCull(shadow_cam, result);
- occlusion_target.flush();
stateSort(shadow_cam, result);
@@ -9613,15 +9513,8 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
for (int j = 0; j < 2; ++j) // 0 -- static, 1 -- rigged
{
bool rigged = j == 1;
- if (!use_shader)
- { //occlusion program is general purpose depth-only no-textures
- gOcclusionProgram.bind(rigged);
- }
- else
- {
- gDeferredShadowProgram.bind(rigged);
- LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
- }
+ gDeferredShadowProgram.bind(rigged);
+ LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
gGL.diffuseColor4f(1, 1, 1, 1);
@@ -9655,12 +9548,14 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
}
gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
- if (!use_shader)
- {
- gOcclusionProgram.unbind();
- }
}
+ if (occlude > 1)
+ { // do occlusion culling against non-masked only to take advantage of hierarchical Z
+ doOcclusion(shadow_cam);
+ }
+
+
if (use_shader)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow geom");
@@ -9760,15 +9655,6 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
gGLLastMatrix = NULL;
gGL.loadMatrix(gGLModelView);
- LLRenderTarget& occlusion_source = LLViewerCamera::sCurCameraID >= LLViewerCamera::CAMERA_SPOT_SHADOW0 ?
- mSpotShadow[LLViewerCamera::sCurCameraID - LLViewerCamera::CAMERA_SPOT_SHADOW0] :
- mRT->shadow[LLViewerCamera::sCurCameraID - LLViewerCamera::CAMERA_SUN_SHADOW0];
-
- if (occlude > 1)
- {
- doOcclusion(shadow_cam, occlusion_source, occlusion_target);
- }
-
if (use_shader)
{
gDeferredShadowProgram.unbind();
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index c698374c8b..d3793da347 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -173,7 +173,6 @@ public:
// if source's depth buffer cannot be bound for reading, a scratch space depth buffer must be provided
void downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space = NULL);
- void doOcclusion(LLCamera& camera, LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space = NULL);
void doOcclusion(LLCamera& camera);
void markNotCulled(LLSpatialGroup* group, LLCamera &camera);
void markMoved(LLDrawable *drawablep, bool damped_motion = false);
@@ -244,7 +243,9 @@ public:
bool visibleObjectsInFrustum(LLCamera& camera);
bool getVisibleExtents(LLCamera& camera, LLVector3 &min, LLVector3& max);
bool getVisiblePointCloud(LLCamera& camera, LLVector3 &min, LLVector3& max, std::vector<LLVector3>& fp, LLVector3 light_dir = LLVector3(0,0,0));
- void updateCull(LLCamera& camera, LLCullResult& result, LLPlane* plane = NULL); //if water_clip is 0, ignore water plane, 1, cull to above plane, -1, cull to below plane
+
+ // Populate given LLCullResult with results of a frustum cull of the entire scene against the given LLCamera
+ void updateCull(LLCamera& camera, LLCullResult& result);
void createObjects(F32 max_dtime);
void createObject(LLViewerObject* vobj);
void processPartitionQ();
@@ -673,12 +674,10 @@ public:
LLRenderTarget fxaaBuffer;
LLRenderTarget edgeMap;
LLRenderTarget deferredDepth;
- LLRenderTarget occlusionDepth;
LLRenderTarget deferredLight;
//sun shadow map
LLRenderTarget shadow[4];
- LLRenderTarget shadowOcclusion[4];
};
// main full resoltuion render target
@@ -691,7 +690,6 @@ public:
RenderTargetPack* mRT;
LLRenderTarget mSpotShadow[2];
- LLRenderTarget mSpotShadowOcclusion[2];
LLRenderTarget mPbrBrdfLut;