summaryrefslogtreecommitdiff
path: root/indra/llrender
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2012-04-26 14:04:55 -0400
committerNat Goodspeed <nat@lindenlab.com>2012-04-26 14:04:55 -0400
commit78f2663c4a61a7983c84cf50e5d2fdd92811a1b0 (patch)
tree56bf81cc39cb8c5180508c37c552c8ab23273300 /indra/llrender
parentd6569db3520f7e0ce2d93febb6f4e26b48c08a3d (diff)
parent75c53a6a269890b9fe78b4b50d9b093a94778650 (diff)
Automated merge with http://hg.secondlife.com/viewer-release
Diffstat (limited to 'indra/llrender')
-rw-r--r--indra/llrender/llgl.cpp97
-rw-r--r--indra/llrender/llgl.h2
-rw-r--r--indra/llrender/llglheaders.h3
-rw-r--r--indra/llrender/llglslshader.cpp12
-rw-r--r--indra/llrender/llimagegl.cpp43
-rw-r--r--indra/llrender/llimagegl.h7
-rw-r--r--indra/llrender/llrendertarget.cpp4
-rw-r--r--indra/llrender/llshadermgr.cpp120
-rw-r--r--indra/llrender/llshadermgr.h2
-rw-r--r--indra/llrender/llvertexbuffer.cpp207
-rw-r--r--indra/llrender/llvertexbuffer.h4
11 files changed, 394 insertions, 107 deletions
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 946e602fee..628a8d6131 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -94,9 +94,15 @@ void APIENTRY gl_debug_callback(GLenum source,
llwarns << "Severity: " << std::hex << severity << llendl;
llwarns << "Message: " << message << llendl;
llwarns << "-----------------------" << llendl;
+ if (severity == GL_DEBUG_SEVERITY_HIGH_ARB)
+ {
+ llerrs << "Halting on GL Error" << llendl;
+ }
}
#endif
+void parse_glsl_version(S32& major, S32& minor);
+
void ll_init_fail_log(std::string filename)
{
gFailLog.open(filename.c_str());
@@ -295,6 +301,7 @@ PFNGLGETACTIVEUNIFORMARBPROC glGetActiveUniformARB = NULL;
PFNGLGETUNIFORMFVARBPROC glGetUniformfvARB = NULL;
PFNGLGETUNIFORMIVARBPROC glGetUniformivARB = NULL;
PFNGLGETSHADERSOURCEARBPROC glGetShaderSourceARB = NULL;
+PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer = NULL;
#if LL_WINDOWS
PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = NULL;
@@ -443,7 +450,8 @@ LLGLManager::LLGLManager() :
mDriverVersionMinor(0),
mDriverVersionRelease(0),
mGLVersion(1.0f),
-
+ mGLSLVersionMajor(0),
+ mGLSLVersionMinor(0),
mVRAM(0),
mGLMaxVertexRange(0),
mGLMaxIndexRange(0)
@@ -554,6 +562,29 @@ bool LLGLManager::initGL()
mGLVersion = mDriverVersionMajor + mDriverVersionMinor * .1f;
+ if (mGLVersion >= 2.f)
+ {
+ parse_glsl_version(mGLSLVersionMajor, mGLSLVersionMinor);
+
+#if LL_DARWIN
+ //never use GLSL greater than 1.20 on OSX
+ if (mGLSLVersionMajor > 1 || mGLSLVersionMinor >= 30)
+ {
+ mGLSLVersionMajor = 1;
+ mGLSLVersionMinor = 20;
+ }
+#endif
+ }
+
+ if (mGLVersion >= 2.1f && LLImageGL::sCompressTextures)
+ { //use texture compression
+ glHint(GL_TEXTURE_COMPRESSION_HINT, GL_NICEST);
+ }
+ else
+ { //GL version is < 3.0, always disable texture compression
+ LLImageGL::sCompressTextures = false;
+ }
+
// Trailing space necessary to keep "nVidia Corpor_ati_on" cards
// from being recognized as ATI.
if (mGLVendor.substr(0,4) == "ATI ")
@@ -574,11 +605,8 @@ bool LLGLManager::initGL()
#endif // LL_WINDOWS
#if (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS
- // release 7277 is a point at which we verify that ATI OpenGL
- // drivers get pretty stable with SL, ~Catalyst 8.2,
- // for both Win32 and Linux.
- if (mDriverVersionRelease < 7277 &&
- mDriverVersionRelease != 0) // 0 == Undetectable driver version - these get to pretend to be new ATI drivers, though that decision may be revisited.
+ // count any pre OpenGL 3.0 implementation as an old driver
+ if (mGLVersion < 3.f)
{
mATIOldDriver = TRUE;
}
@@ -717,6 +745,11 @@ bool LLGLManager::initGL()
}
#endif
+ if (mIsIntel && mGLVersion <= 3.f)
+ { //never try to use framebuffer objects on older intel drivers (crashy)
+ mHasFramebufferObject = FALSE;
+ }
+
if (mHasFramebufferObject)
{
glGetIntegerv(GL_MAX_SAMPLES, &mMaxSamples);
@@ -1300,6 +1333,7 @@ void LLGLManager::initExtensions()
glVertexAttrib4uivARB = (PFNGLVERTEXATTRIB4UIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4uivARB");
glVertexAttrib4usvARB = (PFNGLVERTEXATTRIB4USVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4usvARB");
glVertexAttribPointerARB = (PFNGLVERTEXATTRIBPOINTERARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttribPointerARB");
+ glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttribIPointer");
glEnableVertexAttribArrayARB = (PFNGLENABLEVERTEXATTRIBARRAYARBPROC) GLH_EXT_GET_PROC_ADDRESS("glEnableVertexAttribArrayARB");
glDisableVertexAttribArrayARB = (PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDisableVertexAttribArrayARB");
glProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramStringARB");
@@ -1878,7 +1912,7 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
glClientActiveTextureARB(GL_TEXTURE0_ARB);
gGL.getTexUnit(0)->activate();
- if (gGLManager.mHasVertexShader)
+ if (gGLManager.mHasVertexShader && LLGLSLShader::sNoFixedFunction)
{ //make sure vertex attribs are all disabled
GLint count;
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &count);
@@ -2098,6 +2132,55 @@ void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor
}
}
+
+void parse_glsl_version(S32& major, S32& minor)
+{
+ // GL_SHADING_LANGUAGE_VERSION returns a null-terminated string with the format:
+ // <major>.<minor>[.<release>] [<vendor specific>]
+
+ const char* version = (const char*) glGetString(GL_SHADING_LANGUAGE_VERSION);
+ major = 0;
+ minor = 0;
+
+ if( !version )
+ {
+ return;
+ }
+
+ std::string ver_copy( version );
+ S32 len = (S32)strlen( version ); /* Flawfinder: ignore */
+ S32 i = 0;
+ S32 start;
+ // Find the major version
+ start = i;
+ for( ; i < len; i++ )
+ {
+ if( '.' == version[i] )
+ {
+ break;
+ }
+ }
+ std::string major_str = ver_copy.substr(start,i-start);
+ LLStringUtil::convertToS32(major_str, major);
+
+ if( '.' == version[i] )
+ {
+ i++;
+ }
+
+ // Find the minor version
+ start = i;
+ for( ; i < len; i++ )
+ {
+ if( ('.' == version[i]) || isspace(version[i]) )
+ {
+ break;
+ }
+ }
+ std::string minor_str = ver_copy.substr(start,i-start);
+ LLStringUtil::convertToS32(minor_str, minor);
+}
+
LLGLUserClipPlane::LLGLUserClipPlane(const LLPlane& p, const glh::matrix4f& modelview, const glh::matrix4f& projection, bool apply)
{
mApply = apply;
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index 6a147b8e19..5a33c98708 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -138,6 +138,8 @@ public:
S32 mDriverVersionMinor;
S32 mDriverVersionRelease;
F32 mGLVersion; // e.g = 1.4
+ S32 mGLSLVersionMajor;
+ S32 mGLSLVersionMinor;
std::string mDriverVersionVendorString;
S32 mVRAM; // VRAM in MB
diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h
index 10aad202e1..d61ec707f0 100644
--- a/indra/llrender/llglheaders.h
+++ b/indra/llrender/llglheaders.h
@@ -199,6 +199,7 @@ extern PFNGLVERTEXATTRIB4UBVARBPROC glVertexAttrib4ubvARB;
extern PFNGLVERTEXATTRIB4UIVARBPROC glVertexAttrib4uivARB;
extern PFNGLVERTEXATTRIB4USVARBPROC glVertexAttrib4usvARB;
extern PFNGLVERTEXATTRIBPOINTERARBPROC glVertexAttribPointerARB;
+extern PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer;
extern PFNGLENABLEVERTEXATTRIBARRAYARBPROC glEnableVertexAttribArrayARB;
extern PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glDisableVertexAttribArrayARB;
extern PFNGLPROGRAMSTRINGARBPROC glProgramStringARB;
@@ -460,6 +461,7 @@ extern PFNGLVERTEXATTRIB4UBVARBPROC glVertexAttrib4ubvARB;
extern PFNGLVERTEXATTRIB4UIVARBPROC glVertexAttrib4uivARB;
extern PFNGLVERTEXATTRIB4USVARBPROC glVertexAttrib4usvARB;
extern PFNGLVERTEXATTRIBPOINTERARBPROC glVertexAttribPointerARB;
+extern PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer;
extern PFNGLENABLEVERTEXATTRIBARRAYARBPROC glEnableVertexAttribArrayARB;
extern PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glDisableVertexAttribArrayARB;
extern PFNGLPROGRAMSTRINGARBPROC glProgramStringARB;
@@ -693,6 +695,7 @@ extern PFNGLVERTEXATTRIB4UBVARBPROC glVertexAttrib4ubvARB;
extern PFNGLVERTEXATTRIB4UIVARBPROC glVertexAttrib4uivARB;
extern PFNGLVERTEXATTRIB4USVARBPROC glVertexAttrib4usvARB;
extern PFNGLVERTEXATTRIBPOINTERARBPROC glVertexAttribPointerARB;
+extern PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer;
extern PFNGLENABLEVERTEXATTRIBARRAYARBPROC glEnableVertexAttribArrayARB;
extern PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glDisableVertexAttribArrayARB;
extern PFNGLPROGRAMSTRINGARBPROC glProgramStringARB;
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 3773568ad8..4b7e639aed 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -109,7 +109,12 @@ void LLGLSLShader::unload()
glGetAttachedObjectsARB(mProgramObject, 1024, &count, obj);
for (GLsizei i = 0; i < count; i++)
{
- glDeleteObjectARB(obj[i]);
+#if !LL_DARWIN
+ if (glIsProgramARB(obj[i]))
+#endif
+ {
+ glDeleteObjectARB(obj[i]);
+ }
}
glDeleteObjectARB(mProgramObject);
@@ -161,8 +166,9 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,
return FALSE;
}
- if (gGLManager.mGLVersion < 3.1f)
- { //attachShaderFeatures may have set the number of indexed texture channels, so set to 1 again
+ if (gGLManager.mGLSLVersionMajor < 2 && gGLManager.mGLSLVersionMinor < 3)
+ { //indexed texture rendering requires GLSL 1.3 or later
+ //attachShaderFeatures may have set the number of indexed texture channels, so set to 1 again
mFeatures.mIndexedTextureChannels = llmin(mFeatures.mIndexedTextureChannels, 1);
}
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 78591ddd38..17131c9d8a 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -57,6 +57,7 @@ BOOL LLImageGL::sGlobalUseAnisotropic = FALSE;
F32 LLImageGL::sLastFrameTime = 0.f;
BOOL LLImageGL::sAllowReadBackRaw = FALSE ;
LLImageGL* LLImageGL::sDefaultGLTexture = NULL ;
+bool LLImageGL::sCompressTextures = false;
std::set<LLImageGL*> LLImageGL::sImageList;
@@ -477,6 +478,8 @@ void LLImageGL::init(BOOL usemipmaps)
mDiscardLevelInAtlas = -1 ;
mTexelsInAtlas = 0 ;
mTexelsInGLTexture = 0 ;
+
+ mAllowCompression = true;
mTarget = GL_TEXTURE_2D;
mBindTarget = LLTexUnit::TT_TEXTURE;
@@ -705,7 +708,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
stop_glerror();
}
- LLImageGL::setManualImage(mTarget, gl_level, mFormatInternal, w, h, mFormatPrimary, GL_UNSIGNED_BYTE, (GLvoid*)data_in);
+ LLImageGL::setManualImage(mTarget, gl_level, mFormatInternal, w, h, mFormatPrimary, GL_UNSIGNED_BYTE, (GLvoid*)data_in, mAllowCompression);
if (gl_level == 0)
{
analyzeAlpha(data_in, w, h);
@@ -747,7 +750,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
LLImageGL::setManualImage(mTarget, 0, mFormatInternal,
w, h,
mFormatPrimary, mFormatType,
- data_in);
+ data_in, mAllowCompression);
analyzeAlpha(data_in, w, h);
stop_glerror();
@@ -805,7 +808,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
stop_glerror();
}
- LLImageGL::setManualImage(mTarget, m, mFormatInternal, w, h, mFormatPrimary, mFormatType, cur_mip_data);
+ LLImageGL::setManualImage(mTarget, m, mFormatInternal, w, h, mFormatPrimary, mFormatType, cur_mip_data, mAllowCompression);
if (m == 0)
{
analyzeAlpha(data_in, w, h);
@@ -863,7 +866,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
}
LLImageGL::setManualImage(mTarget, 0, mFormatInternal, w, h,
- mFormatPrimary, mFormatType, (GLvoid *)data_in);
+ mFormatPrimary, mFormatType, (GLvoid *)data_in, mAllowCompression);
analyzeAlpha(data_in, w, h);
updatePickMask(w, h, data_in);
@@ -1110,7 +1113,7 @@ void LLImageGL::deleteTextures(S32 numTextures, U32 *textures, bool immediate)
}
// static
-void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels)
+void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels, bool allow_compression)
{
bool use_scratch = false;
U32* scratch = NULL;
@@ -1173,6 +1176,36 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
}
}
+ if (LLImageGL::sCompressTextures && allow_compression)
+ {
+ switch (intformat)
+ {
+ case GL_RGB:
+ case GL_RGB8:
+ intformat = GL_COMPRESSED_RGB;
+ break;
+ case GL_RGBA:
+ case GL_RGBA8:
+ intformat = GL_COMPRESSED_RGBA;
+ break;
+ case GL_LUMINANCE:
+ case GL_LUMINANCE8:
+ intformat = GL_COMPRESSED_LUMINANCE;
+ break;
+ case GL_LUMINANCE_ALPHA:
+ case GL_LUMINANCE8_ALPHA8:
+ intformat = GL_COMPRESSED_LUMINANCE_ALPHA;
+ break;
+ case GL_ALPHA:
+ case GL_ALPHA8:
+ intformat = GL_COMPRESSED_ALPHA;
+ break;
+ default:
+ llwarns << "Could not compress format: " << std::hex << intformat << llendl;
+ break;
+ }
+ }
+
stop_glerror();
glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, use_scratch ? scratch : pixels);
stop_glerror();
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index 2cfb15b0d9..e23005fe29 100644
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -94,12 +94,13 @@ public:
void setSize(S32 width, S32 height, S32 ncomponents);
void setComponents(S32 ncomponents) { mComponents = (S8)ncomponents ;}
+ void setAllowCompression(bool allow) { mAllowCompression = allow; }
// These 3 functions currently wrap glGenTextures(), glDeleteTextures(), and glTexImage2D()
// for tracking purposes and will be deprecated in the future
static void generateTextures(S32 numTextures, U32 *textures);
static void deleteTextures(S32 numTextures, U32 *textures, bool immediate = false);
- static void setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels);
+ static void setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels, bool allow_compression = true);
BOOL createGLTexture() ;
BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE,
@@ -209,6 +210,8 @@ private:
U32 mTexelsInAtlas ;
U32 mTexelsInGLTexture;
+ bool mAllowCompression;
+
protected:
LLGLenum mTarget; // Normally GL_TEXTURE2D, sometimes something else (ex. cube maps)
LLTexUnit::eTextureType mBindTarget; // Normally TT_TEXTURE, sometimes something else (ex. cube maps)
@@ -246,7 +249,7 @@ public:
static BOOL sGlobalUseAnisotropic;
static LLImageGL* sDefaultGLTexture ;
static BOOL sAutomatedTest;
-
+ static bool sCompressTextures; //use GL texture compression
#if DEBUG_MISS
BOOL mMissed; // Missed on last bind?
BOOL getMissed() const { return mMissed; };
diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
index ef2a7395da..780f1dc484 100644
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -143,7 +143,7 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
{
clear_glerror();
- LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL, false);
if (glGetError() != GL_NO_ERROR)
{
llwarns << "Could not allocate color buffer for render target." << llendl;
@@ -223,7 +223,7 @@ bool LLRenderTarget::allocateDepth()
U32 internal_type = LLTexUnit::getInternalType(mUsage);
stop_glerror();
clear_glerror();
- LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT24, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
+ LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT24, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL, false);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
}
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 908443e8cf..7d384450e6 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -575,34 +575,46 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
GLcharARB* text[4096];
GLuint count = 0;
- F32 version = gGLManager.mGLVersion;
-
-//hack to never use GLSL > 1.20 on OSX
-#if LL_DARWIN
- version = llmin(version, 2.9f);
-#endif
-
- if (version < 2.1f)
- {
- text[count++] = strdup("#version 110\n");
- text[count++] = strdup("#define ATTRIBUTE attribute\n");
- text[count++] = strdup("#define VARYING varying\n");
- }
- else if (version < 3.3f)
+ S32 major_version = gGLManager.mGLSLVersionMajor;
+ S32 minor_version = gGLManager.mGLSLVersionMinor;
+
+ if (major_version == 1 && minor_version < 30)
{
- //set version to 1.20
- text[count++] = strdup("#version 120\n");
- text[count++] = strdup("#define FXAA_GLSL_120 1\n");
- text[count++] = strdup("#define FXAA_FAST_PIXEL_OFFSET 0\n");
- text[count++] = strdup("#define ATTRIBUTE attribute\n");
- text[count++] = strdup("#define VARYING varying\n");
+ if (minor_version < 10)
+ {
+ //should NEVER get here -- if major version is 1 and minor version is less than 10,
+ // viewer should never attempt to use shaders, continuing will result in undefined behavior
+ llerrs << "Unsupported GLSL Version." << llendl;
+ }
+
+ if (minor_version <= 19)
+ {
+ text[count++] = strdup("#version 110\n");
+ text[count++] = strdup("#define ATTRIBUTE attribute\n");
+ text[count++] = strdup("#define VARYING varying\n");
+ text[count++] = strdup("#define VARYING_FLAT varying\n");
+ }
+ else if (minor_version <= 29)
+ {
+ //set version to 1.20
+ text[count++] = strdup("#version 120\n");
+ text[count++] = strdup("#define FXAA_GLSL_120 1\n");
+ text[count++] = strdup("#define FXAA_FAST_PIXEL_OFFSET 0\n");
+ text[count++] = strdup("#define ATTRIBUTE attribute\n");
+ text[count++] = strdup("#define VARYING varying\n");
+ text[count++] = strdup("#define VARYING_FLAT varying\n");
+ }
}
else
{
- if (version < 4.f)
+ if (major_version < 4)
{
//set version to 1.30
text[count++] = strdup("#version 130\n");
+
+ //some implementations of GLSL 1.30 require integer precision be explicitly declared
+ text[count++] = strdup("precision mediump int;\n");
+ text[count++] = strdup("precision highp float;\n");
}
else
{ //set version to 400
@@ -618,16 +630,25 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
{ //"varying" state is "out" in a vertex program, "in" in a fragment program
// ("varying" is deprecated after version 1.20)
text[count++] = strdup("#define VARYING out\n");
+ text[count++] = strdup("#define VARYING_FLAT flat out\n");
}
else
{
text[count++] = strdup("#define VARYING in\n");
+ text[count++] = strdup("#define VARYING_FLAT flat in\n");
}
//backwards compatibility with legacy texture lookup syntax
+ text[count++] = strdup("#define texture2D texture\n");
text[count++] = strdup("#define textureCube texture\n");
text[count++] = strdup("#define texture2DLod textureLod\n");
text[count++] = strdup("#define shadow2D(a,b) vec2(texture(a,b))\n");
+
+ if (major_version > 1 || minor_version >= 40)
+ { //GLSL 1.40 replaces texture2DRect et al with texture
+ text[count++] = strdup("#define texture2DRect texture\n");
+ text[count++] = strdup("#define shadow2DRect(a,b) vec2(texture(a,b))\n");
+ }
}
//copy preprocessor definitions into buffer
@@ -651,22 +672,24 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
.
uniform sampler2D texN;
- VARYING float vary_texture_index;
+ VARYING_FLAT ivec4 vary_texture_index;
+
+ vec4 ret = vec4(1,0,1,1);
vec4 diffuseLookup(vec2 texcoord)
{
- switch (int(vary_texture_index+0.25))
+ switch (vary_texture_index.r))
{
- case 0: return texture2D(tex0, texcoord);
- case 1: return texture2D(tex1, texcoord);
- case 2: return texture2D(tex2, texcoord);
+ case 0: ret = texture2D(tex0, texcoord); break;
+ case 1: ret = texture2D(tex1, texcoord); break;
+ case 2: ret = texture2D(tex2, texcoord); break;
.
.
.
- case N: return texture2D(texN, texcoord);
+ case N: return texture2D(texN, texcoord); break;
}
- return vec4(0,0,0,0);
+ return ret;
}
*/
@@ -679,7 +702,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
if (texture_index_channels > 1)
{
- text[count++] = strdup("VARYING float vary_texture_index;\n");
+ text[count++] = strdup("VARYING_FLAT ivec4 vary_texture_index;\n");
}
text[count++] = strdup("vec4 diffuseLookup(vec2 texcoord)\n");
@@ -691,45 +714,28 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
text[count++] = strdup("return texture2D(tex0, texcoord);\n");
text[count++] = strdup("}\n");
}
- else if (gGLManager.mGLVersion >= 3.f)
- {
- text[count++] = strdup("\tswitch (int(vary_texture_index+0.25))\n");
+ else if (major_version > 1 || minor_version >= 30)
+ { //switches are supported in GLSL 1.30 and later
+ text[count++] = strdup("\tvec4 ret = vec4(1,0,1,1);\n");
+ text[count++] = strdup("\tswitch (vary_texture_index.r)\n");
text[count++] = strdup("\t{\n");
//switch body
for (S32 i = 0; i < texture_index_channels; ++i)
{
- std::string case_str = llformat("\t\tcase %d: return texture2D(tex%d, texcoord);\n", i, i);
+ std::string case_str = llformat("\t\tcase %d: ret = texture2D(tex%d, texcoord); break;\n", i, i);
text[count++] = strdup(case_str.c_str());
}
text[count++] = strdup("\t}\n");
- text[count++] = strdup("\treturn vec4(1,0,1,1);\n");
+ text[count++] = strdup("\treturn ret;\n");
text[count++] = strdup("}\n");
}
else
- {
- //switches aren't supported, make block that looks like:
- /*
- int ti = int(vary_texture_index+0.25);
- if (ti == 0) return texture2D(tex0, texcoord);
- if (ti == 1) return texture2D(tex1, texcoord);
- .
- .
- .
- if (ti == N) return texture2D(texN, texcoord);
- */
-
- text[count++] = strdup("int ti = int(vary_texture_index+0.25);\n");
- for (S32 i = 0; i < texture_index_channels; ++i)
- {
- std::string if_str = llformat("if (ti == %d) return texture2D(tex%d, texcoord);\n", i, i);
- text[count++] = strdup(if_str.c_str());
- }
-
- text[count++] = strdup("\treturn vec4(1,0,1,1);\n");
- text[count++] = strdup("}\n");
- }
+ { //should never get here. Indexed texture rendering requires GLSL 1.30 or later
+ // (for passing integers between vertex and fragment shaders)
+ llerrs << "Indexed texture rendering requires GLSL 1.30 or later." << llendl;
+ }
}
//copy file into memory
@@ -1070,6 +1076,8 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("magnification");
mReservedUniforms.push_back("max_cof");
mReservedUniforms.push_back("res_scale");
+ mReservedUniforms.push_back("dof_width");
+ mReservedUniforms.push_back("dof_height");
mReservedUniforms.push_back("depthMap");
mReservedUniforms.push_back("shadowMap0");
diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h
index 950e6c9c2f..e28bda6de2 100644
--- a/indra/llrender/llshadermgr.h
+++ b/indra/llrender/llshadermgr.h
@@ -142,6 +142,8 @@ public:
DOF_MAGNIFICATION,
DOF_MAX_COF,
DOF_RES_SCALE,
+ DOF_WIDTH,
+ DOF_HEIGHT,
DEFERRED_DEPTH,
DEFERRED_SHADOW0,
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index e4a5cd0299..b4899209c4 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -38,6 +38,8 @@
#include "llglslshader.h"
#include "llmemory.h"
+#define LL_VBO_POOLING 0
+
//Next Highest Power Of Two
//helper function, returns first number > v that is a power of 2, or v if v is already a power of 2
U32 nhpo2(U32 v)
@@ -49,6 +51,35 @@ U32 nhpo2(U32 v)
return r;
}
+//which power of 2 is i?
+//assumes i is a power of 2 > 0
+U32 wpo2(U32 i)
+{
+ llassert(i > 0);
+ llassert(nhpo2(i) == i);
+
+ U32 r = 0;
+
+ while (i >>= 1) ++r;
+
+ return r;
+}
+
+
+const U32 LL_VBO_BLOCK_SIZE = 2048;
+
+U32 vbo_block_size(U32 size)
+{ //what block size will fit size?
+ U32 mod = size % LL_VBO_BLOCK_SIZE;
+ return mod == 0 ? size : size + (LL_VBO_BLOCK_SIZE-mod);
+}
+
+U32 vbo_block_index(U32 size)
+{
+ return vbo_block_size(size)/LL_VBO_BLOCK_SIZE;
+}
+
+
//============================================================================
@@ -57,7 +88,11 @@ LLVBOPool LLVertexBuffer::sStreamVBOPool(GL_STREAM_DRAW_ARB, GL_ARRAY_BUFFER_ARB
LLVBOPool LLVertexBuffer::sDynamicVBOPool(GL_DYNAMIC_DRAW_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 LLVertexBuffer::sAllocatedIndexBytes = 0;
+U32 LLVertexBuffer::sIndexCount = 0;
LLPrivateMemoryPool* LLVertexBuffer::sPrivatePoolp = NULL;
U32 LLVertexBuffer::sBindCount = 0;
@@ -74,6 +109,7 @@ U32 LLVertexBuffer::sLastMask = 0;
bool LLVertexBuffer::sVBOActive = false;
bool LLVertexBuffer::sIBOActive = false;
U32 LLVertexBuffer::sAllocatedBytes = 0;
+U32 LLVertexBuffer::sVertexCount = 0;
bool LLVertexBuffer::sMapped = false;
bool LLVertexBuffer::sUseStreamDraw = true;
bool LLVertexBuffer::sUseVAO = false;
@@ -134,39 +170,35 @@ public:
};
-//which power of 2 is i?
-//assumes i is a power of 2 > 0
-U32 wpo2(U32 i)
-{
- llassert(i > 0);
- llassert(nhpo2(i) == i);
-
- U32 r = 0;
-
- while (i >>= 1) ++r;
-
- return r;
-}
-
volatile U8* LLVBOPool::allocate(U32& name, U32 size)
{
- llassert(nhpo2(size) == size);
+ llassert(vbo_block_size(size) == size);
+
+ volatile U8* ret = NULL;
+
+#if LL_VBO_POOLING
- U32 i = wpo2(size);
+ U32 i = vbo_block_index(size);
if (mFreeList.size() <= i)
{
mFreeList.resize(i+1);
}
- volatile U8* ret = NULL;
-
if (mFreeList[i].empty())
{
//make a new buffer
glGenBuffersARB(1, &name);
glBindBufferARB(mType, name);
- LLVertexBuffer::sAllocatedBytes += size;
+
+ if (mType == GL_ARRAY_BUFFER_ARB)
+ {
+ LLVertexBuffer::sAllocatedBytes += size;
+ }
+ else
+ {
+ LLVertexBuffer::sAllocatedIndexBytes += size;
+ }
if (LLVertexBuffer::sDisableVBOMapping || mUsage != GL_DYNAMIC_DRAW_ARB)
{
@@ -185,19 +217,55 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size)
name = mFreeList[i].front().mGLName;
ret = mFreeList[i].front().mClientData;
- sBytesPooled -= size;
+ if (mType == GL_ARRAY_BUFFER_ARB)
+ {
+ sBytesPooled -= size;
+ }
+ else
+ {
+ sIndexBytesPooled -= size;
+ }
mFreeList[i].pop_front();
}
+#else //no pooling
+
+ glGenBuffersARB(1, &name);
+ glBindBufferARB(mType, name);
+
+ if (mType == GL_ARRAY_BUFFER_ARB)
+ {
+ LLVertexBuffer::sAllocatedBytes += size;
+ }
+ else
+ {
+ LLVertexBuffer::sAllocatedIndexBytes += size;
+ }
+
+ if (LLVertexBuffer::sDisableVBOMapping || mUsage != GL_DYNAMIC_DRAW_ARB)
+ {
+ glBufferDataARB(mType, size, 0, mUsage);
+ ret = (U8*) ll_aligned_malloc_16(size);
+ }
+ else
+ { //always use a true hint of static draw when allocating non-client-backed buffers
+ glBufferDataARB(mType, size, 0, GL_STATIC_DRAW_ARB);
+ }
+
+ glBindBufferARB(mType, 0);
+
+#endif
return ret;
}
void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size)
{
- llassert(nhpo2(size) == size);
+ llassert(vbo_block_size(size) == size);
- U32 i = wpo2(size);
+#if LL_VBO_POOLING
+
+ U32 i = vbo_block_index(size);
llassert(mFreeList.size() > i);
@@ -211,9 +279,29 @@ void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size)
}
else
{
- sBytesPooled += size;
+ if (mType == GL_ARRAY_BUFFER_ARB)
+ {
+ sBytesPooled += size;
+ }
+ else
+ {
+ sIndexBytesPooled += size;
+ }
mFreeList[i].push_back(rec);
}
+#else //no pooling
+ glDeleteBuffersARB(1, &name);
+ ll_aligned_free_16((U8*) buffer);
+
+ if (mType == GL_ARRAY_BUFFER_ARB)
+ {
+ LLVertexBuffer::sAllocatedBytes -= size;
+ }
+ else
+ {
+ LLVertexBuffer::sAllocatedIndexBytes -= size;
+ }
+#endif
}
void LLVBOPool::cleanup()
@@ -237,8 +325,16 @@ void LLVBOPool::cleanup()
l.pop_front();
- LLVertexBuffer::sAllocatedBytes -= size;
- sBytesPooled -= size;
+ if (mType == GL_ARRAY_BUFFER_ARB)
+ {
+ sBytesPooled -= size;
+ LLVertexBuffer::sAllocatedBytes -= size;
+ }
+ else
+ {
+ sIndexBytesPooled -= size;
+ LLVertexBuffer::sAllocatedIndexBytes -= size;
+ }
}
size *= 2;
@@ -284,6 +380,12 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
{
bool error = false;
+ if (gGLManager.mGLSLVersionMajor < 2 && gGLManager.mGLSLVersionMinor < 30)
+ {
+ //make sure texture index is disabled
+ data_mask = data_mask & ~MAP_TEXTURE_INDEX;
+ }
+
if (LLGLSLShader::sNoFixedFunction)
{
for (U32 i = 0; i < TYPE_MAX; ++i)
@@ -892,6 +994,9 @@ LLVertexBuffer::~LLVertexBuffer()
mFence = NULL;
+ sVertexCount -= mNumVerts;
+ sIndexCount -= mNumIndices;
+
llassert_always(!mMappedData && !mMappedIndexData);
};
@@ -923,7 +1028,7 @@ void LLVertexBuffer::waitFence() const
void LLVertexBuffer::genBuffer(U32 size)
{
- mSize = nhpo2(size);
+ mSize = vbo_block_size(size);
if (mUsage == GL_STREAM_DRAW_ARB)
{
@@ -939,7 +1044,7 @@ void LLVertexBuffer::genBuffer(U32 size)
void LLVertexBuffer::genIndices(U32 size)
{
- mIndicesSize = nhpo2(size);
+ mIndicesSize = vbo_block_size(size);
if (mUsage == GL_STREAM_DRAW_ARB)
{
@@ -1115,7 +1220,9 @@ void LLVertexBuffer::updateNumVerts(S32 nverts)
createGLBuffer(needed_size);
}
+ sVertexCount -= mNumVerts;
mNumVerts = nverts;
+ sVertexCount += mNumVerts;
}
void LLVertexBuffer::updateNumIndices(S32 nindices)
@@ -1131,7 +1238,9 @@ void LLVertexBuffer::updateNumIndices(S32 nindices)
createGLIndices(needed_size);
}
+ sIndexCount -= mNumIndices;
mNumIndices = nindices;
+ sIndexCount += mNumIndices;
}
void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
@@ -1193,7 +1302,7 @@ void LLVertexBuffer::setupVertexArray()
1, //TYPE_WEIGHT,
4, //TYPE_WEIGHT4,
4, //TYPE_CLOTHWEIGHT,
- 1, //TYPE_TEXTURE_INDEX
+ 4, //TYPE_TEXTURE_INDEX
};
U32 attrib_type[] =
@@ -1210,7 +1319,24 @@ void LLVertexBuffer::setupVertexArray()
GL_FLOAT, //TYPE_WEIGHT,
GL_FLOAT, //TYPE_WEIGHT4,
GL_FLOAT, //TYPE_CLOTHWEIGHT,
- GL_FLOAT, //TYPE_TEXTURE_INDEX
+ GL_UNSIGNED_BYTE, //TYPE_TEXTURE_INDEX
+ };
+
+ bool attrib_integer[] =
+ {
+ false, //TYPE_VERTEX,
+ false, //TYPE_NORMAL,
+ false, //TYPE_TEXCOORD0,
+ false, //TYPE_TEXCOORD1,
+ false, //TYPE_TEXCOORD2,
+ false, //TYPE_TEXCOORD3,
+ false, //TYPE_COLOR,
+ false, //TYPE_EMISSIVE,
+ false, //TYPE_BINORMAL,
+ false, //TYPE_WEIGHT,
+ false, //TYPE_WEIGHT4,
+ false, //TYPE_CLOTHWEIGHT,
+ true, //TYPE_TEXTURE_INDEX
};
U32 attrib_normalized[] =
@@ -1238,7 +1364,21 @@ void LLVertexBuffer::setupVertexArray()
if (mTypeMask & (1 << i))
{
glEnableVertexAttribArrayARB(i);
- glVertexAttribPointerARB(i, attrib_size[i], attrib_type[i], attrib_normalized[i], sTypeSize[i], (void*) mOffsets[i]);
+
+ if (attrib_integer[i])
+ {
+#if !LL_DARWIN
+ //glVertexattribIPointer requires GLSL 1.30 or later
+ if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30)
+ {
+ glVertexAttribIPointer(i, attrib_size[i], attrib_type[i], sTypeSize[i], (void*) mOffsets[i]);
+ }
+#endif
+ }
+ else
+ {
+ glVertexAttribPointerARB(i, attrib_size[i], attrib_type[i], attrib_normalized[i], sTypeSize[i], (void*) mOffsets[i]);
+ }
}
else
{
@@ -2220,11 +2360,14 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
void* ptr = (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]);
glVertexAttribPointerARB(loc, 4, GL_FLOAT, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], ptr);
}
- if (data_mask & MAP_TEXTURE_INDEX)
+ if (data_mask & MAP_TEXTURE_INDEX &&
+ (gGLManager.mGLSLVersionMajor >= 2 || gGLManager.mGLSLVersionMinor >= 30)) //indexed texture rendering requires GLSL 1.30 or later
{
+#if !LL_DARWIN
S32 loc = TYPE_TEXTURE_INDEX;
void *ptr = (void*) (base + mOffsets[TYPE_VERTEX] + 12);
- glVertexAttribPointerARB(loc, 1, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
+ glVertexAttribIPointer(loc, 4, GL_UNSIGNED_BYTE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
+#endif
}
if (data_mask & MAP_VERTEX)
{
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index d859199663..7477dec3ad 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -55,6 +55,7 @@ class LLVBOPool
{
public:
static U32 sBytesPooled;
+ static U32 sIndexBytesPooled;
LLVBOPool(U32 vboUsage, U32 vboType)
: mUsage(vboUsage)
@@ -332,6 +333,9 @@ public:
static bool sIBOActive;
static U32 sLastMask;
static U32 sAllocatedBytes;
+ static U32 sAllocatedIndexBytes;
+ static U32 sVertexCount;
+ static U32 sIndexCount;
static U32 sBindCount;
static U32 sSetCount;
};