summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXiaohong Bao <bao@lindenlab.com>2010-08-23 11:32:58 -0600
committerXiaohong Bao <bao@lindenlab.com>2010-08-23 11:32:58 -0600
commitf263ee04441f5173a02974c51347f8bb3d23d29d (patch)
treec5df88498d885adaa93a6c345f2084c940c5f27e
parentebab718f32b58ca5a718e8db549ca9d36550bdcf (diff)
added a toggle "LLGLManager::mDebugGPU" for debugging certain CPUs.
added more debug code for EXT-6791: [crashhunters] Intel 965 Crash in glCopyTexSubImage2D
-rw-r--r--indra/llrender/llgl.cpp89
-rw-r--r--indra/llrender/llgl.h9
-rw-r--r--indra/llrender/llimagegl.cpp101
-rw-r--r--indra/newview/lldynamictexture.cpp18
4 files changed, 77 insertions, 140 deletions
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 236594d602..823208b095 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -185,9 +185,6 @@ PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT =
// GL_EXT_framebuffer_blit
PFNGLBLITFRAMEBUFFEREXTPROC glBlitFramebufferEXT = NULL;
-// GL_EXT_blend_func_separate
-PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT = NULL;
-
// GL_ARB_draw_buffers
PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB = NULL;
@@ -327,7 +324,6 @@ LLGLManager::LLGLManager() :
mHasCompressedTextures(FALSE),
mHasFramebufferObject(FALSE),
mHasFramebufferMultisample(FALSE),
- mHasBlendFuncSeparate(FALSE),
mHasVertexBufferObject(FALSE),
mHasPBuffer(FALSE),
@@ -356,6 +352,8 @@ LLGLManager::LLGLManager() :
mHasSeparateSpecularColor(FALSE),
+ mDebugGPU(FALSE),
+
mDriverVersionMajor(1),
mDriverVersionMinor(0),
mDriverVersionRelease(0),
@@ -523,11 +521,23 @@ bool LLGLManager::initGL()
return false;
}
+ setToDebugGPU();
initGLStates();
return true;
}
+void LLGLManager::setToDebugGPU()
+{
+ //"MOBILE INTEL(R) 965 EXPRESS CHIP",
+ if (mGLRenderer.find("INTEL") != std::string::npos && mGLRenderer.find("965") != std::string::npos)
+ {
+ mDebugGPU = TRUE ;
+ }
+
+ return ;
+}
+
void LLGLManager::getGLInfo(LLSD& info)
{
info["GLInfo"]["GLVendor"] = std::string((const char *)glGetString(GL_VENDOR));
@@ -637,11 +647,6 @@ void LLGLManager::initExtensions()
#else
mHasDrawBuffers = FALSE;
# endif
-# if GL_EXT_blend_func_separate
- mHasBlendFuncSeparate = TRUE;
-#else
- mHasBlendFuncSeparate = FALSE;
-# endif
mHasMipMapGeneration = FALSE;
mHasSeparateSpecularColor = FALSE;
mHasAnisotropic = FALSE;
@@ -668,7 +673,6 @@ void LLGLManager::initExtensions()
&& ExtensionExists("GL_EXT_packed_depth_stencil", gGLHExts.mSysExts);
mHasFramebufferMultisample = mHasFramebufferObject && ExtensionExists("GL_EXT_framebuffer_multisample", gGLHExts.mSysExts);
mHasDrawBuffers = ExtensionExists("GL_ARB_draw_buffers", gGLHExts.mSysExts);
- mHasBlendFuncSeparate = ExtensionExists("GL_EXT_blend_func_separate", gGLHExts.mSysExts);
mHasTextureRectangle = ExtensionExists("GL_ARB_texture_rectangle", gGLHExts.mSysExts);
#if !LL_DARWIN
mHasPointParameters = !mIsATI && ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts);
@@ -692,7 +696,6 @@ void LLGLManager::initExtensions()
mHasFramebufferObject = FALSE;
mHasFramebufferMultisample = FALSE;
mHasDrawBuffers = FALSE;
- mHasBlendFuncSeparate = FALSE;
mHasMipMapGeneration = FALSE;
mHasSeparateSpecularColor = FALSE;
mHasAnisotropic = FALSE;
@@ -717,7 +720,6 @@ void LLGLManager::initExtensions()
mHasShaderObjects = FALSE;
mHasVertexShader = FALSE;
mHasFragmentShader = FALSE;
- mHasBlendFuncSeparate = FALSE;
LL_WARNS("RenderInit") << "GL extension support forced to SIMPLE level via LL_GL_BASICEXT" << LL_ENDL;
}
if (getenv("LL_GL_BLACKLIST")) /* Flawfinder: ignore */
@@ -746,8 +748,7 @@ void LLGLManager::initExtensions()
if (strchr(blacklist,'r')) mHasDrawBuffers = FALSE;//S
if (strchr(blacklist,'s')) mHasFramebufferMultisample = FALSE;
if (strchr(blacklist,'t')) mHasTextureRectangle = FALSE;
- if (strchr(blacklist,'u')) mHasBlendFuncSeparate = FALSE;//S
-
+
}
#endif // LL_LINUX || LL_SOLARIS
@@ -795,14 +796,6 @@ void LLGLManager::initExtensions()
{
LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_fragment_shader" << LL_ENDL;
}
- if (!mHasBlendFuncSeparate)
- {
- LL_INFOS("RenderInit") << "Couldn't initialize GL_EXT_blend_func_separate" << LL_ENDL;
- }
- if (!mHasDrawBuffers)
- {
- LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_draw_buffers" << LL_ENDL;
- }
// Disable certain things due to known bugs
if (mIsIntel && mHasMipMapGeneration)
@@ -873,10 +866,6 @@ void LLGLManager::initExtensions()
{
glDrawBuffersARB = (PFNGLDRAWBUFFERSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDrawBuffersARB");
}
- if (mHasBlendFuncSeparate)
- {
- glBlendFuncSeparateEXT = (PFNGLBLENDFUNCSEPARATEEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glBlendFuncSeparateEXT");
- }
#if (!LL_LINUX && !LL_SOLARIS) || LL_LINUX_NV_GL_HEADERS
// This is expected to be a static symbol on Linux GL implementations, except if we use the nvidia headers - bah
glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawRangeElements");
@@ -1039,9 +1028,24 @@ void flush_glerror()
glGetError();
}
-void do_assert_glerror()
+void assert_glerror()
{
- if (LL_UNLIKELY(!gGLManager.mInited))
+ if (!gGLActive)
+ {
+ //llwarns << "GL used while not active!" << llendl;
+
+ if (gDebugSession)
+ {
+ //ll_fail("GL used while not active");
+ }
+ }
+
+ if (gNoRender || !gDebugGL)
+ {
+ return;
+ }
+
+ if (!gGLManager.mInited)
{
LL_ERRS("RenderInit") << "GL not initialized" << LL_ENDL;
}
@@ -1049,9 +1053,10 @@ void do_assert_glerror()
GLenum error;
error = glGetError();
BOOL quit = FALSE;
- while (LL_UNLIKELY(error))
+ while (error)
{
quit = TRUE;
+#ifndef LL_LINUX // *FIX: ! This should be an error for linux as well.
GLubyte const * gl_error_msg = gluErrorString(error);
if (NULL != gl_error_msg)
{
@@ -1075,6 +1080,7 @@ void do_assert_glerror()
}
}
error = glGetError();
+#endif
}
if (quit)
@@ -1090,25 +1096,6 @@ void do_assert_glerror()
}
}
-void assert_glerror()
-{
- if (!gGLActive)
- {
- //llwarns << "GL used while not active!" << llendl;
-
- if (gDebugSession)
- {
- //ll_fail("GL used while not active");
- }
- }
-
- if (!gNoRender && gDebugGL)
- {
- do_assert_glerror();
- }
-}
-
-
void clear_glerror()
{
// Create or update texture to be used with this data
@@ -1122,7 +1109,7 @@ void clear_glerror()
//
// Static members
-boost::unordered_map<LLGLenum, LLGLboolean> LLGLState::sStateMap;
+std::map<LLGLenum, LLGLboolean> LLGLState::sStateMap;
GLboolean LLGLDepthTest::sDepthEnabled = GL_FALSE; // OpenGL default
GLenum LLGLDepthTest::sDepthFunc = GL_LESS; // OpenGL default
@@ -1170,7 +1157,7 @@ void LLGLState::resetTextureStates()
void LLGLState::dumpStates()
{
LL_INFOS("RenderState") << "GL States:" << LL_ENDL;
- for (boost::unordered_map<LLGLenum, LLGLboolean>::iterator iter = sStateMap.begin();
+ for (std::map<LLGLenum, LLGLboolean>::iterator iter = sStateMap.begin();
iter != sStateMap.end(); ++iter)
{
LL_INFOS("RenderState") << llformat(" 0x%04x : %s",(S32)iter->first,iter->second?"TRUE":"FALSE") << LL_ENDL;
@@ -1206,7 +1193,7 @@ void LLGLState::checkStates(const std::string& msg)
}
}
- for (boost::unordered_map<LLGLenum, LLGLboolean>::iterator iter = sStateMap.begin();
+ for (std::map<LLGLenum, LLGLboolean>::iterator iter = sStateMap.begin();
iter != sStateMap.end(); ++iter)
{
LLGLenum state = iter->first;
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index c4f5d91e1a..620aa5bee0 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -36,7 +36,7 @@
// This file contains various stuff for handling gl extensions and other gl related stuff.
#include <string>
-#include <boost/unordered_map.hpp>
+#include <map>
#include <list>
#include "llerror.h"
@@ -87,7 +87,6 @@ public:
BOOL mHasCompressedTextures;
BOOL mHasFramebufferObject;
BOOL mHasFramebufferMultisample;
- BOOL mHasBlendFuncSeparate;
// ARB Extensions
BOOL mHasVertexBufferObject;
@@ -120,6 +119,9 @@ public:
// Misc extensions
BOOL mHasSeparateSpecularColor;
+
+ //whether this GPU is in the debug list.
+ BOOL mDebugGPU;
S32 mDriverVersionMajor;
S32 mDriverVersionMinor;
@@ -148,6 +150,7 @@ private:
void initExtensions();
void initGLStates();
void initGLImages();
+ void setToDebugGPU();
};
extern LLGLManager gGLManager;
@@ -241,7 +244,7 @@ public:
static void checkClientArrays(const std::string& msg = "", U32 data_mask = 0x0001);
protected:
- static boost::unordered_map<LLGLenum, LLGLboolean> sStateMap;
+ static std::map<LLGLenum, LLGLboolean> sStateMap;
public:
enum { CURRENT_STATE = -2 };
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 1a48c8a06c..ee26f9819c 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -150,12 +150,12 @@ void LLImageGL::checkTexSize(bool forced) const
if (gDebugSession)
{
gFailLog << "wrong texture size and discard level!" <<
- mWidth << " Height: " << mHeight << " Current Level: " << mCurrentDiscardLevel << std::endl;
+ mWidth << " Height: " << mHeight << " Current Level: " << (S32)mCurrentDiscardLevel << std::endl;
}
else
{
llerrs << "wrong texture size and discard level: width: " <<
- mWidth << " Height: " << mHeight << " Current Level: " << mCurrentDiscardLevel << llendl ;
+ mWidth << " Height: " << mHeight << " Current Level: " << (S32)mCurrentDiscardLevel << llendl ;
}
}
@@ -1057,8 +1057,12 @@ BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_
{
if (gGL.getTexUnit(0)->bind(this, false, true))
{
- checkTexSize(true) ;
- llcallstacks << fb_x << " : " << fb_y << " : " << x_pos << " : " << y_pos << " : " << width << " : " << height << llcallstacksendl ;
+ if(gGLManager.mDebugGPU)
+ {
+ llinfos << "Calling glCopyTexSubImage2D(...)" << llendl ;
+ checkTexSize(true) ;
+ llcallstacks << fb_x << " : " << fb_y << " : " << x_pos << " : " << y_pos << " : " << width << " : " << height << llcallstacksendl ;
+ }
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, fb_x, fb_y, x_pos, y_pos, width, height);
mGLTextureCreated = true;
@@ -1654,7 +1658,7 @@ void LLImageGL::calcAlphaChannelOffsetAndStride()
}
}
-void LLImageGL::analyzeAlpha(const void* data_in, U32 w, U32 h)
+void LLImageGL::analyzeAlpha(const void* data_in, S32 w, S32 h)
{
if(!mNeedsAlphaAndPickMask)
{
@@ -1662,91 +1666,26 @@ void LLImageGL::analyzeAlpha(const void* data_in, U32 w, U32 h)
}
U32 length = w * h;
- U32 alphatotal = 0;
+ const GLubyte* current = ((const GLubyte*) data_in) + mAlphaOffset ;
- U32 sample[16];
- memset(sample, 0, sizeof(U32)*16);
-
- // generate histogram of quantized alpha.
- // also add-in the histogram of a 2x2 box-sampled version. The idea is
- // this will mid-skew the data (and thus increase the chances of not
- // being used as a mask) from high-frequency alpha maps which
- // suffer the worst from aliasing when used as alpha masks.
- if (w >= 2 && h >= 2)
- {
- llassert(w%2 == 0);
- llassert(h%2 == 0);
- const GLubyte* rowstart = ((const GLubyte*) data_in) + mAlphaOffset;
- for (U32 y = 0; y < h; y+=2)
- {
- const GLubyte* current = rowstart;
- for (U32 x = 0; x < w; x+=2)
- {
- const U32 s1 = current[0];
- alphatotal += s1;
- const U32 s2 = current[w * mAlphaStride];
- alphatotal += s2;
- current += mAlphaStride;
- const U32 s3 = current[0];
- alphatotal += s3;
- const U32 s4 = current[w * mAlphaStride];
- alphatotal += s4;
- current += mAlphaStride;
-
- ++sample[s1/16];
- ++sample[s2/16];
- ++sample[s3/16];
- ++sample[s4/16];
-
- const U32 asum = (s1+s2+s3+s4);
- alphatotal += asum;
- sample[asum/(16*4)] += 4;
- }
-
- rowstart += 2 * w * mAlphaStride;
- }
- length *= 2; // we sampled everything twice, essentially
- }
- else
+ S32 sample[16];
+ memset(sample, 0, sizeof(S32)*16);
+
+ for (U32 i = 0; i < length; i++)
{
- const GLubyte* current = ((const GLubyte*) data_in) + mAlphaOffset;
- for (U32 i = 0; i < length; i++)
- {
- const U32 s1 = *current;
- alphatotal += s1;
- ++sample[s1/16];
- current += mAlphaStride;
- }
+ ++sample[*current/16];
+ current += mAlphaStride ;
}
-
- // if more than 1/16th of alpha samples are mid-range, this
- // shouldn't be treated as a 1-bit mask
- // also, if all of the alpha samples are clumped on one half
- // of the range (but not at an absolute extreme), then consider
- // this to be an intentional effect and don't treat as a mask.
-
- U32 midrangetotal = 0;
+ U32 total = 0;
for (U32 i = 4; i < 11; i++)
{
- midrangetotal += sample[i];
- }
- U32 lowerhalftotal = 0;
- for (U32 i = 0; i < 8; i++)
- {
- lowerhalftotal += sample[i];
- }
- U32 upperhalftotal = 0;
- for (U32 i = 8; i < 16; i++)
- {
- upperhalftotal += sample[i];
+ total += sample[i];
}
- if (midrangetotal > length/16 || // lots of midrange, or
- (lowerhalftotal == length && alphatotal != 0) || // all close to transparent but not all totally transparent, or
- (upperhalftotal == length && alphatotal != 255*length)) // all close to opaque but not all totally opaque
+ if (total > length/16)
{
- mIsMask = FALSE; // not suitable for masking
+ mIsMask = FALSE;
}
else
{
diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp
index bb4e6c7a3e..48b07bcf51 100644
--- a/indra/newview/lldynamictexture.cpp
+++ b/indra/newview/lldynamictexture.cpp
@@ -170,9 +170,12 @@ void LLViewerDynamicTexture::postRender(BOOL success)
if(!mGLTexturep->getHasGLTexture())
{
generateGLTexture() ;
- }
- llcallstacks << "class type: " << (S32)getType() << llcallstacksendl ;
+ }
+ if(gGLManager.mDebugGPU)
+ {
+ LLGLState::dumpStates() ;
+ }
success = mGLTexturep->setSubImageFromFrameBuffer(0, 0, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight);
}
}
@@ -211,11 +214,16 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
{
LLViewerDynamicTexture *dynamicTexture = *iter;
if (dynamicTexture->needsRender())
- {
+ {
+ if(gGLManager.mDebugGPU)
+ {
+ llinfos << "class type: " << (S32)dynamicTexture->getType() << llendl;
+ LLGLState::dumpStates() ;
+ }
+
glClear(GL_DEPTH_BUFFER_BIT);
gDepthDirty = TRUE;
-
-
+
gGL.color4f(1,1,1,1);
dynamicTexture->preRender(); // Must be called outside of startRender()
result = FALSE;