summaryrefslogtreecommitdiff
path: root/indra/llrender
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llrender')
-rwxr-xr-xindra/llrender/llcubemap.cpp2
-rwxr-xr-xindra/llrender/llgl.cpp18
-rwxr-xr-xindra/llrender/llglheaders.h2
-rwxr-xr-xindra/llrender/llglslshader.cpp97
-rwxr-xr-xindra/llrender/llglslshader.h40
-rwxr-xr-xindra/llrender/llimagegl.cpp121
-rwxr-xr-xindra/llrender/llimagegl.h11
-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.cpp70
-rwxr-xr-xindra/llrender/llrendertarget.h3
-rwxr-xr-xindra/llrender/llshadermgr.cpp77
-rwxr-xr-xindra/llrender/llshadermgr.h48
-rwxr-xr-xindra/llrender/llvertexbuffer.cpp102
-rwxr-xr-xindra/llrender/llvertexbuffer.h8
17 files changed, 428 insertions, 317 deletions
diff --git a/indra/llrender/llcubemap.cpp b/indra/llrender/llcubemap.cpp
index 362452d837..45a3b18179 100755
--- a/indra/llrender/llcubemap.cpp
+++ b/indra/llrender/llcubemap.cpp
@@ -81,7 +81,7 @@ void LLCubeMap::initGL()
{
U32 texname = 0;
- LLImageGL::generateTextures(LLTexUnit::TT_CUBE_MAP, GL_RGB8, 1, &texname);
+ LLImageGL::generateTextures(1, &texname);
for (int i = 0; i < 6; i++)
{
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index c3005f1722..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;
}
@@ -1246,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)
{
@@ -1500,7 +1507,7 @@ void do_assert_glerror()
void assert_glerror()
{
- if (!gGLActive)
+/* if (!gGLActive)
{
//llwarns << "GL used while not active!" << llendl;
@@ -1509,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/llglheaders.h b/indra/llrender/llglheaders.h
index 1bec6d376b..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;
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index ac16e30796..1c50a51d02 100755
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -355,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)
{
@@ -375,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++ )
@@ -438,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
@@ -495,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++)
@@ -532,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)
{
@@ -548,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)
{
@@ -618,8 +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
@@ -640,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;
@@ -674,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;
@@ -709,7 +717,14 @@ BOOL LLGLSLShader::mapUniforms(const vector<string> * uniforms)
BOOL LLGLSLShader::link(BOOL suppress_errors)
{
- return LLShaderMgr::instance()->linkProgramObject(mProgramObject, suppress_errors);
+ BOOL success = LLShaderMgr::instance()->linkProgramObject(mProgramObject, suppress_errors);
+
+ if (!suppress_errors)
+ {
+ LLShaderMgr::instance()->dumpObjectLog(mProgramObject, !success, mName);
+ }
+
+ return success;
}
void LLGLSLShader::bind()
@@ -1136,18 +1151,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;
}
@@ -1184,7 +1199,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);
@@ -1200,7 +1215,7 @@ void LLGLSLShader::uniform1i(const string& uniform, GLint v)
}
}
-void LLGLSLShader::uniform2i(const string& uniform, GLint i, GLint j)
+void LLGLSLShader::uniform2i(const LLStaticHashedString& uniform, GLint i, GLint j)
{
GLint location = getUniformLocation(uniform);
@@ -1217,7 +1232,7 @@ void LLGLSLShader::uniform2i(const string& uniform, GLint i, GLint j)
}
-void LLGLSLShader::uniform1f(const string& uniform, GLfloat v)
+void LLGLSLShader::uniform1f(const LLStaticHashedString& uniform, GLfloat v)
{
GLint location = getUniformLocation(uniform);
@@ -1233,7 +1248,7 @@ void LLGLSLShader::uniform1f(const string& uniform, GLfloat v)
}
}
-void LLGLSLShader::uniform2f(const string& uniform, GLfloat x, GLfloat y)
+void LLGLSLShader::uniform2f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y)
{
GLint location = getUniformLocation(uniform);
@@ -1250,7 +1265,7 @@ void LLGLSLShader::uniform2f(const string& uniform, GLfloat x, GLfloat y)
}
-void LLGLSLShader::uniform3f(const string& uniform, GLfloat x, GLfloat y, GLfloat z)
+void LLGLSLShader::uniform3f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y, GLfloat z)
{
GLint location = getUniformLocation(uniform);
@@ -1266,23 +1281,7 @@ void LLGLSLShader::uniform3f(const string& uniform, GLfloat x, GLfloat y, GLfloa
}
}
-void LLGLSLShader::uniform4f(const string& uniform, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
-{
- GLint location = getUniformLocation(uniform);
-
- if (location >= 0)
- {
- std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
- LLVector4 vec(x,y,z,w);
- if (iter == mValue.end() || shouldChange(iter->second,vec))
- {
- glUniform4fARB(location, x,y,z,w);
- 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);
@@ -1298,7 +1297,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);
@@ -1314,7 +1313,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);
@@ -1330,7 +1329,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);
@@ -1348,27 +1347,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 eabdb9fc92..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,30 +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 uniform2i(const std::string& uniform, GLint i, GLint j);
- 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);
@@ -170,7 +168,7 @@ 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;
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 38764eba23..ab875141c5 100755
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -54,8 +54,6 @@ S32 LLImageGL::sGlobalTextureMemoryInBytes = 0;
S32 LLImageGL::sBoundTextureMemoryInBytes = 0;
S32 LLImageGL::sCurBoundTextureMemory = 0;
S32 LLImageGL::sCount = 0;
-LLImageGL::dead_texturelist_t LLImageGL::sDeadTextureList[LLTexUnit::TT_NONE];
-U32 LLImageGL::sCurTexName = 1;
BOOL LLImageGL::sGlobalUseAnisotropic = FALSE;
F32 LLImageGL::sLastFrameTime = 0.f;
@@ -715,9 +713,14 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
mMipLevels = wpo2(llmax(w, h));
- //use legacy mipmap generation mode
- glTexParameteri(mTarget, GL_GENERATE_MIPMAP, GL_TRUE);
-
+ //use legacy mipmap generation mode (note: making this condional can cause rendering issues)
+ // -- but making it not conditional triggers deprecation warnings when core profile is enabled
+ // (some rendering issues while core profile is enabled are acceptable at this point in time)
+ if (!LLRender::sGLCoreProfile)
+ {
+ glTexParameteri(mTarget, GL_GENERATE_MIPMAP, GL_TRUE);
+ }
+
LLImageGL::setManualImage(mTarget, 0, mFormatInternal,
w, h,
mFormatPrimary, mFormatType,
@@ -1084,85 +1087,19 @@ BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_
// static
static LLFastTimer::DeclareTimer FTM_GENERATE_TEXTURES("generate textures");
-void LLImageGL::generateTextures(LLTexUnit::eTextureType type, U32 format, S32 numTextures, U32 *textures)
+void LLImageGL::generateTextures(S32 numTextures, U32 *textures)
{
LLFastTimer t(FTM_GENERATE_TEXTURES);
- bool empty = true;
-
- dead_texturelist_t::iterator iter = sDeadTextureList[type].find(format);
-
- if (iter != sDeadTextureList[type].end())
- {
- empty = iter->second.empty();
- }
-
- for (S32 i = 0; i < numTextures; ++i)
- {
- if (!empty)
- {
- textures[i] = iter->second.front();
- iter->second.pop_front();
- empty = iter->second.empty();
- }
- else
- {
- textures[i] = sCurTexName++;
- }
- }
+ glGenTextures(numTextures, textures);
}
// static
-void LLImageGL::deleteTextures(LLTexUnit::eTextureType type, U32 format, S32 mip_levels, S32 numTextures, U32 *textures, bool immediate)
+void LLImageGL::deleteTextures(S32 numTextures, U32 *textures)
{
if (gGLManager.mInited)
{
- switch (format)
- {
- case 0:
-
- // We get ARB errors in debug when attempting to use glTexImage2D with these deprecated pix formats
- //
- case GL_LUMINANCE8:
- case GL_INTENSITY8:
- case GL_ALPHA8:
- glDeleteTextures(numTextures, textures);
- break;
-
- default:
- {
- if (type == LLTexUnit::TT_CUBE_MAP || mip_levels == -1)
- { //unknown internal format or unknown number of mip levels, not safe to reuse
- glDeleteTextures(numTextures, textures);
- }
- else
- {
- for (S32 i = 0; i < numTextures; ++i)
- { //remove texture from VRAM by setting its size to zero
-
- for (S32 j = 0; j <= mip_levels; j++)
- {
- gGL.getTexUnit(0)->bindManual(type, textures[i]);
- U32 internal_type = LLTexUnit::getInternalType(type);
- glTexImage2D(internal_type, j, format, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- stop_glerror();
- }
-
- llassert(std::find(sDeadTextureList[type][format].begin(),
- sDeadTextureList[type][format].end(), textures[i]) ==
- sDeadTextureList[type][format].end());
-
- sDeadTextureList[type][format].push_back(textures[i]);
- }
- }
+ glDeleteTextures(numTextures, textures);
}
- break;
- }
- }
-
- /*if (immediate)
- {
- LLImageGL::deleteDeadTextures();
- }*/
}
// static
@@ -1290,11 +1227,11 @@ BOOL LLImageGL::createGLTexture()
if(mTexName)
{
- LLImageGL::deleteTextures(mBindTarget, mFormatInternal, mMipLevels, 1, (reinterpret_cast<GLuint*>(&mTexName))) ;
+ LLImageGL::deleteTextures(1, (reinterpret_cast<GLuint*>(&mTexName))) ;
}
- LLImageGL::generateTextures(mBindTarget, mFormatInternal, 1, &mTexName);
+ LLImageGL::generateTextures(1, &mTexName);
stop_glerror();
if (!mTexName)
{
@@ -1409,7 +1346,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
}
else
{
- LLImageGL::generateTextures(mBindTarget, mFormatInternal, 1, &mTexName);
+ LLImageGL::generateTextures(1, &mTexName);
stop_glerror();
{
llverify(gGL.getTexUnit(0)->bind(this));
@@ -1454,7 +1391,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
{
sGlobalTextureMemoryInBytes -= mTextureMemory;
- LLImageGL::deleteTextures(mBindTarget, mFormatInternal, mMipLevels, 1, &old_name);
+ LLImageGL::deleteTextures(1, &old_name);
stop_glerror();
}
@@ -1583,30 +1520,6 @@ void LLImageGL::deleteDeadTextures()
{
bool reset = false;
- /*while (!sDeadTextureList.empty())
- {
- GLuint tex = sDeadTextureList.front();
- sDeadTextureList.pop_front();
- for (int i = 0; i < gGLManager.mNumTextureImageUnits; i++)
- {
- LLTexUnit* tex_unit = gGL.getTexUnit(i);
-
- if (tex_unit && tex_unit->getCurrTexture() == tex)
- {
- tex_unit->unbind(tex_unit->getCurrType());
- stop_glerror();
-
- if (i > 0)
- {
- reset = true;
- }
- }
- }
-
- glDeleteTextures(1, &tex);
- stop_glerror();
- }*/
-
if (reset)
{
gGL.getTexUnit(0)->activate();
@@ -1623,7 +1536,7 @@ void LLImageGL::destroyGLTexture()
mTextureMemory = 0;
}
- LLImageGL::deleteTextures(mBindTarget, mFormatInternal, mMipLevels, 1, &mTexName);
+ LLImageGL::deleteTextures(1, &mTexName);
mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel.
mTexName = 0;
mGLTextureCreated = FALSE ;
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index 57a052b258..0c62dd0d33 100755
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -45,16 +45,9 @@ class LLImageGL : public LLRefCount
{
friend class LLTexUnit;
public:
- static U32 sCurTexName;
-
- //previously used but now available texture names
- // sDeadTextureList[<usage>][<internal format>]
- typedef std::map<U32, std::list<U32> > dead_texturelist_t;
- static dead_texturelist_t sDeadTextureList[LLTexUnit::TT_NONE];
-
// These 2 functions replace glGenTextures() and glDeleteTextures()
- static void generateTextures(LLTexUnit::eTextureType type, U32 format, S32 numTextures, U32 *textures);
- static void deleteTextures(LLTexUnit::eTextureType type, U32 format, S32 mip_levels, S32 numTextures, U32 *textures, bool immediate = false);
+ static void generateTextures(S32 numTextures, U32 *textures);
+ static void deleteTextures(S32 numTextures, U32 *textures);
static void deleteDeadTextures();
// Size calculation
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 5ea8387c04..fe8110904d 100755
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -79,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);
@@ -87,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;
}
@@ -192,7 +194,7 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
}
U32 tex;
- LLImageGL::generateTextures(mUsage, color_fmt, 1, &tex);
+ LLImageGL::generateTextures(1, &tex);
gGL.getTexUnit(0)->bindManual(mUsage, tex);
stop_glerror();
@@ -278,7 +280,7 @@ bool LLRenderTarget::allocateDepth()
}
else
{
- LLImageGL::generateTextures(mUsage, GL_DEPTH_COMPONENT24, 1, &mDepth);
+ LLImageGL::generateTextures(1, &mDepth);
gGL.getTexUnit(0)->bindManual(mUsage, mDepth);
U32 internal_type = LLTexUnit::getInternalType(mUsage);
@@ -355,42 +357,62 @@ void LLRenderTarget::release()
}
else
{
- LLImageGL::deleteTextures(mUsage, 0, 0, 1, &mDepth, true);
+ LLImageGL::deleteTextures(1, &mDepth);
stop_glerror();
}
mDepth = 0;
sBytesAllocated -= mResX*mResY*4;
}
- else if (mUseDepth && mFBO)
- { //detach shared depth buffer
+ else if (mFBO)
+ {
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
- if (mStencil)
- { //attached as a renderbuffer
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
- mStencil = false;
+
+ if (mUseDepth)
+ { //detach shared depth buffer
+ if (mStencil)
+ { //attached as a renderbuffer
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
+ mStencil = false;
+ }
+ else
+ { //attached as a texture
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), 0, 0);
+ }
+ mUseDepth = false;
}
- else
- { //attached as a texture
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), 0, 0);
+ }
+
+ // Detach any extra color buffers (e.g. SRGB spec buffers)
+ //
+ if (mFBO && (mTex.size() > 1))
+ {
+ S32 z;
+ for (z = mTex.size() - 1; z >= 1; z--)
+ {
+ sBytesAllocated -= mResX*mResY*4;
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+z, LLTexUnit::getInternalType(mUsage), 0, 0);
+ stop_glerror();
+ LLImageGL::deleteTextures(1, &mTex[z]);
}
- mUseDepth = false;
}
if (mFBO)
{
glDeleteFramebuffers(1, (GLuint *) &mFBO);
+ stop_glerror();
mFBO = 0;
}
if (mTex.size() > 0)
{
- sBytesAllocated -= mResX*mResY*4*mTex.size();
- LLImageGL::deleteTextures(mUsage, mInternalFormat[0], 0, mTex.size(), &mTex[0], true);
+ sBytesAllocated -= mResX*mResY*4;
+ LLImageGL::deleteTextures(1, &mTex[0]);
+ }
+
mTex.clear();
mInternalFormat.clear();
- }
mResX = mResY = 0;
@@ -473,6 +495,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));
@@ -575,8 +603,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 66a9874a6b..6dc84d978d 100755
--- a/indra/llrender/llrendertarget.h
+++ b/indra/llrender/llrendertarget.h
@@ -79,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
@@ -115,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; }
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index fea4ee2819..6e04fc82df 100755
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -505,9 +505,25 @@ static std::string get_object_log(GLhandleARB ret)
return res;
}
-void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns)
+void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns, const std::string& filename)
{
std::string log = get_object_log(ret);
+
+ if (log.length() > 0 || warns)
+ {
+ if (!filename.empty())
+ {
+ if (warns)
+ {
+ LL_WARNS("ShaderLoading") << "From " << filename << ":" << LL_ENDL;
+ }
+ else
+ {
+ LL_INFOS("ShaderLoading") << "From " << filename << ":" << LL_ENDL;
+ }
+ }
+ }
+
if ( log.length() > 0 )
{
if (warns)
@@ -558,7 +574,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
file = LLFile::fopen(fname.str(), "r"); /* Flawfinder: ignore */
if (file)
{
- LL_INFOS("ShaderLoading") << "Loading file: shaders/class" << gpu_class << "/" << filename << " (Want class " << gpu_class << ")" << LL_ENDL;
+ LL_DEBUGS("ShaderLoading") << "Loading file: shaders/class" << gpu_class << "/" << filename << " (Want class " << gpu_class << ")" << LL_ENDL;
break; // done
}
}
@@ -812,8 +828,8 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
if (error != GL_NO_ERROR || success == GL_FALSE)
{
//an error occured, print log
- LL_WARNS("ShaderLoading") << "GLSL Compilation Error: (" << error << ") in " << filename << LL_ENDL;
- dumpObjectLog(ret);
+ LL_WARNS("ShaderLoading") << "GLSL Compilation Error:" << LL_ENDL;
+ dumpObjectLog(ret, TRUE, filename);
#if LL_WINDOWS
std::stringstream ostr;
//dump shader source for debugging
@@ -938,11 +954,6 @@ BOOL LLShaderMgr::linkProgramObject(GLhandleARB obj, BOOL suppress_errors)
suppress_errors = FALSE;
}
#endif
- if (!suppress_errors)
- {
- dumpObjectLog(obj, !success);
- }
-
return success;
}
@@ -993,7 +1004,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 +1148,55 @@ 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("translationPalette");
+
+ 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..394b38f832 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,55 @@ public:
DEFERRED_LIGHT,
DEFERRED_BLOOM,
DEFERRED_PROJECTION,
-
+ DEFERRED_NORM_MATRIX,
+
GLOBAL_GAMMA,
TEXTURE_GAMMA,
SPECULAR_COLOR,
ENVIRONMENT_INTENSITY,
+ AVATAR_MATRIX,
+ AVATAR_TRANSLATION,
+
+ 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;
@@ -181,7 +225,7 @@ public:
virtual void initAttribsAndUniforms(void);
BOOL attachShaderFeatures(LLGLSLShader * shader);
- void dumpObjectLog(GLhandleARB ret, BOOL warns = TRUE);
+ void dumpObjectLog(GLhandleARB ret, BOOL warns = TRUE, const std::string& filename = "");
BOOL linkProgramObject(GLhandleARB obj, BOOL suppress_errors = FALSE);
BOOL validateProgramObject(GLhandleARB obj);
GLhandleARB loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, boost::unordered_map<std::string, std::string>* defines = NULL, S32 texture_index_channels = -1);
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 01541026b1..e6f20cd40e 100755
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -85,12 +85,12 @@ 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);
U32 LLVBOPool::sBytesPooled = 0;
U32 LLVBOPool::sIndexBytesPooled = 0;
-U32 LLVBOPool::sCurGLName = 1;
std::list<U32> LLVertexBuffer::sAvailableVAOName;
U32 LLVertexBuffer::sCurVAOName = 1;
@@ -124,16 +124,8 @@ U32 LLVBOPool::genBuffer()
{
U32 ret = 0;
- if (mGLNamePool.empty())
- {
- ret = sCurGLName++;
- }
- else
- {
- ret = mGLNamePool.front();
- mGLNamePool.pop_front();
- }
-
+ glGenBuffersARB(1, &ret);
+
return ret;
}
@@ -145,12 +137,9 @@ void LLVBOPool::deleteBuffer(U32 name)
glBindBufferARB(mType, name);
glBufferDataARB(mType, 0, NULL, mUsage);
-
- llassert(std::find(mGLNamePool.begin(), mGLNamePool.end(), name) == mGLNamePool.end());
-
- mGLNamePool.push_back(name);
-
glBindBufferARB(mType, 0);
+
+ glDeleteBuffersARB(1, &name);
}
}
@@ -199,7 +188,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 +244,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 +298,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 +404,7 @@ void LLVertexBuffer::seedPools()
{
sStreamVBOPool.seedPool();
sDynamicVBOPool.seedPool();
+ sDynamicCopyVBOPool.seedPool();
sStreamIBOPool.seedPool();
sDynamicIBOPool.seedPool();
}
@@ -910,6 +903,7 @@ void LLVertexBuffer::cleanupClass()
sDynamicIBOPool.cleanup();
sStreamVBOPool.cleanup();
sDynamicVBOPool.cleanup();
+ sDynamicCopyVBOPool.cleanup();
if(sPrivatePoolp)
{
@@ -946,6 +940,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 +951,7 @@ S32 LLVertexBuffer::determineUsage(S32 usage)
ret_usage = GL_DYNAMIC_DRAW_ARB;
}
}
+ }
return ret_usage;
}
@@ -1102,10 +1099,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++;
}
@@ -1319,7 +1321,7 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
//actually allocate space for the vertex buffer if using VBO mapping
flush();
- if (gGLManager.mHasVertexArrayObject && useVBOs() && (LLRender::sGLCoreProfile || sUseVAO))
+ if (gGLManager.mHasVertexArrayObject && useVBOs() && sUseVAO)
{
#if GL_ARB_vertex_array_object
mGLArray = getVAOName();
@@ -2144,21 +2146,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 +2234,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 +2435,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 +2444,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 +2535,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..619a0cec46 100755
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -57,8 +57,6 @@ public:
static U32 sBytesPooled;
static U32 sIndexBytesPooled;
- static U32 sCurGLName;
-
LLVBOPool(U32 vboUsage, U32 vboType);
const U32 mUsage;
@@ -86,8 +84,6 @@ public:
volatile U8* mClientData;
};
- std::list<U32> mGLNamePool;
-
typedef std::list<Record> record_list_t;
std::vector<record_list_t> mFreeList;
std::vector<U32> mMissCount;
@@ -107,6 +103,7 @@ public:
S32 mType;
S32 mIndex;
S32 mCount;
+ S32 mEnd;
MappedRegion(S32 type, S32 index, S32 count);
};
@@ -125,9 +122,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;