Improved error handling (introduced debugsession commandline argument). Startup/shutdown now more verbose. SSE checks if project was compiled with SSE(2)... not sure if windows would reach it if hardware lacked support, but linux/mac may (from V2). Fixed Mac crashes in deferred.
This commit is contained in:
@@ -45,10 +45,12 @@
|
||||
#include "llrender.h"
|
||||
|
||||
#include "llerror.h"
|
||||
#include "llerrorcontrol.h"
|
||||
#include "llquaternion.h"
|
||||
#include "llmath.h"
|
||||
#include "m4math.h"
|
||||
#include "llstring.h"
|
||||
#include "llstacktrace.h"
|
||||
|
||||
#include "llglheaders.h"
|
||||
|
||||
@@ -56,10 +58,49 @@
|
||||
//#define GL_STATE_VERIFY
|
||||
#endif
|
||||
|
||||
|
||||
BOOL gDebugSession = FALSE;
|
||||
BOOL gDebugGL = FALSE;
|
||||
BOOL gClothRipple = FALSE;
|
||||
BOOL gNoRender = FALSE;
|
||||
BOOL gGLActive = FALSE;
|
||||
|
||||
std::ofstream gFailLog;
|
||||
|
||||
void ll_init_fail_log(std::string filename)
|
||||
{
|
||||
gFailLog.open(filename.c_str());
|
||||
}
|
||||
|
||||
|
||||
void ll_fail(std::string msg)
|
||||
{
|
||||
|
||||
if (gDebugSession)
|
||||
{
|
||||
std::vector<std::string> lines;
|
||||
|
||||
gFailLog << LLError::utcTime() << " " << msg << std::endl;
|
||||
|
||||
gFailLog << "Stack Trace:" << std::endl;
|
||||
|
||||
ll_get_stack_trace(lines);
|
||||
|
||||
for(size_t i = 0; i < lines.size(); ++i)
|
||||
{
|
||||
gFailLog << lines[i] << std::endl;
|
||||
}
|
||||
|
||||
gFailLog << "End of Stack Trace." << std::endl << std::endl;
|
||||
|
||||
gFailLog.flush();
|
||||
}
|
||||
};
|
||||
|
||||
void ll_close_fail_log()
|
||||
{
|
||||
gFailLog.close();
|
||||
}
|
||||
LLMatrix4 gGLObliqueProjectionInverse;
|
||||
|
||||
#define LL_GL_NAME_POOLING 0
|
||||
@@ -133,12 +174,9 @@ PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glFramebufferTexture3DEXT = NULL;
|
||||
PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT = NULL;
|
||||
PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glGetFramebufferAttachmentParameterivEXT = NULL;
|
||||
PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT = NULL;
|
||||
|
||||
// GL_EXT_framebuffer_multisample
|
||||
PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT = NULL;
|
||||
|
||||
// GL_EXT_framebuffer_blit
|
||||
PFNGLBLITFRAMEBUFFEREXTPROC glBlitFramebufferEXT = NULL;
|
||||
PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT = NULL;
|
||||
PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC glFramebufferTextureLayerEXT = NULL;
|
||||
|
||||
// GL_EXT_blend_func_separate
|
||||
PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT = NULL;
|
||||
@@ -277,6 +315,8 @@ LLGLManager::LLGLManager() :
|
||||
mIsDisabled(FALSE),
|
||||
|
||||
mHasMultitexture(FALSE),
|
||||
mHasATIMemInfo(FALSE),
|
||||
mHasNVXMemInfo(FALSE),
|
||||
mNumTextureUnits(1),
|
||||
mHasMipMapGeneration(FALSE),
|
||||
mHasCompressedTextures(FALSE),
|
||||
@@ -289,6 +329,7 @@ LLGLManager::LLGLManager() :
|
||||
mHasShaderObjects(FALSE),
|
||||
mHasVertexShader(FALSE),
|
||||
mHasFragmentShader(FALSE),
|
||||
mNumTextureImageUnits(0),
|
||||
mHasOcclusionQuery(FALSE),
|
||||
mHasOcclusionQuery2(FALSE),
|
||||
mHasPointParameters(FALSE),
|
||||
@@ -460,6 +501,20 @@ bool LLGLManager::initGL()
|
||||
// This is called here because it depends on the setting of mIsGF2or4MX, and sets up mHasMultitexture.
|
||||
initExtensions();
|
||||
|
||||
if (mHasATIMemInfo)
|
||||
{ //ask the gl how much vram is free at startup and attempt to use no more than half of that
|
||||
S32 meminfo[4];
|
||||
glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo);
|
||||
|
||||
mVRAM = meminfo[0]/1024;
|
||||
}
|
||||
else if (mHasNVXMemInfo)
|
||||
{
|
||||
S32 dedicated_memory;
|
||||
glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &dedicated_memory);
|
||||
mVRAM = dedicated_memory/1024;
|
||||
}
|
||||
|
||||
if (mHasMultitexture)
|
||||
{
|
||||
GLint num_tex_units;
|
||||
@@ -479,6 +534,12 @@ bool LLGLManager::initGL()
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mHasFragmentShader)
|
||||
{
|
||||
GLint num_tex_image_units;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &num_tex_image_units);
|
||||
mNumTextureImageUnits = num_tex_image_units;
|
||||
}
|
||||
|
||||
initGLStates();
|
||||
return true;
|
||||
@@ -504,14 +565,13 @@ void LLGLManager::getGLInfo(LLSD& info)
|
||||
std::string LLGLManager::getGLInfoString()
|
||||
{
|
||||
std::string info_str;
|
||||
std::string all_exts, line;
|
||||
|
||||
info_str += std::string("GL_VENDOR ") + ll_safe_string((const char *)glGetString(GL_VENDOR)) + std::string("\n");
|
||||
info_str += std::string("GL_RENDERER ") + ll_safe_string((const char *)glGetString(GL_RENDERER)) + std::string("\n");
|
||||
info_str += std::string("GL_VERSION ") + ll_safe_string((const char *)glGetString(GL_VERSION)) + std::string("\n");
|
||||
|
||||
#if !LL_MESA_HEADLESS
|
||||
all_exts = (const char *)gGLHExts.mSysExts;
|
||||
std::string all_exts= ll_safe_string(((const char *)gGLHExts.mSysExts));
|
||||
LLStringUtil::replaceChar(all_exts, ' ', '\n');
|
||||
info_str += std::string("GL_EXTENSIONS:\n") + all_exts + std::string("\n");
|
||||
#endif
|
||||
@@ -522,14 +582,13 @@ std::string LLGLManager::getGLInfoString()
|
||||
void LLGLManager::printGLInfoString()
|
||||
{
|
||||
std::string info_str;
|
||||
std::string all_exts, line;
|
||||
|
||||
LL_INFOS("RenderInit") << "GL_VENDOR: " << ((const char *)glGetString(GL_VENDOR)) << LL_ENDL;
|
||||
LL_INFOS("RenderInit") << "GL_RENDERER: " << ((const char *)glGetString(GL_RENDERER)) << LL_ENDL;
|
||||
LL_INFOS("RenderInit") << "GL_VERSION: " << ((const char *)glGetString(GL_VERSION)) << LL_ENDL;
|
||||
|
||||
#if !LL_MESA_HEADLESS
|
||||
all_exts = std::string(gGLHExts.mSysExts);
|
||||
std::string all_exts= ll_safe_string(((const char *)gGLHExts.mSysExts));
|
||||
LLStringUtil::replaceChar(all_exts, ' ', '\n');
|
||||
LL_DEBUGS("RenderInit") << "GL_EXTENSIONS:\n" << all_exts << LL_ENDL;
|
||||
#endif
|
||||
@@ -615,6 +674,8 @@ void LLGLManager::initExtensions()
|
||||
mHasTextureRectangle = FALSE;
|
||||
#else // LL_MESA_HEADLESS
|
||||
mHasMultitexture = glh_init_extensions("GL_ARB_multitexture");
|
||||
mHasATIMemInfo = ExtensionExists("GL_ATI_meminfo", gGLHExts.mSysExts);
|
||||
mHasNVXMemInfo = ExtensionExists("GL_NVX_gpu_memory_info", gGLHExts.mSysExts);
|
||||
mHasMipMapGeneration = glh_init_extensions("GL_SGIS_generate_mipmap");
|
||||
mHasSeparateSpecularColor = glh_init_extensions("GL_EXT_separate_specular_color");
|
||||
mHasAnisotropic = glh_init_extensions("GL_EXT_texture_filter_anisotropic");
|
||||
@@ -626,9 +687,15 @@ void LLGLManager::initExtensions()
|
||||
mHasOcclusionQuery2 = ExtensionExists("GL_ARB_occlusion_query2", gGLHExts.mSysExts);
|
||||
mHasVertexBufferObject = ExtensionExists("GL_ARB_vertex_buffer_object", gGLHExts.mSysExts);
|
||||
mHasDepthClamp = ExtensionExists("GL_ARB_depth_clamp", gGLHExts.mSysExts) || ExtensionExists("GL_NV_depth_clamp", gGLHExts.mSysExts);
|
||||
// mask out FBO support when packed_depth_stencil isn't there 'cause we need it for LLRenderTarget -Brad
|
||||
mHasFramebufferObject = ExtensionExists("GL_EXT_framebuffer_object", gGLHExts.mSysExts)
|
||||
&& ExtensionExists("GL_EXT_packed_depth_stencil", gGLHExts.mSysExts);
|
||||
// mask out FBO support when packed_depth_stencil isn't there 'cause we need it for LLRenderTarget -Brad
|
||||
#ifdef GL_ARB_framebuffer_object
|
||||
mHasFramebufferObject = ExtensionExists("GL_ARB_framebuffer_object", gGLHExts.mSysExts);
|
||||
#else
|
||||
mHasFramebufferObject = ExtensionExists("GL_EXT_framebuffer_object", gGLHExts.mSysExts) &&
|
||||
ExtensionExists("GL_EXT_framebuffer_blit", gGLHExts.mSysExts) &&
|
||||
ExtensionExists("GL_EXT_framebuffer_multisample", gGLHExts.mSysExts) &&
|
||||
ExtensionExists("GL_EXT_packed_depth_stencil", gGLHExts.mSysExts);
|
||||
#endif
|
||||
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);
|
||||
@@ -832,11 +899,9 @@ void LLGLManager::initExtensions()
|
||||
glFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) GLH_EXT_GET_PROC_ADDRESS("glFramebufferRenderbufferEXT");
|
||||
glGetFramebufferAttachmentParameterivEXT = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glGetFramebufferAttachmentParameterivEXT");
|
||||
glGenerateMipmapEXT = (PFNGLGENERATEMIPMAPEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glGenerateMipmapEXT");
|
||||
}
|
||||
if (mHasFramebufferMultisample)
|
||||
{
|
||||
glRenderbufferStorageMultisampleEXT = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glRenderbufferStorageMultisampleEXT");
|
||||
glBlitFramebufferEXT = (PFNGLBLITFRAMEBUFFEREXTPROC) GLH_EXT_GET_PROC_ADDRESS("glBlitFramebufferEXT");
|
||||
glRenderbufferStorageMultisampleEXT = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glRenderbufferStorageMultisampleEXT");
|
||||
glFramebufferTextureLayerEXT = (PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) GLH_EXT_GET_PROC_ADDRESS("glFramebufferTextureLayerEXT");
|
||||
}
|
||||
if (mHasDrawBuffers)
|
||||
{
|
||||
@@ -1008,12 +1073,35 @@ void flush_glerror()
|
||||
glGetError();
|
||||
}
|
||||
|
||||
void assert_glerror()
|
||||
//this function outputs gl error to the log file, does not crash the code.
|
||||
void log_glerror()
|
||||
{
|
||||
if (gNoRender || !gDebugGL)
|
||||
if (LL_UNLIKELY(!gGLManager.mInited))
|
||||
{
|
||||
return;
|
||||
return ;
|
||||
}
|
||||
// Create or update texture to be used with this data
|
||||
GLenum error;
|
||||
error = glGetError();
|
||||
while (LL_UNLIKELY(error))
|
||||
{
|
||||
GLubyte const * gl_error_msg = gluErrorString(error);
|
||||
if (NULL != gl_error_msg)
|
||||
{
|
||||
llwarns << "GL Error: " << error << " GL Error String: " << gl_error_msg << llendl ;
|
||||
}
|
||||
else
|
||||
{
|
||||
// gluErrorString returns NULL for some extensions' error codes.
|
||||
// you'll probably have to grep for the number in glext.h.
|
||||
llwarns << "GL Error: UNKNOWN 0x" << std::hex << error << std::dec << llendl;
|
||||
}
|
||||
error = glGetError();
|
||||
}
|
||||
}
|
||||
|
||||
void do_assert_glerror()
|
||||
{
|
||||
if (LL_UNLIKELY(!gGLManager.mInited))
|
||||
{
|
||||
LL_ERRS("RenderInit") << "GL not initialized" << LL_ENDL;
|
||||
@@ -1025,29 +1113,65 @@ void assert_glerror()
|
||||
while (LL_UNLIKELY(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)
|
||||
{
|
||||
LL_WARNS("RenderState") << "GL Error:" << error<< LL_ENDL;
|
||||
LL_WARNS("RenderState") << "GL Error String:" << gl_error_msg << LL_ENDL;
|
||||
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "GL Error:" << gl_error_msg << std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// gluErrorString returns NULL for some extensions' error codes.
|
||||
// you'll probably have to grep for the number in glext.h.
|
||||
LL_WARNS("RenderState") << "GL Error: UNKNOWN 0x" << std::hex << error << std::dec << LL_ENDL;
|
||||
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "GL Error: UNKNOWN 0x" << std::hex << error << std::dec << std::endl;
|
||||
}
|
||||
}
|
||||
error = glGetError();
|
||||
#endif
|
||||
}
|
||||
|
||||
if (quit)
|
||||
{
|
||||
llerrs << "One or more unhandled GL errors." << llendl;
|
||||
if (gDebugSession)
|
||||
{
|
||||
ll_fail("assert_glerror failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
llerrs << "One or more unhandled GL errors." << llendl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void assert_glerror()
|
||||
{
|
||||
if (gNoRender)
|
||||
return;
|
||||
if (!gGLActive)
|
||||
{
|
||||
//llwarns << "GL used while not active!" << llendl;
|
||||
|
||||
if (gDebugSession)
|
||||
{
|
||||
//ll_fail("GL used while not active");
|
||||
}
|
||||
}
|
||||
|
||||
if (gDebugGL)
|
||||
{
|
||||
do_assert_glerror();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void clear_glerror()
|
||||
{
|
||||
// Create or update texture to be used with this data
|
||||
@@ -1130,9 +1254,19 @@ void LLGLState::checkStates(const std::string& msg)
|
||||
glGetIntegerv(GL_BLEND_SRC, &src);
|
||||
glGetIntegerv(GL_BLEND_DST, &dst);
|
||||
|
||||
BOOL error = FALSE;
|
||||
|
||||
if (src != GL_SRC_ALPHA || dst != GL_ONE_MINUS_SRC_ALPHA)
|
||||
{
|
||||
LL_GL_ERRS << "Blend function corrupted: " << std::hex << src << " " << std::hex << dst << " " << msg << std::dec << LL_ENDL;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "Blend function corrupted: " << std::hex << src << " " << std::hex << dst << " " << msg << std::dec << std::endl;
|
||||
error = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_GL_ERRS << "Blend function corrupted: " << std::hex << src << " " << std::hex << dst << " " << msg << std::dec << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
for (boost::unordered_map<LLGLenum, LLGLboolean>::iterator iter = sStateMap.begin();
|
||||
@@ -1144,10 +1278,22 @@ void LLGLState::checkStates(const std::string& msg)
|
||||
if(cur_state != gl_state)
|
||||
{
|
||||
dumpStates();
|
||||
LL_GL_ERRS << llformat("LLGLState error. State: 0x%04x",state) << LL_ENDL;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << llformat("LLGLState error. State: 0x%04x",state) << std::endl;
|
||||
error = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_GL_ERRS << llformat("LLGLState error. State: 0x%04x",state) << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (error)
|
||||
{
|
||||
ll_fail("LLGLState::checkStates failed.");
|
||||
}
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
@@ -1158,9 +1304,12 @@ void LLGLState::checkTextureChannels(const std::string& msg)
|
||||
return;
|
||||
}
|
||||
|
||||
stop_glerror();
|
||||
|
||||
GLint activeTexture;
|
||||
glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &activeTexture);
|
||||
|
||||
stop_glerror();
|
||||
|
||||
BOOL error = FALSE;
|
||||
|
||||
if (activeTexture == GL_TEXTURE0_ARB)
|
||||
@@ -1168,15 +1317,22 @@ void LLGLState::checkTextureChannels(const std::string& msg)
|
||||
GLint tex_env_mode = 0;
|
||||
|
||||
glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &tex_env_mode);
|
||||
stop_glerror();
|
||||
|
||||
if (tex_env_mode != GL_MODULATE)
|
||||
{
|
||||
error = TRUE;
|
||||
LL_WARNS("RenderState") << "GL_TEXTURE_ENV_MODE invalid: " << std::hex << tex_env_mode << std::dec << LL_ENDL;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "GL_TEXTURE_ENV_MODE invalid: " << std::hex << tex_env_mode << std::dec << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GLint maxTextureUnits = 0;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &maxTextureUnits);
|
||||
stop_glerror();
|
||||
|
||||
static const char* label[] =
|
||||
{
|
||||
@@ -1205,35 +1361,44 @@ void LLGLState::checkTextureChannels(const std::string& msg)
|
||||
};
|
||||
|
||||
GLint stackDepth = 0;
|
||||
|
||||
glh::matrix4f mat;
|
||||
glh::matrix4f identity;
|
||||
identity.identity();
|
||||
// LLMatrix4 identity;
|
||||
// LLMatrix4 matrix;
|
||||
|
||||
for (GLint i = 1; i < maxTextureUnits; i++)
|
||||
{
|
||||
gGL.getTexUnit(i)->activate();
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB+i);
|
||||
|
||||
stop_glerror();
|
||||
glGetIntegerv(GL_TEXTURE_STACK_DEPTH, &stackDepth);
|
||||
stop_glerror();
|
||||
|
||||
if (stackDepth != 1)
|
||||
{
|
||||
error = TRUE;
|
||||
LL_WARNS("RenderState") << "Texture matrix stack corrupted." << LL_ENDL;
|
||||
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "Texture matrix stack corrupted." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
//glGetFloatv(GL_TEXTURE_MATRIX, (GLfloat*) matrix.mMatrix);
|
||||
glGetFloatv(GL_TEXTURE_MATRIX, (GLfloat*) mat.m);
|
||||
stop_glerror();
|
||||
|
||||
//if (matrix != identity)
|
||||
if (mat != identity)
|
||||
{
|
||||
error = TRUE;
|
||||
LL_WARNS("RenderState") << "Texture matrix in channel " << i << " corrupt." << LL_ENDL;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "Texture matrix in channel " << i << " corrupt." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (S32 j = (i == 0 ? 1 : 0);
|
||||
j < (gGLManager.mHasTextureRectangle ? 9 : 8); j++)
|
||||
{
|
||||
@@ -1241,24 +1406,42 @@ void LLGLState::checkTextureChannels(const std::string& msg)
|
||||
{
|
||||
error = TRUE;
|
||||
LL_WARNS("RenderState") << "Texture channel " << i << " still has " << label[j] << " enabled." << LL_ENDL;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "Texture channel " << i << " still has " << label[j] << " enabled." << std::endl;
|
||||
}
|
||||
}
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
glGetFloatv(GL_TEXTURE_MATRIX, mat.m);
|
||||
stop_glerror();
|
||||
|
||||
if (mat != identity)
|
||||
{
|
||||
error = TRUE;
|
||||
LL_WARNS("RenderState") << "Texture matrix " << i << " is not identity." << LL_ENDL;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "Texture matrix " << i << " is not identity." << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gGL.getTexUnit(0)->activate();
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
stop_glerror();
|
||||
|
||||
if (error)
|
||||
{
|
||||
LL_GL_ERRS << "GL texture state corruption detected. " << msg << LL_ENDL;
|
||||
if (gDebugSession)
|
||||
{
|
||||
ll_fail("LLGLState::checkTextureChannels failed.");
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_GL_ERRS << "GL texture state corruption detected. " << msg << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1278,6 +1461,10 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
|
||||
if (active_texture != GL_TEXTURE0_ARB)
|
||||
{
|
||||
llwarns << "Client active texture corrupted: " << active_texture << llendl;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "Client active texture corrupted: " << active_texture << std::endl;
|
||||
}
|
||||
error = TRUE;
|
||||
}
|
||||
|
||||
@@ -1285,6 +1472,10 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
|
||||
if (active_texture != GL_TEXTURE0_ARB)
|
||||
{
|
||||
llwarns << "Active texture corrupted: " << active_texture << llendl;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "Active texture corrupted: " << active_texture << std::endl;
|
||||
}
|
||||
error = TRUE;
|
||||
}
|
||||
|
||||
@@ -1321,6 +1512,10 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
|
||||
{
|
||||
error = TRUE;
|
||||
LL_WARNS("RenderState") << "GL still has " << label[j] << " enabled." << LL_ENDL;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "GL still has " << label[j] << " enabled." << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1329,6 +1524,10 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
|
||||
{
|
||||
error = TRUE;
|
||||
LL_WARNS("RenderState") << "GL does not have " << label[j] << " enabled." << LL_ENDL;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "GL does not have " << label[j] << " enabled." << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1341,6 +1540,10 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
|
||||
{
|
||||
error = TRUE;
|
||||
LL_WARNS("RenderState") << "GL still has GL_TEXTURE_COORD_ARRAY enabled on channel 1." << LL_ENDL;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "GL still has GL_TEXTURE_COORD_ARRAY enabled on channel 1." << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1349,6 +1552,10 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
|
||||
{
|
||||
error = TRUE;
|
||||
LL_WARNS("RenderState") << "GL does not have GL_TEXTURE_COORD_ARRAY enabled on channel 1." << LL_ENDL;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "GL does not have GL_TEXTURE_COORD_ARRAY enabled on channel 1." << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1358,6 +1565,10 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
|
||||
{
|
||||
error = TRUE;
|
||||
LL_WARNS("RenderState") << "GL still has GL_TEXTURE_2D enabled on channel 1." << LL_ENDL;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "GL still has GL_TEXTURE_2D enabled on channel 1." << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1366,6 +1577,10 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
|
||||
{
|
||||
error = TRUE;
|
||||
LL_WARNS("RenderState") << "GL does not have GL_TEXTURE_2D enabled on channel 1." << LL_ENDL;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "GL does not have GL_TEXTURE_2D enabled on channel 1." << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1384,13 +1599,24 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
|
||||
{
|
||||
error = TRUE;
|
||||
LL_WARNS("RenderState") << "GL still has vertex attrib array " << i << " enabled." << LL_ENDL;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "GL still has vertex attrib array " << i << " enabled." << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (error)
|
||||
{
|
||||
if (gDebugSession)
|
||||
{
|
||||
ll_fail("LLGLState::checkClientArrays failed.");
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_GL_ERRS << "GL client array corruption detected. " << msg << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1441,7 +1667,17 @@ LLGLState::~LLGLState()
|
||||
{
|
||||
if (gDebugGL)
|
||||
{
|
||||
if (!gDebugSession)
|
||||
{
|
||||
llassert_always(sStateMap[mState] == glIsEnabled(mState));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sStateMap[mState] != glIsEnabled(mState))
|
||||
{
|
||||
ll_fail("GL enabled state does not match expected");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mIsEnabled != mWasEnabled)
|
||||
@@ -1839,6 +2075,11 @@ void LLGLDepthTest::checkState()
|
||||
sWriteEnabled != mask ||
|
||||
sDepthFunc != func)
|
||||
{
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "Unexpected depth testing state." << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_GL_ERRS << "Unexpected depth testing state." << LL_ENDL;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
#include <string>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include <map>
|
||||
#include <list>
|
||||
|
||||
#include "llerror.h"
|
||||
#include "v4color.h"
|
||||
@@ -52,9 +52,17 @@
|
||||
#include "glh/glh_linear.h"
|
||||
|
||||
extern BOOL gDebugGL;
|
||||
extern BOOL gDebugSession;
|
||||
extern std::ofstream gFailLog;
|
||||
|
||||
#define LL_GL_ERRS LL_ERRS("RenderState")
|
||||
|
||||
void ll_init_fail_log(std::string filename);
|
||||
|
||||
void ll_fail(std::string msg);
|
||||
|
||||
void ll_close_fail_log();
|
||||
|
||||
class LLSD;
|
||||
|
||||
// Manage GL extensions...
|
||||
@@ -75,6 +83,8 @@ public:
|
||||
|
||||
// Extensions used by everyone
|
||||
BOOL mHasMultitexture;
|
||||
BOOL mHasATIMemInfo;
|
||||
BOOL mHasNVXMemInfo;
|
||||
S32 mNumTextureUnits;
|
||||
BOOL mHasMipMapGeneration;
|
||||
BOOL mHasCompressedTextures;
|
||||
@@ -88,6 +98,7 @@ public:
|
||||
BOOL mHasShaderObjects;
|
||||
BOOL mHasVertexShader;
|
||||
BOOL mHasFragmentShader;
|
||||
S32 mNumTextureImageUnits;
|
||||
BOOL mHasOcclusionQuery;
|
||||
BOOL mHasOcclusionQuery2;
|
||||
BOOL mHasPointParameters;
|
||||
@@ -154,6 +165,7 @@ void rotate_quat(LLQuaternion& rotation);
|
||||
|
||||
void flush_glerror(); // Flush GL errors when we know we're handling them correctly.
|
||||
|
||||
void log_glerror();
|
||||
void assert_glerror();
|
||||
|
||||
void clear_glerror();
|
||||
@@ -415,4 +427,66 @@ extern BOOL gClothRipple;
|
||||
extern BOOL gNoRender;
|
||||
extern BOOL gGLActive;
|
||||
|
||||
// Deal with changing glext.h definitions for newer SDK versions, specifically
|
||||
// with MAC OSX 10.5 -> 10.6
|
||||
|
||||
|
||||
#ifndef GL_DEPTH_ATTACHMENT
|
||||
#define GL_DEPTH_ATTACHMENT GL_DEPTH_ATTACHMENT_EXT
|
||||
#endif
|
||||
|
||||
#ifndef GL_STENCIL_ATTACHMENT
|
||||
#define GL_STENCIL_ATTACHMENT GL_STENCIL_ATTACHMENT_EXT
|
||||
#endif
|
||||
|
||||
#ifndef GL_FRAMEBUFFER
|
||||
#define GL_FRAMEBUFFER GL_FRAMEBUFFER_EXT
|
||||
#define GL_DRAW_FRAMEBUFFER GL_DRAW_FRAMEBUFFER_EXT
|
||||
#define GL_READ_FRAMEBUFFER GL_READ_FRAMEBUFFER_EXT
|
||||
#define GL_FRAMEBUFFER_COMPLETE GL_FRAMEBUFFER_COMPLETE_EXT
|
||||
#define GL_FRAMEBUFFER_UNSUPPORTED GL_FRAMEBUFFER_UNSUPPORTED_EXT
|
||||
#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT
|
||||
#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT
|
||||
#define glGenFramebuffers glGenFramebuffersEXT
|
||||
#define glBindFramebuffer glBindFramebufferEXT
|
||||
#define glCheckFramebufferStatus glCheckFramebufferStatusEXT
|
||||
#define glBlitFramebuffer glBlitFramebufferEXT
|
||||
#define glDeleteFramebuffers glDeleteFramebuffersEXT
|
||||
#define glFramebufferRenderbuffer glFramebufferRenderbufferEXT
|
||||
#define glFramebufferTexture2D glFramebufferTexture2DEXT
|
||||
#endif
|
||||
|
||||
#ifndef GL_RENDERBUFFER
|
||||
#define GL_RENDERBUFFER GL_RENDERBUFFER_EXT
|
||||
#define glGenRenderbuffers glGenRenderbuffersEXT
|
||||
#define glBindRenderbuffer glBindRenderbufferEXT
|
||||
#define glRenderbufferStorage glRenderbufferStorageEXT
|
||||
#define glRenderbufferStorageMultisample glRenderbufferStorageMultisampleEXT
|
||||
#define glDeleteRenderbuffers glDeleteRenderbuffersEXT
|
||||
#endif
|
||||
|
||||
#ifndef GL_COLOR_ATTACHMENT
|
||||
#define GL_COLOR_ATTACHMENT GL_COLOR_ATTACHMENT_EXT
|
||||
#endif
|
||||
|
||||
#ifndef GL_COLOR_ATTACHMENT0
|
||||
#define GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_EXT
|
||||
#endif
|
||||
|
||||
#ifndef GL_COLOR_ATTACHMENT1
|
||||
#define GL_COLOR_ATTACHMENT1 GL_COLOR_ATTACHMENT1_EXT
|
||||
#endif
|
||||
|
||||
#ifndef GL_COLOR_ATTACHMENT2
|
||||
#define GL_COLOR_ATTACHMENT2 GL_COLOR_ATTACHMENT2_EXT
|
||||
#endif
|
||||
|
||||
#ifndef GL_COLOR_ATTACHMENT3
|
||||
#define GL_COLOR_ATTACHMENT3 GL_COLOR_ATTACHMENT3_EXT
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef GL_DEPTH24_STENCIL8
|
||||
#define GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8_EXT
|
||||
#endif
|
||||
#endif // LL_LLGL_H
|
||||
|
||||
@@ -473,17 +473,17 @@ extern PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glFramebufferTexture3DEXT;
|
||||
extern PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT;
|
||||
extern PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glGetFramebufferAttachmentParameterivEXT;
|
||||
extern PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT;
|
||||
|
||||
// GL_EXT_framebuffer_multisample
|
||||
extern PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT;
|
||||
|
||||
// GL_EXT_framebuffer_blit
|
||||
extern PFNGLBLITFRAMEBUFFEREXTPROC glBlitFramebufferEXT;
|
||||
extern PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT;
|
||||
extern PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC glFramebufferTextureLayerEXT;
|
||||
|
||||
//GL_ARB_draw_buffers
|
||||
extern PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB;
|
||||
|
||||
|
||||
#elif LL_WINDOWS
|
||||
//----------------------------------------------------------------------------
|
||||
// LL_WINDOWS
|
||||
|
||||
// windows gl headers depend on things like APIENTRY, so include windows.
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
@@ -672,12 +672,9 @@ extern PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glFramebufferTexture3DEXT;
|
||||
extern PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT;
|
||||
extern PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glGetFramebufferAttachmentParameterivEXT;
|
||||
extern PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT;
|
||||
|
||||
// GL_EXT_framebuffer_multisample
|
||||
extern PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT;
|
||||
|
||||
// GL_EXT_framebuffer_blit
|
||||
extern PFNGLBLITFRAMEBUFFEREXTPROC glBlitFramebufferEXT;
|
||||
extern PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT;
|
||||
extern PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC glFramebufferTextureLayerEXT;
|
||||
|
||||
//GL_ARB_draw_buffers
|
||||
extern PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB;
|
||||
@@ -720,6 +717,9 @@ extern void glFramebufferRenderbufferEXT(GLenum target, GLenum attachment, GLenu
|
||||
extern void glGetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment, GLenum pname, GLint *params) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
|
||||
extern void glGenerateMipmapEXT(GLenum target) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
|
||||
|
||||
#ifndef GL_ARB_framebuffer_object
|
||||
#define glGenerateMipmap glGenerateMipmapEXT
|
||||
#endif
|
||||
// GL_ARB_draw_buffers
|
||||
extern void glDrawBuffersARB(GLsizei n, const GLenum* bufs) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
|
||||
|
||||
@@ -842,4 +842,21 @@ extern void glGetBufferPointervARB (GLenum, GLenum, GLvoid* *);
|
||||
#define GL_DEPTH_CLAMP 0x864F
|
||||
#endif
|
||||
|
||||
//GL_NVX_gpu_memory_info constants
|
||||
#ifndef GL_NVX_gpu_memory_info
|
||||
#define GL_NVX_gpu_memory_info
|
||||
#define GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX 0x9047
|
||||
#define GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX 0x9048
|
||||
#define GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX 0x9049
|
||||
#define GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX 0x904A
|
||||
#define GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX 0x904B
|
||||
#endif
|
||||
|
||||
//GL_ATI_meminfo constants
|
||||
#ifndef GL_ATI_meminfo
|
||||
#define GL_ATI_meminfo
|
||||
#define GL_VBO_FREE_MEMORY_ATI 0x87FB
|
||||
#define GL_TEXTURE_FREE_MEMORY_ATI 0x87FC
|
||||
#define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD
|
||||
#endif
|
||||
#endif // LL_LLGLHEADERS_H
|
||||
|
||||
@@ -420,7 +420,15 @@ S32 LLGLSLShader::disableTexture(S32 uniform, LLTexUnit::eTextureType mode)
|
||||
{
|
||||
if (gDebugGL && gGL.getTexUnit(index)->getCurrType() != mode)
|
||||
{
|
||||
llerrs << "Texture channel " << index << " texture type corrupted." << llendl;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "Texture channel " << index << " texture type corrupted." << std::endl;
|
||||
ll_fail("LLGLSLShader::disableTexture failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
llerrs << "Texture channel " << index << " texture type corrupted." << llendl;
|
||||
}
|
||||
}
|
||||
gGL.getTexUnit(index)->disable();
|
||||
}
|
||||
@@ -708,16 +716,34 @@ void LLGLSLShader::uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, c
|
||||
|
||||
GLint LLGLSLShader::getUniformLocation(const string& uniform)
|
||||
{
|
||||
GLint ret = -1;
|
||||
if (mProgramObject > 0)
|
||||
{
|
||||
std::map<string, GLint>::iterator iter = mUniformMap.find(uniform);
|
||||
if (iter != mUniformMap.end())
|
||||
{
|
||||
llassert(iter->second == glGetUniformLocationARB(mProgramObject, uniform.c_str()));
|
||||
return iter->second;
|
||||
if (gDebugGL)
|
||||
{
|
||||
stop_glerror();
|
||||
if (iter->second != glGetUniformLocationARB(mProgramObject, uniform.c_str()))
|
||||
{
|
||||
llerrs << "Uniform does not match." << llendl;
|
||||
}
|
||||
stop_glerror();
|
||||
}
|
||||
ret = iter->second;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
|
||||
/*if (gDebugGL)
|
||||
{
|
||||
if (ret == -1 && ret != glGetUniformLocationARB(mProgramObject, uniform.c_str()))
|
||||
{
|
||||
llerrs << "Uniform map invalid." << llendl;
|
||||
}
|
||||
}*/
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
GLint LLGLSLShader::getAttribLocation(U32 attrib)
|
||||
@@ -903,7 +929,9 @@ void LLGLSLShader::uniformMatrix4fv(const string& uniform, U32 count, GLboolean
|
||||
|
||||
if (location >= 0)
|
||||
{
|
||||
stop_glerror();
|
||||
glUniformMatrix4fvARB(location, count, transpose, v);
|
||||
stop_glerror();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -110,24 +110,58 @@ void LLImageGL::checkTexSize(bool forced) const
|
||||
{
|
||||
if ((forced || gDebugGL) && mTarget == GL_TEXTURE_2D)
|
||||
{
|
||||
{
|
||||
//check viewport
|
||||
GLint vp[4] ;
|
||||
glGetIntegerv(GL_VIEWPORT, vp) ;
|
||||
llcallstacks << "viewport: " << vp[0] << " : " << vp[1] << " : " << vp[2] << " : " << vp[3] << llcallstacksendl ;
|
||||
}
|
||||
GLint texname;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &texname);
|
||||
BOOL error = FALSE;
|
||||
if (texname != mTexName)
|
||||
{
|
||||
llerrs << "Invalid texture bound!" << llendl;
|
||||
llinfos << "Bound: " << texname << " Should bind: " << mTexName << " Default: " << LLImageGL::sDefaultGLTexture->getTexName() << llendl;
|
||||
|
||||
error = TRUE;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "Invalid texture bound!" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
llerrs << "Invalid texture bound!" << llendl;
|
||||
}
|
||||
}
|
||||
stop_glerror() ;
|
||||
LLGLint x = 0, y = 0 ;
|
||||
glGetTexLevelParameteriv(mTarget, 0, GL_TEXTURE_WIDTH, (GLint*)&x);
|
||||
glGetTexLevelParameteriv(mTarget, 0, GL_TEXTURE_HEIGHT, (GLint*)&y) ;
|
||||
stop_glerror() ;
|
||||
llcallstacks << "w: " << x << " h: " << y << llcallstacksendl ;
|
||||
|
||||
if(!x || !y)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
if(x != (mWidth >> mCurrentDiscardLevel) || y != (mHeight >> mCurrentDiscardLevel))
|
||||
{
|
||||
llerrs << "wrong texture size and discard level!" << llendl ;
|
||||
error = TRUE;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "wrong texture size and discard level!" <<
|
||||
mWidth << " Height: " << mHeight << " Current Level: " << (S32)mCurrentDiscardLevel << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
llerrs << "wrong texture size and discard level: width: " <<
|
||||
mWidth << " Height: " << mHeight << " Current Level: " << (S32)mCurrentDiscardLevel << llendl ;
|
||||
}
|
||||
}
|
||||
|
||||
if (error)
|
||||
{
|
||||
ll_fail("LLImageGL::checkTexSize failed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -649,7 +683,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
|
||||
}
|
||||
|
||||
// LLFastTimer t2(LLFastTimer::FTM_TEMP2);
|
||||
gGL.getTexUnit(0)->bind(this);
|
||||
llverify(gGL.getTexUnit(0)->bind(this));
|
||||
|
||||
if (mUseMipMaps)
|
||||
{
|
||||
@@ -864,12 +898,14 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
|
||||
}
|
||||
if (mTexName == 0)
|
||||
{
|
||||
llwarns << "Setting subimage on image without GL texture" << llendl;
|
||||
// *TODO: Re-enable warning? Ran into thread locking issues? DK 2011-02-18
|
||||
//llwarns << "Setting subimage on image without GL texture" << llendl;
|
||||
return FALSE;
|
||||
}
|
||||
if (datap == NULL)
|
||||
{
|
||||
llwarns << "Setting subimage on image with NULL datap" << llendl;
|
||||
// *TODO: Re-enable warning? Ran into thread locking issues? DK 2011-02-18
|
||||
//llwarns << "Setting subimage on image with NULL datap" << llendl;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -991,6 +1027,7 @@ void LLImageGL::deleteTextures(S32 numTextures, U32 *textures)
|
||||
void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels)
|
||||
{
|
||||
glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, pixels);
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
//create an empty GL texture: just create a texture name
|
||||
@@ -1143,6 +1180,13 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
|
||||
if (mUseMipMaps)
|
||||
{
|
||||
mAutoGenMips = gGLManager.mHasMipMapGeneration;
|
||||
#if LL_DARWIN
|
||||
// On the Mac GF2 and GF4MX drivers, auto mipmap generation doesn't work right with alpha-only textures.
|
||||
if(gGLManager.mIsGF2or4MX && (mFormatInternal == GL_ALPHA8) && (mFormatPrimary == GL_ALPHA))
|
||||
{
|
||||
mAutoGenMips = FALSE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
mCurrentDiscardLevel = discard_level;
|
||||
|
||||
@@ -120,14 +120,29 @@ void LLTexUnit::refreshState(void)
|
||||
// and we reset the cached tex unit state
|
||||
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB + mIndex);
|
||||
|
||||
//
|
||||
// Per apple spec, don't call glEnable/glDisable when index exceeds max texture units
|
||||
// http://www.mailinglistarchive.com/html/mac-opengl@lists.apple.com/2008-07/msg00653.html
|
||||
//
|
||||
bool enableDisable = (mIndex < gGLManager.mNumTextureUnits);
|
||||
|
||||
if (mCurrTexType != TT_NONE)
|
||||
{
|
||||
glEnable(sGLTextureType[mCurrTexType]);
|
||||
if (enableDisable)
|
||||
{
|
||||
glEnable(sGLTextureType[mCurrTexType]);
|
||||
}
|
||||
|
||||
glBindTexture(sGLTextureType[mCurrTexType], mCurrTexture);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
if (enableDisable)
|
||||
{
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
@@ -165,7 +180,10 @@ void LLTexUnit::enable(eTextureType type)
|
||||
disable(); // Force a disable of a previous texture type if it's enabled.
|
||||
}
|
||||
mCurrTexType = type;
|
||||
glEnable(sGLTextureType[type]);
|
||||
if (mIndex < gGLManager.mNumTextureUnits)
|
||||
{
|
||||
glEnable(sGLTextureType[type]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,7 +195,11 @@ void LLTexUnit::disable(void)
|
||||
{
|
||||
activate();
|
||||
unbind(mCurrTexType);
|
||||
glDisable(sGLTextureType[mCurrTexType]);
|
||||
if (mIndex < gGLManager.mNumTextureUnits)
|
||||
{
|
||||
glDisable(sGLTextureType[mCurrTexType]);
|
||||
}
|
||||
|
||||
mCurrTexType = TT_NONE;
|
||||
}
|
||||
}
|
||||
@@ -1078,6 +1100,7 @@ void LLRender::blendFunc(eBlendFactor color_sfactor, eBlendFactor color_dfactor,
|
||||
sGLBlendFactor[alpha_sfactor], sGLBlendFactor[alpha_dfactor]);
|
||||
}
|
||||
}
|
||||
|
||||
LLTexUnit* LLRender::getTexUnit(U32 index)
|
||||
{
|
||||
if ((index >= 0) && (index < mTexUnits.size()))
|
||||
@@ -1205,6 +1228,34 @@ void LLRender::flush()
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
if (gDebugGL)
|
||||
{
|
||||
if (mMode == LLRender::QUADS)
|
||||
{
|
||||
if (mCount%4 != 0)
|
||||
{
|
||||
llerrs << "Incomplete quad rendered." << llendl;
|
||||
}
|
||||
}
|
||||
|
||||
if (mMode == LLRender::TRIANGLES)
|
||||
{
|
||||
if (mCount%3 != 0)
|
||||
{
|
||||
llerrs << "Incomplete triangle rendered." << llendl;
|
||||
}
|
||||
}
|
||||
|
||||
if (mMode == LLRender::LINES)
|
||||
{
|
||||
if (mCount%2 != 0)
|
||||
{
|
||||
llerrs << "Incomplete line rendered." << llendl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mBuffer->setBuffer(immediate_mask);
|
||||
mBuffer->drawArrays(mMode, 0, mCount);
|
||||
|
||||
|
||||
@@ -36,6 +36,9 @@
|
||||
#include "llrender.h"
|
||||
#include "llgl.h"
|
||||
|
||||
LLRenderTarget* LLRenderTarget::sBoundTarget = NULL;
|
||||
|
||||
|
||||
|
||||
void check_framebuffer_status()
|
||||
{
|
||||
@@ -212,6 +215,16 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target)
|
||||
llerrs << "Cannot share depth buffer between non FBO render targets." << llendl;
|
||||
}
|
||||
|
||||
if (target.mDepth)
|
||||
{
|
||||
llerrs << "Attempting to override existing depth buffer. Detach existing buffer first." << llendl;
|
||||
}
|
||||
|
||||
if (target.mUseDepth)
|
||||
{
|
||||
llerrs << "Attempting to override existing shared depth buffer. Detach existing buffer first." << llendl;
|
||||
}
|
||||
|
||||
if (mDepth)
|
||||
{
|
||||
stop_glerror();
|
||||
@@ -230,11 +243,6 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target)
|
||||
{
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, LLTexUnit::getInternalType(mUsage), mDepth, 0);
|
||||
stop_glerror();
|
||||
if (mStencil)
|
||||
{
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, LLTexUnit::getInternalType(mUsage), mDepth, 0);
|
||||
stop_glerror();
|
||||
}
|
||||
}
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
|
||||
@@ -285,7 +293,9 @@ void LLRenderTarget::release()
|
||||
LLImageGL::deleteTextures(mTex.size(), &mTex[0]);
|
||||
mTex.clear();
|
||||
}
|
||||
|
||||
mSampleBuffer = NULL;
|
||||
sBoundTarget = NULL;
|
||||
}
|
||||
|
||||
void LLRenderTarget::bindTarget()
|
||||
@@ -324,6 +334,7 @@ void LLRenderTarget::bindTarget()
|
||||
}
|
||||
|
||||
glViewport(0, 0, mResX, mResY);
|
||||
sBoundTarget = this;
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -333,6 +344,7 @@ void LLRenderTarget::unbindTarget()
|
||||
{
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
}
|
||||
sBoundTarget = NULL;
|
||||
}
|
||||
|
||||
void LLRenderTarget::clear(U32 mask_in)
|
||||
@@ -399,7 +411,11 @@ void LLRenderTarget::flush(bool fetch_depth)
|
||||
}
|
||||
else
|
||||
{
|
||||
stop_glerror();
|
||||
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
|
||||
stop_glerror();
|
||||
|
||||
if (mSampleBuffer)
|
||||
{
|
||||
@@ -607,6 +623,7 @@ void LLMultisampleBuffer::bindTarget(LLRenderTarget* ref)
|
||||
|
||||
glViewport(0, 0, mResX, mResY);
|
||||
|
||||
sBoundTarget = this;
|
||||
}
|
||||
|
||||
void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo )
|
||||
|
||||
@@ -144,6 +144,8 @@ public:
|
||||
//one renderable attachment (i.e. color buffer, depth buffer).
|
||||
bool isComplete() const;
|
||||
|
||||
static LLRenderTarget* getCurrentBoundTarget() { return sBoundTarget; }
|
||||
|
||||
protected:
|
||||
friend class LLMultisampleBuffer;
|
||||
U32 mResX;
|
||||
@@ -157,6 +159,8 @@ protected:
|
||||
LLTexUnit::eTextureType mUsage;
|
||||
U32 mSamples;
|
||||
LLMultisampleBuffer* mSampleBuffer;
|
||||
|
||||
static LLRenderTarget* sBoundTarget;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -313,7 +313,7 @@ void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns)
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS("ShaderLoading") << log << LL_ENDL;
|
||||
LL_INFOS("ShaderLoading") << log << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,13 +31,13 @@
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
#include "llmemory.h"
|
||||
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
#include "llsys.h"
|
||||
#include "llvertexbuffer.h"
|
||||
// #include "llrender.h"
|
||||
#include "llglheaders.h"
|
||||
#include "llmemory.h"
|
||||
#include "llmemtype.h"
|
||||
#include "llrender.h"
|
||||
|
||||
@@ -141,6 +141,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
|
||||
GL_COLOR_ARRAY,
|
||||
};
|
||||
|
||||
BOOL error = FALSE;
|
||||
for (U32 i = 0; i < 4; ++i)
|
||||
{
|
||||
if (sLastMask & mask[i])
|
||||
@@ -153,7 +154,15 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
|
||||
{ //needs to be enabled, make sure it was (DEBUG TEMPORARY)
|
||||
if (i > 0 && !glIsEnabled(array[i]))
|
||||
{
|
||||
llerrs << "Bad client state! " << array[i] << " disabled." << llendl;
|
||||
if (gDebugSession)
|
||||
{
|
||||
error = TRUE;
|
||||
gFailLog << "Bad client state! " << array[i] << " disabled." << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
llerrs << "Bad client state! " << array[i] << " disabled." << llendl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -165,11 +174,24 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
|
||||
}
|
||||
else if (gDebugGL && i > 0 && glIsEnabled(array[i]))
|
||||
{ //needs to be disabled, make sure it was (DEBUG TEMPORARY)
|
||||
llerrs << "Bad client state! " << array[i] << " enabled." << llendl;
|
||||
if (gDebugSession)
|
||||
{
|
||||
error = TRUE;
|
||||
gFailLog << "Bad client state! " << array[i] << " enabled." << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
llerrs << "Bad client state! " << array[i] << " enabled." << llendl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (error)
|
||||
{
|
||||
ll_fail("LLVertexBuffer::setupClientArrays failed");
|
||||
}
|
||||
|
||||
U32 map_tc[] =
|
||||
{
|
||||
MAP_TEXCOORD1,
|
||||
@@ -268,6 +290,18 @@ void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_of
|
||||
{
|
||||
llerrs << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl;
|
||||
}
|
||||
|
||||
if (gDebugGL && !useVBOs())
|
||||
{
|
||||
U16* idx = ((U16*) getIndicesPointer())+indices_offset;
|
||||
for (U32 i = 0; i < count; ++i)
|
||||
{
|
||||
if (idx[i] < start || idx[i] > end)
|
||||
{
|
||||
llerrs << "Index out of range: " << idx[i] << " not in [" << start << ", " << end << "]" << llendl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const
|
||||
@@ -685,6 +719,8 @@ void LLVertexBuffer::updateNumVerts(S32 nverts)
|
||||
{
|
||||
LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
|
||||
|
||||
llassert(nverts >= 0);
|
||||
|
||||
if (nverts >= 65535)
|
||||
{
|
||||
llwarns << "Vertex buffer overflow!" << llendl;
|
||||
@@ -713,6 +749,9 @@ void LLVertexBuffer::updateNumVerts(S32 nverts)
|
||||
void LLVertexBuffer::updateNumIndices(S32 nindices)
|
||||
{
|
||||
LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
|
||||
|
||||
llassert(nindices >= 0);
|
||||
|
||||
mRequestedNumIndices = nindices;
|
||||
if (!mDynamicSize)
|
||||
{
|
||||
@@ -945,8 +984,16 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 access)
|
||||
|
||||
if (!mMappedData)
|
||||
{
|
||||
log_glerror();
|
||||
|
||||
//check the availability of memory
|
||||
U32 avail_phy_mem, avail_vir_mem;
|
||||
LLMemoryInfo::getAvailableMemoryKB(avail_phy_mem, avail_vir_mem) ;
|
||||
llinfos << "Available physical mwmory(KB): " << avail_phy_mem << llendl ;
|
||||
llinfos << "Available virtual memory(KB): " << avail_vir_mem << llendl;
|
||||
|
||||
if(!sDisableVBOMapping)
|
||||
{
|
||||
{
|
||||
//--------------------
|
||||
//print out more debug info before crash
|
||||
llinfos << "vertex buffer size: (num verts : num indices) = " << getNumVerts() << " : " << getNumIndices() << llendl ;
|
||||
@@ -1003,12 +1050,13 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 access)
|
||||
else
|
||||
{
|
||||
mMappedIndexData = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
|
||||
stop_glerror();
|
||||
}
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
if (!mMappedIndexData)
|
||||
{
|
||||
log_glerror();
|
||||
|
||||
if(!sDisableVBOMapping)
|
||||
{
|
||||
@@ -1094,7 +1142,6 @@ void LLVertexBuffer::unmapBuffer(S32 type)
|
||||
//throw out client data (we won't be using it again)
|
||||
mEmpty = TRUE;
|
||||
mFinal = TRUE;
|
||||
|
||||
if(sDisableVBOMapping)
|
||||
{
|
||||
freeClientBuffer() ;
|
||||
@@ -1267,7 +1314,15 @@ void LLVertexBuffer::setBuffer(U32 data_mask, S32 type)
|
||||
glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
|
||||
if ((GLuint)buff != mGLBuffer)
|
||||
{
|
||||
llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
|
||||
if (gDebugSession)
|
||||
{
|
||||
error = TRUE;
|
||||
gFailLog << "Invalid GL vertex buffer bound: " << buff << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
|
||||
}
|
||||
}
|
||||
|
||||
if (mGLIndices)
|
||||
@@ -1275,7 +1330,15 @@ void LLVertexBuffer::setBuffer(U32 data_mask, S32 type)
|
||||
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
|
||||
if ((GLuint)buff != mGLIndices)
|
||||
{
|
||||
llerrs << "Invalid GL index buffer bound: " << buff << llendl;
|
||||
if (gDebugSession)
|
||||
{
|
||||
error = TRUE;
|
||||
gFailLog << "Invalid GL index buffer bound: " << buff << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
llerrs << "Invalid GL index buffer bound: " << buff << llendl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1288,7 +1351,15 @@ void LLVertexBuffer::setBuffer(U32 data_mask, S32 type)
|
||||
glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
|
||||
if ((GLuint)buff != mGLBuffer)
|
||||
{
|
||||
llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
|
||||
if (gDebugSession)
|
||||
{
|
||||
error = TRUE;
|
||||
gFailLog << "Invalid GL vertex buffer bound: " << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
|
||||
}
|
||||
}
|
||||
|
||||
if (mGLIndices != 0)
|
||||
@@ -1296,7 +1367,15 @@ void LLVertexBuffer::setBuffer(U32 data_mask, S32 type)
|
||||
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
|
||||
if ((GLuint)buff != mGLIndices)
|
||||
{
|
||||
llerrs << "Invalid GL index buffer bound: " << buff << llendl;
|
||||
if (gDebugSession)
|
||||
{
|
||||
error = TRUE;
|
||||
gFailLog << "Invalid GL index buffer bound: "<< std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
llerrs << "Invalid GL index buffer bound: " << buff << llendl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1319,13 +1398,21 @@ void LLVertexBuffer::setBuffer(U32 data_mask, S32 type)
|
||||
|
||||
if (data_mask != 0)
|
||||
{
|
||||
llerrs << "Buffer set for rendering before being filled after resize." << llendl;
|
||||
if (gDebugSession)
|
||||
{
|
||||
error = TRUE;
|
||||
gFailLog << "Buffer set for rendering before being filled after resize." << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
llerrs << "Buffer set for rendering before being filled after resize." << llendl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (error)
|
||||
{
|
||||
llerrs << "LLVertexBuffer::mapBuffer failed" << llendl;
|
||||
ll_fail("LLVertexBuffer::mapBuffer failed");
|
||||
}
|
||||
unmapBuffer(type);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user