summaryrefslogtreecommitdiff
path: root/indra/llrender
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llrender')
-rw-r--r--indra/llrender/llcubemap.cpp2
-rw-r--r--indra/llrender/llfontbitmapcache.cpp18
-rw-r--r--indra/llrender/llfontbitmapcache.h2
-rw-r--r--indra/llrender/llfontfreetype.cpp10
-rw-r--r--indra/llrender/llfontfreetype.h2
-rw-r--r--indra/llrender/llfontgl.cpp35
-rw-r--r--indra/llrender/llfontgl.h4
-rw-r--r--indra/llrender/llfontregistry.cpp5
-rw-r--r--indra/llrender/llgl.cpp306
-rw-r--r--indra/llrender/llgl.h4
-rw-r--r--indra/llrender/llglheaders.h19
-rw-r--r--indra/llrender/llglslshader.cpp166
-rw-r--r--indra/llrender/llglslshader.h82
-rw-r--r--indra/llrender/llgltexture.cpp2
-rw-r--r--indra/llrender/llgltexture.h2
-rw-r--r--indra/llrender/llimagegl.cpp550
-rw-r--r--indra/llrender/llimagegl.h51
-rw-r--r--indra/llrender/llrender.cpp56
-rw-r--r--indra/llrender/llrender.h18
-rw-r--r--indra/llrender/llrender2dutils.cpp8
-rw-r--r--indra/llrender/llrendertarget.cpp2
-rw-r--r--indra/llrender/lltexture.h7
-rw-r--r--indra/llrender/llvertexbuffer.cpp422
-rw-r--r--indra/llrender/llvertexbuffer.h24
24 files changed, 1095 insertions, 702 deletions
diff --git a/indra/llrender/llcubemap.cpp b/indra/llrender/llcubemap.cpp
index 5947bca670..d7f7b2f58e 100644
--- a/indra/llrender/llcubemap.cpp
+++ b/indra/llrender/llcubemap.cpp
@@ -150,6 +150,7 @@ void LLCubeMap::initRawData(const std::vector<LLPointer<LLImageRaw> >& rawimages
void LLCubeMap::initGLData()
{
+ LL_PROFILE_ZONE_SCOPED;
for (int i = 0; i < 6; i++)
{
mImages[i]->setSubImage(mRawImages[i], 0, 0, RESOLUTION, RESOLUTION);
@@ -453,6 +454,7 @@ BOOL LLCubeMap::project(F32& v_min, F32& v_max, F32& h_min, F32& h_max,
void LLCubeMap::paintIn(LLVector3 dir[4], const LLColor4U& col)
{
+ LL_PROFILE_ZONE_SCOPED;
F32 v_min, v_max, h_min, h_max;
LLVector3 center = dir[0] + dir[1] + dir[2] + dir[3];
center.normVec();
diff --git a/indra/llrender/llfontbitmapcache.cpp b/indra/llrender/llfontbitmapcache.cpp
index f128636ab2..c71e24c83a 100644
--- a/indra/llrender/llfontbitmapcache.cpp
+++ b/indra/llrender/llfontbitmapcache.cpp
@@ -30,8 +30,7 @@
#include "llfontbitmapcache.h"
LLFontBitmapCache::LLFontBitmapCache()
-: LLTrace::MemTrackable<LLFontBitmapCache>("LLFontBitmapCache"),
- mNumComponents(0),
+: mNumComponents(0),
mBitmapWidth(0),
mBitmapHeight(0),
mBitmapNum(-1),
@@ -124,9 +123,6 @@ BOOL LLFontBitmapCache::nextOpenPos(S32 width, S32 &pos_x, S32 &pos_y, S32& bitm
image_gl->createGLTexture(0, image_raw);
gGL.getTexUnit(0)->bind(image_gl);
image_gl->setFilteringOption(LLTexUnit::TFO_POINT); // was setMipFilterNearest(TRUE, TRUE);
-
- claimMem(image_raw);
- claimMem(image_gl);
}
else
{
@@ -156,20 +152,8 @@ void LLFontBitmapCache::destroyGL()
void LLFontBitmapCache::reset()
{
- for (std::vector<LLPointer<LLImageRaw> >::iterator it = mImageRawVec.begin(), end_it = mImageRawVec.end();
- it != end_it;
- ++it)
- {
- disclaimMem(**it);
- }
mImageRawVec.clear();
- for (std::vector<LLPointer<LLImageGL> >::iterator it = mImageGLVec.begin(), end_it = mImageGLVec.end();
- it != end_it;
- ++it)
- {
- disclaimMem(**it);
- }
mImageGLVec.clear();
mBitmapWidth = 0;
diff --git a/indra/llrender/llfontbitmapcache.h b/indra/llrender/llfontbitmapcache.h
index 75df3a94a7..7de3a6b56f 100644
--- a/indra/llrender/llfontbitmapcache.h
+++ b/indra/llrender/llfontbitmapcache.h
@@ -32,7 +32,7 @@
// Maintain a collection of bitmaps containing rendered glyphs.
// Generalizes the single-bitmap logic from LLFontFreetype and LLFontGL.
-class LLFontBitmapCache : public LLTrace::MemTrackable<LLFontBitmapCache>
+class LLFontBitmapCache
{
public:
LLFontBitmapCache();
diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp
index c41730ebaa..e964d1586f 100644
--- a/indra/llrender/llfontfreetype.cpp
+++ b/indra/llrender/llfontfreetype.cpp
@@ -104,8 +104,7 @@ LLFontGlyphInfo::LLFontGlyphInfo(U32 index)
}
LLFontFreetype::LLFontFreetype()
-: LLTrace::MemTrackable<LLFontFreetype>("LLFontFreetype"),
- mFontBitmapCachep(new LLFontBitmapCache),
+: mFontBitmapCachep(new LLFontBitmapCache),
mAscender(0.f),
mDescender(0.f),
mLineHeight(0.f),
@@ -222,8 +221,6 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v
S32 max_char_height = ll_round(0.5f + (y_max - y_min));
mFontBitmapCachep->init(components, max_char_width, max_char_height);
- claimMem(mFontBitmapCachep);
-
if (!mFTFace->charmap)
{
@@ -238,7 +235,6 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v
}
mName = filename;
- claimMem(mName);
mPointSize = point_size;
mStyle = LLFontGL::NORMAL;
@@ -460,6 +456,7 @@ LLFontGlyphInfo* LLFontFreetype::addGlyph(llwchar wch) const
LLFontGlyphInfo* LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index) const
{
+ LL_PROFILE_ZONE_SCOPED;
if (mFTFace == NULL)
return NULL;
@@ -585,7 +582,6 @@ void LLFontFreetype::insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const
}
else
{
- claimMem(gi);
mCharGlyphInfoMap[wch] = gi;
}
}
@@ -631,11 +627,9 @@ void LLFontFreetype::resetBitmapCache()
it != end_it;
++it)
{
- disclaimMem(it->second);
delete it->second;
}
mCharGlyphInfoMap.clear();
- disclaimMem(mFontBitmapCachep);
mFontBitmapCachep->reset();
// Adding default glyph is skipped for fallback fonts here as well as in loadFace().
diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h
index 1afe84e770..f61f169987 100644
--- a/indra/llrender/llfontfreetype.h
+++ b/indra/llrender/llfontfreetype.h
@@ -76,7 +76,7 @@ struct LLFontGlyphInfo
extern LLFontManager *gFontManagerp;
-class LLFontFreetype : public LLRefCount, public LLTrace::MemTrackable<LLFontFreetype>
+class LLFontFreetype : public LLRefCount
{
public:
LLFontFreetype();
diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp
index 86a4c35e6d..7f734e41f3 100644
--- a/indra/llrender/llfontgl.cpp
+++ b/indra/llrender/llfontgl.cpp
@@ -109,8 +109,6 @@ S32 LLFontGL::getNumFaces(const std::string& filename)
return mFontFreetype->getNumFaces(filename);
}
-static LLTrace::BlockTimerStatHandle FTM_RENDER_FONTS("Fonts");
-
S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, const LLRect& rect, const LLColor4 &color, HAlign halign, VAlign valign, U8 style,
ShadowType shadow, S32 max_chars, F32* right_x, BOOL use_ellipses) const
{
@@ -147,7 +145,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, const LLRectf& rec
S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style,
ShadowType shadow, S32 max_chars, S32 max_pixels, F32* right_x, BOOL use_ellipses) const
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_FONTS);
+ LL_PROFILE_ZONE_SCOPED;
if(!sDisplayFont) //do not display texts
{
@@ -547,9 +545,19 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars
return cur_x / sScaleX;
}
+void LLFontGL::generateASCIIglyphs()
+{
+ LL_PROFILE_ZONE_SCOPED
+ for (U32 i = 32; (i < 127); i++)
+ {
+ mFontFreetype->getGlyphInfo(i);
+ }
+}
+
// Returns the max number of complete characters from text (up to max_chars) that can be drawn in max_pixels
S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars, EWordWrapStyle end_on_word_boundary) const
{
+ LL_PROFILE_ZONE_SCOPED
if (!wchars || !wchars[0] || max_chars == 0)
{
return 0;
@@ -829,6 +837,8 @@ void LLFontGL::initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::st
{
sFontRegistry->reset();
}
+
+ LLFontGL::loadDefaultFonts();
}
// Force standard fonts to get generated up front.
@@ -838,6 +848,7 @@ void LLFontGL::initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::st
// static
bool LLFontGL::loadDefaultFonts()
{
+ LL_PROFILE_ZONE_SCOPED
bool succ = true;
succ &= (NULL != getFontSansSerifSmall());
succ &= (NULL != getFontSansSerif());
@@ -845,10 +856,18 @@ bool LLFontGL::loadDefaultFonts()
succ &= (NULL != getFontSansSerifHuge());
succ &= (NULL != getFontSansSerifBold());
succ &= (NULL != getFontMonospace());
- succ &= (NULL != getFontExtChar());
return succ;
}
+void LLFontGL::loadCommonFonts()
+{
+ LL_PROFILE_ZONE_SCOPED
+ getFont(LLFontDescriptor("SansSerif", "Small", BOLD));
+ getFont(LLFontDescriptor("SansSerif", "Large", BOLD));
+ getFont(LLFontDescriptor("SansSerif", "Huge", BOLD));
+ getFont(LLFontDescriptor("Monospace", "Medium", 0));
+}
+
// static
void LLFontGL::destroyDefaultFonts()
{
@@ -1015,7 +1034,7 @@ LLFontGL* LLFontGL::getFontSansSerifBig()
//static
LLFontGL* LLFontGL::getFontSansSerifHuge()
{
- static LLFontGL* fontp = getFont(LLFontDescriptor("SansSerif","Large",0));
+ static LLFontGL* fontp = getFont(LLFontDescriptor("SansSerif","Huge",0));
return fontp;
}
@@ -1026,12 +1045,6 @@ LLFontGL* LLFontGL::getFontSansSerifBold()
return fontp;
}
-//static
-LLFontGL* LLFontGL::getFontExtChar()
-{
- return getFontSansSerif();
-}
-
//static
LLFontGL* LLFontGL::getFont(const LLFontDescriptor& desc)
{
diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h
index 10891faed9..3b58a37d33 100644
--- a/indra/llrender/llfontgl.h
+++ b/indra/llrender/llfontgl.h
@@ -160,12 +160,15 @@ public:
const LLFontDescriptor& getFontDesc() const;
+ void generateASCIIglyphs();
+
static void initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::string& app_dir, bool create_gl_textures = true);
// Load sans-serif, sans-serif-small, etc.
// Slow, requires multiple seconds to load fonts.
static bool loadDefaultFonts();
+ static void loadCommonFonts();
static void destroyDefaultFonts();
static void destroyAllGL();
@@ -190,7 +193,6 @@ public:
static LLFontGL* getFontSansSerifBig();
static LLFontGL* getFontSansSerifHuge();
static LLFontGL* getFontSansSerifBold();
- static LLFontGL* getFontExtChar();
static LLFontGL* getFont(const LLFontDescriptor& desc);
// Use with legacy names like "SANSSERIF_SMALL" or "OCRA"
static LLFontGL* getFontByName(const std::string& name);
diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp
index 33a33af160..bc1a2f8887 100644
--- a/indra/llrender/llfontregistry.cpp
+++ b/indra/llrender/llfontregistry.cpp
@@ -597,6 +597,11 @@ LLFontGL *LLFontRegistry::getFont(const LLFontDescriptor& desc)
<<" style=[" << ((S32) desc.getStyle()) << "]"
<< " size=[" << desc.getSize() << "]" << LL_ENDL;
}
+ else
+ {
+ //generate glyphs for ASCII chars to avoid stalls later
+ fontp->generateASCIIglyphs();
+ }
return fontp;
}
}
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 43fedeca64..c7f85aec21 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -62,6 +62,7 @@
BOOL gDebugSession = FALSE;
BOOL gClothRipple = FALSE;
BOOL gHeadlessClient = FALSE;
+BOOL gNonInteractive = FALSE;
BOOL gGLActive = FALSE;
BOOL gGLDebugLoggingEnabled = TRUE;
@@ -434,9 +435,6 @@ LLGLManager::LLGLManager() :
mHasMapBufferRange(FALSE),
mHasFlushBufferRange(FALSE),
mHasPBuffer(FALSE),
- mHasShaderObjects(FALSE),
- mHasVertexShader(FALSE),
- mHasFragmentShader(FALSE),
mNumTextureImageUnits(0),
mHasOcclusionQuery(FALSE),
mHasTimerQuery(FALSE),
@@ -559,7 +557,7 @@ bool LLGLManager::initGL()
glGetIntegerv(GL_NUM_EXTENSIONS, &count);
for (GLint i = 0; i < count; ++i)
{
- std::string ext((const char*) glGetStringi(GL_EXTENSIONS, i));
+ std::string ext = ll_safe_string((const char*) glGetStringi(GL_EXTENSIONS, i));
str << ext << " ";
LL_DEBUGS("GLExtensions") << ext << LL_ENDL;
}
@@ -775,14 +773,9 @@ bool LLGLManager::initGL()
stop_glerror();
- stop_glerror();
-
- if (mHasFragmentShader)
- {
- GLint num_tex_image_units;
- glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &num_tex_image_units);
- mNumTextureImageUnits = llmin(num_tex_image_units, 32);
- }
+ GLint num_tex_image_units;
+ glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &num_tex_image_units);
+ mNumTextureImageUnits = llmin(num_tex_image_units, 32);
if (LLRender::sGLCoreProfile)
{
@@ -975,9 +968,9 @@ void LLGLManager::asLLSD(LLSD& info)
info["has_map_buffer_range"] = mHasMapBufferRange;
info["has_flush_buffer_range"] = mHasFlushBufferRange;
info["has_pbuffer"] = mHasPBuffer;
- info["has_shader_objects"] = mHasShaderObjects;
- info["has_vertex_shader"] = mHasVertexShader;
- info["has_fragment_shader"] = mHasFragmentShader;
+ info["has_shader_objects"] = std::string("Assumed TRUE"); // was mHasShaderObjects;
+ info["has_vertex_shader"] = std::string("Assumed TRUE"); // was mHasVertexShader;
+ info["has_fragment_shader"] = std::string("Assumed TRUE"); // was mHasFragmentShader;
info["num_texture_image_units"] = mNumTextureImageUnits;
info["has_occlusion_query"] = mHasOcclusionQuery;
info["has_timer_query"] = mHasTimerQuery;
@@ -1083,9 +1076,6 @@ void LLGLManager::initExtensions()
mHasCubeMap = FALSE;
mHasOcclusionQuery = FALSE;
mHasPointParameters = FALSE;
- mHasShaderObjects = FALSE;
- mHasVertexShader = FALSE;
- mHasFragmentShader = FALSE;
mHasTextureRectangle = FALSE;
#else // LL_MESA_HEADLESS //important, gGLHExts.mSysExts is uninitialized until after glh_init_extensions is called
mHasMultitexture = glh_init_extensions("GL_ARB_multitexture");
@@ -1143,10 +1133,6 @@ void LLGLManager::initExtensions()
#if !LL_DARWIN
mHasPointParameters = !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));
#endif
#if LL_LINUX
@@ -1169,9 +1155,6 @@ void LLGLManager::initExtensions()
mHasCubeMap = FALSE;
mHasOcclusionQuery = FALSE;
mHasPointParameters = FALSE;
- mHasShaderObjects = FALSE;
- mHasVertexShader = FALSE;
- mHasFragmentShader = FALSE;
LL_WARNS("RenderInit") << "GL extension support DISABLED via LL_GL_NOEXT" << LL_ENDL;
}
else if (getenv("LL_GL_BASICEXT")) /* Flawfinder: ignore */
@@ -1184,9 +1167,6 @@ void LLGLManager::initExtensions()
mHasAnisotropic = FALSE;
//mHasCubeMap = FALSE; // apparently fatal on Intel 915 & similar
//mHasOcclusionQuery = FALSE; // source of many ATI system hangs
- mHasShaderObjects = FALSE;
- mHasVertexShader = FALSE;
- mHasFragmentShader = FALSE;
mHasBlendFuncSeparate = FALSE;
LL_WARNS("RenderInit") << "GL extension support forced to SIMPLE level via LL_GL_BASICEXT" << LL_ENDL;
}
@@ -1208,9 +1188,6 @@ void LLGLManager::initExtensions()
if (strchr(blacklist,'j')) mHasCubeMap = FALSE;//S
// if (strchr(blacklist,'k')) mHasATIVAO = FALSE;//S
if (strchr(blacklist,'l')) mHasOcclusionQuery = FALSE;
- if (strchr(blacklist,'m')) mHasShaderObjects = FALSE;//S
- if (strchr(blacklist,'n')) mHasVertexShader = FALSE;//S
- if (strchr(blacklist,'o')) mHasFragmentShader = FALSE;//S
if (strchr(blacklist,'p')) mHasPointParameters = FALSE;//S
if (strchr(blacklist,'q')) mHasFramebufferObject = FALSE;//S
if (strchr(blacklist,'r')) mHasDrawBuffers = FALSE;//S
@@ -1257,18 +1234,6 @@ void LLGLManager::initExtensions()
{
LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_point_parameters" << LL_ENDL;
}
- if (!mHasShaderObjects)
- {
- LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_shader_objects" << LL_ENDL;
- }
- if (!mHasVertexShader)
- {
- LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_vertex_shader" << LL_ENDL;
- }
- if (!mHasFragmentShader)
- {
- LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_fragment_shader" << LL_ENDL;
- }
if (!mHasBlendFuncSeparate)
{
LL_INFOS("RenderInit") << "Couldn't initialize GL_EXT_blend_func_separate" << LL_ENDL;
@@ -1436,134 +1401,132 @@ void LLGLManager::initExtensions()
glPointParameterfARB = (PFNGLPOINTPARAMETERFARBPROC)GLH_EXT_GET_PROC_ADDRESS("glPointParameterfARB");
glPointParameterfvARB = (PFNGLPOINTPARAMETERFVARBPROC)GLH_EXT_GET_PROC_ADDRESS("glPointParameterfvARB");
}
- 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");
- }
- if (mHasVertexShader)
- {
- LL_INFOS() << "initExtensions() VertexShader-related procs..." << LL_ENDL;
-
- // nSight doesn't support use of ARB funcs that have been normalized in the API
- if (!LLRender::sNsightDebugSupport)
- {
- glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetAttribLocationARB");
- glBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glBindAttribLocationARB");
- }
- else
- {
- glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC)GLH_EXT_GET_PROC_ADDRESS("glGetAttribLocation");
- glBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC)GLH_EXT_GET_PROC_ADDRESS("glBindAttribLocation");
- }
-
- 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");
- glBindProgramARB = (PFNGLBINDPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glBindProgramARB");
- glDeleteProgramsARB = (PFNGLDELETEPROGRAMSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteProgramsARB");
- glGenProgramsARB = (PFNGLGENPROGRAMSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGenProgramsARB");
- glProgramEnvParameter4dARB = (PFNGLPROGRAMENVPARAMETER4DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4dARB");
- glProgramEnvParameter4dvARB = (PFNGLPROGRAMENVPARAMETER4DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4dvARB");
- glProgramEnvParameter4fARB = (PFNGLPROGRAMENVPARAMETER4FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4fARB");
- glProgramEnvParameter4fvARB = (PFNGLPROGRAMENVPARAMETER4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4fvARB");
- glProgramLocalParameter4dARB = (PFNGLPROGRAMLOCALPARAMETER4DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4dARB");
- glProgramLocalParameter4dvARB = (PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4dvARB");
- glProgramLocalParameter4fARB = (PFNGLPROGRAMLOCALPARAMETER4FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4fARB");
- glProgramLocalParameter4fvARB = (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4fvARB");
- glGetProgramEnvParameterdvARB = (PFNGLGETPROGRAMENVPARAMETERDVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramEnvParameterdvARB");
- glGetProgramEnvParameterfvARB = (PFNGLGETPROGRAMENVPARAMETERFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramEnvParameterfvARB");
- 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");
- }
- LL_DEBUGS("RenderInit") << "GL Probe: Got symbols" << LL_ENDL;
+
+ // Assume shader capabilities
+ 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");
+
+ LL_INFOS() << "initExtensions() VertexShader-related procs..." << LL_ENDL;
+
+ // nSight doesn't support use of ARB funcs that have been normalized in the API
+ if (!LLRender::sNsightDebugSupport)
+ {
+ glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetAttribLocationARB");
+ glBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glBindAttribLocationARB");
+ }
+ else
+ {
+ glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetAttribLocation");
+ glBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glBindAttribLocation");
+ }
+
+ 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");
+ glBindProgramARB = (PFNGLBINDPROGRAMARBPROC) GLH_EXT_GET_PROC_ADDRESS("glBindProgramARB");
+ glDeleteProgramsARB = (PFNGLDELETEPROGRAMSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteProgramsARB");
+ glGenProgramsARB = (PFNGLGENPROGRAMSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGenProgramsARB");
+ glProgramEnvParameter4dARB = (PFNGLPROGRAMENVPARAMETER4DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4dARB");
+ glProgramEnvParameter4dvARB = (PFNGLPROGRAMENVPARAMETER4DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4dvARB");
+ glProgramEnvParameter4fARB = (PFNGLPROGRAMENVPARAMETER4FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4fARB");
+ glProgramEnvParameter4fvARB = (PFNGLPROGRAMENVPARAMETER4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramEnvParameter4fvARB");
+ glProgramLocalParameter4dARB = (PFNGLPROGRAMLOCALPARAMETER4DARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4dARB");
+ glProgramLocalParameter4dvARB = (PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4dvARB");
+ glProgramLocalParameter4fARB = (PFNGLPROGRAMLOCALPARAMETER4FARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4fARB");
+ glProgramLocalParameter4fvARB = (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramLocalParameter4fvARB");
+ glGetProgramEnvParameterdvARB = (PFNGLGETPROGRAMENVPARAMETERDVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramEnvParameterdvARB");
+ glGetProgramEnvParameterfvARB = (PFNGLGETPROGRAMENVPARAMETERFVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetProgramEnvParameterfvARB");
+ 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");
+
+ LL_DEBUGS("RenderInit") << "GL Probe: Got symbols" << LL_ENDL;
#endif
- mInited = TRUE;
+ mInited = TRUE;
}
void rotate_quat(LLQuaternion& rotation)
@@ -2116,7 +2079,7 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
glClientActiveTextureARB(GL_TEXTURE0_ARB);
gGL.getTexUnit(0)->activate();
- if (gGLManager.mHasVertexShader && LLGLSLShader::sNoFixedFunction)
+ if (LLGLSLShader::sNoFixedFunction)
{ //make sure vertex attribs are all disabled
GLint count;
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &count);
@@ -2154,6 +2117,7 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
LLGLState::LLGLState(LLGLenum state, S32 enabled) :
mState(state), mWasEnabled(FALSE), mIsEnabled(FALSE)
{
+ LL_PROFILE_ZONE_SCOPED;
if (LLGLSLShader::sNoFixedFunction)
{ //always ignore state that's deprecated post GL 3.0
switch (state)
@@ -2212,6 +2176,7 @@ void LLGLState::setEnabled(S32 enabled)
LLGLState::~LLGLState()
{
+ LL_PROFILE_ZONE_SCOPED;
stop_glerror();
if (mState)
{
@@ -2469,6 +2434,7 @@ void LLGLNamePool::cleanup()
GLuint LLGLNamePool::allocate()
{
+ LL_PROFILE_ZONE_SCOPED;
#if LL_GL_NAME_POOLING
for (name_list_t::iterator iter = mNameList.begin(); iter != mNameList.end(); ++iter)
{
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index a07e2d9bb0..6e1f5e6deb 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -94,9 +94,6 @@ public:
BOOL mHasMapBufferRange;
BOOL mHasFlushBufferRange;
BOOL mHasPBuffer;
- BOOL mHasShaderObjects;
- BOOL mHasVertexShader;
- BOOL mHasFragmentShader;
S32 mNumTextureImageUnits;
BOOL mHasOcclusionQuery;
BOOL mHasTimerQuery;
@@ -488,6 +485,7 @@ void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor
extern BOOL gClothRipple;
extern BOOL gHeadlessClient;
+extern BOOL gNonInteractive;
extern BOOL gGLActive;
// Deal with changing glext.h definitions for newer SDK versions, specifically
diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h
index 6bca3623e0..3d93cc0762 100644
--- a/indra/llrender/llglheaders.h
+++ b/indra/llrender/llglheaders.h
@@ -812,4 +812,23 @@ extern void glGetBufferPointervARB (GLenum, GLenum, GLvoid* *);
#define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD
#endif
+#if defined(TRACY_ENABLE) && LL_PROFILER_ENABLE_TRACY_OPENGL
+ // Tracy uses the following:
+ // glGenQueries
+ // glGetQueryiv
+ // glGetQueryObjectiv
+ #define glGenQueries glGenQueriesARB
+ #define glGetQueryiv glGetQueryivARB
+ #define glGetQueryObjectiv glGetQueryObjectivARB
+ #include <tracy/TracyOpenGL.hpp>
+
+ #define LL_PROFILER_GPU_ZONEC(name,color) TracyGpuZoneC(name,color);
+ #define LL_PROFILER_GPU_COLLECT TracyGpuCollect
+ #define LL_PROFILER_GPU_CONTEXT TracyGpuContext
+#else
+ #define LL_PROFILER_GPU_ZONEC(name,color) (void)name;(void)color;
+ #define LL_PROFILER_GPU_COLLECT
+ #define LL_PROFILER_GPU_CONTEXT
+#endif
+
#endif // LL_LLGLHEADERS_H
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 4351f6e2c8..08c9dd8769 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -208,6 +208,7 @@ void LLGLSLShader::dumpStats()
//static
void LLGLSLShader::startProfile()
{
+ LL_PROFILE_ZONE_SCOPED;
if (sProfileEnabled && sCurBoundShaderPtr)
{
sCurBoundShaderPtr->placeProfileQuery();
@@ -218,6 +219,7 @@ void LLGLSLShader::startProfile()
//static
void LLGLSLShader::stopProfile(U32 count, U32 mode)
{
+ LL_PROFILE_ZONE_SCOPED;
if (sProfileEnabled && sCurBoundShaderPtr)
{
sCurBoundShaderPtr->readProfileQuery(count, mode);
@@ -384,6 +386,8 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
U32 varying_count,
const char** varyings)
{
+ LL_PROFILE_ZONE_SCOPED;
+
unloadInternal();
sInstances.insert(this);
@@ -588,6 +592,8 @@ void LLGLSLShader::attachObjects(GLhandleARB* objects, S32 count)
BOOL LLGLSLShader::mapAttributes(const std::vector<LLStaticHashedString> * attributes)
{
+ LL_PROFILE_ZONE_SCOPED;
+
//before linking, make sure reserved attributes always have consistent locations
for (U32 i = 0; i < LLShaderMgr::instance()->mReservedAttribs.size(); i++)
{
@@ -649,6 +655,8 @@ BOOL LLGLSLShader::mapAttributes(const std::vector<LLStaticHashedString> * attri
void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString> * uniforms)
{
+ LL_PROFILE_ZONE_SCOPED;
+
if (index == -1)
{
return;
@@ -770,6 +778,8 @@ void LLGLSLShader::removePermutation(std::string name)
GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type)
{
+ LL_PROFILE_ZONE_SCOPED;
+
if ((type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB) ||
type == GL_SAMPLER_2D_MULTISAMPLE)
{ //this here is a texture
@@ -782,7 +792,9 @@ GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type)
BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
{
- BOOL res = TRUE;
+ LL_PROFILE_ZONE_SCOPED;
+
+ BOOL res = TRUE;
mTotalUniformSize = 0;
mActiveTextureChannels = 0;
@@ -925,6 +937,8 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
BOOL LLGLSLShader::link(BOOL suppress_errors)
{
+ LL_PROFILE_ZONE_SCOPED;
+
BOOL success = LLShaderMgr::instance()->linkProgramObject(mProgramObject, suppress_errors);
if (!success && !suppress_errors)
@@ -937,56 +951,52 @@ BOOL LLGLSLShader::link(BOOL suppress_errors)
void LLGLSLShader::bind()
{
+ LL_PROFILE_ZONE_SCOPED;
+
gGL.flush();
- if (gGLManager.mHasShaderObjects)
+
+ if (sCurBoundShader != mProgramObject) // Don't re-bind current shader
{
LLVertexBuffer::unbind();
glUseProgramObjectARB(mProgramObject);
sCurBoundShader = mProgramObject;
sCurBoundShaderPtr = this;
- if (mUniformsDirty)
- {
- LLShaderMgr::instance()->updateShaderUniforms(this);
- mUniformsDirty = FALSE;
- }
+ }
+
+ if (mUniformsDirty)
+ {
+ LLShaderMgr::instance()->updateShaderUniforms(this);
+ mUniformsDirty = FALSE;
}
}
void LLGLSLShader::unbind()
{
+ LL_PROFILE_ZONE_SCOPED;
+
gGL.flush();
- if (gGLManager.mHasShaderObjects)
- {
- stop_glerror();
- if (gGLManager.mIsNVIDIA)
- {
- for (U32 i = 0; i < mAttribute.size(); ++i)
- {
- vertexAttrib4f(i, 0,0,0,1);
- stop_glerror();
- }
- }
- LLVertexBuffer::unbind();
- glUseProgramObjectARB(0);
- sCurBoundShader = 0;
- sCurBoundShaderPtr = NULL;
- stop_glerror();
- }
+ stop_glerror();
+ LLVertexBuffer::unbind();
+ glUseProgramObjectARB(0);
+ sCurBoundShader = 0;
+ sCurBoundShaderPtr = NULL;
+ stop_glerror();
}
void LLGLSLShader::bindNoShader(void)
{
+ LL_PROFILE_ZONE_SCOPED;
+
LLVertexBuffer::unbind();
- if (gGLManager.mHasShaderObjects)
- {
- glUseProgramObjectARB(0);
- sCurBoundShader = 0;
- sCurBoundShaderPtr = NULL;
- }
+ glUseProgramObjectARB(0);
+ sCurBoundShader = 0;
+ sCurBoundShaderPtr = NULL;
}
S32 LLGLSLShader::bindTexture(const std::string &uniform, LLTexture *texture, LLTexUnit::eTextureType mode, LLTexUnit::eTextureColorSpace colorspace)
{
+ LL_PROFILE_ZONE_SCOPED;
+
S32 channel = 0;
channel = getUniformLocation(uniform);
@@ -995,6 +1005,8 @@ S32 LLGLSLShader::bindTexture(const std::string &uniform, LLTexture *texture, LL
S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextureType mode, LLTexUnit::eTextureColorSpace colorspace)
{
+ LL_PROFILE_ZONE_SCOPED;
+
if (uniform < 0 || uniform >= (S32)mTexture.size())
{
LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL;
@@ -1005,7 +1017,7 @@ S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextu
if (uniform > -1)
{
- gGL.getTexUnit(uniform)->bind(texture, mode);
+ gGL.getTexUnit(uniform)->bindFast(texture);
gGL.getTexUnit(uniform)->setTextureColorSpace(colorspace);
}
@@ -1014,6 +1026,8 @@ S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextu
S32 LLGLSLShader::unbindTexture(const std::string &uniform, LLTexUnit::eTextureType mode)
{
+ LL_PROFILE_ZONE_SCOPED;
+
S32 channel = 0;
channel = getUniformLocation(uniform);
@@ -1022,6 +1036,8 @@ S32 LLGLSLShader::unbindTexture(const std::string &uniform, LLTexUnit::eTextureT
S32 LLGLSLShader::unbindTexture(S32 uniform, LLTexUnit::eTextureType mode)
{
+ LL_PROFILE_ZONE_SCOPED;
+
if (uniform < 0 || uniform >= (S32)mTexture.size())
{
LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL;
@@ -1032,7 +1048,7 @@ S32 LLGLSLShader::unbindTexture(S32 uniform, LLTexUnit::eTextureType mode)
if (uniform > -1)
{
- gGL.getTexUnit(uniform)->unbind(mode);
+ gGL.getTexUnit(uniform)->unbindFast(mode);
}
return uniform;
@@ -1040,6 +1056,8 @@ S32 LLGLSLShader::unbindTexture(S32 uniform, LLTexUnit::eTextureType mode)
S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode, LLTexUnit::eTextureColorSpace space)
{
+ LL_PROFILE_ZONE_SCOPED;
+
if (uniform < 0 || uniform >= (S32)mTexture.size())
{
LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL;
@@ -1057,6 +1075,8 @@ S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode, LLTex
S32 LLGLSLShader::disableTexture(S32 uniform, LLTexUnit::eTextureType mode, LLTexUnit::eTextureColorSpace space)
{
+ LL_PROFILE_ZONE_SCOPED;
+
if (uniform < 0 || uniform >= (S32)mTexture.size())
{
LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL;
@@ -1084,6 +1104,7 @@ S32 LLGLSLShader::disableTexture(S32 uniform, LLTexUnit::eTextureType mode, LLTe
void LLGLSLShader::uniform1i(U32 index, GLint x)
{
+ LL_PROFILE_ZONE_SCOPED
if (mProgramObject)
{
if (mUniform.size() <= index)
@@ -1094,7 +1115,7 @@ void LLGLSLShader::uniform1i(U32 index, GLint x)
if (mUniform[index] >= 0)
{
- std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
+ const auto& iter = mValue.find(mUniform[index]);
if (iter == mValue.end() || iter->second.mV[0] != x)
{
glUniform1iARB(mUniform[index], x);
@@ -1106,6 +1127,7 @@ void LLGLSLShader::uniform1i(U32 index, GLint x)
void LLGLSLShader::uniform1f(U32 index, GLfloat x)
{
+ LL_PROFILE_ZONE_SCOPED
if (mProgramObject)
{
if (mUniform.size() <= index)
@@ -1116,7 +1138,7 @@ void LLGLSLShader::uniform1f(U32 index, GLfloat x)
if (mUniform[index] >= 0)
{
- std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
+ const auto& iter = mValue.find(mUniform[index]);
if (iter == mValue.end() || iter->second.mV[0] != x)
{
glUniform1fARB(mUniform[index], x);
@@ -1138,7 +1160,7 @@ void LLGLSLShader::uniform2f(U32 index, GLfloat x, GLfloat y)
if (mUniform[index] >= 0)
{
- std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
+ const auto& iter = mValue.find(mUniform[index]);
LLVector4 vec(x,y,0.f,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec))
{
@@ -1161,7 +1183,7 @@ void LLGLSLShader::uniform3f(U32 index, GLfloat x, GLfloat y, GLfloat z)
if (mUniform[index] >= 0)
{
- std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
+ const auto& iter = mValue.find(mUniform[index]);
LLVector4 vec(x,y,z,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec))
{
@@ -1184,7 +1206,7 @@ void LLGLSLShader::uniform4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat
if (mUniform[index] >= 0)
{
- std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
+ const auto& iter = mValue.find(mUniform[index]);
LLVector4 vec(x,y,z,w);
if (iter == mValue.end() || shouldChange(iter->second,vec))
{
@@ -1207,7 +1229,7 @@ void LLGLSLShader::uniform1iv(U32 index, U32 count, const GLint* v)
if (mUniform[index] >= 0)
{
- std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
+ const auto& iter = mValue.find(mUniform[index]);
LLVector4 vec(v[0],0.f,0.f,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
{
@@ -1230,7 +1252,7 @@ void LLGLSLShader::uniform1fv(U32 index, U32 count, const GLfloat* v)
if (mUniform[index] >= 0)
{
- std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
+ const auto& iter = mValue.find(mUniform[index]);
LLVector4 vec(v[0],0.f,0.f,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
{
@@ -1253,7 +1275,7 @@ void LLGLSLShader::uniform2fv(U32 index, U32 count, const GLfloat* v)
if (mUniform[index] >= 0)
{
- std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
+ const auto& iter = mValue.find(mUniform[index]);
LLVector4 vec(v[0],v[1],0.f,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
{
@@ -1276,7 +1298,7 @@ void LLGLSLShader::uniform3fv(U32 index, U32 count, const GLfloat* v)
if (mUniform[index] >= 0)
{
- std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
+ const auto& iter = mValue.find(mUniform[index]);
LLVector4 vec(v[0],v[1],v[2],0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
{
@@ -1299,10 +1321,11 @@ void LLGLSLShader::uniform4fv(U32 index, U32 count, const GLfloat* v)
if (mUniform[index] >= 0)
{
- std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
+ const auto& iter = mValue.find(mUniform[index]);
LLVector4 vec(v[0],v[1],v[2],v[3]);
if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
{
+ LL_PROFILE_ZONE_SCOPED;
glUniform4fvARB(mUniform[index], count, v);
mValue[mUniform[index]] = vec;
}
@@ -1346,6 +1369,8 @@ void LLGLSLShader::uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, c
void LLGLSLShader::uniformMatrix3x4fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v)
{
+ LL_PROFILE_ZONE_SCOPED;
+
if (mProgramObject)
{
if (mUniform.size() <= index)
@@ -1380,6 +1405,8 @@ void LLGLSLShader::uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, c
GLint LLGLSLShader::getUniformLocation(const LLStaticHashedString& uniform)
{
+ LL_PROFILE_ZONE_SCOPED;
+
GLint ret = -1;
if (mProgramObject)
{
@@ -1404,10 +1431,16 @@ GLint LLGLSLShader::getUniformLocation(const LLStaticHashedString& uniform)
GLint LLGLSLShader::getUniformLocation(U32 index)
{
+ LL_PROFILE_ZONE_SCOPED;
+
GLint ret = -1;
if (mProgramObject)
{
- llassert(index < mUniform.size());
+ if (index >= mUniform.size())
+ {
+ LL_WARNS_ONCE("Shader") << "Uniform index " << index << " out of bounds " << (S32)mUniform.size() << LL_ENDL;
+ return ret;
+ }
return mUniform[index];
}
@@ -1416,6 +1449,8 @@ GLint LLGLSLShader::getUniformLocation(U32 index)
GLint LLGLSLShader::getAttribLocation(U32 attrib)
{
+ LL_PROFILE_ZONE_SCOPED;
+
if (attrib < mAttribute.size())
{
return mAttribute[attrib];
@@ -1432,7 +1467,7 @@ void LLGLSLShader::uniform1i(const LLStaticHashedString& uniform, GLint v)
if (location >= 0)
{
- std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
+ const auto& iter = mValue.find(location);
LLVector4 vec(v,0.f,0.f,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec))
{
@@ -1448,7 +1483,7 @@ void LLGLSLShader::uniform2i(const LLStaticHashedString& uniform, GLint i, GLint
if (location >= 0)
{
- std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
+ const auto& iter = mValue.find(location);
LLVector4 vec(i,j,0.f,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec))
{
@@ -1465,7 +1500,7 @@ void LLGLSLShader::uniform1f(const LLStaticHashedString& uniform, GLfloat v)
if (location >= 0)
{
- std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
+ const auto& iter = mValue.find(location);
LLVector4 vec(v,0.f,0.f,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec))
{
@@ -1481,7 +1516,7 @@ void LLGLSLShader::uniform2f(const LLStaticHashedString& uniform, GLfloat x, GLf
if (location >= 0)
{
- std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
+ const auto& iter = mValue.find(location);
LLVector4 vec(x,y,0.f,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec))
{
@@ -1498,7 +1533,7 @@ void LLGLSLShader::uniform3f(const LLStaticHashedString& uniform, GLfloat x, GLf
if (location >= 0)
{
- std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
+ const auto& iter = mValue.find(location);
LLVector4 vec(x,y,z,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec))
{
@@ -1514,7 +1549,7 @@ void LLGLSLShader::uniform1fv(const LLStaticHashedString& uniform, U32 count, co
if (location >= 0)
{
- std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
+ const auto& iter = mValue.find(location);
LLVector4 vec(v[0],0.f,0.f,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
{
@@ -1530,7 +1565,7 @@ void LLGLSLShader::uniform2fv(const LLStaticHashedString& uniform, U32 count, co
if (location >= 0)
{
- std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
+ const auto& iter = mValue.find(location);
LLVector4 vec(v[0],v[1],0.f,0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
{
@@ -1546,7 +1581,7 @@ void LLGLSLShader::uniform3fv(const LLStaticHashedString& uniform, U32 count, co
if (location >= 0)
{
- std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
+ const auto& iter = mValue.find(location);
LLVector4 vec(v[0],v[1],v[2],0.f);
if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
{
@@ -1563,12 +1598,11 @@ void LLGLSLShader::uniform4fv(const LLStaticHashedString& uniform, U32 count, co
if (location >= 0)
{
LLVector4 vec(v);
- std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
+ const auto& iter = mValue.find(location);
if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
{
- stop_glerror();
+ LL_PROFILE_ZONE_SCOPED;
glUniform4fvARB(location, count, v);
- stop_glerror();
mValue[location] = vec;
}
}
@@ -1608,3 +1642,27 @@ void LLGLSLShader::setMinimumAlpha(F32 minimum)
gGL.flush();
uniform1f(LLShaderMgr::MINIMUM_ALPHA, minimum);
}
+
+void LLShaderUniforms::apply(LLGLSLShader* shader)
+{
+ LL_PROFILE_ZONE_SCOPED;
+ for (auto& uniform : mIntegers)
+ {
+ shader->uniform1i(uniform.mUniform, uniform.mValue);
+ }
+
+ for (auto& uniform : mFloats)
+ {
+ shader->uniform1f(uniform.mUniform, uniform.mValue);
+ }
+
+ for (auto& uniform : mVectors)
+ {
+ shader->uniform4fv(uniform.mUniform, 1, uniform.mValue.mV);
+ }
+
+ for (auto& uniform : mVector3s)
+ {
+ shader->uniform3fv(uniform.mUniform, 1, uniform.mValue.mV);
+ }
+}
diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index 7cf6d3c941..3b23cf1b28 100644
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -30,6 +30,7 @@
#include "llgl.h"
#include "llrender.h"
#include "llstaticstringtable.h"
+#include <unordered_map>
class LLShaderFeatures
{
@@ -64,16 +65,79 @@ public:
LLShaderFeatures();
};
+// ============= Structure for caching shader uniforms ===============
+class LLGLSLShader;
+
+class LLShaderUniforms
+{
+public:
+
+ template<typename T>
+ struct UniformSetting
+ {
+ S32 mUniform;
+ T mValue;
+ };
+
+ typedef UniformSetting<S32> IntSetting;
+ typedef UniformSetting<F32> FloatSetting;
+ typedef UniformSetting<LLVector4> VectorSetting;
+ typedef UniformSetting<LLVector3> Vector3Setting;
+
+ void clear()
+ {
+ mIntegers.resize(0);
+ mFloats.resize(0);
+ mVectors.resize(0);
+ mVector3s.resize(0);
+ }
+
+ void uniform1i(S32 index, S32 value)
+ {
+ mIntegers.push_back({ index, value });
+ }
+
+ void uniform1f(S32 index, F32 value)
+ {
+ mFloats.push_back({ index, value });
+ }
+
+ void uniform4fv(S32 index, const LLVector4& value)
+ {
+ mVectors.push_back({ index, value });
+ }
+
+ void uniform4fv(S32 index, const F32* value)
+ {
+ mVectors.push_back({ index, LLVector4(value) });
+ }
+
+ void uniform3fv(S32 index, const LLVector3& value)
+ {
+ mVector3s.push_back({ index, value });
+ }
+
+ void apply(LLGLSLShader* shader);
+
+
+ std::vector<IntSetting> mIntegers;
+ std::vector<FloatSetting> mFloats;
+ std::vector<VectorSetting> mVectors;
+ std::vector<Vector3Setting> mVector3s;
+};
class LLGLSLShader
{
public:
- enum
+ // enum primarily used to control application sky settings uniforms
+ typedef enum
{
- SG_DEFAULT = 0,
- SG_SKY,
- SG_WATER
- };
+ SG_DEFAULT = 0, // not sky or water specific
+ SG_SKY, //
+ SG_WATER,
+ SG_ANY,
+ SG_COUNT
+ } eGroup;
static std::set<LLGLSLShader*> sInstances;
static bool sProfileEnabled;
@@ -190,13 +254,15 @@ public:
U32 mAttributeMask; //mask of which reserved attributes are set (lines up with LLVertexBuffer::getTypeMask())
std::vector<GLint> mUniform; //lookup table of uniform enum to uniform location
LLStaticStringTable<GLint> mUniformMap; //lookup map of uniform name to uniform location
- std::map<GLint, std::string> mUniformNameMap; //lookup map of uniform location to uniform name
- std::map<GLint, LLVector4> mValue; //lookup map of uniform location to last known value
+ typedef std::unordered_map<GLint, std::string> uniform_name_map_t;
+ typedef std::unordered_map<GLint, LLVector4> uniform_value_map_t;
+ uniform_name_map_t mUniformNameMap; //lookup map of uniform location to uniform name
+ uniform_value_map_t mValue; //lookup map of uniform location to last known value
std::vector<GLint> mTexture;
S32 mTotalUniformSize;
S32 mActiveTextureChannels;
S32 mShaderLevel;
- S32 mShaderGroup;
+ S32 mShaderGroup; // see LLGLSLShader::eGroup
BOOL mUniformsDirty;
LLShaderFeatures mFeatures;
std::vector< std::pair< std::string, GLenum > > mShaderFiles;
diff --git a/indra/llrender/llgltexture.cpp b/indra/llrender/llgltexture.cpp
index ad501687ed..a279e85bae 100644
--- a/indra/llrender/llgltexture.cpp
+++ b/indra/llrender/llgltexture.cpp
@@ -262,6 +262,7 @@ LLTexUnit::eTextureType LLGLTexture::getTarget(void) const
BOOL LLGLTexture::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height)
{
+ LL_PROFILE_ZONE_SCOPED;
llassert(mGLTexturep.notNull()) ;
return mGLTexturep->setSubImage(imageraw, x_pos, y_pos, width, height) ;
@@ -269,6 +270,7 @@ BOOL LLGLTexture::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos,
BOOL LLGLTexture::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height)
{
+ LL_PROFILE_ZONE_SCOPED;
llassert(mGLTexturep.notNull()) ;
return mGLTexturep->setSubImage(datap, data_width, data_height, x_pos, y_pos, width, height) ;
diff --git a/indra/llrender/llgltexture.h b/indra/llrender/llgltexture.h
index 071912c2c2..028457c510 100644
--- a/indra/llrender/llgltexture.h
+++ b/indra/llrender/llgltexture.h
@@ -176,7 +176,7 @@ private:
protected:
void setTexelsPerImage();
- //note: do not make this function public.
+public:
/*virtual*/ LLImageGL* getGLTexture() const ;
protected:
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 0151d20128..cbc5392882 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -39,6 +39,7 @@
#include "llgl.h"
#include "llglslshader.h"
#include "llrender.h"
+#include "llwindow.h"
//----------------------------------------------------------------------------
const F32 MIN_TEXTURE_LIFETIME = 10.f;
@@ -170,15 +171,32 @@ BOOL is_little_endian()
return (*c == 0x78) ;
}
+
+LLImageGLThread* LLImageGLThread::sInstance = nullptr;
+
//static
-void LLImageGL::initClass(S32 num_catagories, BOOL skip_analyze_alpha /* = false */)
+void LLImageGL::initClass(LLWindow* window, S32 num_catagories, BOOL skip_analyze_alpha /* = false */)
{
+ LL_PROFILE_ZONE_SCOPED;
sSkipAnalyzeAlpha = skip_analyze_alpha;
+ LLImageGLThread::sInstance = new LLImageGLThread(window);
+ LLImageGLThread::sInstance->start();
+}
+
+//static
+void LLImageGL::updateClass()
+{
+ LL_PROFILE_ZONE_SCOPED;
+ LLImageGLThread::sInstance->executeCallbacks();
}
//static
void LLImageGL::cleanupClass()
-{
+{
+ LL_PROFILE_ZONE_SCOPED;
+ LLImageGLThread::sInstance->mFunctionQueue.close();
+ delete LLImageGLThread::sInstance;
+ LLImageGLThread::sInstance = nullptr;
}
//static
@@ -258,11 +276,10 @@ S32 LLImageGL::dataFormatComponents(S32 dataformat)
//----------------------------------------------------------------------------
-static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE_STATS("Image Stats");
// static
void LLImageGL::updateStats(F32 current_time)
{
- LL_RECORD_BLOCK_TIME(FTM_IMAGE_UPDATE_STATS);
+ LL_PROFILE_ZONE_SCOPED;
sLastFrameTime = current_time;
sBoundTextureMemory = sCurBoundTextureMemory;
sCurBoundTextureMemory = S32Bytes(0);
@@ -295,10 +312,8 @@ void LLImageGL::destroyGL(BOOL save_state)
if (save_state && glimage->isGLTextureCreated() && glimage->mComponents)
{
glimage->mSaveData = new LLImageRaw;
- glimage->claimMem(glimage->mSaveData);
if(!glimage->readBackRaw(glimage->mCurrentDiscardLevel, glimage->mSaveData, false)) //necessary, keep it.
{
- glimage->disclaimMem(glimage->mSaveData);
glimage->mSaveData = NULL ;
}
}
@@ -372,8 +387,7 @@ BOOL LLImageGL::create(LLPointer<LLImageGL>& dest, const LLImageRaw* imageraw, B
//----------------------------------------------------------------------------
LLImageGL::LLImageGL(BOOL usemipmaps)
-: LLTrace::MemTrackable<LLImageGL>("LLImageGL"),
- mSaveData(0), mExternalTexture(FALSE)
+: mSaveData(0), mExternalTexture(FALSE)
{
init(usemipmaps);
setSize(0, 0, 0);
@@ -382,8 +396,7 @@ LLImageGL::LLImageGL(BOOL usemipmaps)
}
LLImageGL::LLImageGL(U32 width, U32 height, U8 components, BOOL usemipmaps)
-: LLTrace::MemTrackable<LLImageGL>("LLImageGL"),
- mSaveData(0), mExternalTexture(FALSE)
+: mSaveData(0), mExternalTexture(FALSE)
{
llassert( components <= 4 );
init(usemipmaps);
@@ -393,8 +406,7 @@ LLImageGL::LLImageGL(U32 width, U32 height, U8 components, BOOL usemipmaps)
}
LLImageGL::LLImageGL(const LLImageRaw* imageraw, BOOL usemipmaps)
-: LLTrace::MemTrackable<LLImageGL>("LLImageGL"),
- mSaveData(0), mExternalTexture(FALSE)
+: mSaveData(0), mExternalTexture(FALSE)
{
init(usemipmaps);
setSize(0, 0, 0);
@@ -412,7 +424,6 @@ LLImageGL::LLImageGL(
LLGLenum formatPrimary,
LLGLenum formatType,
LLTexUnit::eTextureAddressMode addressMode)
- : LLTrace::MemTrackable<LLImageGL>("LLImageGL"), mSaveData(0), mExternalTexture(TRUE)
{
init(false);
mTexName = texName;
@@ -656,6 +667,7 @@ void LLImageGL::setExplicitFormat( LLGLint internal_format, LLGLenum primary_for
void LLImageGL::setImage(const LLImageRaw* imageraw)
{
+ LL_PROFILE_ZONE_SCOPED;
llassert((imageraw->getWidth() == getWidth(mCurrentDiscardLevel)) &&
(imageraw->getHeight() == getHeight(mCurrentDiscardLevel)) &&
(imageraw->getComponents() == getComponents()));
@@ -663,10 +675,9 @@ void LLImageGL::setImage(const LLImageRaw* imageraw)
setImage(rawdata, FALSE);
}
-static LLTrace::BlockTimerStatHandle FTM_SET_IMAGE("setImage");
-BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
+BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips, S32 usename)
{
- LL_RECORD_BLOCK_TIME(FTM_SET_IMAGE);
+ LL_PROFILE_ZONE_SCOPED;
bool is_compressed = false;
switch (mFormatPrimary)
@@ -683,12 +694,11 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
break;
}
-
-
if (mUseMipMaps)
{
//set has mip maps to true before binding image so tex parameters get set properly
- gGL.getTexUnit(0)->unbind(mBindTarget);
+ gGL.getTexUnit(0)->unbind(mBindTarget);
+
mHasMipMaps = true;
mTexOptionsDirty = true;
setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
@@ -698,10 +708,10 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
mHasMipMaps = false;
}
- llverify(gGL.getTexUnit(0)->bind(this));
-
-
- if (mUseMipMaps)
+ gGL.getTexUnit(0)->bind(this, false, false, usename);
+
+
+ if (mUseMipMaps)
{
if (data_hasmips)
{
@@ -728,8 +738,6 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
}
else
{
-// LL_RECORD_BLOCK_TIME(FTM_TEMP4);
-
if(mFormatSwapBytes)
{
glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
@@ -760,8 +768,6 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
{
stop_glerror();
{
-// LL_RECORD_BLOCK_TIME(FTM_TEMP4);
-
if(mFormatSwapBytes)
{
glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
@@ -781,7 +787,7 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
glTexParameteri(mTarget, GL_GENERATE_MIPMAP, GL_TRUE);
}
- LLImageGL::setManualImage(mTarget, 0, mFormatInternal,
+ LLImageGL::setManualImage(mTarget, 0, mFormatInternal,
w, h,
mFormatPrimary, mFormatType,
data_in, mAllowCompression);
@@ -871,14 +877,13 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
llassert(w > 0 && h > 0 && cur_mip_data);
(void)cur_mip_data;
{
-// LL_RECORD_BLOCK_TIME(FTM_TEMP4);
if(mFormatSwapBytes)
{
glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
stop_glerror();
}
- LLImageGL::setManualImage(mTarget, m, mFormatInternal, w, h, mFormatPrimary, mFormatType, cur_mip_data, mAllowCompression);
+ LLImageGL::setManualImage(mTarget, m, mFormatInternal, w, h, mFormatPrimary, mFormatType, cur_mip_data, mAllowCompression);
if (m == 0)
{
analyzeAlpha(data_in, w, h);
@@ -1067,6 +1072,7 @@ void LLImageGL::postAddToAtlas()
BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update)
{
+ LL_PROFILE_ZONE_SCOPED;
if (!width || !height)
{
return TRUE;
@@ -1163,6 +1169,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
BOOL LLImageGL::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update)
{
+ LL_PROFILE_ZONE_SCOPED;
return setSubImage(imageraw->getData(), imageraw->getWidth(), imageraw->getHeight(), x_pos, y_pos, width, height, force_fast_update);
}
@@ -1183,15 +1190,14 @@ BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_
}
// static
-static LLTrace::BlockTimerStatHandle FTM_GENERATE_TEXTURES("generate textures");
void LLImageGL::generateTextures(S32 numTextures, U32 *textures)
{
- LL_RECORD_BLOCK_TIME(FTM_GENERATE_TEXTURES);
+ LL_PROFILE_ZONE_SCOPED;
glGenTextures(numTextures, textures);
}
// static
-void LLImageGL::deleteTextures(S32 numTextures, U32 *textures)
+void LLImageGL::deleteTextures(S32 numTextures, const U32 *textures)
{
if (gGLManager.mInited)
{
@@ -1200,125 +1206,126 @@ void LLImageGL::deleteTextures(S32 numTextures, U32 *textures)
}
// static
-static LLTrace::BlockTimerStatHandle FTM_SET_MANUAL_IMAGE("setManualImage");
-void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels, bool allow_compression)
+void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void* pixels, bool allow_compression)
{
- LL_RECORD_BLOCK_TIME(FTM_SET_MANUAL_IMAGE);
- bool use_scratch = false;
- U32* scratch = NULL;
- if (LLRender::sGLCoreProfile)
- {
- if (pixformat == GL_ALPHA && pixtype == GL_UNSIGNED_BYTE)
- { //GL_ALPHA is deprecated, convert to RGBA
- use_scratch = true;
- scratch = new U32[width*height];
+ LL_PROFILE_ZONE_SCOPED;
+ bool use_scratch = false;
+ U32* scratch = NULL;
+ if (LLRender::sGLCoreProfile)
+ {
+ if (pixformat == GL_ALPHA && pixtype == GL_UNSIGNED_BYTE)
+ { //GL_ALPHA is deprecated, convert to RGBA
+ use_scratch = true;
+ scratch = new U32[width * height];
- U32 pixel_count = (U32) (width*height);
- for (U32 i = 0; i < pixel_count; i++)
- {
- U8* pix = (U8*) &scratch[i];
- pix[0] = pix[1] = pix[2] = 0;
- pix[3] = ((U8*) pixels)[i];
- }
-
- pixformat = GL_RGBA;
- intformat = GL_RGBA8;
- }
+ U32 pixel_count = (U32)(width * height);
+ for (U32 i = 0; i < pixel_count; i++)
+ {
+ U8* pix = (U8*)&scratch[i];
+ pix[0] = pix[1] = pix[2] = 0;
+ pix[3] = ((U8*)pixels)[i];
+ }
- if (pixformat == GL_LUMINANCE_ALPHA && pixtype == GL_UNSIGNED_BYTE)
- { //GL_LUMINANCE_ALPHA is deprecated, convert to RGBA
- use_scratch = true;
- scratch = new U32[width*height];
+ pixformat = GL_RGBA;
+ intformat = GL_RGBA8;
+ }
- U32 pixel_count = (U32) (width*height);
- for (U32 i = 0; i < pixel_count; i++)
- {
- U8 lum = ((U8*) pixels)[i*2+0];
- U8 alpha = ((U8*) pixels)[i*2+1];
+ if (pixformat == GL_LUMINANCE_ALPHA && pixtype == GL_UNSIGNED_BYTE)
+ { //GL_LUMINANCE_ALPHA is deprecated, convert to RGBA
+ use_scratch = true;
+ scratch = new U32[width * height];
- U8* pix = (U8*) &scratch[i];
- pix[0] = pix[1] = pix[2] = lum;
- pix[3] = alpha;
- }
-
- pixformat = GL_RGBA;
- intformat = GL_RGBA8;
- }
+ U32 pixel_count = (U32)(width * height);
+ for (U32 i = 0; i < pixel_count; i++)
+ {
+ U8 lum = ((U8*)pixels)[i * 2 + 0];
+ U8 alpha = ((U8*)pixels)[i * 2 + 1];
- if (pixformat == GL_LUMINANCE && pixtype == GL_UNSIGNED_BYTE)
- { //GL_LUMINANCE_ALPHA is deprecated, convert to RGB
- use_scratch = true;
- scratch = new U32[width*height];
+ U8* pix = (U8*)&scratch[i];
+ pix[0] = pix[1] = pix[2] = lum;
+ pix[3] = alpha;
+ }
- U32 pixel_count = (U32) (width*height);
- for (U32 i = 0; i < pixel_count; i++)
- {
- U8 lum = ((U8*) pixels)[i];
-
- U8* pix = (U8*) &scratch[i];
- pix[0] = pix[1] = pix[2] = lum;
- pix[3] = 255;
- }
-
- pixformat = GL_RGBA;
- intformat = GL_RGB8;
- }
- }
+ pixformat = GL_RGBA;
+ intformat = GL_RGBA8;
+ }
- if (LLImageGL::sCompressTextures && allow_compression)
- {
- switch (intformat)
- {
- case GL_RGB:
- case GL_RGB8:
- intformat = GL_COMPRESSED_RGB;
- break;
- case GL_SRGB:
- case GL_SRGB8:
- intformat = GL_COMPRESSED_SRGB;
- break;
- case GL_RGBA:
- case GL_RGBA8:
- intformat = GL_COMPRESSED_RGBA;
- break;
- case GL_SRGB_ALPHA:
- case GL_SRGB8_ALPHA8:
- intformat = GL_COMPRESSED_SRGB_ALPHA;
- break;
- case GL_LUMINANCE:
- case GL_LUMINANCE8:
- intformat = GL_COMPRESSED_LUMINANCE;
- break;
- case GL_LUMINANCE_ALPHA:
- case GL_LUMINANCE8_ALPHA8:
- intformat = GL_COMPRESSED_LUMINANCE_ALPHA;
- break;
- case GL_ALPHA:
- case GL_ALPHA8:
- intformat = GL_COMPRESSED_ALPHA;
- break;
- default:
- LL_WARNS() << "Could not compress format: " << std::hex << intformat << LL_ENDL;
- break;
- }
- }
+ if (pixformat == GL_LUMINANCE && pixtype == GL_UNSIGNED_BYTE)
+ { //GL_LUMINANCE_ALPHA is deprecated, convert to RGB
+ use_scratch = true;
+ scratch = new U32[width * height];
- stop_glerror();
- glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, use_scratch ? scratch : pixels);
- stop_glerror();
+ U32 pixel_count = (U32)(width * height);
+ for (U32 i = 0; i < pixel_count; i++)
+ {
+ U8 lum = ((U8*)pixels)[i];
- if (use_scratch)
- {
- delete [] scratch;
- }
+ U8* pix = (U8*)&scratch[i];
+ pix[0] = pix[1] = pix[2] = lum;
+ pix[3] = 255;
+ }
+
+ pixformat = GL_RGBA;
+ intformat = GL_RGB8;
+ }
+ }
+
+ if (LLImageGL::sCompressTextures && allow_compression)
+ {
+ switch (intformat)
+ {
+ case GL_RGB:
+ case GL_RGB8:
+ intformat = GL_COMPRESSED_RGB;
+ break;
+ case GL_SRGB:
+ case GL_SRGB8:
+ intformat = GL_COMPRESSED_SRGB;
+ break;
+ case GL_RGBA:
+ case GL_RGBA8:
+ intformat = GL_COMPRESSED_RGBA;
+ break;
+ case GL_SRGB_ALPHA:
+ case GL_SRGB8_ALPHA8:
+ intformat = GL_COMPRESSED_SRGB_ALPHA;
+ break;
+ case GL_LUMINANCE:
+ case GL_LUMINANCE8:
+ intformat = GL_COMPRESSED_LUMINANCE;
+ break;
+ case GL_LUMINANCE_ALPHA:
+ case GL_LUMINANCE8_ALPHA8:
+ intformat = GL_COMPRESSED_LUMINANCE_ALPHA;
+ break;
+ case GL_ALPHA:
+ case GL_ALPHA8:
+ intformat = GL_COMPRESSED_ALPHA;
+ break;
+ default:
+ LL_WARNS() << "Could not compress format: " << std::hex << intformat << LL_ENDL;
+ break;
+ }
+ }
+
+ stop_glerror();
+ {
+ LL_PROFILE_ZONE_NAMED("glTexImage2D");
+ glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, use_scratch ? scratch : pixels);
+ }
+ stop_glerror();
+
+ if (use_scratch)
+ {
+ delete[] scratch;
+ }
}
//create an empty GL texture: just create a texture name
//the texture is assiciate with some image by calling glTexImage outside LLImageGL
-static LLTrace::BlockTimerStatHandle FTM_CREATE_GL_TEXTURE1("createGLTexture()");
BOOL LLImageGL::createGLTexture()
{
- LL_RECORD_BLOCK_TIME(FTM_CREATE_GL_TEXTURE1);
+ LL_PROFILE_ZONE_SCOPED;
if (gGLManager.mIsDisabled)
{
LL_WARNS() << "Trying to create a texture while GL is disabled!" << LL_ENDL;
@@ -1333,6 +1340,7 @@ BOOL LLImageGL::createGLTexture()
if(mTexName)
{
LLImageGL::deleteTextures(1, (reinterpret_cast<GLuint*>(&mTexName))) ;
+ mTexName = 0;
}
@@ -1347,23 +1355,22 @@ BOOL LLImageGL::createGLTexture()
return TRUE ;
}
-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)
{
- LL_RECORD_BLOCK_TIME(FTM_CREATE_GL_TEXTURE2);
+ LL_PROFILE_ZONE_SCOPED;
if (gGLManager.mIsDisabled)
{
LL_WARNS() << "Trying to create a texture while GL is disabled!" << LL_ENDL;
return FALSE;
}
- mGLTextureCreated = false ;
llassert(gGLManager.mInited);
stop_glerror();
if (!imageraw || imageraw->isBufferInvalid())
{
LL_WARNS() << "Trying to create a texture from invalid image data" << LL_ENDL;
+ mGLTextureCreated = false;
return FALSE;
}
@@ -1383,6 +1390,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
if (!setSize(w, h, imageraw->getComponents(), discard_level))
{
LL_WARNS() << "Trying to create a texture with incorrect dimensions!" << LL_ENDL;
+ mGLTextureCreated = false;
return FALSE;
}
@@ -1451,6 +1459,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
destroyGLTexture();
mCurrentDiscardLevel = discard_level;
mLastBindTime = sLastFrameTime;
+ mGLTextureCreated = false;
return TRUE ;
}
@@ -1459,107 +1468,123 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
return createGLTexture(discard_level, rawdata, FALSE, usename);
}
-static LLTrace::BlockTimerStatHandle FTM_CREATE_GL_TEXTURE3("createGLTexture3(data)");
BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips, S32 usename)
{
- LL_RECORD_BLOCK_TIME(FTM_CREATE_GL_TEXTURE3);
- llassert(data_in);
- stop_glerror();
+ LL_PROFILE_ZONE_SCOPED;
+ llassert(data_in);
+ stop_glerror();
- if (discard_level < 0)
- {
- llassert(mCurrentDiscardLevel >= 0);
- discard_level = mCurrentDiscardLevel;
- }
- discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel);
-
- if (mTexName != 0 && discard_level == mCurrentDiscardLevel)
- {
- // This will only be true if the size has not changed
- return setImage(data_in, data_hasmips);
- }
-
- U32 old_name = mTexName;
-// S32 old_discard = mCurrentDiscardLevel;
-
- if (usename != 0)
- {
- mTexName = usename;
- }
- else
- {
- LLImageGL::generateTextures(1, &mTexName);
- stop_glerror();
- {
- llverify(gGL.getTexUnit(0)->bind(this));
- stop_glerror();
- glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_BASE_LEVEL, 0);
- stop_glerror();
- glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAX_LEVEL, mMaxDiscardLevel-discard_level);
- stop_glerror();
- }
- }
- if (!mTexName)
- {
- if (old_name)
- {
- sGlobalTextureMemory -= mTextureMemory;
- LLImageGL::deleteTextures(1, &old_name);
- disclaimMem(mTextureMemory);
- stop_glerror();
- }
+ if (discard_level < 0)
+ {
+ llassert(mCurrentDiscardLevel >= 0);
+ discard_level = mCurrentDiscardLevel;
+ }
+ discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel);
- LL_WARNS() << "LLImageGL::createGLTexture failed to make texture" << LL_ENDL;
- return FALSE;
- }
+ if (mTexName != 0 && discard_level == mCurrentDiscardLevel)
+ {
+ // This will only be true if the size has not changed
+ return setImage(data_in, data_hasmips);
+ }
- if (mUseMipMaps)
- {
- mAutoGenMips = gGLManager.mHasMipMapGeneration;
+ GLuint old_texname = mTexName;
+
+ if (usename != 0)
+ {
+ mNewTexName = usename;
+ }
+ else
+ {
+ LLImageGL::generateTextures(1, &mNewTexName);
+ {
+ gGL.getTexUnit(0)->bind(this, false, false, mNewTexName);
+ glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_BASE_LEVEL, 0);
+ glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAX_LEVEL, mMaxDiscardLevel - discard_level);
+ }
+ }
+
+ if (mUseMipMaps)
+ {
+ mAutoGenMips = gGLManager.mHasMipMapGeneration;
#if LL_DARWIN
- // On the Mac GF2 and GF4MX drivers, auto mipmap generation doesn't work right with alpha-only textures.
- if(gGLManager.mIsGF2or4MX && (mFormatInternal == GL_ALPHA8) && (mFormatPrimary == GL_ALPHA))
- {
- mAutoGenMips = FALSE;
- }
+ // On the Mac GF2 and GF4MX drivers, auto mipmap generation doesn't work right with alpha-only textures.
+ if (gGLManager.mIsGF2or4MX && (mFormatInternal == GL_ALPHA8) && (mFormatPrimary == GL_ALPHA))
+ {
+ mAutoGenMips = FALSE;
+ }
#endif
- }
+ }
- mCurrentDiscardLevel = discard_level;
+ mCurrentDiscardLevel = discard_level;
- if (!setImage(data_in, data_hasmips))
- {
- stop_glerror();
- return FALSE;
- }
+ if (!setImage(data_in, data_hasmips, mNewTexName))
+ {
+ return FALSE;
+ }
- // Set texture options to our defaults.
- gGL.getTexUnit(0)->setHasMipMaps(mHasMipMaps);
- gGL.getTexUnit(0)->setTextureAddressMode(mAddressMode);
- gGL.getTexUnit(0)->setTextureFilteringOption(mFilterOption);
+ // Set texture options to our defaults.
+ gGL.getTexUnit(0)->setHasMipMaps(mHasMipMaps);
+ gGL.getTexUnit(0)->setTextureAddressMode(mAddressMode);
+ gGL.getTexUnit(0)->setTextureFilteringOption(mFilterOption);
- // things will break if we don't unbind after creation
- gGL.getTexUnit(0)->unbind(mBindTarget);
- stop_glerror();
+ // things will break if we don't unbind after creation
+ gGL.getTexUnit(0)->unbind(mBindTarget);
- if (old_name != 0)
- {
- sGlobalTextureMemory -= mTextureMemory;
+ if (old_texname != 0)
+ {
+ sGlobalTextureMemory -= mTextureMemory;
+ }
- LLImageGL::deleteTextures(1, &old_name);
+ //if we're on the image loading thread, be sure to delete old_texname and update mTexName on the main thread
+ if (LLImageGLThread::sInstance != nullptr &&
+ LLThread::currentID() == LLImageGLThread::sInstance->getID())
+ {
+ {
+ LL_PROFILE_ZONE_NAMED("cglt - sync");
+ if (gGLManager.mHasSync)
+ {
+ auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+ glClientWaitSync(sync, 0, 0);
+ glDeleteSync(sync);
+ }
+ else
+ {
+ glFinish();
+ }
+ }
- stop_glerror();
- }
+ ref();
+ LLImageGLThread::sInstance->postCallback([=]()
+ {
+ LL_PROFILE_ZONE_NAMED("cglt - delete callback");
+ if (old_texname != 0)
+ {
+ LLImageGL::deleteTextures(1, &old_texname);
+ }
+ mTexName = mNewTexName;
+ mNewTexName = 0;
+ unref();
+ });
+ }
+ else
+ {
+ //not on background thread, immediately set mTexName
+ if (old_texname != 0)
+ {
+ LLImageGL::deleteTextures(1, &old_texname);
+ }
+ mTexName = mNewTexName;
+ mNewTexName = 0;
+ }
+
+ mTextureMemory = (S32Bytes)getMipBytes(mCurrentDiscardLevel);
+ sGlobalTextureMemory += mTextureMemory;
+ mTexelsInGLTexture = getWidth() * getHeight();
- disclaimMem(mTextureMemory);
- mTextureMemory = (S32Bytes)getMipBytes(discard_level);
- claimMem(mTextureMemory);
- sGlobalTextureMemory += mTextureMemory;
- mTexelsInGLTexture = getWidth() * getHeight() ;
+ // mark this as bound at this point, so we don't throw it out immediately
+ mLastBindTime = sLastFrameTime;
- // mark this as bound at this point, so we don't throw it out immediately
- mLastBindTime = sLastFrameTime;
- return TRUE;
+ return TRUE;
}
BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const
@@ -1690,11 +1715,10 @@ void LLImageGL::destroyGLTexture()
if(mTextureMemory != S32Bytes(0))
{
sGlobalTextureMemory -= mTextureMemory;
- disclaimMem(mTextureMemory);
mTextureMemory = (S32Bytes)0;
}
- LLImageGL::deleteTextures(1, &mTexName);
+ LLImageGL::deleteTextures(1, &mTexName);
mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel.
mTexName = 0;
mGLTextureCreated = FALSE ;
@@ -2043,7 +2067,6 @@ U32 LLImageGL::createPickMask(S32 pWidth, S32 pHeight)
U32 size = pick_width * pick_height;
size = (size + 7) / 8; // pixelcount-to-bits
mPickMask = new U8[size];
- claimMem(size);
mPickMaskWidth = pick_width - 1;
mPickMaskHeight = pick_height - 1;
@@ -2058,7 +2081,6 @@ void LLImageGL::freePickMask()
// pickmask validity depends on old image size, delete it
if (mPickMask != NULL)
{
- disclaimMem((mPickMaskWidth * mPickMaskHeight + 7) / 8);
delete [] mPickMask;
}
mPickMask = NULL;
@@ -2235,3 +2257,75 @@ void LLImageGL::resetCurTexSizebar()
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, nummips);
*/
+
+LLImageGLThread::LLImageGLThread(LLWindow* window)
+ : LLThread("LLImageGL"), mWindow(window)
+{
+ mFinished = false;
+
+ mContext = mWindow->createSharedContext();
+}
+
+// post a function to be executed on the LLImageGL background thread
+
+bool LLImageGLThread::post(const std::function<void()>& func)
+{
+ try
+ {
+ mFunctionQueue.post(func);
+ }
+ catch (LLThreadSafeQueueInterrupt e)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+//post a callback to be executed on the main thread
+
+bool LLImageGLThread::postCallback(const std::function<void()>& callback)
+{
+ try
+ {
+ if (!mCallbackQueue.tryPost(callback))
+ {
+ mPendingCallbackQ.push(callback);
+ }
+ }
+ catch (LLThreadSafeQueueInterrupt e)
+ {
+ //thread is closing, drop request
+ return false;
+ }
+
+ return true;
+}
+
+void LLImageGLThread::executeCallbacks()
+{
+ LL_PROFILE_ZONE_SCOPED;
+ //executed from main thread
+ mCallbackQueue.runPending();
+
+ while (!mPendingCallbackQ.empty())
+ {
+ if (mCallbackQueue.tryPost(mPendingCallbackQ.front()))
+ {
+ mPendingCallbackQ.pop();
+ }
+ else
+ {
+ break;
+ }
+ }
+}
+
+void LLImageGLThread::run()
+{
+ mWindow->makeContextCurrent(mContext);
+ gGL.init();
+ mFunctionQueue.runUntilClose();
+ gGL.shutdown();
+ mWindow->destroySharedContext(mContext);
+}
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index 61ddc8d59b..8264e4a5f2 100644
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -35,20 +35,24 @@
#include "llrefcount.h"
#include "v2math.h"
#include "llunits.h"
-
+#include "llthreadsafequeue.h"
#include "llrender.h"
+#include "workqueue.h"
+
class LLTextureAtlas ;
+class LLWindow;
+
#define BYTES_TO_MEGA_BYTES(x) ((x) >> 20)
#define MEGA_BYTES_TO_BYTES(x) ((x) << 20)
//============================================================================
-class LLImageGL : public LLRefCount, public LLTrace::MemTrackable<LLImageGL>
+class LLImageGL : public LLRefCount
{
friend class LLTexUnit;
public:
// 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, const U32 *textures);
static void deleteDeadTextures();
// Size calculation
@@ -102,13 +106,13 @@ public:
void setAllowCompression(bool allow) { mAllowCompression = allow; }
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,
S32 category = sMaxCategories-1);
BOOL createGLTexture(S32 discard_level, const U8* data, BOOL data_hasmips = FALSE, S32 usename = 0);
void setImage(const LLImageRaw* imageraw);
- BOOL setImage(const U8* data_in, BOOL data_hasmips = FALSE);
+ BOOL setImage(const U8* data_in, BOOL data_hasmips = FALSE, S32 usename = 0);
BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE);
BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE);
BOOL setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height);
@@ -208,8 +212,9 @@ private:
bool mGLTextureCreated ;
LLGLuint mTexName;
+ LLGLuint mNewTexName = 0; // tex name set by background thread to be applied in main thread
U16 mWidth;
- U16 mHeight;
+ U16 mHeight;
S8 mCurrentDiscardLevel;
S8 mDiscardLevelInAtlas;
@@ -265,7 +270,8 @@ public:
#endif
public:
- static void initClass(S32 num_catagories, BOOL skip_analyze_alpha = false);
+ static void initClass(LLWindow* window, S32 num_catagories, BOOL skip_analyze_alpha = false);
+ static void updateClass();
static void cleanupClass() ;
private:
@@ -301,4 +307,35 @@ public:
};
+class LLImageGLThread : public LLThread
+{
+public:
+ LLImageGLThread(LLWindow* window);
+
+ // post a function to be executed on the LLImageGL background thread
+ bool post(const std::function<void()>& func);
+
+ //post a callback to be executed on the main thread
+ bool postCallback(const std::function<void()>& callback);
+
+ void executeCallbacks();
+
+ void run() override;
+
+ // Work Queue for background thread
+ LL::WorkQueue mFunctionQueue;
+
+ // Work Queue for main thread (run from updateClass)
+ LL::WorkQueue mCallbackQueue;
+
+ LLWindow* mWindow;
+ void* mContext;
+ LLAtomicBool mFinished;
+
+ std::queue<std::function<void()>> mPendingCallbackQ;
+
+ static LLImageGLThread* sInstance;
+};
+
+
#endif // LL_LLIMAGEGL_H
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index 03b6aac20c..aad04beea2 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -36,7 +36,7 @@
#include "lltexture.h"
#include "llshadermgr.h"
-LLRender gGL;
+thread_local LLRender gGL;
// Handy copies of last good GL matrices
F32 gGLModelView[16];
@@ -229,8 +229,24 @@ void LLTexUnit::disable(void)
}
}
+void LLTexUnit::bindFast(LLTexture* texture)
+{
+ LLImageGL* gl_tex = texture->getGLTexture();
+
+ glActiveTextureARB(GL_TEXTURE0_ARB + mIndex);
+ gGL.mCurrTextureUnitIndex = mIndex;
+ mCurrTexture = gl_tex->getTexName();
+ if (!mCurrTexture)
+ {
+ mCurrTexture = LLImageGL::sDefaultGLTexture->getTexName();
+ }
+ glBindTexture(sGLTextureType[gl_tex->getTarget()], mCurrTexture);
+ mHasMipMaps = gl_tex->mHasMipMaps;
+}
+
bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind)
{
+ LL_PROFILE_ZONE_SCOPED;
stop_glerror();
if (mIndex >= 0)
{
@@ -294,18 +310,20 @@ bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind)
return true;
}
-bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind)
+bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind, S32 usename)
{
stop_glerror();
if (mIndex < 0) return false;
+ U32 texname = usename ? usename : texture->getTexName();
+
if(!texture)
{
LL_DEBUGS() << "NULL LLTexUnit::bind texture" << LL_ENDL;
return false;
}
- if(!texture->getTexName())
+ if(!texname)
{
if(LLImageGL::sDefaultGLTexture && LLImageGL::sDefaultGLTexture->getTexName())
{
@@ -315,7 +333,7 @@ bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind)
return false ;
}
- if ((mCurrTexture != texture->getTexName()) || forceBind)
+ if ((mCurrTexture != texname) || forceBind)
{
gGL.flush();
stop_glerror();
@@ -323,7 +341,7 @@ bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind)
stop_glerror();
enable(texture->getTarget());
stop_glerror();
- mCurrTexture = texture->getTexName();
+ mCurrTexture = texname;
glBindTexture(sGLTextureType[texture->getTarget()], mCurrTexture);
stop_glerror();
texture->updateBindStats(texture->mTextureMemory);
@@ -459,6 +477,28 @@ void LLTexUnit::unbind(eTextureType type)
}
}
+void LLTexUnit::unbindFast(eTextureType type)
+{
+ activate();
+
+ // Disabled caching of binding state.
+ if (mCurrTexType == type)
+ {
+ mCurrTexture = 0;
+
+ // Always make sure our texture color space is reset to linear. SRGB sampling should be opt-in in the vast majority of cases. Also prevents color space "popping".
+ mTexColorSpace = TCS_LINEAR;
+ if (type == LLTexUnit::TT_TEXTURE)
+ {
+ glBindTexture(sGLTextureType[type], sWhiteTexture);
+ }
+ else
+ {
+ glBindTexture(sGLTextureType[type], 0);
+ }
+ }
+}
+
void LLTexUnit::setTextureAddressMode(eTextureAddressMode mode)
{
if (mIndex < 0 || mCurrTexture == 0) return;
@@ -1243,8 +1283,6 @@ void LLRender::syncLightState()
void LLRender::syncMatrices()
{
- stop_glerror();
-
static const U32 name[] =
{
LLShaderMgr::MODELVIEW_MATRIX,
@@ -1415,8 +1453,6 @@ void LLRender::syncMatrices()
}
}
}
-
- stop_glerror();
}
void LLRender::translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z)
@@ -1848,6 +1884,7 @@ LLLightState* LLRender::getLight(U32 index)
void LLRender::setAmbientLightColor(const LLColor4& color)
{
+ LL_PROFILE_ZONE_SCOPED
if (color != mAmbientLightColor)
{
++mLightHash;
@@ -1926,6 +1963,7 @@ void LLRender::flush()
{
if (mCount > 0)
{
+ LL_PROFILE_ZONE_SCOPED;
if (!mUIOffset.empty())
{
sUICalls++;
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index af8568f8a3..7f19a45410 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -158,9 +158,20 @@ public:
// Binds the LLImageGL to this texture unit
// (automatically enables the unit for the LLImageGL's texture type)
- bool bind(LLImageGL* texture, bool for_rendering = false, bool forceBind = false);
+ bool bind(LLImageGL* texture, bool for_rendering = false, bool forceBind = false, S32 usename = 0);
bool bind(LLTexture* texture, bool for_rendering = false, bool forceBind = false);
+ // bind implementation for inner loops
+ // makes the following assumptions:
+ // - No need for gGL.flush()
+ // - texture is not null
+ // - gl_tex->getTexName() is not zero
+ // - This texture is not being bound redundantly
+ // - USE_SRGB_DECODE is disabled
+ // - mTexOptionsDirty is false
+ // -
+ void bindFast(LLTexture* texture);
+
// Binds a cubemap to this texture unit
// (automatically enables the texture unit for cubemaps)
bool bind(LLCubeMap* cubeMap);
@@ -177,6 +188,9 @@ public:
// (only if there's a texture of the given type currently bound)
void unbind(eTextureType type);
+ // Fast but unsafe version of unbind
+ void unbindFast(eTextureType type);
+
// Sets the addressing mode used to sample the texture
// Warning: this stays set for the bound texture forever,
// make sure you want to permanently change the address mode for the bound texture.
@@ -511,7 +525,7 @@ extern F32 gGLLastProjection[16];
extern F32 gGLProjection[16];
extern S32 gGLViewport[4];
-extern LLRender gGL;
+extern thread_local LLRender gGL;
// This rotation matrix moves the default OpenGL reference frame
// (-Z at, Y up) to Cory's favorite reference frame (X at, Z up)
diff --git a/indra/llrender/llrender2dutils.cpp b/indra/llrender/llrender2dutils.cpp
index dd34f3e383..5a942996be 100644
--- a/indra/llrender/llrender2dutils.cpp
+++ b/indra/llrender/llrender2dutils.cpp
@@ -1083,8 +1083,6 @@ void gl_rect_2d_simple( S32 width, S32 height )
gGL.end();
}
-static LLTrace::BlockTimerStatHandle FTM_RENDER_SEGMENTED_RECT ("Render segmented rectangle");
-
void gl_segmented_rect_2d_tex(const S32 left,
const S32 top,
const S32 right,
@@ -1094,7 +1092,7 @@ void gl_segmented_rect_2d_tex(const S32 left,
const S32 border_size,
const U32 edges)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_SEGMENTED_RECT);
+ LL_PROFILE_ZONE_SCOPED;
S32 width = llabs(right - left);
S32 height = llabs(top - bottom);
@@ -1253,7 +1251,7 @@ void gl_segmented_rect_2d_fragment_tex(const LLRect& rect,
const F32 end_fragment,
const U32 edges)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_SEGMENTED_RECT);
+ LL_PROFILE_ZONE_SCOPED;
const S32 left = rect.mLeft;
const S32 right = rect.mRight;
const S32 top = rect.mTop;
@@ -1440,7 +1438,7 @@ void gl_segmented_rect_2d_fragment_tex(const LLRect& rect,
void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv_rect, const LLRectf& center_draw_rect,
const LLVector3& width_vec, const LLVector3& height_vec)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_SEGMENTED_RECT);
+ LL_PROFILE_ZONE_SCOPED;
gGL.begin(LLRender::QUADS);
{
diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
index e3c0255290..401085a00b 100644
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -437,11 +437,13 @@ void LLRenderTarget::bindTarget()
GL_COLOR_ATTACHMENT1,
GL_COLOR_ATTACHMENT2,
GL_COLOR_ATTACHMENT3};
+ LL_PROFILER_GPU_ZONEC( "gl.DrawBuffersARB", 0x4000FF )
glDrawBuffersARB(mTex.size(), drawbuffers);
}
if (mTex.empty())
{ //no color buffer to draw to
+ LL_PROFILER_GPU_ZONEC( "gl.DrawBuffer", 0x0000FF )
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
}
diff --git a/indra/llrender/lltexture.h b/indra/llrender/lltexture.h
index 41481fb8a7..e890a5a30b 100644
--- a/indra/llrender/lltexture.h
+++ b/indra/llrender/lltexture.h
@@ -42,7 +42,7 @@ class LLFontGL ;
//
//this is an abstract class as the parent for the class LLGLTexture
//
-class LLTexture : public virtual LLRefCount, public LLTrace::MemTrackable<LLTexture>
+class LLTexture : public virtual LLRefCount
{
friend class LLTexUnit ;
friend class LLFontGL ;
@@ -52,7 +52,6 @@ protected:
public:
LLTexture()
- : LLTrace::MemTrackable<LLTexture>("LLTexture")
{}
//
@@ -67,11 +66,9 @@ public:
virtual S32 getWidth(S32 discard_level = -1) const;
virtual S32 getHeight(S32 discard_level = -1) const;
virtual bool isActiveFetching();
+ virtual LLImageGL* getGLTexture() const;
private:
- //note: do not make this function public.
- virtual LLImageGL* getGLTexture() const;
-
virtual void updateBindStatsForTester();
};
#endif
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 7d2b09ca4a..5ea07ddcb1 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -91,6 +91,8 @@ LLVBOPool LLVertexBuffer::sDynamicIBOPool(GL_DYNAMIC_DRAW_ARB, GL_ELEMENT_ARRAY_
U32 LLVBOPool::sBytesPooled = 0;
U32 LLVBOPool::sIndexBytesPooled = 0;
+U32 LLVBOPool::sNameIdx = 0;
+U32 LLVBOPool::sNamePool[1024];
std::list<U32> LLVertexBuffer::sAvailableVAOName;
U32 LLVertexBuffer::sCurVAOName = 1;
@@ -121,15 +123,20 @@ bool LLVertexBuffer::sPreferStreamDraw = false;
U32 LLVBOPool::genBuffer()
{
- U32 ret = 0;
+ LL_PROFILE_ZONE_SCOPED
- glGenBuffersARB(1, &ret);
-
- return ret;
+ if (sNameIdx == 0)
+ {
+ glGenBuffersARB(1024, sNamePool);
+ sNameIdx = 1024;
+ }
+
+ return sNamePool[--sNameIdx];
}
void LLVBOPool::deleteBuffer(U32 name)
{
+ LL_PROFILE_ZONE_SCOPED
if (gGLManager.mInited)
{
LLVertexBuffer::unbind();
@@ -152,6 +159,7 @@ LLVBOPool::LLVBOPool(U32 vboUsage, U32 vboType)
volatile U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
{
+ LL_PROFILE_ZONE_SCOPED
llassert(vbo_block_size(size) == size);
volatile U8* ret = NULL;
@@ -267,10 +275,12 @@ void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size)
void LLVBOPool::seedPool()
{
+ LL_PROFILE_ZONE_SCOPED
U32 dummy_name = 0;
if (mFreeList.size() < LL_VBO_POOL_SEED_COUNT)
{
+ LL_PROFILE_ZONE_NAMED("VBOPool Resize");
mFreeList.resize(LL_VBO_POOL_SEED_COUNT);
}
@@ -411,6 +421,7 @@ void LLVertexBuffer::releaseVAOName(U32 name)
//static
void LLVertexBuffer::seedPools()
{
+ LL_PROFILE_ZONE_SCOPED
sStreamVBOPool.seedPool();
sDynamicVBOPool.seedPool();
sDynamicCopyVBOPool.seedPool();
@@ -566,62 +577,22 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
}
//static
-static LLTrace::BlockTimerStatHandle FTM_VB_DRAW_ARRAYS("drawArrays");
-void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, const std::vector<LLVector3>& norm)
+void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos)
{
- LL_RECORD_BLOCK_TIME(FTM_VB_DRAW_ARRAYS);
- llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
- gGL.syncMatrices();
-
- U32 count = pos.size();
-
- llassert(norm.size() >= pos.size());
- llassert(count > 0);
-
- if( count == 0 )
- {
- LL_WARNS() << "Called drawArrays with 0 vertices" << LL_ENDL;
- return;
- }
-
- if( norm.size() < pos.size() )
- {
- LL_WARNS() << "Called drawArrays with #" << norm.size() << " normals and #" << pos.size() << " vertices" << LL_ENDL;
- return;
- }
-
- unbind();
-
- setupClientArrays(MAP_VERTEX | MAP_NORMAL);
-
- LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
-
- if (shader)
- {
- S32 loc = LLVertexBuffer::TYPE_VERTEX;
- if (loc > -1)
- {
- glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, 0, pos[0].mV);
- }
- loc = LLVertexBuffer::TYPE_NORMAL;
- if (loc > -1)
- {
- glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, 0, norm[0].mV);
- }
- }
- else
- {
- glVertexPointer(3, GL_FLOAT, 0, pos[0].mV);
- glNormalPointer(GL_FLOAT, 0, norm[0].mV);
- }
- LLGLSLShader::startProfile();
- glDrawArrays(sGLMode[mode], 0, count);
- LLGLSLShader::stopProfile(count, mode);
+ LL_PROFILE_ZONE_SCOPED;
+ gGL.begin(mode);
+ for (auto& v : pos)
+ {
+ gGL.vertex3fv(v.mV);
+ }
+ gGL.end();
+ gGL.flush();
}
//static
void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVector2* tc, S32 num_indices, const U16* indicesp)
{
+ LL_PROFILE_ZONE_SCOPED;
llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
gGL.syncMatrices();
@@ -634,28 +605,27 @@ void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVecto
unbind();
- setupClientArrays(mask);
-
- if (LLGLSLShader::sNoFixedFunction)
- {
- S32 loc = LLVertexBuffer::TYPE_VERTEX;
- glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, 16, pos);
-
- if (tc)
- {
- loc = LLVertexBuffer::TYPE_TEXCOORD0;
- glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, 0, tc);
- }
- }
- else
- {
- glTexCoordPointer(2, GL_FLOAT, 0, tc);
- glVertexPointer(3, GL_FLOAT, 16, pos);
- }
-
- LLGLSLShader::startProfile();
- glDrawElements(sGLMode[mode], num_indices, GL_UNSIGNED_SHORT, indicesp);
- LLGLSLShader::stopProfile(num_indices, mode);
+ gGL.begin(mode);
+
+ if (tc != nullptr)
+ {
+ for (int i = 0; i < num_indices; ++i)
+ {
+ U16 idx = indicesp[i];
+ gGL.texCoord2fv(tc[idx].mV);
+ gGL.vertex3fv(pos[idx].getF32ptr());
+ }
+ }
+ else
+ {
+ for (int i = 0; i < num_indices; ++i)
+ {
+ U16 idx = indicesp[i];
+ gGL.vertex3fv(pos[idx].getF32ptr());
+ }
+ }
+ gGL.end();
+ gGL.flush();
}
void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_offset) const
@@ -763,6 +733,7 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
stop_glerror();
LLGLSLShader::startProfile();
+ LL_PROFILER_GPU_ZONEC( "gl.DrawRangeElements", 0xFFFF00 )
glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT,
idx);
LLGLSLShader::stopProfile(count, mode);
@@ -773,6 +744,18 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
placeFence();
}
+void LLVertexBuffer::drawRangeFast(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const
+{
+ mMappable = false;
+ gGL.syncMatrices();
+
+ U16* idx = ((U16*)(U8*)mAlignedIndexOffset) + indices_offset;
+
+ LL_PROFILER_GPU_ZONEC("gl.DrawRangeElements", 0xFFFF00)
+ glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT,
+ idx);
+}
+
void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
{
llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
@@ -814,6 +797,7 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
stop_glerror();
LLGLSLShader::startProfile();
+ LL_PROFILER_GPU_ZONEC( "gl.DrawElements", 0xA0FFA0 )
glDrawElements(sGLMode[mode], count, GL_UNSIGNED_SHORT,
((U16*) getIndicesPointer()) + indices_offset);
LLGLSLShader::stopProfile(count, mode);
@@ -821,53 +805,51 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
placeFence();
}
-static LLTrace::BlockTimerStatHandle FTM_GL_DRAW_ARRAYS("GL draw arrays");
+
void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
{
- llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
- mMappable = false;
- gGL.syncMatrices();
-
- llassert(mNumVerts >= 0);
- if (first >= (U32) mNumVerts ||
- first + count > (U32) mNumVerts)
- {
- LL_ERRS() << "Bad vertex buffer draw range: [" << first << ", " << first+count << "]" << LL_ENDL;
- }
-
- if (mGLArray)
- {
- if (mGLArray != sGLRenderArray)
- {
- LL_ERRS() << "Wrong vertex array bound." << LL_ENDL;
- }
- }
- else
- {
- if (mGLBuffer != sGLRenderBuffer || useVBOs() != sVBOActive)
- {
- LL_ERRS() << "Wrong vertex buffer bound." << LL_ENDL;
- }
- }
-
- if (mode >= LLRender::NUM_MODES)
- {
- LL_ERRS() << "Invalid draw mode: " << mode << LL_ENDL;
- return;
- }
+ LL_PROFILE_ZONE_SCOPED;
+ llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
+ mMappable = false;
+ gGL.syncMatrices();
+
+#ifndef LL_RELEASE_FOR_DOWNLOAD
+ llassert(mNumVerts >= 0);
+ if (first >= (U32)mNumVerts ||
+ first + count > (U32)mNumVerts)
+ {
+ LL_ERRS() << "Bad vertex buffer draw range: [" << first << ", " << first + count << "]" << LL_ENDL;
+ }
+
+ if (mGLArray)
+ {
+ if (mGLArray != sGLRenderArray)
+ {
+ LL_ERRS() << "Wrong vertex array bound." << LL_ENDL;
+ }
+ }
+ else
+ {
+ if (mGLBuffer != sGLRenderBuffer || useVBOs() != sVBOActive)
+ {
+ LL_ERRS() << "Wrong vertex buffer bound." << LL_ENDL;
+ }
+ }
+
+ if (mode >= LLRender::NUM_MODES)
+ {
+ LL_ERRS() << "Invalid draw mode: " << mode << LL_ENDL;
+ return;
+ }
+#endif
- {
- LL_RECORD_BLOCK_TIME(FTM_GL_DRAW_ARRAYS);
- stop_glerror();
- LLGLSLShader::startProfile();
- stop_glerror();
- glDrawArrays(sGLMode[mode], first, count);
- stop_glerror();
- LLGLSLShader::stopProfile(count, mode);
- }
+ {
+ LL_PROFILER_GPU_ZONEC("gl.DrawArrays", 0xFF4040)
+ glDrawArrays(sGLMode[mode], first, count);
+ }
- stop_glerror();
- placeFence();
+ stop_glerror();
+ placeFence();
}
//static
@@ -964,8 +946,7 @@ S32 LLVertexBuffer::determineUsage(S32 usage)
}
LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage)
-: LLTrace::MemTrackable<LLVertexBuffer>("LLVertexBuffer"),
- LLRefCount(),
+: LLRefCount(),
mNumVerts(0),
mNumIndices(0),
@@ -1110,9 +1091,7 @@ void LLVertexBuffer::waitFence() const
void LLVertexBuffer::genBuffer(U32 size)
{
- disclaimMem(mSize);
mSize = vbo_block_size(size);
- claimMem(mSize);
if (mUsage == GL_STREAM_DRAW_ARB)
{
@@ -1208,9 +1187,7 @@ bool LLVertexBuffer::createGLBuffer(U32 size)
static int gl_buffer_idx = 0;
mGLBuffer = ++gl_buffer_idx;
mMappedData = (U8*)ll_aligned_malloc_16(size);
- disclaimMem(mSize);
mSize = size;
- claimMem(mSize);
}
if (!mMappedData)
@@ -1380,8 +1357,6 @@ bool LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
return success;
}
-static LLTrace::BlockTimerStatHandle FTM_SETUP_VERTEX_ARRAY("Setup VAO");
-
void LLVertexBuffer::setupVertexArray()
{
if (!mGLArray)
@@ -1389,7 +1364,7 @@ void LLVertexBuffer::setupVertexArray()
return;
}
- LL_RECORD_BLOCK_TIME(FTM_SETUP_VERTEX_ARRAY);
+ LL_PROFILE_ZONE_SCOPED;
#if GL_ARB_vertex_array_object
glBindVertexArray(mGLArray);
#endif
@@ -1562,12 +1537,11 @@ bool expand_region(LLVertexBuffer::MappedRegion& region, S32 index, S32 count)
return true;
}
-static LLTrace::BlockTimerStatHandle FTM_VBO_MAP_BUFFER_RANGE("VBO Map Range");
-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)
{
+ LL_PROFILE_ZONE_SCOPED;
bindGLBuffer(true);
if (mFinal)
{
@@ -1634,7 +1608,6 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo
if (map_range)
{
#ifdef GL_ARB_map_buffer_range
- LL_RECORD_BLOCK_TIME(FTM_VBO_MAP_BUFFER_RANGE);
S32 offset = mOffsets[type] + sTypeSize[type]*index;
S32 length = (sTypeSize[type]*count+0xF) & ~0xF;
src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER_ARB, offset, length,
@@ -1658,7 +1631,6 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo
}
}
- LL_RECORD_BLOCK_TIME(FTM_VBO_MAP_BUFFER);
src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER_ARB, 0, mSize,
GL_MAP_WRITE_BIT |
GL_MAP_FLUSH_EXPLICIT_BIT);
@@ -1744,11 +1716,9 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo
}
-static LLTrace::BlockTimerStatHandle FTM_VBO_MAP_INDEX_RANGE("IBO Map Range");
-static LLTrace::BlockTimerStatHandle FTM_VBO_MAP_INDEX("IBO Map");
-
volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
{
+ LL_PROFILE_ZONE_SCOPED;
bindGLIndices(true);
if (mFinal)
{
@@ -1823,7 +1793,6 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range
if (map_range)
{
#ifdef GL_ARB_map_buffer_range
- LL_RECORD_BLOCK_TIME(FTM_VBO_MAP_INDEX_RANGE);
S32 offset = sizeof(U16)*index;
S32 length = sizeof(U16)*count;
src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length,
@@ -1835,7 +1804,6 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range
else
{
#ifdef GL_ARB_map_buffer_range
- LL_RECORD_BLOCK_TIME(FTM_VBO_MAP_INDEX);
src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, sizeof(U16)*mNumIndices,
GL_MAP_WRITE_BIT |
GL_MAP_FLUSH_EXPLICIT_BIT);
@@ -1859,7 +1827,6 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range
}
else
{
- LL_RECORD_BLOCK_TIME(FTM_VBO_MAP_INDEX);
map_range = false;
src = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
}
@@ -1910,13 +1877,6 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range
}
}
-static LLTrace::BlockTimerStatHandle FTM_VBO_UNMAP("VBO Unmap");
-static LLTrace::BlockTimerStatHandle FTM_VBO_FLUSH_RANGE("Flush VBO Range");
-
-
-static LLTrace::BlockTimerStatHandle FTM_IBO_UNMAP("IBO Unmap");
-static LLTrace::BlockTimerStatHandle FTM_IBO_FLUSH_RANGE("Flush IBO Range");
-
void LLVertexBuffer::unmapBuffer()
{
if (!useVBOs())
@@ -1925,10 +1885,10 @@ void LLVertexBuffer::unmapBuffer()
}
bool updated_all = false;
-
+ LL_PROFILE_ZONE_SCOPED;
if (mMappedData && mVertexLocked)
{
- LL_RECORD_BLOCK_TIME(FTM_VBO_UNMAP);
+ LL_PROFILE_ZONE_NAMED("unmapBuffer - vertex");
bindGLBuffer(true);
updated_all = mIndexLocked; //both vertex and index buffers done updating
@@ -1975,7 +1935,7 @@ void LLVertexBuffer::unmapBuffer()
{
if (!mMappedVertexRegions.empty())
{
- stop_glerror();
+ LL_PROFILE_ZONE_NAMED("unmapBuffer - flush vertex");
for (U32 i = 0; i < mMappedVertexRegions.size(); ++i)
{
const MappedRegion& region = mMappedVertexRegions[i];
@@ -1983,18 +1943,16 @@ void LLVertexBuffer::unmapBuffer()
S32 length = sTypeSize[region.mType]*region.mCount;
if (gGLManager.mHasMapBufferRange)
{
- LL_RECORD_BLOCK_TIME(FTM_VBO_FLUSH_RANGE);
#ifdef GL_ARB_map_buffer_range
glFlushMappedBufferRange(GL_ARRAY_BUFFER_ARB, offset, length);
#endif
}
else if (gGLManager.mHasFlushBufferRange)
- {
+ {
#ifndef LL_MESA_HEADLESS
glFlushMappedBufferRangeAPPLE(GL_ARRAY_BUFFER_ARB, offset, length);
#endif
}
- stop_glerror();
}
mMappedVertexRegions.clear();
@@ -2013,7 +1971,7 @@ void LLVertexBuffer::unmapBuffer()
if (mMappedIndexData && mIndexLocked)
{
- LL_RECORD_BLOCK_TIME(FTM_IBO_UNMAP);
+ LL_PROFILE_ZONE_NAMED("unmapBuffer - index");
bindGLIndices();
if(!mMappable)
{
@@ -2059,12 +2017,12 @@ void LLVertexBuffer::unmapBuffer()
{
for (U32 i = 0; i < mMappedIndexRegions.size(); ++i)
{
+ LL_PROFILE_ZONE_NAMED("unmapBuffer - flush index");
const MappedRegion& region = mMappedIndexRegions[i];
S32 offset = region.mIndex >= 0 ? sizeof(U16)*region.mIndex : 0;
S32 length = sizeof(U16)*region.mCount;
if (gGLManager.mHasMapBufferRange)
{
- LL_RECORD_BLOCK_TIME(FTM_IBO_FLUSH_RANGE);
#ifdef GL_ARB_map_buffer_range
glFlushMappedBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length);
#endif
@@ -2083,9 +2041,8 @@ void LLVertexBuffer::unmapBuffer()
mMappedIndexRegions.clear();
}
}
- stop_glerror();
- glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
- stop_glerror();
+
+ glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
mMappedIndexData = NULL;
}
@@ -2208,13 +2165,12 @@ bool LLVertexBuffer::getClothWeightStrider(LLStrider<LLVector4>& strider, S32 in
//----------------------------------------------------------------------------
-static LLTrace::BlockTimerStatHandle FTM_BIND_GL_ARRAY("Bind Array");
bool LLVertexBuffer::bindGLArray()
{
if (mGLArray && sGLRenderArray != mGLArray)
{
{
- LL_RECORD_BLOCK_TIME(FTM_BIND_GL_ARRAY);
+ LL_PROFILE_ZONE_SCOPED;
#if GL_ARB_vertex_array_object
glBindVertexArray(mGLArray);
#endif
@@ -2231,8 +2187,6 @@ bool LLVertexBuffer::bindGLArray()
return false;
}
-static LLTrace::BlockTimerStatHandle FTM_BIND_GL_BUFFER("Bind Buffer");
-
bool LLVertexBuffer::bindGLBuffer(bool force_bind)
{
bindGLArray();
@@ -2241,8 +2195,7 @@ bool LLVertexBuffer::bindGLBuffer(bool force_bind)
if (useVBOs() && (force_bind || (mGLBuffer && (mGLBuffer != sGLRenderBuffer || !sVBOActive))))
{
- //LL_RECORD_BLOCK_TIME(FTM_BIND_GL_BUFFER);
-
+ LL_PROFILE_ZONE_SCOPED;
glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer);
sGLRenderBuffer = mGLBuffer;
sBindCount++;
@@ -2256,16 +2209,29 @@ bool LLVertexBuffer::bindGLBuffer(bool force_bind)
return ret;
}
-static LLTrace::BlockTimerStatHandle FTM_BIND_GL_INDICES("Bind Indices");
+bool LLVertexBuffer::bindGLBufferFast()
+{
+ if (mGLBuffer != sGLRenderBuffer || !sVBOActive)
+ {
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer);
+ sGLRenderBuffer = mGLBuffer;
+ sBindCount++;
+ sVBOActive = true;
+
+ return true;
+ }
+
+ return false;
+}
bool LLVertexBuffer::bindGLIndices(bool force_bind)
{
+ LL_PROFILE_ZONE_SCOPED;
bindGLArray();
bool ret = false;
if (useVBOs() && (force_bind || (mGLIndices && (mGLIndices != sGLRenderIndices || !sIBOActive))))
{
- LL_RECORD_BLOCK_TIME(FTM_BIND_GL_INDICES);
/*if (sMapped)
{
LL_ERRS() << "VBO bound while another VBO mapped!" << LL_ENDL;
@@ -2281,6 +2247,21 @@ bool LLVertexBuffer::bindGLIndices(bool force_bind)
return ret;
}
+bool LLVertexBuffer::bindGLIndicesFast()
+{
+ if (mGLIndices != sGLRenderIndices || !sIBOActive)
+ {
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mGLIndices);
+ sGLRenderIndices = mGLIndices;
+ sBindCount++;
+ sIBOActive = true;
+
+ return true;
+ }
+
+ return false;
+}
+
void LLVertexBuffer::flush()
{
if (useVBOs())
@@ -2471,6 +2452,26 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
}
}
+void LLVertexBuffer::setBufferFast(U32 data_mask)
+{
+ //set up pointers if the data mask is different ...
+ bool setup = (sLastMask != data_mask);
+
+
+ const bool bindBuffer = bindGLBufferFast();
+ const bool bindIndices = bindGLIndicesFast();
+
+ setup = setup || bindBuffer || bindIndices;
+
+ setupClientArrays(data_mask);
+
+ if (data_mask && setup)
+ {
+ setupVertexBufferFast(data_mask);
+ sSetCount++;
+ }
+}
+
// virtual (default)
void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
{
@@ -2628,6 +2629,99 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
llglassertok();
}
+void LLVertexBuffer::setupVertexBufferFast(U32 data_mask)
+{
+ U8* base = (U8*)mAlignedOffset;
+
+ if (data_mask & MAP_NORMAL)
+ {
+ S32 loc = TYPE_NORMAL;
+ void* ptr = (void*)(base + mOffsets[TYPE_NORMAL]);
+ glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_NORMAL], ptr);
+ }
+ if (data_mask & MAP_TEXCOORD3)
+ {
+ S32 loc = TYPE_TEXCOORD3;
+ void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD3]);
+ glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], ptr);
+ }
+ if (data_mask & MAP_TEXCOORD2)
+ {
+ S32 loc = TYPE_TEXCOORD2;
+ void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD2]);
+ glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], ptr);
+ }
+ if (data_mask & MAP_TEXCOORD1)
+ {
+ S32 loc = TYPE_TEXCOORD1;
+ void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD1]);
+ glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], ptr);
+ }
+ if (data_mask & MAP_TANGENT)
+ {
+ S32 loc = TYPE_TANGENT;
+ void* ptr = (void*)(base + mOffsets[TYPE_TANGENT]);
+ glVertexAttribPointerARB(loc, 4, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TANGENT], ptr);
+ }
+ if (data_mask & MAP_TEXCOORD0)
+ {
+ S32 loc = TYPE_TEXCOORD0;
+ void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD0]);
+ glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], ptr);
+ }
+ if (data_mask & MAP_COLOR)
+ {
+ S32 loc = TYPE_COLOR;
+ //bind emissive instead of color pointer if emissive is present
+ void* ptr = (data_mask & MAP_EMISSIVE) ? (void*)(base + mOffsets[TYPE_EMISSIVE]) : (void*)(base + mOffsets[TYPE_COLOR]);
+ glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], ptr);
+ }
+ if (data_mask & MAP_EMISSIVE)
+ {
+ S32 loc = TYPE_EMISSIVE;
+ void* ptr = (void*)(base + mOffsets[TYPE_EMISSIVE]);
+ glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr);
+
+ if (!(data_mask & MAP_COLOR))
+ { //map emissive to color channel when color is not also being bound to avoid unnecessary shader swaps
+ loc = TYPE_COLOR;
+ glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr);
+ }
+ }
+ if (data_mask & MAP_WEIGHT)
+ {
+ S32 loc = TYPE_WEIGHT;
+ void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT]);
+ glVertexAttribPointerARB(loc, 1, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], ptr);
+ }
+ if (data_mask & MAP_WEIGHT4)
+ {
+ S32 loc = TYPE_WEIGHT4;
+ void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT4]);
+ glVertexAttribPointerARB(loc, 4, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], ptr);
+ }
+ if (data_mask & MAP_CLOTHWEIGHT)
+ {
+ S32 loc = TYPE_CLOTHWEIGHT;
+ void* ptr = (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]);
+ glVertexAttribPointerARB(loc, 4, GL_FLOAT, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], ptr);
+ }
+ if (data_mask & MAP_TEXTURE_INDEX)
+ {
+#if !LL_DARWIN
+ S32 loc = TYPE_TEXTURE_INDEX;
+ void* ptr = (void*)(base + mOffsets[TYPE_VERTEX] + 12);
+ glVertexAttribIPointer(loc, 1, GL_UNSIGNED_INT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
+#endif
+ }
+ if (data_mask & MAP_VERTEX)
+ {
+ S32 loc = TYPE_VERTEX;
+ void* ptr = (void*)(base + mOffsets[TYPE_VERTEX]);
+ glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
+ }
+}
+
LLVertexBuffer::MappedRegion::MappedRegion(S32 type, S32 index, S32 count)
: mType(type), mIndex(index), mCount(count)
{
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index dbe1a3687f..1b400b3aad 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -89,13 +89,16 @@ public:
std::vector<record_list_t> mFreeList;
std::vector<U32> mMissCount;
+ //used to avoid calling glGenBuffers for every VBO creation
+ static U32 sNamePool[1024];
+ static U32 sNameIdx;
};
//============================================================================
// base class
class LLPrivateMemoryPool;
-class LLVertexBuffer : public LLRefCount, public LLTrace::MemTrackable<LLVertexBuffer>
+class LLVertexBuffer : public LLRefCount
{
public:
class MappedRegion
@@ -110,8 +113,7 @@ public:
};
LLVertexBuffer(const LLVertexBuffer& rhs)
- : LLTrace::MemTrackable<LLVertexBuffer>("LLVertexBuffer"),
- mUsage(rhs.mUsage)
+ : mUsage(rhs.mUsage)
{
*this = rhs;
}
@@ -127,7 +129,7 @@ public:
static LLVBOPool sDynamicCopyVBOPool;
static LLVBOPool sStreamIBOPool;
static LLVBOPool sDynamicIBOPool;
-
+
static std::list<U32> sAvailableVAOName;
static U32 sCurVAOName;
@@ -143,8 +145,7 @@ public:
static void initClass(bool use_vbo, bool no_vbo_mapping);
static void cleanupClass();
static void setupClientArrays(U32 data_mask);
- static void pushPositions(U32 mode, const LLVector4a* pos, U32 count);
- static void drawArrays(U32 mode, const std::vector<LLVector3>& pos, const std::vector<LLVector3>& norm);
+ static void drawArrays(U32 mode, const std::vector<LLVector3>& pos);
static void drawElements(U32 mode, const LLVector4a* pos, const LLVector2* tc, S32 num_indices, const U16* indicesp);
static void unbind(); //unbind any bound vertex buffer
@@ -207,13 +208,17 @@ protected:
virtual ~LLVertexBuffer(); // use unref()
- virtual void setupVertexBuffer(U32 data_mask); // pure virtual, called from mapBuffer()
+ virtual void setupVertexBuffer(U32 data_mask);
+ void setupVertexBufferFast(U32 data_mask);
+
void setupVertexArray();
void genBuffer(U32 size);
void genIndices(U32 size);
bool bindGLBuffer(bool force_bind = false);
+ bool bindGLBufferFast();
bool bindGLIndices(bool force_bind = false);
+ bool bindGLIndicesFast();
bool bindGLArray();
void releaseBuffer();
void releaseIndices();
@@ -236,6 +241,8 @@ public:
// set for rendering
virtual void setBuffer(U32 data_mask); // calls setupVertexBuffer() if data_mask is not 0
+ void setBufferFast(U32 data_mask); // calls setupVertexBufferFast(), assumes data_mask is not 0 among other assumptions
+
void flush(); //flush pending data to GL memory
// allocate buffer
bool allocateBuffer(S32 nverts, S32 nindices, bool create);
@@ -287,6 +294,9 @@ public:
void drawArrays(U32 mode, U32 offset, U32 count) const;
void drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const;
+ //implementation for inner loops that does no safety checking
+ void drawRangeFast(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const;
+
//for debugging, validate data in given range is valid
void validateRange(U32 start, U32 end, U32 count, U32 offset) const;