summaryrefslogtreecommitdiff
path: root/indra/llrender
diff options
context:
space:
mode:
authorIma Mechanique <ima.mechanique@secondlife.com>2013-10-04 20:47:54 +0100
committerIma Mechanique <ima.mechanique@secondlife.com>2013-10-04 20:47:54 +0100
commit0c1d6d7d9e89a6d3169621157bcba335ead477a9 (patch)
treec5523eeb99bcd8ee77cf28a1d6f5e5cef8b52f2c /indra/llrender
parent02097397e06a6cf45c639823c7f633dffe3684e8 (diff)
parentf7158bc5afcec1da8b9d2d5a4ed86921e62d4959 (diff)
Merge v3.6.7 in
Diffstat (limited to 'indra/llrender')
-rwxr-xr-xindra/llrender/llgl.cpp21
-rwxr-xr-xindra/llrender/llgl.h1
-rwxr-xr-xindra/llrender/llglheaders.h7
-rwxr-xr-xindra/llrender/llglslshader.cpp141
-rwxr-xr-xindra/llrender/llglslshader.h45
-rwxr-xr-x[-rw-r--r--]indra/llrender/llimagegl.cpp14
-rwxr-xr-xindra/llrender/llpostprocess.cpp59
-rwxr-xr-xindra/llrender/llpostprocess.h3
-rwxr-xr-xindra/llrender/llrender.cpp83
-rwxr-xr-xindra/llrender/llrender.h1
-rwxr-xr-xindra/llrender/llrendertarget.cpp57
-rwxr-xr-xindra/llrender/llrendertarget.h9
-rwxr-xr-xindra/llrender/llshadermgr.cpp47
-rwxr-xr-xindra/llrender/llshadermgr.h45
-rwxr-xr-xindra/llrender/llvertexbuffer.cpp80
-rwxr-xr-xindra/llrender/llvertexbuffer.h4
16 files changed, 456 insertions, 161 deletions
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 088ba95b75..acfb3c085a 100755
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -59,6 +59,7 @@ BOOL gDebugGL = FALSE;
BOOL gClothRipple = FALSE;
BOOL gHeadlessClient = FALSE;
BOOL gGLActive = FALSE;
+BOOL gGLDebugLoggingEnabled = TRUE;
static const std::string HEADLESS_VENDOR_STRING("Linden Lab");
static const std::string HEADLESS_RENDERER_STRING("Headless");
@@ -80,6 +81,8 @@ void APIENTRY gl_debug_callback(GLenum source,
const GLchar* message,
GLvoid* userParam)
{
+ if (gGLDebugLoggingEnabled)
+ {
if (severity == GL_DEBUG_SEVERITY_HIGH_ARB)
{
llwarns << "----- GL ERROR --------" << llendl;
@@ -98,6 +101,7 @@ void APIENTRY gl_debug_callback(GLenum source,
llerrs << "Halting on GL Error" << llendl;
}
}
+}
#endif
void parse_glsl_version(S32& major, S32& minor);
@@ -258,6 +262,7 @@ PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback = NULL;
PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback = NULL;
PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings = NULL;
PFNGLBINDBUFFERRANGEPROC glBindBufferRange = NULL;
+PFNGLBINDBUFFERBASEPROC glBindBufferBase = NULL;
//GL_ARB_debug_output
PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControlARB = NULL;
@@ -647,7 +652,8 @@ bool LLGLManager::initGL()
}
#if LL_DARWIN
else if ((mGLRenderer.find("9400M") != std::string::npos)
- || (mGLRenderer.find("9600M") != std::string::npos))
+ || (mGLRenderer.find("9600M") != std::string::npos)
+ || (mGLRenderer.find("9800M") != std::string::npos))
{
mIsMobileGF = TRUE;
}
@@ -1154,7 +1160,8 @@ void LLGLManager::initExtensions()
// Misc
glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, (GLint*) &mGLMaxVertexRange);
glGetIntegerv(GL_MAX_ELEMENTS_INDICES, (GLint*) &mGLMaxIndexRange);
-
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint*) &mGLMaxTextureSize);
+
#if (LL_WINDOWS || LL_LINUX || LL_SOLARIS) && !LL_MESA_HEADLESS
LL_DEBUGS("RenderInit") << "GL Probe: Getting symbols" << LL_ENDL;
if (mHasVertexBufferObject)
@@ -1245,6 +1252,7 @@ void LLGLManager::initExtensions()
glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC) GLH_EXT_GET_PROC_ADDRESS("glEndTransformFeedback");
glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC) GLH_EXT_GET_PROC_ADDRESS("glTransformFeedbackVaryings");
glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC) GLH_EXT_GET_PROC_ADDRESS("glBindBufferRange");
+ glBindBufferBase = (PFNGLBINDBUFFERBASEPROC) GLH_EXT_GET_PROC_ADDRESS("glBindBufferBase");
}
if (mHasDebugOutput)
{
@@ -1499,7 +1507,7 @@ void do_assert_glerror()
void assert_glerror()
{
- if (!gGLActive)
+/* if (!gGLActive)
{
//llwarns << "GL used while not active!" << llendl;
@@ -1508,8 +1516,13 @@ void assert_glerror()
//ll_fail("GL used while not active");
}
}
+*/
- if (gDebugGL)
+ if (!gDebugGL)
+ {
+ //funny looking if for branch prediction -- gDebugGL is almost always false and assert_glerror is called often
+ }
+ else
{
do_assert_glerror();
}
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index 60597fd090..75e5fe86ec 100755
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -155,6 +155,7 @@ public:
S32 mVRAM; // VRAM in MB
S32 mGLMaxVertexRange;
S32 mGLMaxIndexRange;
+ S32 mGLMaxTextureSize;
void getPixelFormat(); // Get the best pixel format
diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h
index dace572953..5a80a8faa4 100755
--- a/indra/llrender/llglheaders.h
+++ b/indra/llrender/llglheaders.h
@@ -543,6 +543,7 @@ extern PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback;
extern PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback;
extern PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings;
extern PFNGLBINDBUFFERRANGEPROC glBindBufferRange;
+extern PFNGLBINDBUFFERBASEPROC glBindBufferBase;
#elif LL_WINDOWS
@@ -787,6 +788,7 @@ extern PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback;
extern PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback;
extern PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings;
extern PFNGLBINDBUFFERRANGEPROC glBindBufferRange;
+extern PFNGLBINDBUFFERBASEPROC glBindBufferBase;
//GL_ARB_debug_output
extern PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControlARB;
@@ -1009,12 +1011,7 @@ extern void glGetBufferPointervARB (GLenum, GLenum, GLvoid* *);
}
#endif
-#if __MAC_OS_X_VERSION_MAX_ALLOWED <= 1070
#include <OpenGL/gl.h>
-#else
-#include <AGL/gl.h>
-#endif
-
#endif // LL_MESA / LL_WINDOWS / LL_DARWIN
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 62191b4c1a..35620bb656 100755
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -149,6 +149,9 @@ void LLGLSLShader::clearStats()
mTimeElapsed = 0;
mSamplesDrawn = 0;
mDrawCalls = 0;
+ mTextureStateFetched = false;
+ mTextureMagFilter.clear();
+ mTextureMinFilter.clear();
}
void LLGLSLShader::dumpStats()
@@ -161,6 +164,16 @@ void LLGLSLShader::dumpStats()
{
llinfos << mShaderFiles[i].first << llendl;
}
+ for (U32 i = 0; i < mTexture.size(); ++i)
+ {
+ GLint idx = mTexture[i];
+
+ if (idx >= 0)
+ {
+ GLint uniform_idx = getUniformLocation(i);
+ llinfos << mUniformNameMap[uniform_idx] << " - " << std::hex << mTextureMagFilter[i] << "/" << mTextureMinFilter[i] << std::dec << llendl;
+ }
+ }
llinfos << "=============================================" << llendl;
F32 ms = mTimeElapsed/1000000.f;
@@ -211,6 +224,39 @@ void LLGLSLShader::placeProfileQuery()
glGenQueriesARB(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)
+ {
+ 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;
+ }
+ }
+
+ gGL.getTexUnit(cur_active)->activate();
+ }
+
+
glBeginQueryARB(GL_SAMPLES_PASSED, 1);
glBeginQueryARB(GL_TIME_ELAPSED, mTimerQuery);
#endif
@@ -309,8 +355,8 @@ void LLGLSLShader::unload()
stop_glerror();
}
-BOOL LLGLSLShader::createShader(vector<string> * attributes,
- vector<string> * uniforms,
+BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
+ std::vector<LLStaticHashedString> * uniforms,
U32 varying_count,
const char** varyings)
{
@@ -329,6 +375,11 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,
// Create program
mProgramObject = glCreateProgramObjectARB();
+#if LL_DARWIN
+ // work-around missing mix(vec3,vec3,bvec3)
+ mDefines["OLD_SELECT"] = "1";
+#endif
+
//compile new source
vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin();
for ( ; fileIter != mShaderFiles.end(); fileIter++ )
@@ -392,7 +443,8 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,
for (S32 i = 0; i < channel_count; i++)
{
- uniform1i(llformat("tex%d", i), i);
+ LLStaticHashedString uniName(llformat("tex%d", i));
+ uniform1i(uniName, i);
}
S32 cur_tex = channel_count; //adjust any texture channels that might have been overwritten
@@ -449,7 +501,7 @@ void LLGLSLShader::attachObjects(GLhandleARB* objects, S32 count)
}
}
-BOOL LLGLSLShader::mapAttributes(const vector<string> * attributes)
+BOOL LLGLSLShader::mapAttributes(const std::vector<LLStaticHashedString> * attributes)
{
//before linking, make sure reserved attributes always have consistent locations
for (U32 i = 0; i < LLShaderMgr::instance()->mReservedAttribs.size(); i++)
@@ -486,7 +538,7 @@ BOOL LLGLSLShader::mapAttributes(const vector<string> * attributes)
{
for (U32 i = 0; i < numAttributes; i++)
{
- const char* name = (*attributes)[i].c_str();
+ const char* name = (*attributes)[i].String().c_str();
S32 index = glGetAttribLocationARB(mProgramObject, name);
if (index != -1)
{
@@ -502,7 +554,7 @@ BOOL LLGLSLShader::mapAttributes(const vector<string> * attributes)
return FALSE;
}
-void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)
+void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString> * uniforms)
{
if (index == -1)
{
@@ -572,7 +624,10 @@ void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)
is_array[0] = 0;
}
- mUniformMap[name] = location;
+ LLStaticHashedString hashedName(name);
+ mUniformNameMap[location] = name;
+ mUniformMap[hashedName] = location;
+
LL_DEBUGS("ShaderLoading") << "Uniform " << name << " is at location " << location << LL_ENDL;
//find the index of this uniform
@@ -593,7 +648,7 @@ void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)
for (U32 i = 0; i < uniforms->size(); i++)
{
if ( (mUniform[i+LLShaderMgr::instance()->mReservedUniforms.size()] == -1)
- && ((*uniforms)[i] == name))
+ && ((*uniforms)[i].String() == name))
{
//found it
mUniform[i+LLShaderMgr::instance()->mReservedUniforms.size()] = location;
@@ -627,7 +682,7 @@ GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type)
return -1;
}
-BOOL LLGLSLShader::mapUniforms(const vector<string> * uniforms)
+BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
{
BOOL res = TRUE;
@@ -635,6 +690,7 @@ BOOL LLGLSLShader::mapUniforms(const vector<string> * uniforms)
mActiveTextureChannels = 0;
mUniform.clear();
mUniformMap.clear();
+ mUniformNameMap.clear();
mTexture.clear();
mValue.clear();
//initialize arrays
@@ -1088,18 +1144,18 @@ void LLGLSLShader::uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, c
}
}
-GLint LLGLSLShader::getUniformLocation(const string& uniform)
+GLint LLGLSLShader::getUniformLocation(const LLStaticHashedString& uniform)
{
GLint ret = -1;
if (mProgramObject > 0)
{
- std::map<string, GLint>::iterator iter = mUniformMap.find(uniform);
+ LLStaticStringTable<GLint>::iterator iter = mUniformMap.find(uniform);
if (iter != mUniformMap.end())
{
if (gDebugGL)
{
stop_glerror();
- if (iter->second != glGetUniformLocationARB(mProgramObject, uniform.c_str()))
+ if (iter->second != glGetUniformLocationARB(mProgramObject, uniform.String().c_str()))
{
llerrs << "Uniform does not match." << llendl;
}
@@ -1136,7 +1192,7 @@ GLint LLGLSLShader::getAttribLocation(U32 attrib)
}
}
-void LLGLSLShader::uniform1i(const string& uniform, GLint v)
+void LLGLSLShader::uniform1i(const LLStaticHashedString& uniform, GLint v)
{
GLint location = getUniformLocation(uniform);
@@ -1152,72 +1208,73 @@ void LLGLSLShader::uniform1i(const string& uniform, GLint v)
}
}
-void LLGLSLShader::uniform1f(const string& uniform, GLfloat v)
+void LLGLSLShader::uniform2i(const LLStaticHashedString& uniform, GLint i, GLint j)
{
GLint location = getUniformLocation(uniform);
if (location >= 0)
{
std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
- LLVector4 vec(v,0.f,0.f,0.f);
+ LLVector4 vec(i,j,0.f,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec))
{
- glUniform1fARB(location, v);
+ glUniform2iARB(location, i, j);
mValue[location] = vec;
}
}
}
-void LLGLSLShader::uniform2f(const string& uniform, GLfloat x, GLfloat y)
+
+void LLGLSLShader::uniform1f(const LLStaticHashedString& uniform, GLfloat v)
{
GLint location = getUniformLocation(uniform);
if (location >= 0)
{
std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
- LLVector4 vec(x,y,0.f,0.f);
+ LLVector4 vec(v,0.f,0.f,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec))
{
- glUniform2fARB(location, x,y);
+ glUniform1fARB(location, v);
mValue[location] = vec;
}
}
-
}
-void LLGLSLShader::uniform3f(const string& uniform, GLfloat x, GLfloat y, GLfloat z)
+void LLGLSLShader::uniform2f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y)
{
GLint location = getUniformLocation(uniform);
if (location >= 0)
{
std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
- LLVector4 vec(x,y,z,0.f);
+ LLVector4 vec(x,y,0.f,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec))
{
- glUniform3fARB(location, x,y,z);
+ glUniform2fARB(location, x,y);
mValue[location] = vec;
}
}
+
}
-void LLGLSLShader::uniform4f(const string& uniform, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+void LLGLSLShader::uniform3f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y, GLfloat z)
{
GLint location = getUniformLocation(uniform);
-
+
if (location >= 0)
{
std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
- LLVector4 vec(x,y,z,w);
+ LLVector4 vec(x,y,z,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec))
{
- glUniform4fARB(location, x,y,z,w);
+ glUniform3fARB(location, x,y,z);
mValue[location] = vec;
}
}
}
-void LLGLSLShader::uniform1fv(const string& uniform, U32 count, const GLfloat* v)
+void LLGLSLShader::uniform1fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v)
{
GLint location = getUniformLocation(uniform);
@@ -1233,7 +1290,7 @@ void LLGLSLShader::uniform1fv(const string& uniform, U32 count, const GLfloat* v
}
}
-void LLGLSLShader::uniform2fv(const string& uniform, U32 count, const GLfloat* v)
+void LLGLSLShader::uniform2fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v)
{
GLint location = getUniformLocation(uniform);
@@ -1249,7 +1306,7 @@ void LLGLSLShader::uniform2fv(const string& uniform, U32 count, const GLfloat* v
}
}
-void LLGLSLShader::uniform3fv(const string& uniform, U32 count, const GLfloat* v)
+void LLGLSLShader::uniform3fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v)
{
GLint location = getUniformLocation(uniform);
@@ -1265,7 +1322,7 @@ void LLGLSLShader::uniform3fv(const string& uniform, U32 count, const GLfloat* v
}
}
-void LLGLSLShader::uniform4fv(const string& uniform, U32 count, const GLfloat* v)
+void LLGLSLShader::uniform4fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v)
{
GLint location = getUniformLocation(uniform);
@@ -1283,27 +1340,7 @@ void LLGLSLShader::uniform4fv(const string& uniform, U32 count, const GLfloat* v
}
}
-void LLGLSLShader::uniformMatrix2fv(const string& uniform, U32 count, GLboolean transpose, const GLfloat* v)
-{
- GLint location = getUniformLocation(uniform);
-
- if (location >= 0)
- {
- glUniformMatrix2fvARB(location, count, transpose, v);
- }
-}
-
-void LLGLSLShader::uniformMatrix3fv(const string& uniform, U32 count, GLboolean transpose, const GLfloat* v)
-{
- GLint location = getUniformLocation(uniform);
-
- if (location >= 0)
- {
- glUniformMatrix3fvARB(location, count, transpose, v);
- }
-}
-
-void LLGLSLShader::uniformMatrix4fv(const string& uniform, U32 count, GLboolean transpose, const GLfloat* v)
+void LLGLSLShader::uniformMatrix4fv(const LLStaticHashedString& uniform, U32 count, GLboolean transpose, const GLfloat* v)
{
GLint location = getUniformLocation(uniform);
diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index 3c775cde27..7b2f5f04c2 100755
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -29,6 +29,7 @@
#include "llgl.h"
#include "llrender.h"
+#include "llstaticstringtable.h"
class LLShaderFeatures
{
@@ -90,16 +91,16 @@ public:
void placeProfileQuery();
void readProfileQuery(U32 count, U32 mode);
- BOOL createShader(std::vector<std::string> * attributes,
- std::vector<std::string> * uniforms,
+ BOOL createShader(std::vector<LLStaticHashedString> * attributes,
+ std::vector<LLStaticHashedString> * uniforms,
U32 varying_count = 0,
const char** varyings = NULL);
BOOL attachObject(std::string object);
void attachObject(GLhandleARB object);
void attachObjects(GLhandleARB* objects = NULL, S32 count = 0);
- BOOL mapAttributes(const std::vector<std::string> * attributes);
- BOOL mapUniforms(const std::vector<std::string> * uniforms);
- void mapUniform(GLint index, const std::vector<std::string> * uniforms);
+ 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 uniform2f(U32 index, GLfloat x, GLfloat y);
@@ -110,29 +111,27 @@ public:
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 uniform1i(const std::string& uniform, GLint i);
- void uniform1f(const std::string& uniform, GLfloat v);
- void uniform2f(const std::string& uniform, GLfloat x, GLfloat y);
- void uniform3f(const std::string& uniform, GLfloat x, GLfloat y, GLfloat z);
- void uniform4f(const std::string& uniform, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
- void uniform1iv(const std::string& uniform, U32 count, const GLint* i);
- void uniform1fv(const std::string& uniform, U32 count, const GLfloat* v);
- void uniform2fv(const std::string& uniform, U32 count, const GLfloat* v);
- void uniform3fv(const std::string& uniform, U32 count, const GLfloat* v);
- void uniform4fv(const std::string& uniform, 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 uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v);
- void uniformMatrix2fv(const std::string& uniform, U32 count, GLboolean transpose, const GLfloat *v);
- void uniformMatrix3fv(const std::string& uniform, U32 count, GLboolean transpose, const GLfloat *v);
- void uniformMatrix4fv(const std::string& uniform, U32 count, GLboolean transpose, const GLfloat *v);
+ void uniform1i(const LLStaticHashedString& uniform, GLint i);
+ 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 std::string& uniform);
+ GLint getUniformLocation(const LLStaticHashedString& uniform);
GLint getUniformLocation(U32 index);
GLint getAttribLocation(U32 attrib);
@@ -169,7 +168,8 @@ public:
std::vector<GLint> mAttribute; //lookup table of attribute enum to attribute channel
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
- std::map<std::string, GLint> mUniformMap; //lookup map of uniform name to uniform location
+ LLStaticStringTable<GLint> mUniformMap; //lookup map of uniform name to uniform location
+ std::map<GLint, std::string> mUniformNameMap; //lookup map of uniform location to uniform name
std::map<GLint, LLVector4> mValue; //lookup map of uniform location to last known value
std::vector<GLint> mTexture;
S32 mTotalUniformSize;
@@ -192,6 +192,11 @@ public:
static U64 sTotalSamplesDrawn;
U32 mDrawCalls;
static U32 sTotalDrawCalls;
+
+ bool mTextureStateFetched;
+ std::vector<U32> mTextureMagFilter;
+ std::vector<U32> mTextureMinFilter;
+
};
//UI shader (declared here so llui_libtest will link properly)
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 38764eba23..6a37d31415 100644..100755
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -715,9 +715,9 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
mMipLevels = wpo2(llmax(w, h));
- //use legacy mipmap generation mode
+ //use legacy mipmap generation mode (note: making this condional can cause rendering issues)
glTexParameteri(mTarget, GL_GENERATE_MIPMAP, GL_TRUE);
-
+
LLImageGL::setManualImage(mTarget, 0, mFormatInternal,
w, h,
mFormatPrimary, mFormatType,
@@ -1089,6 +1089,16 @@ void LLImageGL::generateTextures(LLTexUnit::eTextureType type, U32 format, S32 n
LLFastTimer t(FTM_GENERATE_TEXTURES);
bool empty = true;
+ if (LLRender::sGLCoreProfile)
+ {
+ switch (format)
+ {
+ case GL_LUMINANCE8: format = GL_RGB8; break;
+ case GL_LUMINANCE8_ALPHA8:
+ case GL_ALPHA8: format = GL_RGBA8; break;
+ }
+ }
+
dead_texturelist_t::iterator iter = sDeadTextureList[type].find(format);
if (iter != sDeadTextureList[type].end())
diff --git a/indra/llrender/llpostprocess.cpp b/indra/llrender/llpostprocess.cpp
index c0045c8044..4c36185b08 100755
--- a/indra/llrender/llpostprocess.cpp
+++ b/indra/llrender/llpostprocess.cpp
@@ -31,6 +31,21 @@
#include "llsdserialize.h"
#include "llrender.h"
+static LLStaticHashedString sRenderTexture("RenderTexture");
+static LLStaticHashedString sBrightness("brightness");
+static LLStaticHashedString sContrast("contrast");
+static LLStaticHashedString sContrastBase("contrastBase");
+static LLStaticHashedString sSaturation("saturation");
+static LLStaticHashedString sLumWeights("lumWeights");
+static LLStaticHashedString sNoiseTexture("NoiseTexture");
+static LLStaticHashedString sBrightMult("brightMult");
+static LLStaticHashedString sNoiseStrength("noiseStrength");
+static LLStaticHashedString sExtractLow("extractLow");
+static LLStaticHashedString sExtractHigh("extractHigh");
+static LLStaticHashedString sBloomStrength("bloomStrength");
+static LLStaticHashedString sTexelSize("texelSize");
+static LLStaticHashedString sBlurDirection("blurDirection");
+static LLStaticHashedString sBlurWidth("blurWidth");
LLPostProcess * gPostProcess = NULL;
@@ -258,12 +273,12 @@ void LLPostProcess::applyColorFilterShader(void)
void LLPostProcess::createColorFilterShader(void)
{
/// Define uniform names
- colorFilterUniforms["RenderTexture"] = 0;
- colorFilterUniforms["brightness"] = 0;
- colorFilterUniforms["contrast"] = 0;
- colorFilterUniforms["contrastBase"] = 0;
- colorFilterUniforms["saturation"] = 0;
- colorFilterUniforms["lumWeights"] = 0;
+ colorFilterUniforms[sRenderTexture] = 0;
+ colorFilterUniforms[sBrightness] = 0;
+ colorFilterUniforms[sContrast] = 0;
+ colorFilterUniforms[sContrastBase] = 0;
+ colorFilterUniforms[sSaturation] = 0;
+ colorFilterUniforms[sLumWeights] = 0;
}
void LLPostProcess::applyNightVisionShader(void)
@@ -307,11 +322,11 @@ void LLPostProcess::applyNightVisionShader(void)
void LLPostProcess::createNightVisionShader(void)
{
/// Define uniform names
- nightVisionUniforms["RenderTexture"] = 0;
- nightVisionUniforms["NoiseTexture"] = 0;
- nightVisionUniforms["brightMult"] = 0;
- nightVisionUniforms["noiseStrength"] = 0;
- nightVisionUniforms["lumWeights"] = 0;
+ nightVisionUniforms[sRenderTexture] = 0;
+ nightVisionUniforms[sNoiseTexture] = 0;
+ nightVisionUniforms[sBrightMult] = 0;
+ nightVisionUniforms[sNoiseStrength] = 0;
+ nightVisionUniforms[sLumWeights] = 0;
createNoiseTexture(mNoiseTexture);
}
@@ -326,25 +341,25 @@ void LLPostProcess::createBloomShader(void)
createTexture(mTempBloomTexture, unsigned(screenW * 0.5), unsigned(screenH * 0.5));
/// Create Bloom Extract Shader
- bloomExtractUniforms["RenderTexture"] = 0;
- bloomExtractUniforms["extractLow"] = 0;
- bloomExtractUniforms["extractHigh"] = 0;
- bloomExtractUniforms["lumWeights"] = 0;
+ bloomExtractUniforms[sRenderTexture] = 0;
+ bloomExtractUniforms[sExtractLow] = 0;
+ bloomExtractUniforms[sExtractHigh] = 0;
+ bloomExtractUniforms[sLumWeights] = 0;
/// Create Bloom Blur Shader
- bloomBlurUniforms["RenderTexture"] = 0;
- bloomBlurUniforms["bloomStrength"] = 0;
- bloomBlurUniforms["texelSize"] = 0;
- bloomBlurUniforms["blurDirection"] = 0;
- bloomBlurUniforms["blurWidth"] = 0;
+ bloomBlurUniforms[sRenderTexture] = 0;
+ bloomBlurUniforms[sBloomStrength] = 0;
+ bloomBlurUniforms[sTexelSize] = 0;
+ bloomBlurUniforms[sBlurDirection] = 0;
+ bloomBlurUniforms[sBlurWidth] = 0;
}
void LLPostProcess::getShaderUniforms(glslUniforms & uniforms, GLhandleARB & prog)
{
/// Find uniform locations and insert into map
- std::map<const char *, GLuint>::iterator i;
+ glslUniforms::iterator i;
for (i = uniforms.begin(); i != uniforms.end(); ++i){
- i->second = glGetUniformLocationARB(prog, i->first);
+ i->second = glGetUniformLocationARB(prog, i->first.String().c_str());
}
}
diff --git a/indra/llrender/llpostprocess.h b/indra/llrender/llpostprocess.h
index e19de44c60..ce17b6693d 100755
--- a/indra/llrender/llpostprocess.h
+++ b/indra/llrender/llpostprocess.h
@@ -31,6 +31,7 @@
#include <fstream>
#include "llgl.h"
#include "llglheaders.h"
+#include "llstaticstringtable.h"
class LLPostProcess
{
@@ -44,7 +45,7 @@ public:
} QuadType;
/// GLSL Shader Encapsulation Struct
- typedef std::map<const char *, GLuint> glslUniforms;
+ typedef LLStaticStringTable<GLuint> glslUniforms;
struct PostProcessTweaks : public LLSD {
inline PostProcessTweaks() : LLSD(LLSD::emptyMap())
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index c60eb8d9d9..0ac30b4d63 100755
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -225,26 +225,15 @@ void LLTexUnit::disable(void)
bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind)
{
stop_glerror();
- if (mIndex < 0) return false;
-
+ if (mIndex >= 0)
+ {
gGL.flush();
LLImageGL* gl_tex = NULL ;
- if (texture == NULL || !(gl_tex = texture->getGLTexture()))
+ if (texture != NULL && (gl_tex = texture->getGLTexture()))
{
- llwarns << "NULL LLTexUnit::bind texture" << llendl;
- return false;
- }
-
- if (!gl_tex->getTexName()) //if texture does not exist
+ if (gl_tex->getTexName()) //if texture exists
{
- //if deleted, will re-generate it immediately
- texture->forceImmediateUpdate() ;
-
- gl_tex->forceUpdateBindStats() ;
- return texture->bindDefaultImage(mIndex);
- }
-
//in audit, replace the selected texture by the default one.
if ((mCurrTexture != gl_tex->getTexName()) || forceBind)
{
@@ -265,6 +254,27 @@ bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind)
setTextureFilteringOption(gl_tex->mFilterOption);
}
}
+ }
+ else
+ {
+ //if deleted, will re-generate it immediately
+ texture->forceImmediateUpdate() ;
+
+ gl_tex->forceUpdateBindStats() ;
+ return texture->bindDefaultImage(mIndex);
+ }
+ }
+ else
+ {
+ llwarns << "NULL LLTexUnit::bind texture" << llendl;
+ return false;
+ }
+ }
+ else
+ { // mIndex < 0
+ return false;
+ }
+
return true;
}
@@ -1058,6 +1068,16 @@ LLRender::~LLRender()
void LLRender::init()
{
+ if (sGLCoreProfile && !LLVertexBuffer::sUseVAO)
+ { //bind a dummy vertex array object so we're core profile compliant
+#ifdef GL_ARB_vertex_array_object
+ U32 ret;
+ glGenVertexArrays(1, &ret);
+ glBindVertexArray(ret);
+#endif
+ }
+
+
llassert_always(mBuffer.isNull()) ;
stop_glerror();
mBuffer = new LLVertexBuffer(immediate_mask, 0);
@@ -1849,13 +1869,15 @@ void LLRender::flush()
sUIVerts += mCount;
}
- if (gDebugGL)
- {
+ //store mCount in a local variable to avoid re-entrance (drawArrays may call flush)
+ U32 count = mCount;
+
if (mMode == LLRender::QUADS && !sGLCoreProfile)
{
if (mCount%4 != 0)
{
- llerrs << "Incomplete quad rendered." << llendl;
+ count -= (mCount % 4);
+ llwarns << "Incomplete quad requested." << llendl;
}
}
@@ -1863,7 +1885,8 @@ void LLRender::flush()
{
if (mCount%3 != 0)
{
- llerrs << "Incomplete triangle rendered." << llendl;
+ count -= (mCount % 3);
+ llwarns << "Incomplete triangle requested." << llendl;
}
}
@@ -1871,13 +1894,11 @@ void LLRender::flush()
{
if (mCount%2 != 0)
{
- llerrs << "Incomplete line rendered." << llendl;
- }
+ count -= (mCount % 2);
+ llwarns << "Incomplete line requested." << llendl;
}
}
- //store mCount in a local variable to avoid re-entrance (drawArrays may call flush)
- U32 count = mCount;
mCount = 0;
if (mBuffer->useVBOs() && !mBuffer->isLocked())
@@ -2280,6 +2301,22 @@ void LLRender::diffuseColor4ubv(const U8* c)
}
}
+void LLRender::diffuseColor4ub(U8 r, U8 g, U8 b, U8 a)
+{
+ LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+ llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL);
+
+ if (shader)
+ {
+ shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, r/255.f, g/255.f, b/255.f, a/255.f);
+ }
+ else
+ {
+ glColor4ub(r,g,b,a);
+ }
+}
+
+
void LLRender::debugTexUnits(void)
{
LL_INFOS("TextureUnit") << "Active TexUnit: " << mCurrTextureUnitIndex << LL_ENDL;
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index 98222939e7..42b02a8159 100755
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -396,6 +396,7 @@ public:
void diffuseColor4f(F32 r, F32 g, F32 b, F32 a);
void diffuseColor4fv(const F32* c);
void diffuseColor4ubv(const U8* c);
+ void diffuseColor4ub(U8 r, U8 g, U8 b, U8 a);
void vertexBatchPreTransformed(LLVector3* verts, S32 vert_count);
void vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, S32 vert_count);
diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
index 5fb4fc8e52..353e61105a 100755
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -53,11 +53,19 @@ void check_framebuffer_status()
bool LLRenderTarget::sUseFBO = false;
U32 LLRenderTarget::sCurFBO = 0;
+
+extern S32 gGLViewport[4];
+
+U32 LLRenderTarget::sCurResX = 0;
+U32 LLRenderTarget::sCurResY = 0;
+
LLRenderTarget::LLRenderTarget() :
mResX(0),
mResY(0),
mFBO(0),
mPreviousFBO(0),
+ mPreviousResX(0),
+ mPreviousResY(0),
mDepth(0),
mStencil(0),
mUseDepth(false),
@@ -71,7 +79,7 @@ LLRenderTarget::~LLRenderTarget()
release();
}
-void LLRenderTarget::resize(U32 resx, U32 resy, U32 color_fmt)
+void LLRenderTarget::resize(U32 resx, U32 resy)
{
//for accounting, get the number of pixels added/subtracted
S32 pix_diff = (resx*resy)-(mResX*mResY);
@@ -79,10 +87,12 @@ void LLRenderTarget::resize(U32 resx, U32 resy, U32 color_fmt)
mResX = resx;
mResY = resy;
+ llassert(mInternalFormat.size() == mTex.size());
+
for (U32 i = 0; i < mTex.size(); ++i)
{ //resize color attachments
gGL.getTexUnit(0)->bindManual(mUsage, mTex[i]);
- LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL, false);
+ LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, mInternalFormat[i], mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL, false);
sBytesAllocated += pix_diff*4;
}
@@ -109,8 +119,8 @@ void LLRenderTarget::resize(U32 resx, U32 resy, U32 color_fmt)
bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, S32 samples)
{
- resx = llmin(resx, (U32) 4096);
- resy = llmin(resy, (U32) 4096);
+ resx = llmin(resx, (U32) gGLManager.mGLMaxTextureSize);
+ resy = llmin(resy, (U32) gGLManager.mGLMaxTextureSize);
stop_glerror();
release();
@@ -244,12 +254,15 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
mTex.push_back(tex);
mInternalFormat.push_back(color_fmt);
+#if !LL_DARWIN
if (gDebugGL)
{ //bind and unbind to validate target
bindTarget();
flush();
}
-
+#endif
+
+
return true;
}
@@ -390,13 +403,12 @@ void LLRenderTarget::bindTarget()
{
if (mFBO)
{
- mPreviousFBO = sCurFBO;
-
stop_glerror();
+ mPreviousFBO = sCurFBO;
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
sCurFBO = mFBO;
-
+
stop_glerror();
if (gGLManager.mHasDrawBuffers)
{ //setup multiple render targets
@@ -418,7 +430,12 @@ void LLRenderTarget::bindTarget()
stop_glerror();
}
+ mPreviousResX = sCurResX;
+ mPreviousResY = sCurResY;
glViewport(0, 0, mResX, mResY);
+ sCurResX = mResX;
+ sCurResY = mResY;
+
sBoundTarget = this;
}
@@ -458,6 +475,12 @@ U32 LLRenderTarget::getTexture(U32 attachment) const
return mTex[attachment];
}
+U32 LLRenderTarget::getNumTextures() const
+{
+ return mTex.size();
+}
+
+
void LLRenderTarget::bindTexture(U32 index, S32 channel)
{
gGL.getTexUnit(channel)->bindManual(mUsage, getTexture(index));
@@ -489,6 +512,20 @@ void LLRenderTarget::flush(bool fetch_depth)
stop_glerror();
glBindFramebuffer(GL_FRAMEBUFFER, mPreviousFBO);
sCurFBO = mPreviousFBO;
+
+ if (mPreviousFBO)
+ {
+ glViewport(0, 0, mPreviousResX, mPreviousResY);
+ sCurResX = mPreviousResX;
+ sCurResY = mPreviousResY;
+ }
+ else
+ {
+ glViewport(gGLViewport[0],gGLViewport[1],gGLViewport[2],gGLViewport[3]);
+ sCurResX = gGLViewport[2];
+ sCurResY = gGLViewport[3];
+ }
+
stop_glerror();
}
}
@@ -546,8 +583,10 @@ void LLRenderTarget::copyContentsToFramebuffer(LLRenderTarget& source, S32 srcX0
{
if (!source.mFBO)
{
- llerrs << "Cannot copy framebuffer contents for non FBO render targets." << llendl;
+ llwarns << "Cannot copy framebuffer contents for non FBO render targets." << llendl;
+ return;
}
+
{
GLboolean write_depth = mask & GL_DEPTH_BUFFER_BIT ? TRUE : FALSE;
diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h
index 765a727b5b..6dc84d978d 100755
--- a/indra/llrender/llrendertarget.h
+++ b/indra/llrender/llrendertarget.h
@@ -63,6 +63,9 @@ public:
static bool sUseFBO;
static U32 sBytesAllocated;
static U32 sCurFBO;
+ static U32 sCurResX;
+ static U32 sCurResY;
+
LLRenderTarget();
~LLRenderTarget();
@@ -76,7 +79,7 @@ public:
// CAUTION: if the GL runs out of memory attempting to resize, this render target will be undefined
// DO NOT use for screen space buffers or for scratch space for an image that might be uploaded
// DO use for render targets that resize often and aren't likely to ruin someone's day if they break
- void resize(U32 resx, U32 resy, U32 color_fmt);
+ void resize(U32 resx, U32 resy);
//add color buffer attachment
//limit of 4 color attachments per render target
@@ -112,6 +115,7 @@ public:
LLTexUnit::eTextureType getUsage(void) const { return mUsage; }
U32 getTexture(U32 attachment = 0) const;
+ U32 getNumTextures() const;
U32 getDepth(void) const { return mDepth; }
bool hasStencil() const { return mStencil; }
@@ -146,6 +150,9 @@ protected:
std::vector<U32> mInternalFormat;
U32 mFBO;
U32 mPreviousFBO;
+ U32 mPreviousResX;
+ U32 mPreviousResY;
+
U32 mDepth;
bool mStencil;
bool mUseDepth;
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index fea4ee2819..d230574752 100755
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -993,7 +993,9 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("texture_matrix1");
mReservedUniforms.push_back("texture_matrix2");
mReservedUniforms.push_back("texture_matrix3");
- llassert(mReservedUniforms.size() == LLShaderMgr::TEXTURE_MATRIX3+1);
+ mReservedUniforms.push_back("object_plane_s");
+ mReservedUniforms.push_back("object_plane_t");
+ llassert(mReservedUniforms.size() == LLShaderMgr::OBJECT_PLANE_T+1);
mReservedUniforms.push_back("viewport");
@@ -1135,13 +1137,54 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("lightMap");
mReservedUniforms.push_back("bloomMap");
mReservedUniforms.push_back("projectionMap");
-
+ mReservedUniforms.push_back("norm_mat");
+
mReservedUniforms.push_back("global_gamma");
mReservedUniforms.push_back("texture_gamma");
mReservedUniforms.push_back("specular_color");
mReservedUniforms.push_back("env_intensity");
+ mReservedUniforms.push_back("matrixPalette");
+
+ mReservedUniforms.push_back("screenTex");
+ mReservedUniforms.push_back("screenDepth");
+ mReservedUniforms.push_back("refTex");
+ mReservedUniforms.push_back("eyeVec");
+ mReservedUniforms.push_back("time");
+ mReservedUniforms.push_back("d1");
+ mReservedUniforms.push_back("d2");
+ mReservedUniforms.push_back("lightDir");
+ mReservedUniforms.push_back("specular");
+ mReservedUniforms.push_back("lightExp");
+ mReservedUniforms.push_back("waterFogColor");
+ mReservedUniforms.push_back("waterFogDensity");
+ mReservedUniforms.push_back("waterFogKS");
+ mReservedUniforms.push_back("refScale");
+ mReservedUniforms.push_back("waterHeight");
+ mReservedUniforms.push_back("waterPlane");
+ mReservedUniforms.push_back("normScale");
+ mReservedUniforms.push_back("fresnelScale");
+ mReservedUniforms.push_back("fresnelOffset");
+ mReservedUniforms.push_back("blurMultiplier");
+ mReservedUniforms.push_back("sunAngle");
+ mReservedUniforms.push_back("scaledAngle");
+ mReservedUniforms.push_back("sunAngle2");
+
+ mReservedUniforms.push_back("camPosLocal");
+
+ mReservedUniforms.push_back("gWindDir");
+ mReservedUniforms.push_back("gSinWaveParams");
+ mReservedUniforms.push_back("gGravity");
+
+ mReservedUniforms.push_back("detail_0");
+ mReservedUniforms.push_back("detail_1");
+ mReservedUniforms.push_back("detail_2");
+ mReservedUniforms.push_back("detail_3");
+ mReservedUniforms.push_back("alpha_ramp");
+
+ mReservedUniforms.push_back("origin");
+ mReservedUniforms.push_back("display_gamma");
llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS);
std::set<std::string> dupe_check;
diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h
index c049e935b8..51c27fc8b6 100755
--- a/indra/llrender/llshadermgr.h
+++ b/indra/llrender/llshadermgr.h
@@ -47,6 +47,8 @@ public:
TEXTURE_MATRIX1,
TEXTURE_MATRIX2,
TEXTURE_MATRIX3,
+ OBJECT_PLANE_S,
+ OBJECT_PLANE_T,
VIEWPORT,
LIGHT_POSITION,
LIGHT_DIRECTION,
@@ -165,13 +167,54 @@ public:
DEFERRED_LIGHT,
DEFERRED_BLOOM,
DEFERRED_PROJECTION,
-
+ DEFERRED_NORM_MATRIX,
+
GLOBAL_GAMMA,
TEXTURE_GAMMA,
SPECULAR_COLOR,
ENVIRONMENT_INTENSITY,
+ AVATAR_MATRIX,
+
+ WATER_SCREENTEX,
+ WATER_SCREENDEPTH,
+ WATER_REFTEX,
+ WATER_EYEVEC,
+ WATER_TIME,
+ WATER_WAVE_DIR1,
+ WATER_WAVE_DIR2,
+ WATER_LIGHT_DIR,
+ WATER_SPECULAR,
+ WATER_SPECULAR_EXP,
+ WATER_FOGCOLOR,
+ WATER_FOGDENSITY,
+ WATER_FOGKS,
+ WATER_REFSCALE,
+ WATER_WATERHEIGHT,
+ WATER_WATERPLANE,
+ WATER_NORM_SCALE,
+ WATER_FRESNEL_SCALE,
+ WATER_FRESNEL_OFFSET,
+ WATER_BLUR_MULTIPLIER,
+ WATER_SUN_ANGLE,
+ WATER_SCALED_ANGLE,
+ WATER_SUN_ANGLE2,
+
+ WL_CAMPOSLOCAL,
+
+ AVATAR_WIND,
+ AVATAR_SINWAVE,
+ AVATAR_GRAVITY,
+
+ TERRAIN_DETAIL0,
+ TERRAIN_DETAIL1,
+ TERRAIN_DETAIL2,
+ TERRAIN_DETAIL3,
+ TERRAIN_ALPHARAMP,
+
+ SHINY_ORIGIN,
+DISPLAY_GAMMA,
END_RESERVED_UNIFORMS
} eGLSLReservedUniforms;
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 01541026b1..f168b3af14 100755
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -85,6 +85,7 @@ const U32 LL_VBO_POOL_SEED_COUNT = vbo_block_index(LL_VBO_POOL_MAX_SEED_SIZE);
//static
LLVBOPool LLVertexBuffer::sStreamVBOPool(GL_STREAM_DRAW_ARB, GL_ARRAY_BUFFER_ARB);
LLVBOPool LLVertexBuffer::sDynamicVBOPool(GL_DYNAMIC_DRAW_ARB, GL_ARRAY_BUFFER_ARB);
+LLVBOPool LLVertexBuffer::sDynamicCopyVBOPool(GL_DYNAMIC_COPY_ARB, GL_ARRAY_BUFFER_ARB);
LLVBOPool LLVertexBuffer::sStreamIBOPool(GL_STREAM_DRAW_ARB, GL_ELEMENT_ARRAY_BUFFER_ARB);
LLVBOPool LLVertexBuffer::sDynamicIBOPool(GL_DYNAMIC_DRAW_ARB, GL_ELEMENT_ARRAY_BUFFER_ARB);
@@ -199,7 +200,10 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
if (LLVertexBuffer::sDisableVBOMapping || mUsage != GL_DYNAMIC_DRAW_ARB)
{
glBufferDataARB(mType, size, 0, mUsage);
- ret = (U8*) ll_aligned_malloc_16(size);
+ if (mUsage != GL_DYNAMIC_COPY_ARB)
+ { //data will be provided by application
+ ret = (U8*) ll_aligned_malloc(size, 64);
+ }
}
else
{ //always use a true hint of static draw when allocating non-client-backed buffers
@@ -252,7 +256,7 @@ void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size)
llassert(vbo_block_size(size) == size);
deleteBuffer(name);
- ll_aligned_free_16((U8*) buffer);
+ ll_aligned_free((U8*) buffer);
if (mType == GL_ARRAY_BUFFER_ARB)
{
@@ -306,7 +310,7 @@ void LLVBOPool::cleanup()
if (r.mClientData)
{
- ll_aligned_free_16((void*) r.mClientData);
+ ll_aligned_free((void*) r.mClientData);
}
l.pop_front();
@@ -412,6 +416,7 @@ void LLVertexBuffer::seedPools()
{
sStreamVBOPool.seedPool();
sDynamicVBOPool.seedPool();
+ sDynamicCopyVBOPool.seedPool();
sStreamIBOPool.seedPool();
sDynamicIBOPool.seedPool();
}
@@ -910,6 +915,7 @@ void LLVertexBuffer::cleanupClass()
sDynamicIBOPool.cleanup();
sStreamVBOPool.cleanup();
sDynamicVBOPool.cleanup();
+ sDynamicCopyVBOPool.cleanup();
if(sPrivatePoolp)
{
@@ -946,6 +952,8 @@ S32 LLVertexBuffer::determineUsage(S32 usage)
if (ret_usage && ret_usage != GL_STREAM_DRAW_ARB)
{ //only stream_draw and dynamic_draw are supported when using VBOs, dynamic draw is the default
+ if (ret_usage != GL_DYNAMIC_COPY_ARB)
+ {
if (sDisableVBOMapping)
{ //always use stream draw if VBO mapping is disabled
ret_usage = GL_STREAM_DRAW_ARB;
@@ -955,6 +963,7 @@ S32 LLVertexBuffer::determineUsage(S32 usage)
ret_usage = GL_DYNAMIC_DRAW_ARB;
}
}
+ }
return ret_usage;
}
@@ -1102,10 +1111,15 @@ void LLVertexBuffer::genBuffer(U32 size)
{
mMappedData = sStreamVBOPool.allocate(mGLBuffer, mSize);
}
- else
+ else if (mUsage == GL_DYNAMIC_DRAW_ARB)
{
mMappedData = sDynamicVBOPool.allocate(mGLBuffer, mSize);
}
+ else
+ {
+ mMappedData = sDynamicCopyVBOPool.allocate(mGLBuffer, mSize);
+ }
+
sGLCount++;
}
@@ -2144,21 +2158,14 @@ bool LLVertexBuffer::bindGLBuffer(bool force_bind)
if (useVBOs() && (force_bind || (mGLBuffer && (mGLBuffer != sGLRenderBuffer || !sVBOActive))))
{
- LLFastTimer t(FTM_BIND_GL_BUFFER);
- /*if (sMapped)
- {
- llerrs << "VBO bound while another VBO mapped!" << llendl;
- }*/
+ //LLFastTimer t(FTM_BIND_GL_BUFFER); <-- this timer is showing up as a hotspot (irony)
+
glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer);
sGLRenderBuffer = mGLBuffer;
sBindCount++;
sVBOActive = true;
- if (mGLArray)
- {
- llassert(sGLRenderArray == mGLArray);
- //mCachedRenderBuffer = mGLBuffer;
- }
+ llassert(!mGLArray || sGLRenderArray == mGLArray);
ret = true;
}
@@ -2239,7 +2246,38 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
if ((data_mask & required_mask) != required_mask)
{
- llwarns << "Shader consumption mismatches data provision." << llendl;
+
+ U32 unsatisfied_mask = (required_mask & ~data_mask);
+ U32 i = 0;
+
+ while (i < TYPE_MAX)
+ {
+ U32 unsatisfied_flag = unsatisfied_mask & (1 << i);
+ switch (unsatisfied_flag)
+ {
+ case MAP_VERTEX: llinfos << "Missing vert pos" << llendl; break;
+ case MAP_NORMAL: llinfos << "Missing normals" << llendl; break;
+ case MAP_TEXCOORD0: llinfos << "Missing TC 0" << llendl; break;
+ case MAP_TEXCOORD1: llinfos << "Missing TC 1" << llendl; break;
+ case MAP_TEXCOORD2: llinfos << "Missing TC 2" << llendl; break;
+ case MAP_TEXCOORD3: llinfos << "Missing TC 3" << llendl; break;
+ case MAP_COLOR: llinfos << "Missing vert color" << llendl; break;
+ case MAP_EMISSIVE: llinfos << "Missing emissive" << llendl; break;
+ case MAP_TANGENT: llinfos << "Missing tangent" << llendl; break;
+ case MAP_WEIGHT: llinfos << "Missing weight" << llendl; break;
+ case MAP_WEIGHT4: llinfos << "Missing weightx4" << llendl; break;
+ case MAP_CLOTHWEIGHT: llinfos << "Missing clothweight" << llendl; break;
+ case MAP_TEXTURE_INDEX: llinfos << "Missing tex index" << llendl; break;
+ default: llinfos << "Missing who effin knows: " << unsatisfied_flag << llendl;
+ }
+ }
+
+ if (unsatisfied_mask & (1 << TYPE_INDEX))
+ {
+ llinfos << "Missing indices" << llendl;
+ }
+
+ llerrs << "Shader consumption mismatches data provision." << llendl;
}
}
}
@@ -2409,7 +2447,8 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
if (data_mask & MAP_COLOR)
{
S32 loc = TYPE_COLOR;
- void* ptr = (void*)(base + mOffsets[TYPE_COLOR]);
+ //bind emissive instead of color pointer if emissive is present
+ void* ptr = (data_mask & MAP_EMISSIVE) ? (void*)(base + mOffsets[TYPE_EMISSIVE]) : (void*)(base + mOffsets[TYPE_COLOR]);
glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], ptr);
}
if (data_mask & MAP_EMISSIVE)
@@ -2417,6 +2456,12 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
S32 loc = TYPE_EMISSIVE;
void* ptr = (void*)(base + mOffsets[TYPE_EMISSIVE]);
glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr);
+
+ if (!(data_mask & MAP_COLOR))
+ { //map emissive to color channel when color is not also being bound to avoid unnecessary shader swaps
+ loc = TYPE_COLOR;
+ glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr);
+ }
}
if (data_mask & MAP_WEIGHT)
{
@@ -2502,8 +2547,7 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
LLVertexBuffer::MappedRegion::MappedRegion(S32 type, S32 index, S32 count)
: mType(type), mIndex(index), mCount(count)
{
- llassert(mType == LLVertexBuffer::TYPE_INDEX ||
- mType < LLVertexBuffer::TYPE_TEXTURE_INDEX);
+ mEnd = mIndex+mCount;
}
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index 04806c1d8c..de58207c23 100755
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -107,6 +107,7 @@ public:
S32 mType;
S32 mIndex;
S32 mCount;
+ S32 mEnd;
MappedRegion(S32 type, S32 index, S32 count);
};
@@ -125,9 +126,10 @@ public:
static LLVBOPool sStreamVBOPool;
static LLVBOPool sDynamicVBOPool;
+ static LLVBOPool sDynamicCopyVBOPool;
static LLVBOPool sStreamIBOPool;
static LLVBOPool sDynamicIBOPool;
-
+
static std::list<U32> sAvailableVAOName;
static U32 sCurVAOName;