diff options
Diffstat (limited to 'indra/llrender')
-rwxr-xr-x | indra/llrender/llcubemap.cpp | 2 | ||||
-rwxr-xr-x | indra/llrender/llgl.cpp | 18 | ||||
-rwxr-xr-x | indra/llrender/llglheaders.h | 2 | ||||
-rwxr-xr-x | indra/llrender/llglslshader.cpp | 97 | ||||
-rwxr-xr-x | indra/llrender/llglslshader.h | 40 | ||||
-rwxr-xr-x | indra/llrender/llimagegl.cpp | 121 | ||||
-rwxr-xr-x | indra/llrender/llimagegl.h | 11 | ||||
-rwxr-xr-x | indra/llrender/llpostprocess.cpp | 59 | ||||
-rwxr-xr-x | indra/llrender/llpostprocess.h | 3 | ||||
-rwxr-xr-x | indra/llrender/llrender.cpp | 83 | ||||
-rwxr-xr-x | indra/llrender/llrender.h | 1 | ||||
-rwxr-xr-x | indra/llrender/llrendertarget.cpp | 70 | ||||
-rwxr-xr-x | indra/llrender/llrendertarget.h | 3 | ||||
-rwxr-xr-x | indra/llrender/llshadermgr.cpp | 77 | ||||
-rwxr-xr-x | indra/llrender/llshadermgr.h | 48 | ||||
-rwxr-xr-x | indra/llrender/llvertexbuffer.cpp | 102 | ||||
-rwxr-xr-x | indra/llrender/llvertexbuffer.h | 8 |
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; |