Track glEnable states via static refs instead of map lookups.

Sync light state, bound shader, and various gl context states similarly to render matrices.
Texture handles now refcounted, as multiple viewer textures could ref the same handle (cubemaps do this)
Clean up gl extension loading a bit. Not necessary, but only look for ARB variants if not included in current core version. Removed unused extensions.
Use core shader api if supported, else use ARB. (FN signatures are identical. Just doing some pointer substitution to ARB if not core.)
Attempt at improving VBO update batching. Subdata updates better batched to gether per-frame.
There's probably other stuff I forgot that is in this changeset, too.

Todo: Fix lightstate assertion when toggling fullscreen with shaders off.
This commit is contained in:
Shyotl
2018-11-19 00:37:48 -06:00
parent 0b4d789afb
commit 736696ac36
96 changed files with 2870 additions and 2266 deletions

View File

@@ -80,9 +80,7 @@ void LLCubeMap::initGL()
// Not initialized, do stuff.
if (mImages[0].isNull())
{
U32 texname = 0;
LLImageGL::generateTextures(1, &texname);
auto texname = LLImageGL::createTextureName();
for (int i = 0; i < 6; i++)
{
@@ -91,7 +89,7 @@ void LLCubeMap::initGL()
mRawImages[i] = new LLImageRaw(64, 64, 4);
mImages[i]->createGLTexture(0, mRawImages[i], texname);
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_CUBE_MAP, texname);
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_CUBE_MAP, texname->getTexName());
mImages[i]->setAddressMode(LLTexUnit::TAM_CLAMP);
stop_glerror();
}
@@ -169,7 +167,7 @@ void LLCubeMap::init(const std::vector<LLPointer<LLImageRaw> >& rawimages)
}
}
GLuint LLCubeMap::getGLName()
GLuint LLCubeMap::getTexName()
{
return mImages[0]->getTexName();
}
@@ -301,7 +299,7 @@ void LLCubeMap::restoreMatrix()
void LLCubeMap::setReflection (void)
{
gGL.getTexUnit(mTextureStage)->bindManual(LLTexUnit::TT_CUBE_MAP, getGLName());
gGL.getTexUnit(mTextureStage)->bindManual(LLTexUnit::TT_CUBE_MAP, getTexName());
mImages[0]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
mImages[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
}

View File

@@ -59,7 +59,7 @@ public:
void finishPaint();
GLuint getGLName();
GLuint getTexName();
LLVector3 map(U8 side, U16 v_val, U16 h_val) const;
BOOL project(F32& v_val, F32& h_val, BOOL& outside,

View File

@@ -72,6 +72,12 @@ void* gl_get_proc_address(const char *pStr)
}
#undef GLH_EXT_GET_PROC_ADDRESS
#define GLH_EXT_GET_PROC_ADDRESS(p) gl_get_proc_address(p)
#undef GLH_EXT_GET_PROC_ADDRESS_CORE
#define GLH_EXT_GET_PROC_ADDRESS_CORE(ver, p) gl_get_proc_address((mGLVersion >= ver) ? p : p##"ARB")
#undef GLH_EXT_GET_PROC_ADDRESS_CORE_EXT
#define GLH_EXT_GET_PROC_ADDRESS_CORE_EXT(ver, p) gl_get_proc_address((mGLVersion >= ver) ? p : p##"EXT")
#undef GLH_EXT_GET_PROC_ADDRESS_CORE_OR_ARB
#define GLH_EXT_GET_PROC_ADDRESS_CORE_OR_ARB(ver, p, arb) gl_get_proc_address((mGLVersion >= ver) ? p : arb)
#endif //!LL_DARWIN
#if GL_ARB_debug_output
@@ -96,6 +102,7 @@ void APIENTRY gl_debug_callback(GLenum source,
{
LL_WARNS() << "----- GL WARNING -------" << LL_ENDL;
}
LL_WARNS() << "Source: " << std::hex << source << std::dec << LL_ENDL;
LL_WARNS() << "Type: " << std::hex << type << std::dec << LL_ENDL;
LL_WARNS() << "ID: " << std::hex << id << std::dec<< LL_ENDL;
LL_WARNS() << "Severity: " << std::hex << severity << std::dec << LL_ENDL;
@@ -276,7 +283,8 @@ PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT = NULL;
PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB = NULL;
//shader object prototypes
PFNGLDELETEOBJECTARBPROC glDeleteObjectARB = NULL;
PFNGLDELETEOBJECTARBPROC glDeleteShader = NULL;
PFNGLDELETEOBJECTARBPROC glDeleteProgram = NULL;
PFNGLGETHANDLEARBPROC glGetHandleARB = NULL;
PFNGLDETACHOBJECTARBPROC glDetachObjectARB = NULL;
PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB = NULL;
@@ -307,9 +315,10 @@ PFNGLUNIFORMMATRIX2FVARBPROC glUniformMatrix2fvARB = NULL;
PFNGLUNIFORMMATRIX3FVARBPROC glUniformMatrix3fvARB = NULL;
PFNGLUNIFORMMATRIX3X4FVPROC glUniformMatrix3x4fv = NULL;
PFNGLUNIFORMMATRIX4FVARBPROC glUniformMatrix4fvARB = NULL;
PFNGLGETOBJECTPARAMETERFVARBPROC glGetObjectParameterfvARB = NULL;
PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB = NULL;
PFNGLGETINFOLOGARBPROC glGetInfoLogARB = NULL;
PFNGLGETOBJECTPARAMETERIVARBPROC glGetShaderiv = NULL;
PFNGLGETOBJECTPARAMETERIVARBPROC glGetProgramiv = NULL;
PFNGLGETINFOLOGARBPROC glGetShaderInfoLog = NULL;
PFNGLGETINFOLOGARBPROC glGetProgramInfoLog = NULL;
PFNGLGETATTACHEDOBJECTSARBPROC glGetAttachedObjectsARB = NULL;
PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB = NULL;
PFNGLGETACTIVEUNIFORMARBPROC glGetActiveUniformARB = NULL;
@@ -435,7 +444,6 @@ LLGLManager::LLGLManager() :
mHasOcclusionQuery2(FALSE),
mHasPointParameters(FALSE),
mHasDrawBuffers(FALSE),
mHasTextureRectangle(FALSE),
mHasTransformFeedback(FALSE),
mMaxIntegerSamples(0),
@@ -462,8 +470,6 @@ LLGLManager::LLGLManager() :
#endif
mHasRequirements(TRUE),
mHasSeparateSpecularColor(FALSE),
mDebugGPU(FALSE),
mDriverVersionMajor(1),
@@ -742,6 +748,7 @@ bool LLGLManager::initGL()
if (LLRender::sGLCoreProfile)
{
// If core is true, then mNumTextureUnits is pretty much unused.
mNumTextureUnits = llmin(mNumTextureImageUnits, MAX_GL_TEXTURE_UNITS);
}
else if (mHasMultitexture)
@@ -776,8 +783,10 @@ bool LLGLManager::initGL()
#if LL_WINDOWS
if (mHasDebugOutput && gDebugGL)
{ //setup debug output callback
glEnable(GL_DEBUG_OUTPUT);
glDebugMessageCallbackARB((GLDEBUGPROCARB) gl_debug_callback, NULL);
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
glDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, true);
}
#endif
stop_glerror();
@@ -929,7 +938,6 @@ void LLGLManager::initExtensions()
mHasBlendFuncSeparate = FALSE;
# endif // GL_EXT_blend_func_separate
mHasMipMapGeneration = FALSE;
mHasSeparateSpecularColor = FALSE;
mHasAnisotropic = FALSE;
mHasCubeMap = FALSE;
mHasOcclusionQuery = FALSE;
@@ -937,7 +945,6 @@ void LLGLManager::initExtensions()
mHasShaderObjects = FALSE;
mHasVertexShader = FALSE;
mHasFragmentShader = FALSE;
mHasTextureRectangle = FALSE;
#ifdef GL_ARB_gpu_shader5
mHasGpuShader5 = FALSE;
#endif
@@ -945,48 +952,46 @@ void LLGLManager::initExtensions()
mHasMultitexture = glh_init_extensions("GL_ARB_multitexture");
mHasATIMemInfo = ExtensionExists("GL_ATI_meminfo", gGLHExts.mSysExts);
mHasNVXMemInfo = ExtensionExists("GL_NVX_gpu_memory_info", gGLHExts.mSysExts);
mHasSeparateSpecularColor = glh_init_extensions("GL_EXT_separate_specular_color");
mHasAnisotropic = glh_init_extensions("GL_EXT_texture_filter_anisotropic");
glh_init_extensions("GL_ARB_texture_cube_map");
mHasCubeMap = ExtensionExists("GL_ARB_texture_cube_map", gGLHExts.mSysExts);
mHasCubeMap = mGLVersion >= 1.3f || ExtensionExists("GL_ARB_texture_cube_map", gGLHExts.mSysExts);
mHasARBEnvCombine = ExtensionExists("GL_ARB_texture_env_combine", gGLHExts.mSysExts);
mHasCompressedTextures = glh_init_extensions("GL_ARB_texture_compression");
mHasOcclusionQuery = ExtensionExists("GL_ARB_occlusion_query", gGLHExts.mSysExts);
mHasOcclusionQuery2 = ExtensionExists("GL_ARB_occlusion_query2", gGLHExts.mSysExts);
mHasVertexBufferObject = ExtensionExists("GL_ARB_vertex_buffer_object", gGLHExts.mSysExts);
mHasVertexArrayObject = ExtensionExists("GL_ARB_vertex_array_object", gGLHExts.mSysExts);
mHasSync = ExtensionExists("GL_ARB_sync", gGLHExts.mSysExts);
mHasMapBufferRange = ExtensionExists("GL_ARB_map_buffer_range", gGLHExts.mSysExts);
mHasCompressedTextures = mGLVersion >= 1.3f || glh_init_extensions("GL_ARB_texture_compression");
mHasOcclusionQuery = mGLVersion >= 1.5f || ExtensionExists("GL_ARB_occlusion_query", gGLHExts.mSysExts);
mHasOcclusionQuery2 = mGLVersion >= 3.3f || ExtensionExists("GL_ARB_occlusion_query2", gGLHExts.mSysExts);
mHasVertexBufferObject = mGLVersion >= 1.5f || ExtensionExists("GL_ARB_vertex_buffer_object", gGLHExts.mSysExts);
mHasVertexArrayObject = mGLVersion >= 3.f || ExtensionExists("GL_ARB_vertex_array_object", gGLHExts.mSysExts);
mHasSync = mGLVersion >= 3.2f || ExtensionExists("GL_ARB_sync", gGLHExts.mSysExts);
mHasMapBufferRange = mGLVersion >= 3.f || ExtensionExists("GL_ARB_map_buffer_range", gGLHExts.mSysExts);
mHasFlushBufferRange = ExtensionExists("GL_APPLE_flush_buffer_range", gGLHExts.mSysExts);
mHasDepthClamp = ExtensionExists("GL_ARB_depth_clamp", gGLHExts.mSysExts) || ExtensionExists("GL_NV_depth_clamp", gGLHExts.mSysExts);
mHasDepthClamp = mGLVersion >= 3.2f || 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
#ifdef GL_ARB_framebuffer_object
mHasFramebufferObject = ExtensionExists("GL_ARB_framebuffer_object", gGLHExts.mSysExts);
mHasFramebufferObject = mGLVersion >= 3.f || ExtensionExists("GL_ARB_framebuffer_object", gGLHExts.mSysExts);
#else
mHasFramebufferObject = ExtensionExists("GL_EXT_framebuffer_object", gGLHExts.mSysExts) &&
mHasFramebufferObject = mGLVersion >= 3.f || (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);
ExtensionExists("GL_EXT_packed_depth_stencil", gGLHExts.mSysExts));
#endif
mHasFramebufferMultisample = mHasFramebufferObject && ExtensionExists("GL_EXT_framebuffer_multisample", gGLHExts.mSysExts);
mHasFramebufferMultisample = mGLVersion >= 3.f || (mHasFramebufferObject && ExtensionExists("GL_EXT_framebuffer_multisample", gGLHExts.mSysExts));
mHasMipMapGeneration = mHasFramebufferObject || mGLVersion >= 1.4f;
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);
mHasDebugOutput = ExtensionExists("GL_ARB_debug_output", gGLHExts.mSysExts);
mHasDrawBuffers = mGLVersion >= 2.f || ExtensionExists("GL_ARB_draw_buffers", gGLHExts.mSysExts);
mHasBlendFuncSeparate = mGLVersion >= 1.4f || ExtensionExists("GL_EXT_blend_func_separate", gGLHExts.mSysExts);
mHasDebugOutput = mGLVersion >= 4.3f || ExtensionExists("GL_ARB_debug_output", gGLHExts.mSysExts);
mHasTransformFeedback = mGLVersion >= 4.f || ExtensionExists("GL_EXT_transform_feedback", gGLHExts.mSysExts);
#if !LL_DARWIN
mHasPointParameters = !mIsATI && ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts);
mHasPointParameters = mGLVersion >= 2.f || (!mIsATI && ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts));
#endif
mHasShaderObjects = ExtensionExists("GL_ARB_shader_objects", gGLHExts.mSysExts) && (LLRender::sGLCoreProfile || ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts));
mHasVertexShader = ExtensionExists("GL_ARB_vertex_program", gGLHExts.mSysExts) && ExtensionExists("GL_ARB_vertex_shader", gGLHExts.mSysExts)
&& (LLRender::sGLCoreProfile || ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts));
mHasFragmentShader = ExtensionExists("GL_ARB_fragment_shader", gGLHExts.mSysExts) && (LLRender::sGLCoreProfile || ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts));
mHasShaderObjects = mGLVersion >= 2.f || ExtensionExists("GL_ARB_shader_objects", gGLHExts.mSysExts) && (LLRender::sGLCoreProfile || ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts));
mHasVertexShader = mGLVersion >= 2.f || (ExtensionExists("GL_ARB_vertex_program", gGLHExts.mSysExts) && ExtensionExists("GL_ARB_vertex_shader", gGLHExts.mSysExts)
&& (LLRender::sGLCoreProfile || ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts)));
mHasFragmentShader = mGLVersion >= 2.f || ExtensionExists("GL_ARB_fragment_shader", gGLHExts.mSysExts) && (LLRender::sGLCoreProfile || ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts));
#endif
#ifdef GL_ARB_gpu_shader5
mHasGpuShader5 = ExtensionExists("GL_ARB_gpu_shader5", gGLHExts.mSysExts);;
mHasGpuShader5 = mGLVersion >= 4.f || ExtensionExists("GL_ARB_gpu_shader5", gGLHExts.mSysExts);;
#endif
#if LL_WINDOWS
mHasAdaptiveVsync = ExtensionExists("WGL_EXT_swap_control_tear", gGLHExts.mSysExts);
@@ -995,7 +1000,7 @@ void LLGLManager::initExtensions()
#endif
#ifdef GL_ARB_texture_swizzle
mHasTextureSwizzle = ExtensionExists("GL_ARB_texture_swizzle", gGLHExts.mSysExts);
mHasTextureSwizzle = mGLVersion >= 3.3f || ExtensionExists("GL_ARB_texture_swizzle", gGLHExts.mSysExts);
#endif
#if LL_LINUX || LL_SOLARIS
@@ -1014,7 +1019,6 @@ void LLGLManager::initExtensions()
mHasDrawBuffers = FALSE;
mHasBlendFuncSeparate = FALSE;
mHasMipMapGeneration = FALSE;
mHasSeparateSpecularColor = FALSE;
mHasAnisotropic = FALSE;
mHasCubeMap = FALSE;
mHasOcclusionQuery = FALSE;
@@ -1055,7 +1059,6 @@ void LLGLManager::initExtensions()
if (strchr(blacklist,'d')) mHasMipMapGeneration = FALSE;//S
// if (strchr(blacklist,'f')) mHasNVVertexArrayRange = FALSE;//S
// if (strchr(blacklist,'g')) mHasNVFence = FALSE;//S
if (strchr(blacklist,'h')) mHasSeparateSpecularColor = FALSE;
if (strchr(blacklist,'i')) mHasAnisotropic = FALSE;//S
if (strchr(blacklist,'j')) mHasCubeMap = FALSE;//S
// if (strchr(blacklist,'k')) mHasATIVAO = FALSE;//S
@@ -1067,7 +1070,6 @@ void LLGLManager::initExtensions()
if (strchr(blacklist,'q')) mHasFramebufferObject = FALSE;//S
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
if (strchr(blacklist,'v')) mHasDepthClamp = FALSE;
@@ -1086,10 +1088,6 @@ void LLGLManager::initExtensions()
{
LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_texture_env_combine" << LL_ENDL;
}
if (!mHasSeparateSpecularColor)
{
LL_INFOS("RenderInit") << "Couldn't initialize separate specular color" << LL_ENDL;
}
if (!mHasAnisotropic)
{
LL_INFOS("RenderInit") << "Couldn't initialize anisotropic filtering" << LL_ENDL;
@@ -1153,19 +1151,19 @@ void LLGLManager::initExtensions()
LL_DEBUGS("RenderInit") << "GL Probe: Getting symbols" << LL_ENDL;
if (mHasVertexBufferObject)
{
glBindBufferARB = (PFNGLBINDBUFFERARBPROC)GLH_EXT_GET_PROC_ADDRESS("glBindBufferARB");
glBindBufferARB = (PFNGLBINDBUFFERARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(1.5, "glBindBuffer");
if (glBindBufferARB)
{
glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)GLH_EXT_GET_PROC_ADDRESS("glDeleteBuffersARB");
glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGenBuffersARB");
glIsBufferARB = (PFNGLISBUFFERARBPROC)GLH_EXT_GET_PROC_ADDRESS("glIsBufferARB");
glBufferDataARB = (PFNGLBUFFERDATAARBPROC)GLH_EXT_GET_PROC_ADDRESS("glBufferDataARB");
glBufferSubDataARB = (PFNGLBUFFERSUBDATAARBPROC)GLH_EXT_GET_PROC_ADDRESS("glBufferSubDataARB");
glGetBufferSubDataARB = (PFNGLGETBUFFERSUBDATAARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetBufferSubDataARB");
glMapBufferARB = (PFNGLMAPBUFFERARBPROC)GLH_EXT_GET_PROC_ADDRESS("glMapBufferARB");
glUnmapBufferARB = (PFNGLUNMAPBUFFERARBPROC)GLH_EXT_GET_PROC_ADDRESS("glUnmapBufferARB");
glGetBufferParameterivARB = (PFNGLGETBUFFERPARAMETERIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetBufferParameterivARB");
glGetBufferPointervARB = (PFNGLGETBUFFERPOINTERVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetBufferPointervARB");
glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(1.5, "glDeleteBuffers");
glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(1.5, "glGenBuffers");
glIsBufferARB = (PFNGLISBUFFERARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(1.5, "glIsBuffer");
glBufferDataARB = (PFNGLBUFFERDATAARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(1.5, "glBufferData");
glBufferSubDataARB = (PFNGLBUFFERSUBDATAARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(1.5, "glBufferSubData");
glGetBufferSubDataARB = (PFNGLGETBUFFERSUBDATAARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(1.5, "glGetBufferSubData");
glMapBufferARB = (PFNGLMAPBUFFERARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(1.5, "glMapBuffer");
glUnmapBufferARB = (PFNGLUNMAPBUFFERARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(1.5, "glUnmapBuffer");
glGetBufferParameterivARB = (PFNGLGETBUFFERPARAMETERIVARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(1.5, "glGetBufferParameteriv");
glGetBufferPointervARB = (PFNGLGETBUFFERPOINTERVARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(1.5, "glGetBufferPointerv");
}
else
{
@@ -1220,25 +1218,25 @@ void LLGLManager::initExtensions()
}
if (mHasDrawBuffers)
{
glDrawBuffersARB = (PFNGLDRAWBUFFERSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDrawBuffersARB");
glDrawBuffersARB = (PFNGLDRAWBUFFERSARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glDrawBuffers");
}
if (mHasBlendFuncSeparate)
{
glBlendFuncSeparateEXT = (PFNGLBLENDFUNCSEPARATEEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glBlendFuncSeparateEXT");
glBlendFuncSeparateEXT = (PFNGLBLENDFUNCSEPARATEEXTPROC)GLH_EXT_GET_PROC_ADDRESS_CORE_EXT(1.4, "glBlendFuncSeparate");
}
if (mHasTransformFeedback)
{
glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC) GLH_EXT_GET_PROC_ADDRESS("glBeginTransformFeedback");
glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC) GLH_EXT_GET_PROC_ADDRESS("glEndTransformFeedback");
glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC) GLH_EXT_GET_PROC_ADDRESS("glTransformFeedbackVaryings");
glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC) GLH_EXT_GET_PROC_ADDRESS("glBindBufferRange");
glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC)GLH_EXT_GET_PROC_ADDRESS_CORE_EXT(4.0, "glBeginTransformFeedback");
glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC)GLH_EXT_GET_PROC_ADDRESS_CORE_EXT(4.0, "glEndTransformFeedback");
glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC)GLH_EXT_GET_PROC_ADDRESS_CORE_EXT(4.0, "glTransformFeedbackVaryings");
glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC)GLH_EXT_GET_PROC_ADDRESS_CORE_EXT(3.0, "glBindBufferRange");
}
if (mHasDebugOutput)
{
glDebugMessageControlARB = (PFNGLDEBUGMESSAGECONTROLARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDebugMessageControlARB");
glDebugMessageInsertARB = (PFNGLDEBUGMESSAGEINSERTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDebugMessageInsertARB");
glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDebugMessageCallbackARB");
glGetDebugMessageLogARB = (PFNGLGETDEBUGMESSAGELOGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetDebugMessageLogARB");
glDebugMessageControlARB = (PFNGLDEBUGMESSAGECONTROLARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(4.3, "glDebugMessageControl");
glDebugMessageInsertARB = (PFNGLDEBUGMESSAGEINSERTARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(4.3, "glDebugMessageInsert");
glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(4.3, "glDebugMessageCallback");
glGetDebugMessageLogARB = (PFNGLGETDEBUGMESSAGELOGARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(4.3, "glGetDebugMessageLog");
}
#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
@@ -1258,114 +1256,117 @@ void LLGLManager::initExtensions()
if (mHasOcclusionQuery)
{
LL_INFOS() << "initExtensions() OcclusionQuery-related procs..." << LL_ENDL;
glGenQueriesARB = (PFNGLGENQUERIESARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGenQueriesARB");
glDeleteQueriesARB = (PFNGLDELETEQUERIESARBPROC)GLH_EXT_GET_PROC_ADDRESS("glDeleteQueriesARB");
glIsQueryARB = (PFNGLISQUERYARBPROC)GLH_EXT_GET_PROC_ADDRESS("glIsQueryARB");
glBeginQueryARB = (PFNGLBEGINQUERYARBPROC)GLH_EXT_GET_PROC_ADDRESS("glBeginQueryARB");
glEndQueryARB = (PFNGLENDQUERYARBPROC)GLH_EXT_GET_PROC_ADDRESS("glEndQueryARB");
glGetQueryivARB = (PFNGLGETQUERYIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryivARB");
glGetQueryObjectivARB = (PFNGLGETQUERYOBJECTIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjectivARB");
glGetQueryObjectuivARB = (PFNGLGETQUERYOBJECTUIVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjectuivARB");
glGenQueriesARB = (PFNGLGENQUERIESARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(1.4, "glGenQueries");
glDeleteQueriesARB = (PFNGLDELETEQUERIESARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(1.4, "glDeleteQueries");
glIsQueryARB = (PFNGLISQUERYARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(1.4, "glIsQuery");
glBeginQueryARB = (PFNGLBEGINQUERYARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(1.4, "glBeginQuery");
glEndQueryARB = (PFNGLENDQUERYARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(1.4, "glEndQuery");
glGetQueryivARB = (PFNGLGETQUERYIVARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(1.4, "glGetQueryiv");
glGetQueryObjectivARB = (PFNGLGETQUERYOBJECTIVARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(1.4, "glGetQueryObjectiv");
glGetQueryObjectuivARB = (PFNGLGETQUERYOBJECTUIVARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(1.4, "glGetQueryObjectuiv");
}
#if !LL_DARWIN
glGetQueryObjectui64vEXT = (PFNGLGETQUERYOBJECTUI64VEXTPROC)GLH_EXT_GET_PROC_ADDRESS("glGetQueryObjectui64vEXT");
glGetQueryObjectui64vEXT = (PFNGLGETQUERYOBJECTUI64VEXTPROC)GLH_EXT_GET_PROC_ADDRESS_CORE_EXT(3.2, "glGetQueryObjectui64v");
#endif
if (mHasPointParameters)
{
LL_INFOS() << "initExtensions() PointParameters-related procs..." << LL_ENDL;
glPointParameterfARB = (PFNGLPOINTPARAMETERFARBPROC)GLH_EXT_GET_PROC_ADDRESS("glPointParameterfARB");
glPointParameterfvARB = (PFNGLPOINTPARAMETERFVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glPointParameterfvARB");
glPointParameterfARB = (PFNGLPOINTPARAMETERFARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glPointParameterf");
glPointParameterfvARB = (PFNGLPOINTPARAMETERFVARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glPointParameterfv");
}
if (mHasShaderObjects)
{
glDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteObjectARB");
glGetHandleARB = (PFNGLGETHANDLEARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetHandleARB");
glDetachObjectARB = (PFNGLDETACHOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDetachObjectARB");
glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glCreateShaderObjectARB");
glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC) GLH_EXT_GET_PROC_ADDRESS("glShaderSourceARB");
glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC) GLH_EXT_GET_PROC_ADDRESS("glCompileShaderARB");
glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glCreateProgramObjectARB");
glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glAttachObjectARB");
glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glLinkProgramARB");
glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUseProgramObjectARB");
glValidateProgramARB = (PFNGLVALIDATEPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glValidateProgramARB");
glUniform1fARB = (PFNGLUNIFORM1FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform1fARB");
glUniform2fARB = (PFNGLUNIFORM2FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform2fARB");
glUniform3fARB = (PFNGLUNIFORM3FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform3fARB");
glUniform4fARB = (PFNGLUNIFORM4FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform4fARB");
glUniform1iARB = (PFNGLUNIFORM1IARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform1iARB");
glUniform2iARB = (PFNGLUNIFORM2IARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform2iARB");
glUniform3iARB = (PFNGLUNIFORM3IARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform3iARB");
glUniform4iARB = (PFNGLUNIFORM4IARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform4iARB");
glUniform1fvARB = (PFNGLUNIFORM1FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform1fvARB");
glUniform2fvARB = (PFNGLUNIFORM2FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform2fvARB");
glUniform3fvARB = (PFNGLUNIFORM3FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform3fvARB");
glUniform4fvARB = (PFNGLUNIFORM4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform4fvARB");
glUniform1ivARB = (PFNGLUNIFORM1IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform1ivARB");
glUniform2ivARB = (PFNGLUNIFORM2IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform2ivARB");
glUniform3ivARB = (PFNGLUNIFORM3IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform3ivARB");
glUniform4ivARB = (PFNGLUNIFORM4IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniform4ivARB");
glUniformMatrix2fvARB = (PFNGLUNIFORMMATRIX2FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix2fvARB");
glUniformMatrix3fvARB = (PFNGLUNIFORMMATRIX3FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix3fvARB");
glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix3x4fv");
glUniformMatrix4fvARB = (PFNGLUNIFORMMATRIX4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glUniformMatrix4fvARB");
glGetObjectParameterfvARB = (PFNGLGETOBJECTPARAMETERFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetObjectParameterfvARB");
glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetObjectParameterivARB");
glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetInfoLogARB");
glGetAttachedObjectsARB = (PFNGLGETATTACHEDOBJECTSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetAttachedObjectsARB");
glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetUniformLocationARB");
glGetActiveUniformARB = (PFNGLGETACTIVEUNIFORMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetActiveUniformARB");
glGetUniformfvARB = (PFNGLGETUNIFORMFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetUniformfvARB");
glGetUniformivARB = (PFNGLGETUNIFORMIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetUniformivARB");
glGetShaderSourceARB = (PFNGLGETSHADERSOURCEARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetShaderSourceARB");
glDeleteShader = (PFNGLDELETEOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE_OR_ARB(2.0, "glDeleteShader", "glDeleteObjectARB");
glDeleteProgram = (PFNGLDELETEOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE_OR_ARB(2.0, "glDeleteProgram", "glDeleteObjectARB");
glGetHandleARB = (PFNGLGETHANDLEARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glGetHandle");
glDetachObjectARB = (PFNGLDETACHOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE_OR_ARB(2.0, "glDetachShader", "glDetachObjectARB");
glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE_OR_ARB(2.0, "glCreateShader", "glCreateShaderObjectARB");
glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glShaderSource");
glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glCompileShader");
glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE_OR_ARB(2.0, "glCreateProgram", "glCreateProgramObjectARB");
glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE_OR_ARB(2.0, "glAttachShader", "glAttachObjectARB");
glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glLinkProgram");
glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE_OR_ARB(2.0, "glUseProgram", "glUseProgramObjectARB");
glValidateProgramARB = (PFNGLVALIDATEPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glValidateProgram");
glUniform1fARB = (PFNGLUNIFORM1FARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glUniform1f");
glUniform2fARB = (PFNGLUNIFORM2FARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glUniform2f");
glUniform3fARB = (PFNGLUNIFORM3FARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glUniform3f");
glUniform4fARB = (PFNGLUNIFORM4FARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glUniform4f");
glUniform1iARB = (PFNGLUNIFORM1IARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glUniform1i");
glUniform2iARB = (PFNGLUNIFORM2IARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glUniform2i");
glUniform3iARB = (PFNGLUNIFORM3IARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glUniform3i");
glUniform4iARB = (PFNGLUNIFORM4IARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glUniform4i");
glUniform1fvARB = (PFNGLUNIFORM1FVARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glUniform1fv");
glUniform2fvARB = (PFNGLUNIFORM2FVARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glUniform2fv");
glUniform3fvARB = (PFNGLUNIFORM3FVARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glUniform3fv");
glUniform4fvARB = (PFNGLUNIFORM4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glUniform4fv");
glUniform1ivARB = (PFNGLUNIFORM1IVARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glUniform1iv");
glUniform2ivARB = (PFNGLUNIFORM2IVARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glUniform2iv");
glUniform3ivARB = (PFNGLUNIFORM3IVARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glUniform3iv");
glUniform4ivARB = (PFNGLUNIFORM4IVARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glUniform4iv");
glUniformMatrix2fvARB = (PFNGLUNIFORMMATRIX2FVARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glUniformMatrix2fv");
glUniformMatrix3fvARB = (PFNGLUNIFORMMATRIX3FVARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glUniformMatrix3fv");
glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC) GLH_EXT_GET_PROC_ADDRESS_CORE(2.1, "glUniformMatrix3x4fv");
glUniformMatrix4fvARB = (PFNGLUNIFORMMATRIX4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glUniformMatrix4fv");
glGetShaderiv = (PFNGLGETOBJECTPARAMETERIVARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE_OR_ARB(2.0, "glGetShaderiv", "glGetObjectParameterivARB");
glGetProgramiv = (PFNGLGETOBJECTPARAMETERIVARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE_OR_ARB(2.0, "glGetProgramiv", "glGetObjectParameterivARB");
glGetShaderInfoLog = (PFNGLGETINFOLOGARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE_OR_ARB(2.0, "glGetShaderInfoLog", "glGetInfoLogARB");
glGetProgramInfoLog = (PFNGLGETINFOLOGARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE_OR_ARB(2.0, "glGetProgramInfoLog", "glGetInfoLogARB");
glGetAttachedObjectsARB = (PFNGLGETATTACHEDOBJECTSARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE_OR_ARB(2.0, "glGetAttachedShaders", "glGetAttachedObjectsARB");
glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glGetUniformLocation");
glGetActiveUniformARB = (PFNGLGETACTIVEUNIFORMARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glGetActiveUniform");
glGetUniformfvARB = (PFNGLGETUNIFORMFVARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glGetUniformfv");
glGetUniformivARB = (PFNGLGETUNIFORMIVARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glGetUniformiv");
glGetShaderSourceARB = (PFNGLGETSHADERSOURCEARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glGetShaderSource");
}
if (mHasVertexShader)
{
LL_INFOS() << "initExtensions() VertexShader-related procs..." << LL_ENDL;
glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetAttribLocationARB");
glBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glBindAttribLocationARB");
glGetActiveAttribARB = (PFNGLGETACTIVEATTRIBARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetActiveAttribARB");
glVertexAttrib1dARB = (PFNGLVERTEXATTRIB1DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1dARB");
glVertexAttrib1dvARB = (PFNGLVERTEXATTRIB1DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1dvARB");
glVertexAttrib1fARB = (PFNGLVERTEXATTRIB1FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1fARB");
glVertexAttrib1fvARB = (PFNGLVERTEXATTRIB1FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1fvARB");
glVertexAttrib1sARB = (PFNGLVERTEXATTRIB1SARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1sARB");
glVertexAttrib1svARB = (PFNGLVERTEXATTRIB1SVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib1svARB");
glVertexAttrib2dARB = (PFNGLVERTEXATTRIB2DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2dARB");
glVertexAttrib2dvARB = (PFNGLVERTEXATTRIB2DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2dvARB");
glVertexAttrib2fARB = (PFNGLVERTEXATTRIB2FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2fARB");
glVertexAttrib2fvARB = (PFNGLVERTEXATTRIB2FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2fvARB");
glVertexAttrib2sARB = (PFNGLVERTEXATTRIB2SARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2sARB");
glVertexAttrib2svARB = (PFNGLVERTEXATTRIB2SVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib2svARB");
glVertexAttrib3dARB = (PFNGLVERTEXATTRIB3DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3dARB");
glVertexAttrib3dvARB = (PFNGLVERTEXATTRIB3DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3dvARB");
glVertexAttrib3fARB = (PFNGLVERTEXATTRIB3FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3fARB");
glVertexAttrib3fvARB = (PFNGLVERTEXATTRIB3FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3fvARB");
glVertexAttrib3sARB = (PFNGLVERTEXATTRIB3SARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3sARB");
glVertexAttrib3svARB = (PFNGLVERTEXATTRIB3SVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib3svARB");
glVertexAttrib4nbvARB = (PFNGLVERTEXATTRIB4NBVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nbvARB");
glVertexAttrib4nivARB = (PFNGLVERTEXATTRIB4NIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nivARB");
glVertexAttrib4nsvARB = (PFNGLVERTEXATTRIB4NSVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nsvARB");
glVertexAttrib4nubARB = (PFNGLVERTEXATTRIB4NUBARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nubARB");
glVertexAttrib4nubvARB = (PFNGLVERTEXATTRIB4NUBVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nubvARB");
glVertexAttrib4nuivARB = (PFNGLVERTEXATTRIB4NUIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nuivARB");
glVertexAttrib4nusvARB = (PFNGLVERTEXATTRIB4NUSVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4nusvARB");
glVertexAttrib4bvARB = (PFNGLVERTEXATTRIB4BVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4bvARB");
glVertexAttrib4dARB = (PFNGLVERTEXATTRIB4DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4dARB");
glVertexAttrib4dvARB = (PFNGLVERTEXATTRIB4DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4dvARB");
glVertexAttrib4fARB = (PFNGLVERTEXATTRIB4FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4fARB");
glVertexAttrib4fvARB = (PFNGLVERTEXATTRIB4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4fvARB");
glVertexAttrib4ivARB = (PFNGLVERTEXATTRIB4IVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4ivARB");
glVertexAttrib4sARB = (PFNGLVERTEXATTRIB4SARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4sARB");
glVertexAttrib4svARB = (PFNGLVERTEXATTRIB4SVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4svARB");
glVertexAttrib4ubvARB = (PFNGLVERTEXATTRIB4UBVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4ubvARB");
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");
glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glGetAttribLocation");
glBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glBindAttribLocation");
glGetActiveAttribARB = (PFNGLGETACTIVEATTRIBARBPROC) GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glGetActiveAttrib");
glVertexAttrib1dARB = (PFNGLVERTEXATTRIB1DARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glVertexAttrib1d");
glVertexAttrib1dvARB = (PFNGLVERTEXATTRIB1DVARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glVertexAttrib1dv");
glVertexAttrib1fARB = (PFNGLVERTEXATTRIB1FARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glVertexAttrib1f");
glVertexAttrib1fvARB = (PFNGLVERTEXATTRIB1FVARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glVertexAttrib1fv");
glVertexAttrib1sARB = (PFNGLVERTEXATTRIB1SARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glVertexAttrib1s");
glVertexAttrib1svARB = (PFNGLVERTEXATTRIB1SVARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glVertexAttrib1sv");
glVertexAttrib2dARB = (PFNGLVERTEXATTRIB2DARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glVertexAttrib2d");
glVertexAttrib2dvARB = (PFNGLVERTEXATTRIB2DVARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glVertexAttrib2dv");
glVertexAttrib2fARB = (PFNGLVERTEXATTRIB2FARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glVertexAttrib2f");
glVertexAttrib2fvARB = (PFNGLVERTEXATTRIB2FVARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glVertexAttrib2fv");
glVertexAttrib2sARB = (PFNGLVERTEXATTRIB2SARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glVertexAttrib2s");
glVertexAttrib2svARB = (PFNGLVERTEXATTRIB2SVARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glVertexAttrib2sv");
glVertexAttrib3dARB = (PFNGLVERTEXATTRIB3DARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glVertexAttrib3d");
glVertexAttrib3dvARB = (PFNGLVERTEXATTRIB3DVARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glVertexAttrib3dv");
glVertexAttrib3fARB = (PFNGLVERTEXATTRIB3FARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glVertexAttrib3f");
glVertexAttrib3fvARB = (PFNGLVERTEXATTRIB3FVARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glVertexAttrib3fv");
glVertexAttrib3sARB = (PFNGLVERTEXATTRIB3SARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glVertexAttrib3s");
glVertexAttrib3svARB = (PFNGLVERTEXATTRIB3SVARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glVertexAttrib3sv");
glVertexAttrib4nbvARB = (PFNGLVERTEXATTRIB4NBVARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glVertexAttrib4Nbv");
glVertexAttrib4nivARB = (PFNGLVERTEXATTRIB4NIVARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glVertexAttrib4Niv");
glVertexAttrib4nsvARB = (PFNGLVERTEXATTRIB4NSVARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glVertexAttrib4Nsv");
glVertexAttrib4nubARB = (PFNGLVERTEXATTRIB4NUBARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glVertexAttrib4Nub");
glVertexAttrib4nubvARB = (PFNGLVERTEXATTRIB4NUBVARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glVertexAttrib4Nubv");
glVertexAttrib4nuivARB = (PFNGLVERTEXATTRIB4NUIVARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glVertexAttrib4Nuiv");
glVertexAttrib4nusvARB = (PFNGLVERTEXATTRIB4NUSVARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glVertexAttrib4Nusv");
glVertexAttrib4bvARB = (PFNGLVERTEXATTRIB4BVARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glVertexAttrib4bv");
glVertexAttrib4dARB = (PFNGLVERTEXATTRIB4DARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glVertexAttrib4d");
glVertexAttrib4dvARB = (PFNGLVERTEXATTRIB4DVARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glVertexAttrib4dv");
glVertexAttrib4fARB = (PFNGLVERTEXATTRIB4FARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glVertexAttrib4f");
glVertexAttrib4fvARB = (PFNGLVERTEXATTRIB4FVARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glVertexAttrib4fv");
glVertexAttrib4ivARB = (PFNGLVERTEXATTRIB4IVARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glVertexAttrib4iv");
glVertexAttrib4sARB = (PFNGLVERTEXATTRIB4SARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glVertexAttrib4s");
glVertexAttrib4svARB = (PFNGLVERTEXATTRIB4SVARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glVertexAttrib4sv");
glVertexAttrib4ubvARB = (PFNGLVERTEXATTRIB4UBVARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glVertexAttrib4ubv");
glVertexAttrib4uivARB = (PFNGLVERTEXATTRIB4UIVARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glVertexAttrib4uiv");
glVertexAttrib4usvARB = (PFNGLVERTEXATTRIB4USVARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glVertexAttrib4usv");
glVertexAttribPointerARB = (PFNGLVERTEXATTRIBPOINTERARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glVertexAttribPointer");
glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(3.0, "glVertexAttribIPointer");
glEnableVertexAttribArrayARB = (PFNGLENABLEVERTEXATTRIBARRAYARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glEnableVertexAttribArray");
glDisableVertexAttribArrayARB = (PFNGLDISABLEVERTEXATTRIBARRAYARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glDisableVertexAttribArray");
// These are all related to defunct ARB assembly language.
/*glProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramStringARB");
glBindProgramARB = (PFNGLBINDPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glBindProgramARB");
glDeleteProgramsARB = (PFNGLDELETEPROGRAMSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteProgramsARB");
glGenProgramsARB = (PFNGLGENPROGRAMSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGenProgramsARB");
@@ -1382,12 +1383,12 @@ void LLGLManager::initExtensions()
glGetProgramLocalParameterdvARB = (PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramLocalParameterdvARB");
glGetProgramLocalParameterfvARB = (PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramLocalParameterfvARB");
glGetProgramivARB = (PFNGLGETPROGRAMIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramivARB");
glGetProgramStringARB = (PFNGLGETPROGRAMSTRINGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramStringARB");
glGetVertexAttribdvARB = (PFNGLGETVERTEXATTRIBDVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribdvARB");
glGetVertexAttribfvARB = (PFNGLGETVERTEXATTRIBFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribfvARB");
glGetVertexAttribivARB = (PFNGLGETVERTEXATTRIBIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetVertexAttribivARB");
glGetVertexAttribPointervARB = (PFNGLGETVERTEXATTRIBPOINTERVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glgetVertexAttribPointervARB");
glIsProgramARB = (PFNGLISPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glIsProgramARB");
glGetProgramStringARB = (PFNGLGETPROGRAMSTRINGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramStringARB");*/
glGetVertexAttribdvARB = (PFNGLGETVERTEXATTRIBDVARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glGetVertexAttribdv");
glGetVertexAttribfvARB = (PFNGLGETVERTEXATTRIBFVARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glGetVertexAttribfv");
glGetVertexAttribivARB = (PFNGLGETVERTEXATTRIBIVARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glGetVertexAttribiv");
glGetVertexAttribPointervARB = (PFNGLGETVERTEXATTRIBPOINTERVARBPROC)GLH_EXT_GET_PROC_ADDRESS_CORE(2.0, "glGetVertexAttribPointerv");
//glIsProgramARB = (PFNGLISPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glIsProgramARB");
}
LL_DEBUGS("RenderInit") << "GL Probe: Got symbols" << LL_ENDL;
#endif
@@ -1530,33 +1531,49 @@ void clear_glerror()
//
// Static members
boost::unordered_map<LLGLenum, LLGLboolean> LLGLState::sStateMap;
std::vector<LLGLStateStaticData*> LLGLStateValidator::sStateDataVec;
GLboolean LLGLDepthTest::sDepthEnabled = GL_FALSE; // OpenGL default
GLenum LLGLDepthTest::sDepthFunc = GL_LESS; // OpenGL default
GLboolean LLGLDepthTest::sWriteEnabled = GL_TRUE; // OpenGL default
//static
void LLGLState::initClass()
void LLGLStateValidator::initClass()
{
sStateMap[GL_DITHER] = GL_TRUE;
// sStateMap[GL_TEXTURE_2D] = GL_TRUE;
stop_glerror();
gGL.setSceneBlendType(LLRender::BT_ALPHA);
//make sure multisample defaults to disabled
sStateMap[GL_MULTISAMPLE_ARB] = GL_FALSE;
glDisable(GL_MULTISAMPLE_ARB);
stop_glerror();
for (auto data : sStateDataVec)
{
llassert_always(data->depth == 0);
llassert_always(data->activeInstance == nullptr);
if (data->disabler && *data->disabler)
{
continue;
}
const char* stateStr = data->stateStr;
LLGLenum state = data->state;
LLGLboolean cur_state = data->currentState;
llassert_always_msg(cur_state == glIsEnabled(state), llformat("%s expected %s", stateStr, cur_state ? "TRUE" : "FALSE"));
}
const bool old = gDebugGL;
gDebugGL = true;
checkStates();
gDebugGL = old;
}
//static
void LLGLState::restoreGL()
void LLGLStateValidator::restoreGL()
{
sStateMap.clear();
initClass();
}
//static
// Really shouldn't be needed, but seems we sometimes do.
void LLGLState::resetTextureStates()
void LLGLStateValidator::resetTextureStates()
{
gGL.flush();
GLint maxTextureUnits;
@@ -1570,35 +1587,60 @@ void LLGLState::resetTextureStates()
}
}
void LLGLState::dumpStates()
void LLGLStateValidator::dumpStates()
{
LL_INFOS("RenderState") << "GL States:" << LL_ENDL;
for (boost::unordered_map<LLGLenum, LLGLboolean>::iterator iter = sStateMap.begin();
iter != sStateMap.end(); ++iter)
for (auto data : sStateDataVec)
{
LL_INFOS("RenderState") << llformat(" 0x%04x : %s",(S32)iter->first,iter->second?"TRUE":"FALSE") << LL_ENDL;
LL_INFOS("RenderState") << llformat("%s : %s", data->stateStr, data->currentState ? "TRUE" : "FALSE") << LL_ENDL;
}
}
void LLGLState::checkStates(const std::string& msg)
void LLGLStateValidator::checkState(LLGLStateStaticData& data)
{
if (!gDebugGL)
if (gDebugGL)
{
if (data.disabler && *data.disabler)
{
return;
}
if (!gDebugSession)
{
llassert_always(data.currentState == (bool)glIsEnabled(data.state));
}
else
{
if (data.currentState != (bool)glIsEnabled(data.state))
{
ll_fail(llformat("GL enabled state for %s does not match expected state of %s.", data.stateStr, data.currentState ? "TRUE" : "FALSE"));
}
}
}
}
bool LLGLStateValidator::registerStateData(LLGLStateStaticData& data)
{
sStateDataVec.emplace_back(&data);
return true;
}
void LLGLStateValidator::checkStates(const std::string& msg)
{
if (!gDebugGL || gGLManager.mIsDisabled)
{
return;
}
stop_glerror();
GLint src;
GLint dst;
glGetIntegerv(GL_BLEND_SRC, &src);
glGetIntegerv(GL_BLEND_DST, &dst);
GLint src = gGL.getContextSnapshot().blendColorSFactor;
GLint dst = gGL.getContextSnapshot().blendColorDFactor;
stop_glerror();
BOOL error = FALSE;
if (src != GL_SRC_ALPHA || dst != GL_ONE_MINUS_SRC_ALPHA)
if (src != LLRender::BF_SOURCE_ALPHA || dst != LLRender::BF_ONE_MINUS_SOURCE_ALPHA)
{
if (gDebugSession)
{
@@ -1611,11 +1653,15 @@ void LLGLState::checkStates(const std::string& msg)
}
}
for (boost::unordered_map<LLGLenum, LLGLboolean>::iterator iter = sStateMap.begin();
iter != sStateMap.end(); ++iter)
for (auto data : sStateDataVec)
{
LLGLenum state = iter->first;
LLGLboolean cur_state = iter->second;
if (data->disabler && *data->disabler)
{
continue;
}
const char* stateStr = data->stateStr;
LLGLenum state = data->state;
LLGLboolean cur_state = data->currentState;
stop_glerror();
LLGLboolean gl_state = glIsEnabled(state);
stop_glerror();
@@ -1624,24 +1670,24 @@ void LLGLState::checkStates(const std::string& msg)
dumpStates();
if (gDebugSession)
{
gFailLog << llformat("LLGLState error. State: 0x%04x",state) << std::endl;
gFailLog << llformat("LLGLState error. State: %s 0x%04x. Expected %s", stateStr, state, cur_state ? "TRUE" : "FALSE") << std::endl;
error = TRUE;
}
else
{
LL_GL_ERRS << llformat("LLGLState error. State: 0x%04x",state) << LL_ENDL;
LL_GL_ERRS << llformat("LLGLState error. State: %s 0x%04x. Expected %s", stateStr, state, cur_state ? "TRUE" : "FALSE") << LL_ENDL;
}
}
}
if (error)
{
ll_fail("LLGLState::checkStates failed.");
ll_fail("LLGLStateValidator::checkStates failed.");
}
stop_glerror();
}
void LLGLState::checkTextureChannels(const std::string& msg)
void LLGLStateValidator::checkTextureChannels(const std::string& msg)
{
#if 0
if (!gDebugGL)
@@ -1738,7 +1784,7 @@ void LLGLState::checkTextureChannels(const std::string& msg)
for (S32 j = (i == 0 ? 1 : 0);
j < (gGLManager.mHasTextureRectangle ? 9 : 8); j++)
j < 8; j++)
{
if (glIsEnabled(value[j]))
{
@@ -1793,7 +1839,7 @@ void LLGLState::checkTextureChannels(const std::string& msg)
{
if (gDebugSession)
{
ll_fail("LLGLState::checkTextureChannels failed.");
ll_fail("LLGLStateValidator::checkTextureChannels failed.");
}
else
{
@@ -1803,7 +1849,7 @@ void LLGLState::checkTextureChannels(const std::string& msg)
#endif
}
void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
void LLGLStateValidator::checkClientArrays(const std::string& msg, U32 data_mask)
{
if (!gDebugGL || LLGLSLShader::sNoFixedFunction)
{
@@ -1969,7 +2015,7 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
{
if (gDebugSession)
{
ll_fail("LLGLState::checkClientArrays failed.");
ll_fail("LLGLStateValidator::checkClientArrays failed.");
}
else
{
@@ -1980,108 +2026,36 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
///////////////////////////////////////////////////////////////////////
LLGLState::LLGLState(LLGLenum state, S32 enabled) :
mState(state), mWasEnabled(FALSE), mIsEnabled(FALSE)
{
if (LLGLSLShader::sNoFixedFunction)
{ //always ignore state that's deprecated post GL 3.0
switch (state)
{
case GL_ALPHA_TEST:
case GL_NORMALIZE:
case GL_TEXTURE_GEN_R:
case GL_TEXTURE_GEN_S:
case GL_TEXTURE_GEN_T:
case GL_TEXTURE_GEN_Q:
case GL_LIGHTING:
case GL_COLOR_MATERIAL:
case GL_FOG:
case GL_LINE_STIPPLE:
case GL_POLYGON_STIPPLE:
mState = 0;
break;
}
}
stop_glerror();
if (mState)
{
mWasEnabled = sStateMap[state];
llassert(mWasEnabled == glIsEnabled(state));
setEnabled(enabled);
stop_glerror();
}
}
void LLGLState::setEnabled(S32 enabled)
{
if (!mState)
{
return;
}
if (enabled == CURRENT_STATE)
{
enabled = sStateMap[mState] == GL_TRUE ? TRUE : FALSE;
}
else if (enabled == TRUE && sStateMap[mState] != GL_TRUE)
{
gGL.flush();
glEnable(mState);
sStateMap[mState] = GL_TRUE;
}
else if (enabled == FALSE && sStateMap[mState] != GL_FALSE)
{
gGL.flush();
glDisable(mState);
sStateMap[mState] = GL_FALSE;
}
mIsEnabled = enabled;
}
LLGLState::~LLGLState()
{
stop_glerror();
if (mState)
{
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)
{
gGL.flush();
if (mWasEnabled)
{
glEnable(mState);
sStateMap[mState] = GL_TRUE;
}
else
{
glDisable(mState);
sStateMap[mState] = GL_FALSE;
}
}
}
stop_glerror();
}
////////////////////////////////////////////////////////////////////////////////
initLLGLState(GL_BLEND, false, nullptr);
initLLGLState(GL_CLIP_PLANE0, false, nullptr);
initLLGLState(GL_CULL_FACE, false, nullptr);
initLLGLState(GL_DEPTH_CLAMP, false, nullptr);
initLLGLState(GL_DITHER, true, nullptr);
initLLGLState(GL_LINE_SMOOTH, false, nullptr);
initLLGLState(GL_MULTISAMPLE_ARB, false, nullptr);
initLLGLState(GL_POLYGON_OFFSET_FILL, false, nullptr);
initLLGLState(GL_POLYGON_OFFSET_LINE, false, nullptr);
initLLGLState(GL_POLYGON_SMOOTH, false, nullptr);
initLLGLState(GL_SCISSOR_TEST, false, nullptr);
initLLGLState(GL_STENCIL_TEST, false, nullptr);
initLLGLState(GL_ALPHA_TEST, false, &LLGLSLShader::sNoFixedFunction);
initLLGLState(GL_COLOR_MATERIAL, false, &LLGLSLShader::sNoFixedFunction);
initLLGLState(GL_FOG, false, &LLGLSLShader::sNoFixedFunction);
initLLGLState(GL_LINE_STIPPLE, false, &LLGLSLShader::sNoFixedFunction);
initLLGLState(GL_LIGHTING, false, &LLGLSLShader::sNoFixedFunction);
initLLGLState(GL_NORMALIZE, false, &LLGLSLShader::sNoFixedFunction);
initLLGLState(GL_POLYGON_STIPPLE, false, &LLGLSLShader::sNoFixedFunction);
initLLGLState(GL_TEXTURE_GEN_Q, false, &LLGLSLShader::sNoFixedFunction);
initLLGLState(GL_TEXTURE_GEN_R, false, &LLGLSLShader::sNoFixedFunction);
initLLGLState(GL_TEXTURE_GEN_S, false, &LLGLSLShader::sNoFixedFunction);
initLLGLState(GL_TEXTURE_GEN_T, false, &LLGLSLShader::sNoFixedFunction);
void LLGLManager::initGLStates()
{
//gl states moved to classes in llglstates.h
LLGLState::initClass();
LLGLStateValidator::initClass();
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -30,7 +30,7 @@
// This file contains various stuff for handling gl extensions and other gl related stuff.
#include <string>
#include <boost/unordered_map.hpp>
#include <vector>
#include <list>
#include "llerror.h"
@@ -41,6 +41,7 @@
#include "llmatrix4a.h"
#include "llplane.h"
#include "llgltypes.h"
#include "llrender.h"
#include "llinstancetracker.h"
#include "llglheaders.h"
@@ -103,7 +104,6 @@ public:
BOOL mHasPointParameters;
BOOL mHasDrawBuffers;
BOOL mHasDepthClamp;
BOOL mHasTextureRectangle;
BOOL mHasTransformFeedback;
S32 mMaxIntegerSamples;
@@ -136,7 +136,6 @@ public:
BOOL mHasRequirements;
// Misc extensions
BOOL mHasSeparateSpecularColor;
//whether this GPU is in the debug list.
BOOL mDebugGPU;
@@ -227,13 +226,13 @@ void clear_glerror();
//disable lighting for rendering hud objects
//INCORRECT USAGE
LLGLEnable lighting(GL_LIGHTING);
LLGLEnable<GL_LIGHTING> lighting;
renderHUD();
LLGLDisable lighting(GL_LIGHTING);
LLGLDisable<GL_LIGHTING> lighting;
//CORRECT USAGE
{
LLGLEnable lighting(GL_LIGHTING);
LLGLEnable<GL_LIGHTING> lighting;
renderHUD();
}
@@ -241,12 +240,10 @@ void clear_glerror();
is useful:
{
LLGLEnable lighting(light_hud ? GL_LIGHTING : 0);
LLGLEnable<GL_LIGHTING> lighting(light_hud);
renderHUD();
}
A LLGLState initialized with a parameter of 0 does nothing.
LLGLState works by maintaining a map of the current GL states, and ignoring redundant
enables/disables. If a redundant call is attempted, it becomes a noop, otherwise,
it is set in the constructor and reset in the destructor.
@@ -255,59 +252,116 @@ void clear_glerror();
if the existing GL state does not match the expected GL state.
*/
class LLGLState
{
public:
static void initClass();
static void restoreGL();
struct LLGLStateStaticData
{
const char* stateStr;
LLGLenum state;
bool currentState;
U32 depth;
char* activeInstance;
bool* disabler;
};
class LLGLStateValidator {
public:
static void resetTextureStates();
static void dumpStates();
static void checkStates(const std::string& msg = "");
static void checkTextureChannels(const std::string& msg = "");
static void checkClientArrays(const std::string& msg = "", U32 data_mask = 0);
protected:
static boost::unordered_map<LLGLenum, LLGLboolean> sStateMap;
static void checkState(LLGLStateStaticData& data);
static void initClass();
static void restoreGL();
static bool registerStateData(LLGLStateStaticData& data);
private:
static std::vector<LLGLStateStaticData*> sStateDataVec;
};
class LLGLStateIface {
public:
enum { CURRENT_STATE = -2 };
LLGLState(LLGLenum state, S32 enabled = CURRENT_STATE);
~LLGLState();
void setEnabled(S32 enabled);
void enable() { setEnabled(TRUE); }
void disable() { setEnabled(FALSE); }
protected:
LLGLenum mState;
BOOL mWasEnabled;
BOOL mIsEnabled;
virtual ~LLGLStateIface() {}
virtual void enable() = 0;
virtual void disable() = 0;
};
// New LLGLState class wrappers that don't depend on actual GL flags.
class LLGLEnableBlending : public LLGLState
template <LLGLenum state>
class LLGLState : public LLGLStateIface
{
public:
LLGLEnableBlending(bool enable);
LLGLState(S8 newState = CURRENT_STATE)
{
++staticData.depth;
mPriorInstance = staticData.activeInstance;
staticData.activeInstance = (char*)this;
mPriorState = staticData.currentState;
setEnabled(newState);
}
virtual ~LLGLState()
{
llassert_always(staticData.activeInstance == (char*)this);
if (staticData.depth != 0)
{
staticData.activeInstance = mPriorInstance;
--staticData.depth;
if (gDebugGL) {
LLGLStateValidator::checkState(staticData);
}
setState(mPriorState);
}
else
{
llassert_always(mPriorInstance == nullptr);
}
}
virtual void enable() { setEnabled(true); }
virtual void disable() { setEnabled(false); }
static LLGLStateStaticData staticData;
// Getter
static bool isEnabled() { return staticData.currentState && (!staticData.disabler || !*staticData.disabler); }
// For assertions. If feature is on or unsupported, return true.
static bool checkEnabled() { return (!staticData.disabler || !*staticData.disabler) ? staticData.currentState : true; }
// For assertions. If feature is off or unsupported, return true.
static bool checkDisabled() { return (!staticData.disabler || !*staticData.disabler) ? !staticData.currentState : true; }
private:
char *mPriorInstance;
bool mPriorState;
void setEnabled(S32 newState)
{
llassert_always(staticData.activeInstance == (char*)this);
bool enabled = newState == CURRENT_STATE ? staticData.currentState : !!newState;
setState(enabled);
}
static void setState(bool enabled)
{
if (staticData.currentState != enabled && (!staticData.disabler || !*staticData.disabler))
{
gGL.flush();
staticData.currentState = enabled;
staticData.currentState ? glEnable(state) : glDisable(state);
}
}
};
#define initLLGLState(state, value, disabler_ptr) \
LLGLStateStaticData LLGLState<state>::staticData = {#state, state, value, 0, nullptr, disabler_ptr}; \
bool registered_##state = LLGLStateValidator::registerStateData(LLGLState<state>::staticData);
template <LLGLenum state>
struct LLGLEnable : public LLGLState<state>
{
LLGLEnable(bool noskip = true) : LLGLState<state>(noskip ? TRUE : LLGLState<state>::CURRENT_STATE) {}
};
class LLGLEnableAlphaReject : public LLGLState
template <LLGLenum state>
struct LLGLDisable : public LLGLState<state>
{
public:
LLGLEnableAlphaReject(bool enable);
};
/// TODO: Being deprecated.
class LLGLEnable : public LLGLState
{
public:
LLGLEnable(LLGLenum state) : LLGLState(state, TRUE) {}
};
/// TODO: Being deprecated.
class LLGLDisable : public LLGLState
{
public:
LLGLDisable(LLGLenum state) : LLGLState(state, FALSE) {}
LLGLDisable(bool noskip = true) : LLGLState<state>(noskip ? FALSE : LLGLState<state>::CURRENT_STATE) {}
};
/*
@@ -460,8 +514,6 @@ public:
#include "llglstates.h"
void init_glstates();
void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor_specific, std::string* version_string );
extern BOOL gClothRipple;

View File

@@ -122,7 +122,8 @@ extern PFNGLPOINTPARAMETERFARBPROC glPointParameterfARB;
extern PFNGLPOINTPARAMETERFVARBPROC glPointParameterfvARB;
// GL_ARB_shader_objects
extern PFNGLDELETEOBJECTARBPROC glDeleteObjectARB;
extern PFNGLDELETEOBJECTARBPROC glDeleteShader;
extern PFNGLDELETEOBJECTARBPROC glDeleteProgram;
extern PFNGLGETHANDLEARBPROC glGetHandleARB;
extern PFNGLDETACHOBJECTARBPROC glDetachObjectARB;
extern PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB;
@@ -153,9 +154,10 @@ extern PFNGLUNIFORMMATRIX2FVARBPROC glUniformMatrix2fvARB;
extern PFNGLUNIFORMMATRIX3FVARBPROC glUniformMatrix3fvARB;
extern PFNGLUNIFORMMATRIX3X4FVPROC glUniformMatrix3x4fv;
extern PFNGLUNIFORMMATRIX4FVARBPROC glUniformMatrix4fvARB;
extern PFNGLGETOBJECTPARAMETERFVARBPROC glGetObjectParameterfvARB;
extern PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB;
extern PFNGLGETINFOLOGARBPROC glGetInfoLogARB;
extern PFNGLGETOBJECTPARAMETERIVARBPROC glGetShaderiv;
extern PFNGLGETOBJECTPARAMETERIVARBPROC glGetProgramiv;
extern PFNGLGETINFOLOGARBPROC glGetShaderInfoLog;
extern PFNGLGETINFOLOGARBPROC glGetProgramInfoLog;
extern PFNGLGETATTACHEDOBJECTSARBPROC glGetAttachedObjectsARB;
extern PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB;
extern PFNGLGETACTIVEUNIFORMARBPROC glGetActiveUniformARB;
@@ -386,7 +388,8 @@ extern PFNGLPOINTPARAMETERFARBPROC glPointParameterfARB;
extern PFNGLPOINTPARAMETERFVARBPROC glPointParameterfvARB;
// GL_ARB_shader_objects
extern PFNGLDELETEOBJECTARBPROC glDeleteObjectARB;
extern PFNGLDELETEOBJECTARBPROC glDeleteShader;
extern PFNGLDELETEOBJECTARBPROC glDeleteProgram;
extern PFNGLGETHANDLEARBPROC glGetHandleARB;
extern PFNGLDETACHOBJECTARBPROC glDetachObjectARB;
extern PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB;
@@ -417,9 +420,10 @@ extern PFNGLUNIFORMMATRIX2FVARBPROC glUniformMatrix2fvARB;
extern PFNGLUNIFORMMATRIX3FVARBPROC glUniformMatrix3fvARB;
extern PFNGLUNIFORMMATRIX3X4FVPROC glUniformMatrix3x4fv;
extern PFNGLUNIFORMMATRIX4FVARBPROC glUniformMatrix4fvARB;
extern PFNGLGETOBJECTPARAMETERFVARBPROC glGetObjectParameterfvARB;
extern PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB;
extern PFNGLGETINFOLOGARBPROC glGetInfoLogARB;
extern PFNGLGETOBJECTPARAMETERIVARBPROC glGetShaderiv;
extern PFNGLGETOBJECTPARAMETERIVARBPROC glGetProgramiv;
extern PFNGLGETINFOLOGARBPROC glGetShaderInfoLog;
extern PFNGLGETINFOLOGARBPROC glGetProgramInfoLog;
extern PFNGLGETATTACHEDOBJECTSARBPROC glGetAttachedObjectsARB;
extern PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB;
extern PFNGLGETACTIVEUNIFORMARBPROC glGetActiveUniformARB;
@@ -626,7 +630,8 @@ extern PFNGLPOINTPARAMETERFARBPROC glPointParameterfARB;
extern PFNGLPOINTPARAMETERFVARBPROC glPointParameterfvARB;
// GL_ARB_shader_objects
extern PFNGLDELETEOBJECTARBPROC glDeleteObjectARB;
extern PFNGLDELETEOBJECTARBPROC glDeleteShader;
extern PFNGLDELETEOBJECTARBPROC glDeleteProgram;
extern PFNGLGETHANDLEARBPROC glGetHandleARB;
extern PFNGLDETACHOBJECTARBPROC glDetachObjectARB;
extern PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB;
@@ -657,9 +662,10 @@ extern PFNGLUNIFORMMATRIX2FVARBPROC glUniformMatrix2fvARB;
extern PFNGLUNIFORMMATRIX3FVARBPROC glUniformMatrix3fvARB;
extern PFNGLUNIFORMMATRIX3X4FVPROC glUniformMatrix3x4fv;
extern PFNGLUNIFORMMATRIX4FVARBPROC glUniformMatrix4fvARB;
extern PFNGLGETOBJECTPARAMETERFVARBPROC glGetObjectParameterfvARB;
extern PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB;
extern PFNGLGETINFOLOGARBPROC glGetInfoLogARB;
extern PFNGLGETOBJECTPARAMETERIVARBPROC glGetShaderiv;
extern PFNGLGETOBJECTPARAMETERIVARBPROC glGetProgramiv;
extern PFNGLGETINFOLOGARBPROC glGetShaderInfoLog;
extern PFNGLGETINFOLOGARBPROC glGetProgramInfoLog;
extern PFNGLGETATTACHEDOBJECTSARBPROC glGetAttachedObjectsARB;
extern PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB;
extern PFNGLGETACTIVEUNIFORMARBPROC glGetActiveUniformARB;

View File

@@ -348,7 +348,7 @@ void LLGLSLShader::unload()
glDeleteObjectARB(obj[i]);
}*/
if(mProgramObject)
glDeleteObjectARB(mProgramObject);
glDeleteProgram(mProgramObject);
mProgramObject = 0;
}
@@ -388,7 +388,7 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
BOOL success = TRUE;
if(mProgramObject) //purge the old program
glDeleteObjectARB(mProgramObject);
glDeleteProgram(mProgramObject);
// Create program
mProgramObject = glCreateProgramObjectARB();
@@ -417,7 +417,7 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
if (!LLShaderMgr::instance()->attachClassSharedShaders(*this, mShaderClass) || !LLShaderMgr::instance()->attachShaderFeatures(this))
{
if(mProgramObject)
glDeleteObjectARB(mProgramObject);
glDeleteProgram(mProgramObject);
mProgramObject = 0;
return FALSE;
}
@@ -447,7 +447,7 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
if( !success )
{
if(mProgramObject)
glDeleteObjectARB(mProgramObject);
glDeleteProgram(mProgramObject);
mProgramObject = 0;
LL_WARNS("ShaderLoading") << "Failed to link shader: " << mName << LL_ENDL;
@@ -723,6 +723,7 @@ GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type)
if (type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB /*||
type == GL_SAMPLER_2D_MULTISAMPLE*/)
{ //this here is a texture
gGL.syncShaders();
glUniform1iARB(location, mActiveTextureChannels);
LL_DEBUGS("ShaderLoading") << "Assigned to texture channel " << mActiveTextureChannels << LL_ENDL;
return mActiveTextureChannels++;
@@ -752,7 +753,7 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
//get the number of active uniforms
GLint activeCount;
glGetObjectParameterivARB(mProgramObject, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &activeCount);
glGetProgramiv(mProgramObject, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &activeCount);
for (S32 i = 0; i < activeCount; i++)
{
@@ -776,7 +777,7 @@ void LLGLSLShader::bind()
if (gGLManager.mHasShaderObjects)
{
LLVertexBuffer::unbind();
glUseProgramObjectARB(mProgramObject);
gGL.setShader(mProgramObject);
sCurBoundShader = mProgramObject;
sCurBoundShaderPtr = this;
if (mUniformsDirty)
@@ -802,7 +803,7 @@ void LLGLSLShader::unbind()
}
}
LLVertexBuffer::unbind();
glUseProgramObjectARB(0);
gGL.setShader(0);
sCurBoundShader = 0;
sCurBoundShaderPtr = NULL;
stop_glerror();
@@ -814,7 +815,7 @@ void LLGLSLShader::bindNoShader(void)
LLVertexBuffer::unbind();
if (gGLManager.mHasShaderObjects)
{
glUseProgramObjectARB(0);
gGL.setShader(0);
sCurBoundShader = 0;
sCurBoundShaderPtr = NULL;
}

View File

@@ -82,6 +82,7 @@ public:
static GLhandleARB sCurBoundShader;
static LLGLSLShader* sCurBoundShaderPtr;
static S32 sIndexedTextureChannels;
static bool sNoFixedFunction;
@@ -145,6 +146,7 @@ public:
F32 val = x;
if (updateUniform<LLVector4, 1>(mValueVec4, getUniformFromIndex(index), &val))
{
gGL.syncShaders();
glUniform1iARB(mUniform[index], x);
}
}
@@ -152,6 +154,7 @@ public:
{
if (updateUniform<LLVector4, 1>(mValueVec4, getUniformFromIndex(index), &x))
{
gGL.syncShaders();
glUniform1fARB(mUniform[index], x);
}
}
@@ -160,6 +163,7 @@ public:
F32 val[] = { x, y };
if (updateUniform<LLVector4, 2>(mValueVec4, getUniformFromIndex(index), val))
{
gGL.syncShaders();
glUniform2fARB(mUniform[index], x, y);
}
}
@@ -168,6 +172,7 @@ public:
F32 val[] = { x, y, z };
if (updateUniform<LLVector4, 3>(mValueVec4, getUniformFromIndex(index), val))
{
gGL.syncShaders();
glUniform3fARB(mUniform[index], x, y, z);
}
}
@@ -176,6 +181,7 @@ public:
F32 val[] = { x, y, z, w };
if (updateUniform<LLVector4, 4>(mValueVec4, getUniformFromIndex(index), val))
{
gGL.syncShaders();
glUniform4fARB(mUniform[index], x, y, z, w);
}
}
@@ -184,6 +190,7 @@ public:
F32 val[] = { static_cast<const F32>(v[0]) };
if (updateUniform<LLVector4, 1>(mValueVec4, getUniformFromIndex(index), val) || count > 1)
{
gGL.syncShaders();
glUniform1ivARB(mUniform[index], count, v);
}
}
@@ -191,6 +198,7 @@ public:
{
if (updateUniform<LLVector4, 1>(mValueVec4, getUniformFromIndex(index), v) || count > 1)
{
gGL.syncShaders();
glUniform1fvARB(mUniform[index], count, v);
}
}
@@ -198,6 +206,7 @@ public:
{
if (updateUniform<LLVector4, 2>(mValueVec4, getUniformFromIndex(index), v) || count > 1)
{
gGL.syncShaders();
glUniform2fvARB(mUniform[index], count, v);
}
}
@@ -205,6 +214,7 @@ public:
{
if (updateUniform<LLVector4, 3>(mValueVec4, getUniformFromIndex(index), v) || count > 1)
{
gGL.syncShaders();
glUniform3fvARB(mUniform[index], count, v);
}
}
@@ -212,6 +222,7 @@ public:
{
if (updateUniform<LLVector4, 4>(mValueVec4, getUniformFromIndex(index), v) || count > 1)
{
gGL.syncShaders();
glUniform4fvARB(mUniform[index], count, v);
}
}
@@ -219,6 +230,7 @@ public:
{
if (updateUniform<LLMatrix3, 9>(mValueMat3, getUniformFromIndex(index), v) || count > 1)
{
gGL.syncShaders();
glUniformMatrix3fvARB(mUniform[index], count, transpose, v);
}
}
@@ -226,6 +238,7 @@ public:
{
if (updateUniform<LLMatrix4, 12>(mValueMat4, getUniformFromIndex(index), v) || count > 1)
{
gGL.syncShaders();
glUniformMatrix3x4fv(mUniform[index], count, transpose, v);
}
}
@@ -233,6 +246,7 @@ public:
{
if (updateUniform<LLMatrix4, 16>(mValueMat4, getUniformFromIndex(index), v) || count > 1)
{
gGL.syncShaders();
glUniformMatrix4fvARB(mUniform[index], count, transpose, v);
}
}
@@ -244,6 +258,7 @@ public:
F32 val = i;
if (updateUniform<LLVector4, 1>(mValueVec4, getUniformLocation(uniform), &val))
{
gGL.syncShaders();
glUniform1iARB(location, i);
}
}
@@ -254,6 +269,7 @@ public:
return;
if (updateUniform<LLVector4, 1>(mValueVec4, location, &v))
{
gGL.syncShaders();
glUniform1fARB(location, v);
}
}
@@ -265,6 +281,7 @@ public:
F32 val[] = { x, y };
if (updateUniform<LLVector4, 2>(mValueVec4, location, val))
{
gGL.syncShaders();
glUniform2fARB(location, x, y);
}
}
@@ -276,6 +293,7 @@ public:
F32 val[] = { x, y, z };
if (updateUniform<LLVector4, 3>(mValueVec4, location, val))
{
gGL.syncShaders();
glUniform3fARB(location, x, y, z);
}
}
@@ -286,6 +304,7 @@ public:
return;
if (updateUniform<LLVector4, 1>(mValueVec4, location, v))
{
gGL.syncShaders();
glUniform1fvARB(location, count, v);
}
}
@@ -296,6 +315,7 @@ public:
return;
if (updateUniform<LLVector4, 2>(mValueVec4, location, v))
{
gGL.syncShaders();
glUniform2fvARB(location, count, v);
}
}
@@ -306,6 +326,7 @@ public:
return;
if (updateUniform<LLVector4, 3>(mValueVec4, location, v))
{
gGL.syncShaders();
glUniform3fvARB(location, count, v);
}
}
@@ -316,6 +337,7 @@ public:
return;
if (updateUniform<LLVector4, 4>(mValueVec4, location, v))
{
gGL.syncShaders();
glUniform4fvARB(location, count, v);
}
}
@@ -326,6 +348,7 @@ public:
return;
if (updateUniform<LLMatrix4, 16>(mValueMat4, location, v))
{
gGL.syncShaders();
glUniformMatrix4fvARB(location, count, transpose, v);
}
}
@@ -344,6 +367,7 @@ public:
{
if (gDebugGL)
{
gGL.syncShaders();
stop_glerror();
if (iter->second != glGetUniformLocationARB(mProgramObject, uniform.String().c_str()))
{

View File

@@ -53,181 +53,128 @@ private:
//----------------------------------------------------------------------------
class LLGLSDefault
struct LLGLSDefault
{
protected:
LLGLEnable mColorMaterial;
LLGLDisable mAlphaTest, mBlend, mCullFace, mDither, mFog,
mLineSmooth, mLineStipple, mNormalize, mPolygonSmooth,
mGLMultisample;
public:
LLGLSDefault()
:
// Enable
mColorMaterial(GL_COLOR_MATERIAL),
// Disable
mAlphaTest(GL_ALPHA_TEST),
mBlend(GL_BLEND),
mCullFace(GL_CULL_FACE),
mDither(GL_DITHER),
mFog(GL_FOG),
mLineSmooth(GL_LINE_SMOOTH),
mLineStipple(GL_LINE_STIPPLE),
mNormalize(GL_NORMALIZE),
mPolygonSmooth(GL_POLYGON_SMOOTH),
mGLMultisample(GL_MULTISAMPLE_ARB)
{ }
private:
LLGLEnable<GL_COLOR_MATERIAL> mColorMaterial;
LLGLDisable<GL_ALPHA_TEST> mAlphaTest;
LLGLDisable<GL_BLEND> mBlend;
LLGLDisable<GL_CULL_FACE> mCullFace;
LLGLDisable<GL_DITHER> mDither;
LLGLDisable<GL_FOG> mFog;
LLGLDisable<GL_LINE_SMOOTH> mLineSmooth;
LLGLDisable<GL_LINE_STIPPLE> mLineStipple;
LLGLDisable<GL_NORMALIZE> mNormalize;
LLGLDisable<GL_POLYGON_SMOOTH> mPolygonSmooth;
LLGLDisable<GL_MULTISAMPLE_ARB> mGLMultisample;
LLGLDisable<GL_LIGHTING> lighting;
};
class LLGLSObjectSelect
{
protected:
LLGLDisable mBlend, mFog, mAlphaTest;
LLGLEnable mCullFace;
public:
LLGLSObjectSelect()
: mBlend(GL_BLEND), mFog(GL_FOG),
mAlphaTest(GL_ALPHA_TEST),
mCullFace(GL_CULL_FACE)
{ }
struct LLGLSObjectSelect
{
private:
LLGLDisable<GL_BLEND> mBlend;
LLGLDisable<GL_ALPHA_TEST> mAlphaTest;
LLGLDisable<GL_FOG> mFog;
LLGLEnable<GL_CULL_FACE> mCullFace;
};
class LLGLSObjectSelectAlpha
struct LLGLSObjectSelectAlpha
{
protected:
LLGLEnable mAlphaTest;
public:
LLGLSObjectSelectAlpha()
: mAlphaTest(GL_ALPHA_TEST)
{}
private:
LLGLEnable<GL_ALPHA_TEST> mAlphaTest;
};
//----------------------------------------------------------------------------
class LLGLSUIDefault
struct LLGLSUIDefault
{
protected:
LLGLEnable mBlend, mAlphaTest;
LLGLDisable mCullFace;
private:
LLGLEnable<GL_BLEND> mBlend;
LLGLEnable<GL_ALPHA_TEST> mAlphaTest;
LLGLDisable<GL_CULL_FACE> mCullFace;
LLGLDisable<GL_MULTISAMPLE_ARB> mMSAA;
//LLGLEnable<GL_SCISSOR_TEST> mScissor;
LLGLDepthTest mDepthTest;
LLGLDisable mMSAA;
public:
LLGLSUIDefault()
: mBlend(GL_BLEND), mAlphaTest(GL_ALPHA_TEST),
mCullFace(GL_CULL_FACE),
mDepthTest(GL_FALSE, GL_TRUE, GL_LEQUAL),
mMSAA(GL_MULTISAMPLE_ARB)
LLGLSUIDefault()
: mDepthTest(GL_FALSE, GL_TRUE, GL_LEQUAL)
{}
};
class LLGLSNoAlphaTest // : public LLGLSUIDefault
struct LLGLSNoAlphaTest // : public LLGLSUIDefault
{
protected:
LLGLDisable mAlphaTest;
public:
LLGLSNoAlphaTest()
: mAlphaTest(GL_ALPHA_TEST)
{}
private:
LLGLDisable<GL_ALPHA_TEST> mAlphaTest;
};
//----------------------------------------------------------------------------
class LLGLSFog
struct LLGLSFog
{
protected:
LLGLEnable mFog;
public:
LLGLSFog()
: mFog(GL_FOG)
{}
private:
LLGLEnable<GL_FOG> mFog;
};
class LLGLSNoFog
struct LLGLSNoFog
{
protected:
LLGLDisable mFog;
public:
LLGLSNoFog()
: mFog(GL_FOG)
{}
private:
LLGLDisable<GL_FOG> mFog;
};
//----------------------------------------------------------------------------
class LLGLSPipeline
struct LLGLSPipeline
{
protected:
LLGLEnable mCullFace;
private:
LLGLEnable<GL_CULL_FACE> mCullFace;
LLGLDepthTest mDepthTest;
public:
LLGLSPipeline()
: mCullFace(GL_CULL_FACE),
mDepthTest(GL_TRUE, GL_TRUE, GL_LEQUAL)
{ }
: mDepthTest(GL_TRUE, GL_TRUE, GL_LEQUAL)
{}
};
class LLGLSPipelineAlpha // : public LLGLSPipeline
struct LLGLSPipelineAlpha // : public LLGLSPipeline
{
protected:
LLGLEnable mBlend, mAlphaTest;
public:
LLGLSPipelineAlpha()
: mBlend(GL_BLEND),
mAlphaTest(GL_ALPHA_TEST)
{ }
private:
LLGLEnable<GL_ALPHA_TEST> mAlphaTest;
LLGLEnable<GL_BLEND> mBlend;
};
class LLGLSPipelineEmbossBump
struct LLGLSPipelineEmbossBump
{
protected:
LLGLDisable mFog;
public:
LLGLSPipelineEmbossBump()
: mFog(GL_FOG)
{ }
private:
LLGLDisable<GL_FOG> mFog;
};
class LLGLSPipelineSelection
struct LLGLSPipelineSelection
{
protected:
LLGLDisable mCullFace;
public:
LLGLSPipelineSelection()
: mCullFace(GL_CULL_FACE)
{}
private:
LLGLDisable<GL_CULL_FACE> mCullFace;
};
class LLGLSPipelineAvatar
struct LLGLSPipelineAvatar
{
protected:
LLGLEnable mNormalize;
public:
LLGLSPipelineAvatar()
: mNormalize(GL_NORMALIZE)
{}
private:
LLGLEnable<GL_NORMALIZE> mNormalize;
};
class LLGLSPipelineSkyBox
struct LLGLSPipelineSkyBox
{
protected:
LLGLDisable mAlphaTest, mCullFace, mFog;
public:
LLGLSPipelineSkyBox()
: mAlphaTest(GL_ALPHA_TEST), mCullFace(GL_CULL_FACE), mFog(GL_FOG)
{ }
private:
LLGLDisable<GL_ALPHA_TEST> mAlphaTest;
LLGLDisable<GL_CULL_FACE> mCullFace;
LLGLDisable<GL_FOG> mFog;
LLGLDisable<GL_LIGHTING> mLighting;
};
class LLGLSTracker
struct LLGLSTracker
{
protected:
LLGLEnable mCullFace, mBlend, mAlphaTest;
public:
LLGLSTracker() :
mCullFace(GL_CULL_FACE),
mBlend(GL_BLEND),
mAlphaTest(GL_ALPHA_TEST)
{ }
private:
LLGLEnable<GL_ALPHA_TEST> mAlphaTest;
LLGLEnable<GL_BLEND> mBlend;
LLGLEnable<GL_CULL_FACE> mCullFace;
};
//----------------------------------------------------------------------------

View File

@@ -167,7 +167,7 @@ BOOL LLGLTexture::createGLTexture()
return mGLTexturep->createGLTexture() ;
}
BOOL LLGLTexture::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename, BOOL to_create, S32 category)
BOOL LLGLTexture::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, LLImageGL::GLTextureName& usename, BOOL to_create, S32 category)
{
llassert(mGLTexturep.notNull()) ;

View File

@@ -123,8 +123,7 @@ public:
BOOL hasGLTexture() const ;
LLGLuint getTexName() const ;
BOOL createGLTexture() ;
BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE, S32 category = LLGLTexture::OTHER);
BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, LLImageGL::GLTextureName& usename = LLImageGL::GLTextureName(), BOOL to_create = TRUE, S32 category = LLGLTexture::OTHER);
void setFilteringOption(LLTexUnit::eTextureFilterOptions option);
void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE);
void setAddressMode(LLTexUnit::eTextureAddressMode mode);

View File

@@ -86,6 +86,9 @@ std::vector<S64Bytes> LLImageGL::sTextureCurMemByCategoryBound ;
//End for texture auditing use only
// ****************************************************************************************************
//static std::vector<U32> sActiveTextureNames;
//static std::vector<U32> sDeletedTextureNames;
// **************************************************************************************
//below are functions for debug use
//do not delete them even though they are not currently being used.
@@ -118,9 +121,9 @@ void LLImageGL::checkTexSize(bool forced) const
GLint texname;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &texname);
BOOL error = FALSE;
if (texname != mTexName)
if (texname != getTexName())
{
LL_INFOS() << "Bound: " << texname << " Should bind: " << mTexName << " Default: " << LLImageGL::sDefaultGLTexture->getTexName() << LL_ENDL;
LL_INFOS() << "Bound: " << texname << " Should bind: " << getTexName() << " Default: " << (LLImageGL::sDefaultGLTexture ? LLImageGL::sDefaultGLTexture->getTexName() : 0) << LL_ENDL;
error = TRUE;
if (gDebugSession)
@@ -219,7 +222,7 @@ void LLImageGL::setHighlightTexture(S32 category)
}
}
}
sHighlightTexturep->createGLTexture(0, image_raw, 0, TRUE, category);
sHighlightTexturep->createGLTexture(0, image_raw, LLImageGL::GLTextureName(), TRUE, category);
image_raw = NULL;
}
@@ -328,47 +331,48 @@ S32 LLImageGL::updateBoundTexMem(const S32Bytes mem, const S32 ncomponents, S32
//static
void LLImageGL::destroyGL(BOOL save_state)
{
LLTexUnit::sWhiteTexture = 0;
if (save_state)
{
U32 count = 0;
sAllowReadBackRaw = true;
for (std::set<LLImageGL*>::iterator iter = sImageList.begin();
iter != sImageList.end(); iter++)
{
LLImageGL* glimage = *iter;
GLuint tex = glimage->getTexName();
if (tex)
{
if (glimage->isGLTextureCreated())
{
glimage->mSaveData = new LLImageRaw;
if (glimage->mComponents && glimage->readBackRaw(-1, glimage->mSaveData, false))//necessary, keep it.
{
++count;
glimage->mSaveDiscardLevel = glimage->mCurrentDiscardLevel;
glimage->destroyGLTexture();
continue;
}
}
}
glimage->mSaveData = nullptr;
glimage->forceToInvalidateGLTexture();
stop_glerror();
}
LL_INFOS() << "Storing " << count << " images..." << LL_ENDL;
sAllowReadBackRaw = false;
}
for (S32 stage = 0; stage < gGLManager.mNumTextureUnits; stage++)
{
gGL.getTexUnit(stage)->unbind(LLTexUnit::TT_TEXTURE);
}
sAllowReadBackRaw = true ;
std::set<LLImageGL*> stored_images;
for (std::set<LLImageGL*>::iterator iter = sImageList.begin();
iter != sImageList.end(); iter++)
{
LLImageGL* glimage = *iter;
if (glimage->mTexName)
{
if (save_state && glimage->isGLTextureCreated() && glimage->mComponents)
{
glimage->mSaveData = new LLImageRaw;
if(!glimage->readBackRaw(glimage->mCurrentDiscardLevel, glimage->mSaveData, false)) //necessary, keep it.
{
delete glimage;
}
else
{
glimage->mSaveDiscardLevel = glimage->mCurrentDiscardLevel;
stored_images.insert(glimage);
glimage->destroyGLTexture();
}
}
stop_glerror();
}
}
sImageList = stored_images;
LL_INFOS() << "Storing " << stored_images.size() << " images..." << LL_ENDL;
sAllowReadBackRaw = false ;
//clean_validate_buffers();
}
//static
void LLImageGL::restoreGL()
{
std::set<LLImageGL*> restored_images;
U32 count = 0;
for (std::set<LLImageGL*>::iterator iter = sImageList.begin();
iter != sImageList.end(); iter++)
{
@@ -377,22 +381,32 @@ void LLImageGL::restoreGL()
{
LL_ERRS() << "tex name is not 0." << LL_ENDL ;
}
if (glimage->mSaveData.notNull() && glimage->getComponents() &&
glimage->mSaveData->getComponents() &&
LLPointer<LLImageRaw> data = glimage->mSaveData;
glimage->mSaveData = nullptr;
if (data.notNull() && glimage->getComponents() &&
data->getComponents() &&
glimage->mSaveDiscardLevel >= 0 &&
glimage->createGLTexture(glimage->mSaveDiscardLevel, glimage->mSaveData, 0, TRUE, glimage->getCategory()))
glimage->createGLTexture(glimage->mSaveDiscardLevel, data, LLImageGL::GLTextureName(), TRUE, glimage->getCategory()))
{
stop_glerror();
restored_images.insert(glimage);
/*if (glimage->getHasGLTexture())
{
LL_INFOS() << "Restored " << glimage << " texid:" << glimage->getTexName() << LL_ENDL;
}
else
{
LL_INFOS() << "Restored " << glimage << " texid: (null)" << LL_ENDL;
}*/
++count;
}
else
{
delete glimage;
//LL_INFOS() << "Skipped " << glimage << LL_ENDL;
glimage->forceToInvalidateGLTexture();
}
}
restored_images = restored_images;
LL_INFOS() << "Restored " << restored_images.size() << " images" << LL_ENDL;
LL_INFOS() << "Restored " << count << " images" << LL_ENDL;
}
//static
@@ -499,7 +513,7 @@ void LLImageGL::init(BOOL usemipmaps)
mAlphaOffset = INVALID_OFFSET ;
mGLTextureCreated = FALSE ;
mTexName = 0;
mTexName.reset();
mWidth = 0;
mHeight = 0;
mCurrentDiscardLevel = -1;
@@ -577,7 +591,7 @@ void LLImageGL::setSize(S32 width, S32 height, S32 ncomponents, S32 discard_leve
if (mTexName)
{
// LL_WARNS() << "Setting Size of LLImageGL with existing mTexName = " << mTexName << LL_ENDL;
// LL_WARNS() << "Setting Size of LLImageGL with existing mTexName = " << getTexName() << LL_ENDL;
destroyGLTexture();
}
@@ -634,7 +648,7 @@ void LLImageGL::dump()
<< LL_ENDL;
LL_INFOS() << " mTextureMemory " << mTextureMemory
<< " mTexNames " << mTexName
<< " mTexNames " << getTexName()
<< " mIsResident " << S32(mIsResident)
<< LL_ENDL;
}
@@ -647,7 +661,7 @@ void LLImageGL::forceUpdateBindStats(void) const
BOOL LLImageGL::updateBindStats(S32Bytes tex_mem) const
{
if (mTexName != 0)
if (getTexName())
{
#ifdef DEBUG_MISS
mMissed = ! getIsResident(TRUE);
@@ -959,7 +973,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
{
return TRUE;
}
if (mTexName == 0)
if (!getTexName())
{
// *TODO: Re-enable warning? Ran into thread locking issues? DK 2011-02-18
//LL_WARNS() << "Setting subimage on image without GL texture" << LL_ENDL;
@@ -1027,7 +1041,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
datap += (y_pos * data_width + x_pos) * getComponents();
// Update the GL texture
BOOL res = gGL.getTexUnit(0)->bindManual(mBindTarget, mTexName);
BOOL res = gGL.getTexUnit(0)->bindManual(mBindTarget, getTexName());
if (!res) LL_ERRS() << "LLImageGL::setSubImage(): bindTexture failed" << LL_ENDL;
stop_glerror();
@@ -1071,23 +1085,118 @@ BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_
}
}
/*void validate_add_texture(U32 name)
{
auto found = std::find(sActiveTextureNames.begin(), sActiveTextureNames.end(), name);
if (found != sActiveTextureNames.end())
{
LL_ERRS() << "Allocating allocated texture name " << name << LL_ENDL;
}
else
{
//LL_INFOS() << "Allocated buffer name " << name << LL_ENDL;
sActiveTextureNames.push_back(name);
}
}
void validate_del_texture(U32 name)
{
auto found = std::find(sActiveTextureNames.begin(), sActiveTextureNames.end(), name);
if (found == sActiveTextureNames.end())
{
if (std::find(sDeletedTextureNames.begin(), sDeletedTextureNames.end(), name) == sDeletedTextureNames.end())
{
LL_ERRS() << "Deleting unknown texture name " << name << LL_ENDL;
}
else
{
LL_ERRS() << "Deleting deleted texture name " << name << LL_ENDL;
}
}
else
{
//LL_INFOS() << "Deleted buffer name " << name << LL_ENDL;
sActiveTextureNames.erase(found);
sDeletedTextureNames.push_back(name);
}
}
void validate_bind_texture(U32 name)
{
auto found = std::find(sActiveTextureNames.begin(), sActiveTextureNames.end(), name);
if (found == sActiveTextureNames.end())
{
if (std::find(sDeletedTextureNames.begin(), sDeletedTextureNames.end(), name) == sDeletedTextureNames.end())
{
LL_ERRS() << "Binding unknown texture name " << name << LL_ENDL;
}
else
{
LL_ERRS() << "Binding deleted texture name " << name << LL_ENDL;
}
}
}
void clean_validate_buffers()
{
LL_INFOS() << "Clearing active buffer names. Count " << sActiveBufferNames.size() << LL_ENDL;
sActiveTextureNames.clear();
LL_INFOS() << "Clearing deleted buffer names. Count " << sDeletedBufferNames.size() << LL_ENDL;
sDeletedTextureNames.clear();
}*/
// static
static LLTrace::BlockTimerStatHandle FTM_GENERATE_TEXTURES("generate textures");
void LLImageGL::generateTextures(S32 numTextures, U32 *textures)
{
LL_RECORD_BLOCK_TIME(FTM_GENERATE_TEXTURES);
glGenTextures(numTextures, textures);
/*for (S32 i = 0; i < numTextures; ++i)
{
validate_add_texture(textures[i]);
}*/
}
// static
void LLImageGL::deleteTextures(S32 numTextures, U32 *textures)
void LLImageGL::deleteTextures(S32 numTextures, U32 *textures, const std::vector<AllocationInfo>& allocationData)
{
if (gGLManager.mInited)
{
for (auto& entry : allocationData)
{
texMemoryDeallocated(entry);
}
glDeleteTextures(numTextures, textures);
/*for (S32 i = 0; i < numTextures; ++i)
{
validate_del_texture(textures[i]);
}*/
}
}
// static
void LLImageGL::texMemoryAllocated(const AllocationInfo& entry)
{
sGlobalTextureMemory += (S64Bytes)entry.size;
if (gAuditTexture)
{
incTextureCounter((S64Bytes)entry.size, entry.components, entry.category);
}
}
// static
void LLImageGL::texMemoryDeallocated(const AllocationInfo& entry)
{
sGlobalTextureMemory -= (S64Bytes)entry.size;
if (gAuditTexture)
{
decTextureCounter((S64Bytes)entry.size, entry.components, entry.category);
}
}
//#include "crnlib.h"
struct DDS_PIXELFORMAT {
U32 dwSize;
@@ -1512,15 +1621,10 @@ BOOL LLImageGL::createGLTexture()
llassert(gGLManager.mInited);
stop_glerror();
if(mTexName)
{
LLImageGL::deleteTextures(1, (reinterpret_cast<GLuint*>(&mTexName))) ;
}
mTexName = createTextureName();
LLImageGL::generateTextures(1, &mTexName);
stop_glerror();
if (!mTexName)
if (!getTexName())
{
LL_ERRS() << "LLImageGL::createGLTexture failed to make an empty texture" << LL_ENDL;
}
@@ -1529,7 +1633,7 @@ BOOL LLImageGL::createGLTexture()
}
static LLTrace::BlockTimerStatHandle FTM_CREATE_GL_TEXTURE2("createGLTexture(raw)");
BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/, BOOL to_create, S32 category)
BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, GLTextureName& usename, BOOL to_create, S32 category)
{
LL_RECORD_BLOCK_TIME(FTM_CREATE_GL_TEXTURE2);
if (gGLManager.mIsDisabled)
@@ -1606,7 +1710,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
}
static LLTrace::BlockTimerStatHandle FTM_CREATE_GL_TEXTURE3("createGLTexture3(data)");
BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips, S32 usename)
BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips, GLTextureName& usename)
{
LL_RECORD_BLOCK_TIME(FTM_CREATE_GL_TEXTURE3);
llassert(data_in);
@@ -1619,23 +1723,23 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
}
discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel);
if (mTexName != 0 && discard_level == mCurrentDiscardLevel)
if (getTexName() != 0 && discard_level == mCurrentDiscardLevel)
{
// This will only be true if the size has not changed
setImage(data_in, data_hasmips);
//checkTexSize();
return TRUE;
}
U32 old_name = mTexName;
// S32 old_discard = mCurrentDiscardLevel;
if (usename != 0)
if (usename)
{
mTexName = usename;
}
else
{
LLImageGL::generateTextures(1, &mTexName);
mTexName = createTextureName();
stop_glerror();
{
llverify(gGL.getTexUnit(0)->bind(this));
@@ -1646,7 +1750,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
stop_glerror();
}
}
if (!mTexName)
if (!getTexName())
{
LL_ERRS() << "LLImageGL::createGLTexture failed to make texture" << LL_ENDL;
}
@@ -1666,37 +1770,25 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
mCurrentDiscardLevel = discard_level;
setImage(data_in, data_hasmips);
glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAX_LEVEL, mMaxDiscardLevel - discard_level);
// Set texture options to our defaults.
gGL.getTexUnit(0)->setHasMipMaps(mHasMipMaps);
gGL.getTexUnit(0)->setTextureAddressMode(mAddressMode);
gGL.getTexUnit(0)->setTextureFilteringOption(mFilterOption);
//gGL.getTexUnit(0)->unbind(mBindTarget);
//llverify(gGL.getTexUnit(0)->bindManual(mBindTarget, getTexName()));
//checkTexSize();
// things will break if we don't unbind after creation
gGL.getTexUnit(0)->unbind(mBindTarget);
stop_glerror();
if (old_name != 0)
{
sGlobalTextureMemory -= mTextureMemory;
if(gAuditTexture)
{
decTextureCounter(mTextureMemory, mComponents, mCategory) ;
}
LLImageGL::deleteTextures(1, &old_name);
stop_glerror();
}
mTextureMemory = (S32Bytes)getMipBytes(discard_level);
sGlobalTextureMemory += mTextureMemory;
if(gAuditTexture)
{
incTextureCounter(mTextureMemory, mComponents, mCategory) ;
}
mTexName->addAllocatedMemory(mTextureMemory, mComponents, mCategory);
// mark this as bound at this point, so we don't throw it out immediately
mLastBindTime = sLastFrameTime;
return TRUE;
@@ -1715,7 +1807,7 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre
return FALSE;
}
if (mTexName == 0 || discard_level < mCurrentDiscardLevel || discard_level > mMaxDiscardLevel )
if (getTexName() == 0 || discard_level < mCurrentDiscardLevel || discard_level > mMaxDiscardLevel )
{
return FALSE;
}
@@ -1724,7 +1816,7 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre
//explicitly unbind texture
gGL.getTexUnit(0)->unbind(mBindTarget);
llverify(gGL.getTexUnit(0)->bindManual(mBindTarget, mTexName));
llverify(gGL.getTexUnit(0)->bindManual(mBindTarget, getTexName()));
//debug code, leave it there commented.
checkTexSize() ;
@@ -1828,21 +1920,10 @@ void LLImageGL::deleteDeadTextures()
void LLImageGL::destroyGLTexture()
{
if (mTexName != 0)
if (getTexName())
{
if(mTextureMemory != S32Bytes(0))
{
if(gAuditTexture)
{
decTextureCounter(mTextureMemory, mComponents, mCategory) ;
}
sGlobalTextureMemory -= mTextureMemory;
mTextureMemory = (S32Bytes)0;
}
LLImageGL::deleteTextures(1, &mTexName);
mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel.
mTexName = 0;
mTexName.reset();
mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel.
mGLTextureCreated = FALSE ;
}
}
@@ -1850,7 +1931,7 @@ void LLImageGL::destroyGLTexture()
//force to invalidate the gl texture, most likely a sculpty texture
void LLImageGL::forceToInvalidateGLTexture()
{
if (mTexName != 0)
if (getTexName() != 0)
{
destroyGLTexture();
}
@@ -1870,7 +1951,8 @@ void LLImageGL::setAddressMode(LLTexUnit::eTextureAddressMode mode)
mAddressMode = mode;
}
if (gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->getCurrTexture() == mTexName)
GLuint tex = getTexName();
if (tex && gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->getCurrTexture() == tex)
{
gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->setTextureAddressMode(mode);
mTexOptionsDirty = false;
@@ -1885,7 +1967,8 @@ void LLImageGL::setFilteringOption(LLTexUnit::eTextureFilterOptions option)
mFilterOption = option;
}
if (mTexName != 0 && gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->getCurrTexture() == mTexName)
GLuint tex = getTexName();
if (tex && gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->getCurrTexture() == tex)
{
gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->setTextureFilteringOption(option);
mTexOptionsDirty = false;
@@ -1897,9 +1980,10 @@ BOOL LLImageGL::getIsResident(BOOL test_now)
{
if (test_now)
{
if (mTexName != 0)
GLuint tex = getTexName();
if (tex)
{
glAreTexturesResident(1, (GLuint*)&mTexName, &mIsResident);
glAreTexturesResident(1, (GLuint*)&tex, &mIsResident);
}
else
{

View File

@@ -45,12 +45,66 @@
class LLImageGL : public LLRefCount
{
friend class LLTexUnit;
friend class GLTextureName;
public:
struct AllocationInfo;
private:
// These 2 functions replace glGenTextures() and glDeleteTextures()
static void generateTextures(S32 numTextures, U32 *textures);
static void deleteTextures(S32 numTextures, U32 *textures);
static void deleteTextures(S32 numTextures, U32 *textures, const std::vector<AllocationInfo>& allocationData);
static void texMemoryAllocated(const AllocationInfo& entry);
static void texMemoryDeallocated(const AllocationInfo& entry);
public:
static void deleteDeadTextures();
struct AllocationInfo
{
AllocationInfo(S32Bytes& _size, U8 _components, U32 _category) :
size(_size), components(_components), category(_category)
{}
S32Bytes size;
U8 components;
U32 category;
};
// Singu Note:
// The topology of GLImageGL is wrong. As a result, tex names are shared across multiple LLImageGL
// instances. To avoid redundant glDelete calls gl tex names have been wrapped in GLTextureName,
// which is refcounted via std::shared_ptr.
class GLTextureNameInstance {
public:
GLTextureNameInstance(U32 size = 1) : mTexCount(size)
{
mTexNames.resize(mTexCount, 0);
LLImageGL::generateTextures(1, mTexNames.data());
}
~GLTextureNameInstance()
{
LLImageGL::deleteTextures(1, mTexNames.data(), mAllocationData);
}
GLuint getTexName(U32 idx = 0) const
{
return mTexNames[idx];
}
void addAllocatedMemory(S32Bytes size, U8 components, U32 category)
{
mAllocationData.emplace_back(size, components, category);
LLImageGL::texMemoryAllocated(mAllocationData.back());
}
const std::vector<AllocationInfo>& getAllocatedMemoryInfo() const
{
return mAllocationData;
}
private:
const size_t mTexCount;
std::vector<GLuint> mTexNames;
std::vector<AllocationInfo> mAllocationData;
};
typedef std::shared_ptr<GLTextureNameInstance> GLTextureName;
static GLTextureName createTextureName(U32 size = 0) {
return std::make_shared<GLTextureNameInstance>();
}
// Size calculation
static S32 dataFormatBits(S32 dataformat);
static S32 dataFormatBytes(S32 dataformat, S32 width, S32 height);
@@ -101,9 +155,9 @@ public:
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,
BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, GLTextureName& usename = GLTextureName(), BOOL to_create = TRUE,
S32 category = sMaxCategories-1);
BOOL createGLTexture(S32 discard_level, const U8* data, BOOL data_hasmips = FALSE, S32 usename = 0);
BOOL createGLTexture(S32 discard_level, const U8* data, BOOL data_hasmips = FALSE, GLTextureName& usename = GLTextureName());
void setImage(const LLImageRaw* imageraw);
void setImage(const U8* data_in, BOOL data_hasmips = FALSE);
BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE);
@@ -133,8 +187,8 @@ public:
LLGLenum getPrimaryFormat() const { return mFormatPrimary; }
LLGLenum getFormatType() const { return mFormatType; }
BOOL getHasGLTexture() const { return mTexName != 0; }
LLGLuint getTexName() const { return mTexName; }
BOOL getHasGLTexture() const { return mTexName != nullptr; }
LLGLuint getTexName() const { return mTexName ? mTexName->getTexName() : 0; }
BOOL getIsAlphaMask(const F32 max_rmse, const F32 max_mid) const { return mNeedsAlphaAndPickMask && (max_rmse < 0.f ? (bool)mIsMask : (mMaskRMSE <= max_rmse && mMaskMidPercentile <= max_mid)); }
@@ -197,7 +251,7 @@ private:
S8 mAlphaOffset ;
bool mGLTextureCreated ;
LLGLuint mTexName;
GLTextureName mTexName;
U16 mWidth;
U16 mHeight;
S8 mCurrentDiscardLevel;

View File

@@ -294,6 +294,7 @@ public:
{
if((S32)pass > mNumPasses*2)
return false;
gGL.syncShaders();
glUniform1iARB(mPassLoc, (pass-1) % 2);
return true;
}
@@ -445,18 +446,14 @@ void LLPostProcess::createScreenTextures()
mRenderTarget[1].allocate(mScreenWidth,mScreenHeight,GL_RGBA,FALSE,FALSE,type,FALSE);
stop_glerror();
if(mDepthTexture)
{
LLImageGL::deleteTextures(1, &mDepthTexture);
mDepthTexture = 0;
}
mDepthTexture.reset();
for(std::list<LLPointer<LLPostProcessShader> >::iterator it=mShaders.begin();it!=mShaders.end();++it)
{
if((*it)->getDepthChannel()>=0)
{
LLImageGL::generateTextures(1, &mDepthTexture);
gGL.getTexUnit(0)->bindManual(type, mDepthTexture);
mDepthTexture = LLImageGL::createTextureName();
gGL.getTexUnit(0)->bindManual(type, mDepthTexture->getTexName());
LLImageGL::setManualImage(LLTexUnit::getInternalType(type), 0, GL_DEPTH_COMPONENT24, mScreenWidth, mScreenHeight, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL, false);
stop_glerror();
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
@@ -477,15 +474,9 @@ void LLPostProcess::createNoiseTexture()
}
}
if(mNoiseTexture)
{
LLImageGL::deleteTextures(1, &mNoiseTexture);
mNoiseTexture = 0;
}
LLImageGL::generateTextures(1, &mNoiseTexture);
mNoiseTexture = LLImageGL::createTextureName();
stop_glerror();
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseTexture);
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseTexture->getTexName());
stop_glerror();
LLImageGL::setManualImage(GL_TEXTURE_2D, 0, GL_LUMINANCE8, NOISE_SIZE, NOISE_SIZE, GL_LUMINANCE, GL_UNSIGNED_BYTE, &buffer[0], false);
@@ -500,11 +491,8 @@ void LLPostProcess::destroyGL()
{
mRenderTarget[0].release();
mRenderTarget[1].release();
if(mDepthTexture)
LLImageGL::deleteTextures(1, &mDepthTexture);
mDepthTexture=0;
if(mNoiseTexture)
LLImageGL::deleteTextures(1, &mNoiseTexture);
mDepthTexture.reset();
mNoiseTexture.reset();
mNoiseTexture=0 ;
mVBO = NULL ;
}
@@ -527,7 +515,7 @@ void LLPostProcess::copyFrameBuffer()
{
if((*it)->isEnabled() && (*it)->getDepthChannel()>=0)
{
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mDepthTexture);
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mDepthTexture->getTexName());
glCopyTexSubImage2D(GL_TEXTURE_2D,0,0,0,0,0,mScreenWidth, mScreenHeight);
stop_glerror();
break;
@@ -539,7 +527,7 @@ void LLPostProcess::copyFrameBuffer()
void LLPostProcess::bindNoise(U32 channel)
{
gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE,mNoiseTexture);
gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE,mNoiseTexture->getTexName());
}
void LLPostProcess::renderEffects(unsigned int width, unsigned int height)
@@ -570,7 +558,7 @@ void LLPostProcess::doEffects(void)
//Disable depth. Set blendmode to replace.
LLGLDepthTest depth(GL_FALSE,GL_FALSE);
LLGLEnable blend(GL_BLEND);
LLGLEnable<GL_BLEND> blend;
gGL.setSceneBlendType(LLRender::BT_REPLACE);
/// Change to an orthogonal view
@@ -608,7 +596,7 @@ void LLPostProcess::applyShaders(void)
S32 color_channel = (*it)->getColorChannel();
S32 depth_channel = (*it)->getDepthChannel();
if(depth_channel >= 0)
gGL.getTexUnit(depth_channel)->bindManual(LLTexUnit::TT_TEXTURE, mDepthTexture);
gGL.getTexUnit(depth_channel)->bindManual(LLTexUnit::TT_TEXTURE, mDepthTexture->getTexName());
U32 pass = 1;
(*it)->bindShader();

View File

@@ -89,8 +89,8 @@ private:
U32 mNextDrawTarget; //Need to pingpong between two rendertargets. Cannot sample target texture of currently bound FBO.
// However this is ONLY the case if fbos are actually supported, else swapping isn't needed.
LLRenderTarget mRenderTarget[2];
U32 mDepthTexture;
U32 mNoiseTexture ;
LLImageGL::GLTextureName mDepthTexture;
LLImageGL::GLTextureName mNoiseTexture ;
U32 mScreenWidth;
U32 mScreenHeight;

File diff suppressed because it is too large Load Diff

View File

@@ -221,31 +221,26 @@ protected:
void setTextureCombiner(eTextureBlendOp op, eTextureBlendSrc src1, eTextureBlendSrc src2, bool isAlpha = false);
};
class LLLightState
struct LLLightStateData
{
public:
LLLightState(S32 index);
LLLightStateData(bool notSun=true) :
mConstantAtten(1.f),
mLinearAtten(0.f),
mQuadraticAtten(0.f),
mSpotExponent(0.f),
mSpotCutoff(180.f)
{
if (!notSun)
{
mDiffuse.set(1, 1, 1, 1);
mSpecular.set(1, 1, 1, 1);
}
;
mPosition.set(0, 0, 1, 0);
mSpotDirection.set(0, 0, -1);
}
void enable();
void disable();
void setDiffuse(const LLColor4& diffuse);
void setAmbient(const LLColor4& ambient);
void setSpecular(const LLColor4& specular);
void setPosition(const LLVector4& position);
void setConstantAttenuation(const F32& atten);
void setLinearAttenuation(const F32& atten);
void setQuadraticAttenuation(const F32& atten);
void setSpotExponent(const F32& exponent);
void setSpotCutoff(const F32& cutoff);
void setSpotDirection(const LLVector3& direction);
protected:
friend class LLRender;
S32 mIndex;
bool mEnabled;
LLColor4 mDiffuse;
LLColor4 mAmbient;
LLColor4 mSpecular;
LLVector4 mPosition;
LLVector3 mSpotDirection;
@@ -258,10 +253,51 @@ protected:
F32 mSpotCutoff;
};
class LLLightState
{
public:
LLLightState(S32 index);
void enable() { setEnabled(true); }
void disable() { setEnabled(false); }
void setState(LLLightStateData& state) {
setDiffuse(state.mDiffuse);
setSpecular(state.mSpecular);
setPosition(state.mPosition);
setConstantAttenuation(state.mConstantAtten);
setLinearAttenuation(state.mLinearAtten);
setQuadraticAttenuation(state.mQuadraticAtten);
setSpotExponent(state.mSpotExponent);
setSpotCutoff(state.mSpotCutoff);
setSpotDirection(state.mSpotDirection);
}
const LLColor4& getDiffuse() const { return mState.mDiffuse; }
void setDiffuse(const LLColor4& diffuse);
void setSpecular(const LLColor4& specular);
void setPosition(const LLVector4& position);
void setConstantAttenuation(const F32& atten);
void setLinearAttenuation(const F32& atten);
void setQuadraticAttenuation(const F32& atten);
void setSpotExponent(const F32& exponent);
void setSpotCutoff(const F32& cutoff);
void setSpotDirection(const LLVector3& direction);
void setEnabled(const bool enabled);
protected:
friend class LLRender;
S32 mIndex;
LLLightStateData mState;
bool mEnabled;
LLMatrix4a mPosMatrix;
LLMatrix4a mSpotMatrix;
};
LL_ALIGN_PREFIX(16)
class LLRender
{
friend class LLTexUnit;
friend void check_blend_funcs();
public:
enum eTexIndex
@@ -335,10 +371,101 @@ public:
MM_TEXTURE
} eMatrixMode;
typedef enum
{
PF_FRONT,
PF_BACK,
PF_FRONT_AND_BACK
} ePolygonFaceType;
typedef enum
{
PM_POINT,
PM_LINE,
PM_FILL
} ePolygonMode;
static const U8 NUM_LIGHTS = 8;
// Cache of global gl state. (excludes nested texunit/light states)
struct Context {
Context() :
texUnit(0),
color{ 1.f,1.f,1.f,1.f },
colorMask{ true },
alphaFunc(CF_ALWAYS),
alphaVal(0.f),
blendColorSFactor(BF_ONE),
blendAlphaDFactor(BF_ZERO),
blendAlphaSFactor(BF_ONE),
blendColorDFactor(BF_ZERO),
lineWidth(1.f),
pointSize(1.f),
polygonMode{ PM_FILL, PM_FILL },
polygonOffset{ 0.f, 0.f },
viewPort(),
scissor()
{
}
U32 texUnit;
LLColor4 color;
U8 colorMask : 4;
eCompareFunc alphaFunc;
F32 alphaVal;
eBlendFactor blendColorSFactor;
eBlendFactor blendColorDFactor;
eBlendFactor blendAlphaSFactor;
eBlendFactor blendAlphaDFactor;
F32 lineWidth;
F32 pointSize;
ePolygonMode polygonMode[2];
F32 polygonOffset[2];
LLRect viewPort;
LLRect scissor;
void printDiff(const Context& other) const
{
if (memcmp(this, &other, sizeof(other)) == 0)
{
return;
}
#define PRINT_DIFF(prop) \
LL_INFOS() << #prop << ": " << other.prop; \
if (prop != other.prop) { LL_CONT << " -> " << prop; } \
LL_CONT << LL_ENDL;
#define PRINT_DIFF_BIT(prop, bit) \
LL_INFOS() << #prop << "(1<<" << #bit << "): " << (other.prop&(1<<bit)); \
if ((prop&(1<<bit)) != (other.prop&(1<<bit))) { LL_CONT << " -> " << (prop&(1<<bit)); } \
LL_CONT << LL_ENDL;
PRINT_DIFF(texUnit);
PRINT_DIFF(color.mV[0]);
PRINT_DIFF(color.mV[1]);
PRINT_DIFF(color.mV[2]);
PRINT_DIFF(color.mV[3]);
PRINT_DIFF_BIT(colorMask, 0);
PRINT_DIFF_BIT(colorMask, 1);
PRINT_DIFF_BIT(colorMask, 2);
PRINT_DIFF_BIT(colorMask, 3);
PRINT_DIFF(alphaFunc);
PRINT_DIFF(blendColorSFactor);
PRINT_DIFF(blendColorDFactor);
PRINT_DIFF(blendAlphaSFactor);
PRINT_DIFF(blendAlphaDFactor);
PRINT_DIFF(lineWidth);
PRINT_DIFF(pointSize);
PRINT_DIFF(polygonMode[0]);
PRINT_DIFF(polygonMode[1]);
PRINT_DIFF(polygonOffset[0]);
PRINT_DIFF(polygonOffset[1]);
PRINT_DIFF(viewPort);
PRINT_DIFF(scissor);
}
};
LLRender();
~LLRender();
void init() ;
void shutdown();
void destroyGL();
// Refreshes renderer state to the cached values
// Needed when the render context has changed and invalidated the current state
@@ -374,8 +501,10 @@ public:
const LLMatrix4a& getModelviewMatrix();
const LLMatrix4a& getProjectionMatrix();
void syncContextState();
void syncMatrices();
void syncLightState();
void syncShaders();
void translateUI(F32 x, F32 y, F32 z);
void scaleUI(F32 x, F32 y, F32 z);
@@ -427,6 +556,18 @@ public:
void setAlphaRejectSettings(eCompareFunc func, F32 value = 0.01f);
void setPolygonMode(ePolygonFaceType type, ePolygonMode mode);
void setPolygonOffset(F32 factor, F32 bias);
void setViewport(S32 x, S32 y, U32 w, U32 h) { setViewport(LLRect(x, y + h, x + w, y)); };
void setViewport(const LLRect& rect);
void setScissor(S32 x, S32 y, U32 w, U32 h) { setScissor(LLRect(x, y + h, x + w, y)); };
void setScissor(const LLRect& rect);
const LLRect& getScissor() const { return mNewContext.scissor; }
void setShader(U32 shader) { mNextShader = shader; }
// applies blend func to both color and alpha
void blendFunc(eBlendFactor sfactor, eBlendFactor dfactor);
// applies separate blend functions to color and alpha
@@ -437,10 +578,12 @@ public:
void setAmbientLightColor(const LLColor4& color);
void setLineWidth(F32 line_width);
F32 getLineWidth() const { return mNewContext.lineWidth; }
void setPointSize(F32 point_size);
LLTexUnit* getTexUnit(U32 index);
U32 getCurrentTexUnitIndex(void) const { return mCurrTextureUnitIndex; }
U32 getCurrentTexUnitIndex(void) const { return mNewContext.texUnit; }
bool verifyTexUnitActive(U32 unitToVerify);
@@ -448,6 +591,8 @@ public:
void clearErrors();
const Context& getContextSnapshot() const { return mNewContext; }
struct Vertex
{
GLfloat v[3];
@@ -455,6 +600,8 @@ public:
GLfloat uv[2];
};
void resetSyncHashes();
public:
static U32 sUICalls;
static U32 sUIVerts;
@@ -467,18 +614,26 @@ private:
U32 mMatIdx[NUM_MATRIX_MODES];
U32 mMatHash[NUM_MATRIX_MODES];
LL_ALIGN_16(LLMatrix4a mMatrix[NUM_MATRIX_MODES][LL_MATRIX_STACK_DEPTH]);
U32 mCurMatHash[NUM_MATRIX_MODES];
U32 mCurLegacyMatHash[NUM_MATRIX_MODES];
U32 mLightHash;
U32 mCurLegacyLightHash;
U32 mLightPositionTransformHash[NUM_LIGHTS];
U32 mLightSpotTransformHash[NUM_LIGHTS];
U32 mCurLightPositionTransformHash[NUM_LIGHTS];
U32 mCurLightSpotTransformHash[NUM_LIGHTS];
LLVector4 mCurLightPosition[NUM_LIGHTS];
LLVector3 mCurSpotDirection[NUM_LIGHTS];
LLColor4 mAmbientLightColor;
U32 mCurShader;
U32 mNextShader;
bool mDirty;
Context mContext;
Context mNewContext;
U32 mCount;
U32 mMode;
U32 mCurrTextureUnitIndex;
bool mCurrColorMask[4];
eCompareFunc mCurrAlphaFunc;
F32 mCurrAlphaFuncVal;
F32 mLineWidth;
LLPointer<LLVertexBuffer> mBuffer;
LLStrider<LLVector4a> mVerticesp;
@@ -488,11 +643,6 @@ private:
LLTexUnit* mDummyTexUnit;
std::vector<LLLightState*> mLightState;
eBlendFactor mCurrBlendColorSFactor;
eBlendFactor mCurrBlendColorDFactor;
eBlendFactor mCurrBlendAlphaSFactor;
eBlendFactor mCurrBlendAlphaDFactor;
F32 mMaxAnisotropy;
std::vector<LLVector4a, boost::alignment::aligned_allocator<LLVector4a, 64> > mUIOffset;
@@ -508,7 +658,7 @@ extern LLMatrix4a gGLLastModelView;
extern LLMatrix4a gGLLastProjection;
extern LLMatrix4a gGLPreviousModelView;
extern LLMatrix4a gGLProjection;
extern S32 gGLViewport[4];
extern LLRect gGLViewport;
extern LLRender gGL;

View File

@@ -759,12 +759,12 @@ void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LL
S32 shift = S32(phase * 4.f) % 4;
// Stippled line
LLGLEnable stipple(GL_LINE_STIPPLE);
LLGLEnable<GL_LINE_STIPPLE> stipple;
gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], color.mV[VALPHA]);
gGL.flush();
glLineWidth(2.5f);
gGL.setLineWidth(2.5f);
if (!LLGLSLShader::sNoFixedFunction)
{

View File

@@ -195,8 +195,8 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
return false;
}
U32 tex;
LLImageGL::generateTextures(1, &tex);
auto texName = LLImageGL::createTextureName();
U32 tex = texName->getTexName();
gGL.getTexUnit(0)->bindManual(mUsage, tex);
stop_glerror();
@@ -245,6 +245,7 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
}
mTex.push_back(tex);
mTexName.push_back(texName);
mInternalFormat.push_back(color_fmt);
if (gDebugGL)
@@ -258,6 +259,7 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
bool LLRenderTarget::allocateDepth()
{
mDepthName.reset();
if (mStencil && mFBO)
{
//use render buffers where stencil buffers are in play
@@ -270,7 +272,9 @@ bool LLRenderTarget::allocateDepth()
}
else
{
LLImageGL::generateTextures(1, &mDepth);
mDepthName = LLImageGL::createTextureName();
mDepth = mDepthName->getTexName();
gGL.getTexUnit(0)->bindManual(mUsage, mDepth);
U32 internal_type = LLTexUnit::getInternalType(mUsage);
@@ -357,7 +361,6 @@ void LLRenderTarget::release()
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), 0, 0);
glBindFramebuffer(GL_FRAMEBUFFER,0);
}
LLImageGL::deleteTextures(1, &mDepth);
stop_glerror();
}
mDepth = 0;
@@ -387,13 +390,11 @@ void LLRenderTarget::release()
mFBO = 0;
}
if (mTex.size() > 0)
{
sBytesAllocated -= mResX*mResY*4*mTex.size();
LLImageGL::deleteTextures(mTex.size(), &mTex[0]);
mTex.clear();
mInternalFormat.clear();
}
sBytesAllocated -= mResX * mResY * 4 * mTex.size();
mTex.clear();
mInternalFormat.clear();
mDepthName.reset();
mTexName.clear(); // Were textures not being released at all..?
mResX = mResY = 0;
@@ -440,8 +441,7 @@ void LLRenderTarget::bindTarget()
stop_glerror();
}
}
glViewport(0, 0, mResX, mResY);
gGL.setViewport(0, 0, mResX, mResY);
sBoundTarget = this;
}
@@ -452,18 +452,22 @@ void LLRenderTarget::clear(U32 mask_in)
{
mask |= GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
}
if (mFBO)
{
check_framebuffer_status();
stop_glerror();
LLGLDisable<GL_SCISSOR_TEST> scissor;
gGL.syncContextState();
glClear(mask & mask_in);
stop_glerror();
}
else
{
LLGLEnable scissor(GL_SCISSOR_TEST);
glScissor(0, 0, mResX, mResY);
LLGLEnable<GL_SCISSOR_TEST> scissor;
gGL.setScissor(0, 0, mResX, mResY);
stop_glerror();
gGL.syncContextState();
glClear(mask & mask_in);
}
}
@@ -515,7 +519,7 @@ void LLRenderTarget::flush(bool fetch_depth)
stop_glerror();
if(mSampleBuffer)
{
LLGLEnable multisample(GL_MULTISAMPLE);
LLGLEnable<GL_MULTISAMPLE> multisample;
stop_glerror();
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
stop_glerror();
@@ -575,12 +579,12 @@ void LLRenderTarget::flush(bool fetch_depth)
if(mPreviousFBO)
{
glViewport(0, 0, mPreviousFBO->mResX, mPreviousFBO->mResY);
gGL.setViewport(0, 0, mPreviousFBO->mResX, mPreviousFBO->mResY);
mPreviousFBO = NULL;
}
else
{
glViewport(gGLViewport[0],gGLViewport[1],gGLViewport[2],gGLViewport[3]);
gGL.setViewport(gGLViewport);
}
stop_glerror();
}
@@ -683,12 +687,9 @@ bool LLRenderTarget::isComplete() const
return (!mTex.empty() || mDepth) ? true : false;
}
void LLRenderTarget::getViewport(S32* viewport)
void LLRenderTarget::getViewport(LLRect& viewport)
{
viewport[0] = 0;
viewport[1] = 0;
viewport[2] = mResX;
viewport[3] = mResY;
viewport = LLRect(0, mResY, mResX, 0);
}
//==================================================
@@ -754,7 +755,7 @@ void LLMultisampleBuffer::bindTarget(LLRenderTarget* ref)
check_framebuffer_status();
glViewport(0, 0, mResX, mResY);
gGL.setViewport(0, 0, mResX, mResY);
sBoundTarget = this;
}

View File

@@ -107,7 +107,7 @@ public:
void clear(U32 mask = 0xFFFFFFFF);
//get applied viewport
void getViewport(S32* viewport);
void getViewport(LLRect& viewport);
//get X resolution
U32 getWidth() const { return mResX; }
@@ -152,9 +152,11 @@ protected:
U32 mResX;
U32 mResY;
std::vector<U32> mTex;
std::vector<LLImageGL::GLTextureName> mTexName;
std::vector<U32> mInternalFormat;
U32 mFBO;
LLRenderTarget* mPreviousFBO;
LLImageGL::GLTextureName mDepthName;
U32 mDepth;
bool mStencil;
bool mUseDepth;

View File

@@ -498,27 +498,28 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
//============================================================================
// Load Shader
static std::string get_object_log(GLhandleARB ret)
static std::string get_object_log(GLhandleARB ret, bool isProgram)
{
std::string res;
//get log length
GLint length;
glGetObjectParameterivARB(ret, GL_OBJECT_INFO_LOG_LENGTH_ARB, &length);
(isProgram ? glGetProgramiv : glGetShaderiv)(ret, GL_INFO_LOG_LENGTH, &length);
if (length > 0)
{
//the log could be any size, so allocate appropriately
GLcharARB* log = new GLcharARB[length];
glGetInfoLogARB(ret, length, &length, log);
(isProgram ? glGetProgramInfoLog : glGetShaderInfoLog)(ret, length, &length, log);
res = std::string((char *)log);
delete[] log;
}
return res;
}
void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns)
void LLShaderMgr::dumpObjectLog(GLhandleARB ret, bool isProgram, bool warns)
{
std::string log = get_object_log(ret);
std::string log = get_object_log(ret, isProgram);
if ( log.length() > 0 )
{
if (warns)
@@ -555,7 +556,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
}
}
LL_DEBUGS("ShaderLoading") << "Loading shader file: " << filename << " class " << shader_level << LL_ENDL;
LL_INFOS("ShaderLoading") << "Loading shader file: " << filename << " class " << shader_level << LL_ENDL;
if (filename.empty())
{
@@ -811,7 +812,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
if (error != GL_NO_ERROR)
{
LL_WARNS("ShaderLoading") << "GL ERROR in glCreateShaderObjectARB: " << error << LL_ENDL;
glDeleteObjectARB(ret); //no longer need handle
glDeleteShader(ret); //no longer need handle
ret=0;
}
}
@@ -827,7 +828,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
if (error != GL_NO_ERROR)
{
LL_WARNS("ShaderLoading") << "GL ERROR in glShaderSourceARB: " << error << LL_ENDL;
glDeleteObjectARB(ret); //no longer need handle
glDeleteShader(ret); //no longer need handle
ret=0;
}
}
@@ -844,7 +845,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
if (error != GL_NO_ERROR)
{
LL_WARNS("ShaderLoading") << "GL ERROR in glCompileShaderARB: " << error << LL_ENDL;
glDeleteObjectARB(ret); //no longer need handle
glDeleteShader(ret); //no longer need handle
ret=0;
}
}
@@ -856,7 +857,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
{
//check for errors
GLint success = GL_TRUE;
glGetObjectParameterivARB(ret, GL_OBJECT_COMPILE_STATUS_ARB, &success);
glGetShaderiv(ret, GL_COMPILE_STATUS, &success);
if (gDebugGL || success == GL_FALSE)
{
error = glGetError();
@@ -864,8 +865,8 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
{
//an error occured, print log
LL_WARNS("ShaderLoading") << "GLSL Compilation Error: (" << error << ") in " << filename << LL_ENDL;
dumpObjectLog(ret);
error_str = get_object_log(ret);
dumpObjectLog(ret, false);
error_str = get_object_log(ret, false);
std::stringstream ostr;
//dump shader source for debugging
@@ -884,12 +885,12 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
}
LL_WARNS("ShaderLoading") << "\n" << ostr.str() << LL_ENDL;
glDeleteObjectARB(ret); //no longer need handle
glDeleteShader(ret); //no longer need handle
ret = 0;
}
}
if(ret)
dumpObjectLog(ret,false);
dumpObjectLog(ret, false, false);
}
static const LLCachedControl<bool> dump_raw_shaders("ShyotlDumpRawShaders",false);
@@ -961,7 +962,7 @@ void LLShaderMgr::unloadShaderObjects()
std::multimap<std::string, LLShaderMgr::CachedObjectInfo >::iterator it = mShaderObjects.begin();
for (; it != mShaderObjects.end(); ++it)
if (it->second.mHandle)
glDeleteObjectARB(it->second.mHandle);
glDeleteShader(it->second.mHandle);
mShaderObjects.clear();
cleanupShaderSources();
}
@@ -1007,7 +1008,7 @@ BOOL LLShaderMgr::linkProgramObject(GLhandleARB obj, BOOL suppress_errors)
//check for errors
glLinkProgramARB(obj);
GLint success = GL_TRUE;
glGetObjectParameterivARB(obj, GL_OBJECT_LINK_STATUS_ARB, &success);
glGetProgramiv(obj, GL_LINK_STATUS, &success);
if (!suppress_errors && success == GL_FALSE)
{
//an error occured, print log
@@ -1051,7 +1052,7 @@ BOOL LLShaderMgr::linkProgramObject(GLhandleARB obj, BOOL suppress_errors)
}
#else
std::string log = get_object_log(obj);
std::string log = get_object_log(obj, true);
LLStringUtil::toLower(log);
if (log.find("software") != std::string::npos)
{
@@ -1062,7 +1063,7 @@ BOOL LLShaderMgr::linkProgramObject(GLhandleARB obj, BOOL suppress_errors)
#endif
if (!suppress_errors)
{
dumpObjectLog(obj, !success);
dumpObjectLog(obj, true, !success);
}
return success;
@@ -1073,15 +1074,15 @@ BOOL LLShaderMgr::validateProgramObject(GLhandleARB obj)
//check program validity against current GL
glValidateProgramARB(obj);
GLint success = GL_TRUE;
glGetObjectParameterivARB(obj, GL_OBJECT_VALIDATE_STATUS_ARB, &success);
glGetProgramiv(obj, GL_VALIDATE_STATUS, &success);
if (success == GL_FALSE)
{
LL_WARNS("ShaderLoading") << "GLSL program not valid: " << LL_ENDL;
dumpObjectLog(obj);
dumpObjectLog(obj, true);
}
else
{
dumpObjectLog(obj, FALSE);
dumpObjectLog(obj, true, false);
}
return success;

View File

@@ -228,7 +228,7 @@ DISPLAY_GAMMA,
virtual void initAttribsAndUniforms(void);
BOOL attachShaderFeatures(LLGLSLShader * shader);
void dumpObjectLog(GLhandleARB ret, BOOL warns = TRUE);
void dumpObjectLog(GLhandleARB ret, bool isProgram, bool warns = TRUE);
BOOL linkProgramObject(GLhandleARB obj, BOOL suppress_errors = FALSE);
BOOL validateProgramObject(GLhandleARB obj);
GLhandleARB loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, std::map<std::string, std::string>* defines = NULL, S32 texture_index_channels = -1);

View File

@@ -90,6 +90,7 @@ LLVBOPool LLVertexBuffer::sDynamicIBOPool(GL_DYNAMIC_DRAW_ARB, GL_ELEMENT_ARRAY_
U32 LLVBOPool::sBytesPooled = 0;
U32 LLVBOPool::sIndexBytesPooled = 0;
std::vector<U32> LLVBOPool::sPendingDeletions;
std::list<U32> LLVertexBuffer::sAvailableVAOName;
U32 LLVertexBuffer::sCurVAOName = 1;
@@ -118,12 +119,75 @@ bool LLVertexBuffer::sUseVAO = false;
bool LLVertexBuffer::sPreferStreamDraw = false;
LLVertexBuffer* LLVertexBuffer::sUtilityBuffer = nullptr;
static std::vector<U32> sActiveBufferNames;
static std::vector<U32> sDeletedBufferNames;
/*void validate_add_buffer(U32 name)
{
auto found = std::find(sActiveBufferNames.begin(), sActiveBufferNames.end(), name);
if (found != sActiveBufferNames.end())
{
LL_ERRS() << "Allocating allocated buffer name " << name << LL_ENDL;
}
else
{
//LL_INFOS() << "Allocated buffer name " << name << LL_ENDL;
sActiveBufferNames.push_back(name);
}
}
void validate_del_buffer(U32 name)
{
auto found = std::find(sActiveBufferNames.begin(), sActiveBufferNames.end(), name);
if (found == sActiveBufferNames.end())
{
if (std::find(sDeletedBufferNames.begin(), sDeletedBufferNames.end(), name) == sDeletedBufferNames.end())
{
LL_ERRS() << "Deleting unknown buffer name " << name << LL_ENDL;
}
else
{
LL_ERRS() << "Deleting deleted buffer name " << name << LL_ENDL;
}
}
else
{
//LL_INFOS() << "Deleted buffer name " << name << LL_ENDL;
sActiveBufferNames.erase(found);
sDeletedBufferNames.push_back(name);
}
}
void validate_bind_buffer(U32 name)
{
auto found = std::find(sActiveBufferNames.begin(), sActiveBufferNames.end(), name);
if (found == sActiveBufferNames.end())
{
if (std::find(sDeletedBufferNames.begin(), sDeletedBufferNames.end(), name) == sDeletedBufferNames.end())
{
LL_ERRS() << "Binding unknown buffer name " << name << LL_ENDL;
}
else
{
LL_ERRS() << "Binding deleted buffer name " << name << LL_ENDL;
}
}
}
void clean_validate_buffers()
{
LL_INFOS() << "Clearing active buffer names. Count " << sActiveBufferNames.size() << LL_ENDL;
sActiveBufferNames.clear();
LL_INFOS() << "Clearing deleted buffer names. Count " << sDeletedBufferNames.size() << LL_ENDL;
sDeletedBufferNames.clear();
}*/
U32 LLVBOPool::genBuffer()
{
U32 ret = 0;
glGenBuffersARB(1, &ret);
//validate_add_buffer(ret);
return ret;
}
@@ -132,13 +196,20 @@ void LLVBOPool::deleteBuffer(U32 name)
{
if (gGLManager.mInited)
{
LLVertexBuffer::unbind();
//LLVertexBuffer::unbind();
glBindBufferARB(mType, name);
glBufferDataARB(mType, 0, nullptr, mUsage);
glBindBufferARB(mType, 0);
//validate_bind_buffer(name);
//glBindBufferARB(mType, name);
//glBufferDataARB(mType, 0, nullptr, mUsage);
//glBindBufferARB(mType, 0);
glDeleteBuffersARB(1, &name);
//validate_del_buffer(name);
if (LLVertexBuffer::sGLRenderBuffer == name) {
//LLVertexBuffer::sGLRenderBuffer = 0;
LLVertexBuffer::unbind();
}
sPendingDeletions.emplace_back(name);
//glDeleteBuffersARB(1, &name);
}
}
@@ -150,7 +221,7 @@ LLVBOPool::LLVBOPool(U32 vboUsage, U32 vboType)
std::fill(mMissCount.begin(), mMissCount.end(), 0);
}
volatile U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
volatile U8* LLVBOPool::allocate(U32& name, U32 size, U32 seed)
{
llassert(vbo_block_size(size) == size);
@@ -163,16 +234,17 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
mFreeList.resize(i+1);
}
if (mFreeList[i].empty() || for_seed)
if (mFreeList[i].empty() || seed)
{
//make a new buffer
name = genBuffer();
name = seed > 0 ? seed : genBuffer();
//validate_bind_buffer(name);
glBindBufferARB(mType, name);
if (!for_seed && i < LL_VBO_POOL_SEED_COUNT)
if (!seed && i < LL_VBO_POOL_SEED_COUNT)
{ //record this miss
mMissCount[i]++;
mMissCount[i]++;
}
if (mType == GL_ARRAY_BUFFER_ARB)
@@ -187,16 +259,19 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
if (LLVertexBuffer::sDisableVBOMapping || mUsage != GL_DYNAMIC_DRAW_ARB)
{
glBufferDataARB(mType, size, nullptr, mUsage);
ret = (U8*) ll_aligned_malloc<64>(size);
ret = (U8*)ll_aligned_malloc<64>(size);
}
else
{ //always use a true hint of static draw when allocating non-client-backed buffers
glBufferDataARB(mType, size, nullptr, GL_STATIC_DRAW_ARB);
}
glBindBufferARB(mType, 0);
if (!seed)
{
glBindBufferARB(mType, 0);
}
if (for_seed)
if (seed)
{ //put into pool for future use
llassert(mFreeList.size() > i);
@@ -206,11 +281,11 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
if (mType == GL_ARRAY_BUFFER_ARB)
{
sBytesPooled += size;
}
else
{
sIndexBytesPooled += size;
sBytesPooled += size;
}
else
{
sIndexBytesPooled += size;
}
mFreeList[i].push_back(rec);
}
@@ -261,22 +336,45 @@ void LLVBOPool::seedPool()
mFreeList.resize(LL_VBO_POOL_SEED_COUNT);
}
static std::vector< U32 > sizes;
for (U32 i = 0; i < LL_VBO_POOL_SEED_COUNT; i++)
{
if (mMissCount[i] > mFreeList[i].size())
{
U32 size = i*LL_VBO_BLOCK_SIZE;
{
U32 size = i * LL_VBO_BLOCK_SIZE;
S32 count = mMissCount[i] - mFreeList[i].size();
for (S32 j = 0; j < count; ++j)
{
allocate(dummy_name, size, true);
sizes.push_back(size);
}
}
}
if (!sizes.empty())
{
const U32 len = sizes.size();
U32* names = new U32[len];
glGenBuffersARB(len, names);
for (U32 i = 0; i < len; ++i)
{
allocate(dummy_name, sizes[i], names[i]);
}
delete[] names;
glBindBufferARB(mType, 0);
}
sizes.clear();
}
void LLVBOPool::deleteReleasedBuffers()
{
if (!sPendingDeletions.empty())
{
glDeleteBuffersARB(sPendingDeletions.size(), sPendingDeletions.data());
sPendingDeletions.clear();
}
}
void LLVBOPool::cleanup()
{
@@ -316,6 +414,7 @@ void LLVBOPool::cleanup()
//reset miss counts
std::fill(mMissCount.begin(), mMissCount.end(), 0);
deleteReleasedBuffers();
}
@@ -895,6 +994,14 @@ void LLVertexBuffer::cleanupClass()
sDynamicIBOPool.cleanup();
sStreamVBOPool.cleanup();
sDynamicVBOPool.cleanup();
//clean_validate_buffers();
if (!sAvailableVAOName.empty())
{
glDeleteVertexArrays(1, &sAvailableVAOName.front());
sAvailableVAOName.pop_front();
}
sLastMask = 0;
delete sUtilityBuffer;
sUtilityBuffer = nullptr;
@@ -949,7 +1056,9 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
mAlignedOffset(0),
mAlignedIndexOffset(0),
mSize(0),
mResidentSize(0),
mIndicesSize(0),
mResidentIndicesSize(0),
mTypeMask(typemask),
mUsage(LLVertexBuffer::determineUsage(usage)),
mGLBuffer(0),
@@ -997,7 +1106,7 @@ S32 LLVertexBuffer::calcOffsets(const U32& typemask, S32* offsets, S32 num_verti
offsets[TYPE_TEXTURE_INDEX] = offsets[TYPE_VERTEX] + 12;
return offset+16;
return offset;
}
//static
@@ -1155,6 +1264,7 @@ void LLVertexBuffer::createGLBuffer(U32 size)
}
mEmpty = true;
mResidentSize = size;
mMappedDataUsingVBOs = useVBOs();
@@ -1184,6 +1294,7 @@ void LLVertexBuffer::createGLIndices(U32 size)
}
mEmpty = true;
mResidentIndicesSize = size;
//pad by 16 bytes for aligned copies
size += 16;
@@ -1394,8 +1505,8 @@ void LLVertexBuffer::setupVertexArray()
GL_FALSE, //TYPE_TEXTURE_INDEX
};
bindGLBuffer(true);
bindGLIndices(true);
bindGLBuffer();
bindGLIndices();
for (U32 i = 0; i < TYPE_MAX; ++i)
{
@@ -1457,21 +1568,21 @@ bool LLVertexBuffer::useVBOs() const
//----------------------------------------------------------------------------
bool expand_region(LLVertexBuffer::MappedRegion& region, S32 index, S32 count)
bool expand_region(LLVertexBuffer::MappedRegion& region, U32 offset, U32 length)
{
S32 end = index+count;
S32 region_end = region.mIndex+region.mCount;
U32 end = offset + length;
U32 region_end = region.mOffset + region.mLength;
if (end < region.mIndex ||
index > region_end)
if (end < region.mOffset ||
offset > region_end)
{ //gap exists, do not merge
return false;
}
S32 new_end = llmax(end, region_end);
S32 new_index = llmin(index, region.mIndex);
region.mIndex = new_index;
region.mCount = new_end-new_index;
U32 new_end = llmax(end, region_end);
U32 new_offset = llmin(offset, region.mOffset);
region.mOffset = new_offset;
region.mLength = new_end-new_offset;
return true;
}
@@ -1481,7 +1592,7 @@ static LLTrace::BlockTimerStatHandle FTM_VBO_MAP_BUFFER("VBO Map");
// Map for data access
volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range)
{
bindGLBuffer(true);
bindGLBuffer();
if (mFinal)
{
LL_ERRS() << "LLVertexBuffer::mapVeretxBuffer() called on a finalized buffer." << LL_ENDL;
@@ -1500,26 +1611,41 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo
count = mNumVerts-index;
}
bool mapped = false;
//see if range is already mapped
for (U32 i = 0; i < mMappedVertexRegions.size(); ++i)
if (getSize() > LL_VBO_BLOCK_SIZE)
{
MappedRegion& region = mMappedVertexRegions[i];
if (region.mType == type)
U32 offset = mOffsets[type] + sTypeSize[type] * index;
U32 length = sTypeSize[type] * count;
bool mapped = false;
//see if range is already mapped
for (U32 i = 0; i < mMappedVertexRegions.size(); ++i)
{
if (expand_region(region, index, count))
MappedRegion& region = mMappedVertexRegions[i];
if (expand_region(region, offset, length))
{
++i;
while (MappedRegion* pNext = i < mMappedVertexRegions.size() ? &mMappedVertexRegions[i] : nullptr)
{
if (expand_region(region, pNext->mOffset, pNext->mLength))
{
mMappedVertexRegions.erase(mMappedVertexRegions.begin() + i);
}
else
{
++i;
}
}
mapped = true;
break;
}
}
}
if (!mapped)
{
//not already mapped, map new region
MappedRegion region(type, mMappable && map_range ? -1 : index, count);
mMappedVertexRegions.push_back(region);
if (!mapped)
{
//not already mapped, map new region
MappedRegion region(type, mMappable && map_range ? -1 : offset, length);
mMappedVertexRegions.push_back(region);
}
}
}
@@ -1660,7 +1786,7 @@ static LLTrace::BlockTimerStatHandle FTM_VBO_MAP_INDEX("IBO Map");
volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
{
bindGLIndices(true);
bindGLIndices();
if (mFinal)
{
LL_ERRS() << "LLVertexBuffer::mapIndexBuffer() called on a finalized buffer." << LL_ENDL;
@@ -1679,23 +1805,41 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range
count = mNumIndices-index;
}
bool mapped = false;
//see if range is already mapped
for (U32 i = 0; i < mMappedIndexRegions.size(); ++i)
if (getIndicesSize() > LL_VBO_BLOCK_SIZE)
{
MappedRegion& region = mMappedIndexRegions[i];
if (expand_region(region, index, count))
{
mapped = true;
break;
}
}
U32 offset = sizeof(U16) * index;
U32 length = sizeof(U16) * count;
if (!mapped)
{
//not already mapped, map new region
MappedRegion region(TYPE_INDEX, mMappable && map_range ? -1 : index, count);
mMappedIndexRegions.push_back(region);
bool mapped = false;
//see if range is already mapped
for (U32 i = 0; i < mMappedIndexRegions.size(); ++i)
{
MappedRegion& region = mMappedIndexRegions[i];
if (expand_region(region, offset, length))
{
++i;
while (MappedRegion* pNext = i < mMappedIndexRegions.size() ? &mMappedIndexRegions[i] : nullptr)
{
if (expand_region(region, pNext->mOffset, pNext->mLength))
{
mMappedIndexRegions.erase(mMappedIndexRegions.begin() + i);
}
else
{
++i;
}
}
mapped = true;
break;
}
}
if (!mapped)
{
//not already mapped, map new region
MappedRegion region(TYPE_INDEX, mMappable && map_range ? -1 : offset, length);
mMappedIndexRegions.push_back(region);
}
}
}
@@ -1838,7 +1982,7 @@ void LLVertexBuffer::unmapBuffer()
if (mMappedData && mVertexLocked)
{
//LL_RECORD_BLOCK_TIME(FTM_VBO_UNMAP);
bindGLBuffer(true);
bindGLBuffer();
updated_all = mIndexLocked; //both vertex and index buffers done updating
if(!mMappable)
@@ -1849,9 +1993,18 @@ void LLVertexBuffer::unmapBuffer()
for (U32 i = 0; i < mMappedVertexRegions.size(); ++i)
{
const MappedRegion& region = mMappedVertexRegions[i];
S32 offset = region.mIndex >= 0 ? mOffsets[region.mType]+sTypeSize[region.mType]*region.mIndex : 0;
S32 length = sTypeSize[region.mType]*region.mCount;
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, offset, length, (U8*) mMappedData+offset);
U32 offset = region.mOffset;
U32 length = region.mLength;
if ((mResidentSize - length) <= LL_VBO_BLOCK_SIZE * 2 || (offset == 0 && length >= mResidentSize))
{
glBufferDataARB(GL_ARRAY_BUFFER_ARB, getSize(), nullptr, mUsage);
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, getSize(), (U8*)mMappedData);
break;
}
else
{
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, offset, length, (U8*)mMappedData + offset);
}
stop_glerror();
}
@@ -1875,8 +2028,8 @@ void LLVertexBuffer::unmapBuffer()
for (U32 i = 0; i < mMappedVertexRegions.size(); ++i)
{
const MappedRegion& region = mMappedVertexRegions[i];
S32 offset = region.mIndex >= 0 ? mOffsets[region.mType]+sTypeSize[region.mType]*region.mIndex : 0;
S32 length = sTypeSize[region.mType]*region.mCount;
U32 offset = region.mOffset;
U32 length = region.mLength;
if (gGLManager.mHasMapBufferRange)
{
//LL_RECORD_BLOCK_TIME(FTM_VBO_FLUSH_RANGE);
@@ -1916,9 +2069,18 @@ void LLVertexBuffer::unmapBuffer()
for (U32 i = 0; i < mMappedIndexRegions.size(); ++i)
{
const MappedRegion& region = mMappedIndexRegions[i];
S32 offset = region.mIndex >= 0 ? sizeof(U16)*region.mIndex : 0;
S32 length = sizeof(U16)*region.mCount;
glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length, (U8*) mMappedIndexData+offset);
U32 offset = region.mOffset;
U32 length = region.mLength;
if ((mResidentIndicesSize - length) <= LL_VBO_BLOCK_SIZE * 2 || (offset == 0 && length >= mResidentIndicesSize))
{
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, getIndicesSize(), nullptr, mUsage); // <alchemy/>
glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, getIndicesSize(), (U8*)mMappedIndexData);
break;
}
else
{
glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length, (U8*)mMappedIndexData + offset);
}
stop_glerror();
}
@@ -1941,8 +2103,8 @@ void LLVertexBuffer::unmapBuffer()
for (U32 i = 0; i < mMappedIndexRegions.size(); ++i)
{
const MappedRegion& region = mMappedIndexRegions[i];
S32 offset = region.mIndex >= 0 ? sizeof(U16)*region.mIndex : 0;
S32 length = sizeof(U16)*region.mCount;
U32 offset = region.mOffset;
U32 length = region.mLength;
if (gGLManager.mHasMapBufferRange)
{
//LL_RECORD_BLOCK_TIME(FTM_IBO_FLUSH_RANGE);
@@ -2127,7 +2289,9 @@ static LLTrace::BlockTimerStatHandle FTM_BIND_GL_BUFFER("Bind Buffer");
bool LLVertexBuffer::bindGLBuffer(bool force_bind)
{
//stop_glerror();
bindGLArray();
//stop_glerror();
bool ret = false;
@@ -2138,7 +2302,11 @@ bool LLVertexBuffer::bindGLBuffer(bool force_bind)
{
LL_ERRS() << "VBO bound while another VBO mapped!" << LL_ENDL;
}*/
//stop_glerror();
//validate_bind_buffer(mGLBuffer);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer);
//stop_glerror();
sGLRenderBuffer = mGLBuffer;
sBindCount++;
sVBOActive = true;
@@ -2169,6 +2337,7 @@ bool LLVertexBuffer::bindGLIndices(bool force_bind)
{
LL_ERRS() << "VBO bound while another VBO mapped!" << LL_ENDL;
}*/
//validate_bind_buffer(mGLIndices);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mGLIndices);
sGLRenderIndices = mGLIndices;
stop_glerror();
@@ -2485,8 +2654,8 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
llglassertok();
}
LLVertexBuffer::MappedRegion::MappedRegion(S32 type, S32 index, S32 count)
: mType(type), mIndex(index), mCount(count)
LLVertexBuffer::MappedRegion::MappedRegion(S32 type, U32 offset, U32 length)
: mType(type), mOffset(offset), mLength(length)
{
llassert(mType == LLVertexBuffer::TYPE_INDEX ||
mType < LLVertexBuffer::TYPE_TEXTURE_INDEX);

View File

@@ -56,14 +56,18 @@ class LLVBOPool
public:
static U32 sBytesPooled;
static U32 sIndexBytesPooled;
static std::vector<U32> sPendingDeletions;
// Periodically call from render loop. Batches VBO deletions together in a single call.
static void deleteReleasedBuffers();
LLVBOPool(U32 vboUsage, U32 vboType);
const U32 mUsage;
const U32 mType;
//size MUST be a power of 2
volatile U8* allocate(U32& name, U32 size, bool for_seed = false);
volatile U8* allocate(U32& name, U32 size, U32 seed = 0);
//size MUST be the size provided to allocate that returned the given name
void release(U32 name, volatile U8* buffer, U32 size);
@@ -100,10 +104,10 @@ public:
{
public:
S32 mType;
S32 mIndex;
S32 mCount;
U32 mOffset;
U32 mLength;
MappedRegion(S32 type, S32 index, S32 count);
MappedRegion(S32 type, U32 offset, U32 length);
};
LLVertexBuffer(const LLVertexBuffer& rhs)
@@ -291,7 +295,9 @@ protected:
ptrdiff_t mAlignedOffset;
ptrdiff_t mAlignedIndexOffset;
S32 mSize;
S32 mResidentSize;
S32 mIndicesSize;
S32 mResidentIndicesSize;
U32 mTypeMask;
const S32 mUsage; // GL usage