summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Parks <davep@lindenlab.com>2013-02-26 15:15:08 -0600
committerDave Parks <davep@lindenlab.com>2013-02-26 15:15:08 -0600
commitf5e5396c3a17b6bcdc4eb49cda304a9047920fe1 (patch)
tree84886a620931efbed65bd0ef52df9a884dc90f56
parent543500c58592e04ba1ef017abd49ef67cab0797e (diff)
MAINT-2371 First set of profile guided optimizations.
Reviewed by Graham
-rw-r--r--indra/llmath/llvolume.cpp97
-rw-r--r--indra/llmath/llvolume.h3
-rw-r--r--indra/llrender/llgl.cpp37
-rw-r--r--indra/llrender/llglheaders.h2
-rw-r--r--indra/llrender/llrender.cpp76
-rw-r--r--indra/llrender/llvertexbuffer.cpp47
-rw-r--r--indra/llrender/llvertexbuffer.h3
-rwxr-xr-xindra/newview/llface.cpp28
-rwxr-xr-xindra/newview/llmeshrepository.cpp2
-rw-r--r--indra/newview/llvovolume.cpp29
10 files changed, 203 insertions, 121 deletions
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 02c8d2b86f..77d89568df 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -5187,7 +5187,8 @@ LLVolumeFace::LLVolumeFace() :
mTexCoords(NULL),
mIndices(NULL),
mWeights(NULL),
- mOctree(NULL)
+ mOctree(NULL),
+ mOptimized(FALSE)
{
mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3);
mExtents[0].splat(-0.5f);
@@ -5517,14 +5518,14 @@ class LLVCacheVertexData
public:
S32 mIdx;
S32 mCacheTag;
- F32 mScore;
+ F64 mScore;
U32 mActiveTriangles;
std::vector<LLVCacheTriangleData*> mTriangles;
LLVCacheVertexData()
{
mCacheTag = -1;
- mScore = 0.f;
+ mScore = 0.0;
mActiveTriangles = 0;
mIdx = -1;
}
@@ -5534,13 +5535,13 @@ class LLVCacheTriangleData
{
public:
bool mActive;
- F32 mScore;
+ F64 mScore;
LLVCacheVertexData* mVertex[3];
LLVCacheTriangleData()
{
mActive = true;
- mScore = 0.f;
+ mScore = 0.0;
mVertex[0] = mVertex[1] = mVertex[2] = NULL;
}
@@ -5551,7 +5552,7 @@ public:
{
if (mVertex[i])
{
- llassert_always(mVertex[i]->mActiveTriangles > 0);
+ llassert(mVertex[i]->mActiveTriangles > 0);
mVertex[i]->mActiveTriangles--;
}
}
@@ -5563,44 +5564,44 @@ public:
}
};
-const F32 FindVertexScore_CacheDecayPower = 1.5f;
-const F32 FindVertexScore_LastTriScore = 0.75f;
-const F32 FindVertexScore_ValenceBoostScale = 2.0f;
-const F32 FindVertexScore_ValenceBoostPower = 0.5f;
+const F64 FindVertexScore_CacheDecayPower = 1.5;
+const F64 FindVertexScore_LastTriScore = 0.75;
+const F64 FindVertexScore_ValenceBoostScale = 2.0;
+const F64 FindVertexScore_ValenceBoostPower = 0.5;
const U32 MaxSizeVertexCache = 32;
+const F64 FindVertexScore_Scaler = 1.0/(MaxSizeVertexCache-3);
-F32 find_vertex_score(LLVCacheVertexData& data)
+F64 find_vertex_score(LLVCacheVertexData& data)
{
- if (data.mActiveTriangles == 0)
- { //no triangle references this vertex
- return -1.f;
- }
-
- F32 score = 0.f;
+ F64 score = -1.0;
- S32 cache_idx = data.mCacheTag;
+ if (data.mActiveTriangles >= 0)
+ {
+ score = 0.0;
+
+ S32 cache_idx = data.mCacheTag;
- if (cache_idx < 0)
- {
- //not in cache
- }
- else
- {
- if (cache_idx < 3)
- { //vertex was in the last triangle
- score = FindVertexScore_LastTriScore;
+ if (cache_idx < 0)
+ {
+ //not in cache
}
else
- { //more points for being higher in the cache
- F32 scaler = 1.f/(MaxSizeVertexCache-3);
- score = 1.f-((cache_idx-3)*scaler);
- score = powf(score, FindVertexScore_CacheDecayPower);
+ {
+ if (cache_idx < 3)
+ { //vertex was in the last triangle
+ score = FindVertexScore_LastTriScore;
+ }
+ else
+ { //more points for being higher in the cache
+ score = 1.0-((cache_idx-3)*FindVertexScore_Scaler);
+ score = pow(score, FindVertexScore_CacheDecayPower);
+ }
}
- }
- //bonus points for having low valence
- F32 valence_boost = powf((F32)data.mActiveTriangles, -FindVertexScore_ValenceBoostPower);
- score += FindVertexScore_ValenceBoostScale * valence_boost;
+ //bonus points for having low valence
+ F64 valence_boost = pow((F64)data.mActiveTriangles, -FindVertexScore_ValenceBoostPower);
+ score += FindVertexScore_ValenceBoostScale * valence_boost;
+ }
return score;
}
@@ -5720,7 +5721,7 @@ public:
if (mCache[i])
{
mCache[i]->mScore = find_vertex_score(*(mCache[i]));
- llassert_always(mCache[i]->mCacheTag == i);
+ llassert(mCache[i]->mCacheTag == i);
}
}
@@ -5728,11 +5729,14 @@ public:
//update triangle scores
for (U32 i = 0; i < MaxSizeVertexCache+3; ++i)
{
- if (mCache[i])
+ LLVCacheVertexData* data = mCache[i];
+ if (data)
{
- for (U32 j = 0; j < mCache[i]->mTriangles.size(); ++j)
+ U32 count = data->mTriangles.size();
+
+ for (U32 j = 0; j < count; ++j)
{
- LLVCacheTriangleData* tri = mCache[i]->mTriangles[j];
+ LLVCacheTriangleData* tri = data->mTriangles[j];
if (tri->mActive)
{
tri->mScore = tri->mVertex[0]->mScore;
@@ -5753,7 +5757,7 @@ public:
{
if (mCache[i])
{
- llassert_always(mCache[i]->mCacheTag == -1);
+ llassert(mCache[i]->mCacheTag == -1);
mCache[i] = NULL;
}
}
@@ -5765,6 +5769,9 @@ void LLVolumeFace::cacheOptimize()
{ //optimize for vertex cache according to Forsyth method:
// http://home.comcast.net/~tom_forsyth/papers/fast_vert_cache_opt.html
+ llassert(!mOptimized);
+ mOptimized = TRUE;
+
LLVCacheLRU cache;
if (mNumVertices < 3)
@@ -5810,12 +5817,14 @@ void LLVolumeFace::cacheOptimize()
for (U32 i = 0; i < mNumVertices; i++)
{ //initialize score values (no cache -- might try a fifo cache here)
- vertex_data[i].mScore = find_vertex_score(vertex_data[i]);
- vertex_data[i].mActiveTriangles = vertex_data[i].mTriangles.size();
+ LLVCacheVertexData& data = vertex_data[i];
+
+ data.mScore = find_vertex_score(data);
+ data.mActiveTriangles = data.mTriangles.size();
- for (U32 j = 0; j < vertex_data[i].mTriangles.size(); ++j)
+ for (U32 j = 0; j < data.mActiveTriangles; ++j)
{
- vertex_data[i].mTriangles[j]->mScore += vertex_data[i].mScore;
+ data.mTriangles[j]->mScore += data.mScore;
}
}
diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h
index c845556557..99158c1c44 100644
--- a/indra/llmath/llvolume.h
+++ b/indra/llmath/llvolume.h
@@ -933,6 +933,9 @@ public:
LLOctreeNode<LLVolumeTriangle>* mOctree;
+ //whether or not face has been cache optimized
+ BOOL mOptimized;
+
private:
BOOL createUnCutCubeCap(LLVolume* volume, BOOL partial_build = FALSE);
BOOL createCap(LLVolume* volume, BOOL partial_build = FALSE);
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 9d06dd6904..89f1f36297 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -59,6 +59,7 @@ BOOL gDebugGL = FALSE;
BOOL gClothRipple = FALSE;
BOOL gHeadlessClient = FALSE;
BOOL gGLActive = FALSE;
+BOOL gGLDebugLoggingEnabled = TRUE;
static const std::string HEADLESS_VENDOR_STRING("Linden Lab");
static const std::string HEADLESS_RENDERER_STRING("Headless");
@@ -72,6 +73,7 @@ std::ofstream gFailLog;
#define APIENTRY
#endif
+
void APIENTRY gl_debug_callback(GLenum source,
GLenum type,
GLuint id,
@@ -80,22 +82,25 @@ void APIENTRY gl_debug_callback(GLenum source,
const GLchar* message,
GLvoid* userParam)
{
- if (severity == GL_DEBUG_SEVERITY_HIGH_ARB)
- {
- llwarns << "----- GL ERROR --------" << llendl;
- }
- else
+ if (gGLDebugLoggingEnabled)
{
- llwarns << "----- GL WARNING -------" << llendl;
- }
- llwarns << "Type: " << std::hex << type << llendl;
- llwarns << "ID: " << std::hex << id << llendl;
- llwarns << "Severity: " << std::hex << severity << llendl;
- llwarns << "Message: " << message << llendl;
- llwarns << "-----------------------" << llendl;
- if (severity == GL_DEBUG_SEVERITY_HIGH_ARB)
- {
- llerrs << "Halting on GL Error" << llendl;
+ if (severity == GL_DEBUG_SEVERITY_HIGH_ARB)
+ {
+ llwarns << "----- GL ERROR --------" << llendl;
+ }
+ else
+ {
+ llwarns << "----- GL WARNING -------" << llendl;
+ }
+ llwarns << "Type: " << std::hex << type << llendl;
+ llwarns << "ID: " << std::hex << id << llendl;
+ llwarns << "Severity: " << std::hex << severity << llendl;
+ llwarns << "Message: " << message << llendl;
+ llwarns << "-----------------------" << llendl;
+ if (severity == GL_DEBUG_SEVERITY_HIGH_ARB)
+ {
+ llerrs << "Halting on GL Error" << llendl;
+ }
}
}
#endif
@@ -253,6 +258,7 @@ PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback = NULL;
PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback = NULL;
PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings = NULL;
PFNGLBINDBUFFERRANGEPROC glBindBufferRange = NULL;
+PFNGLBINDBUFFERBASEPROC glBindBufferBase = NULL;
//GL_ARB_debug_output
PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControlARB = NULL;
@@ -1224,6 +1230,7 @@ void LLGLManager::initExtensions()
glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC) GLH_EXT_GET_PROC_ADDRESS("glEndTransformFeedback");
glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC) GLH_EXT_GET_PROC_ADDRESS("glTransformFeedbackVaryings");
glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC) GLH_EXT_GET_PROC_ADDRESS("glBindBufferRange");
+ glBindBufferBase = (PFNGLBINDBUFFERBASEPROC) GLH_EXT_GET_PROC_ADDRESS("glBindBufferBase");
}
if (mHasDebugOutput)
{
diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h
index 509de51f4d..a92ed428da 100644
--- a/indra/llrender/llglheaders.h
+++ b/indra/llrender/llglheaders.h
@@ -533,6 +533,7 @@ extern PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback;
extern PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback;
extern PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings;
extern PFNGLBINDBUFFERRANGEPROC glBindBufferRange;
+extern PFNGLBINDBUFFERBASEPROC glBindBufferBase;
#elif LL_WINDOWS
@@ -771,6 +772,7 @@ extern PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback;
extern PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback;
extern PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings;
extern PFNGLBINDBUFFERRANGEPROC glBindBufferRange;
+extern PFNGLBINDBUFFERBASEPROC glBindBufferBase;
//GL_ARB_debug_output
extern PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControlARB;
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index a12e9caf4c..cb82cbfb74 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -225,46 +225,56 @@ void LLTexUnit::disable(void)
bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind)
{
stop_glerror();
- if (mIndex < 0) return false;
-
- gGL.flush();
-
- LLImageGL* gl_tex = NULL ;
- if (texture == NULL || !(gl_tex = texture->getGLTexture()))
- {
- llwarns << "NULL LLTexUnit::bind texture" << llendl;
- return false;
- }
-
- if (!gl_tex->getTexName()) //if texture does not exist
+ if (mIndex >= 0)
{
- //if deleted, will re-generate it immediately
- texture->forceImmediateUpdate() ;
-
- gl_tex->forceUpdateBindStats() ;
- return texture->bindDefaultImage(mIndex);
- }
+ gGL.flush();
- //in audit, replace the selected texture by the default one.
- if ((mCurrTexture != gl_tex->getTexName()) || forceBind)
- {
- activate();
- enable(gl_tex->getTarget());
- mCurrTexture = gl_tex->getTexName();
- glBindTexture(sGLTextureType[gl_tex->getTarget()], mCurrTexture);
- if(gl_tex->updateBindStats(gl_tex->mTextureMemory))
+ LLImageGL* gl_tex = NULL ;
+ if (texture != NULL && (gl_tex = texture->getGLTexture()))
{
- texture->setActive() ;
- texture->updateBindStatsForTester() ;
+ if (gl_tex->getTexName()) //if texture exists
+ {
+ //in audit, replace the selected texture by the default one.
+ if ((mCurrTexture != gl_tex->getTexName()) || forceBind)
+ {
+ activate();
+ enable(gl_tex->getTarget());
+ mCurrTexture = gl_tex->getTexName();
+ glBindTexture(sGLTextureType[gl_tex->getTarget()], mCurrTexture);
+ if(gl_tex->updateBindStats(gl_tex->mTextureMemory))
+ {
+ texture->setActive() ;
+ texture->updateBindStatsForTester() ;
+ }
+ mHasMipMaps = gl_tex->mHasMipMaps;
+ if (gl_tex->mTexOptionsDirty)
+ {
+ gl_tex->mTexOptionsDirty = false;
+ setTextureAddressMode(gl_tex->mAddressMode);
+ setTextureFilteringOption(gl_tex->mFilterOption);
+ }
+ }
+ }
+ else
+ {
+ //if deleted, will re-generate it immediately
+ texture->forceImmediateUpdate() ;
+
+ gl_tex->forceUpdateBindStats() ;
+ return texture->bindDefaultImage(mIndex);
+ }
}
- mHasMipMaps = gl_tex->mHasMipMaps;
- if (gl_tex->mTexOptionsDirty)
+ else
{
- gl_tex->mTexOptionsDirty = false;
- setTextureAddressMode(gl_tex->mAddressMode);
- setTextureFilteringOption(gl_tex->mFilterOption);
+ llwarns << "NULL LLTexUnit::bind texture" << llendl;
+ return false;
}
}
+ else
+ { // mIndex < 0
+ return false;
+ }
+
return true;
}
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index dfbd8cd4ee..f152911b24 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -85,6 +85,7 @@ const U32 LL_VBO_POOL_SEED_COUNT = vbo_block_index(LL_VBO_POOL_MAX_SEED_SIZE);
//static
LLVBOPool LLVertexBuffer::sStreamVBOPool(GL_STREAM_DRAW_ARB, GL_ARRAY_BUFFER_ARB);
LLVBOPool LLVertexBuffer::sDynamicVBOPool(GL_DYNAMIC_DRAW_ARB, GL_ARRAY_BUFFER_ARB);
+LLVBOPool LLVertexBuffer::sDynamicCopyVBOPool(GL_DYNAMIC_COPY_ARB, GL_ARRAY_BUFFER_ARB);
LLVBOPool LLVertexBuffer::sStreamIBOPool(GL_STREAM_DRAW_ARB, GL_ELEMENT_ARRAY_BUFFER_ARB);
LLVBOPool LLVertexBuffer::sDynamicIBOPool(GL_DYNAMIC_DRAW_ARB, GL_ELEMENT_ARRAY_BUFFER_ARB);
@@ -199,7 +200,10 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
if (LLVertexBuffer::sDisableVBOMapping || mUsage != GL_DYNAMIC_DRAW_ARB)
{
glBufferDataARB(mType, size, 0, mUsage);
- ret = (U8*) ll_aligned_malloc_16(size);
+ if (mUsage != GL_DYNAMIC_COPY_ARB)
+ { //data will be provided by application
+ ret = (U8*) ll_aligned_malloc_16(size);
+ }
}
else
{ //always use a true hint of static draw when allocating non-client-backed buffers
@@ -393,6 +397,7 @@ void LLVertexBuffer::seedPools()
{
sStreamVBOPool.seedPool();
sDynamicVBOPool.seedPool();
+ sDynamicCopyVBOPool.seedPool();
sStreamIBOPool.seedPool();
sDynamicIBOPool.seedPool();
}
@@ -875,6 +880,7 @@ void LLVertexBuffer::cleanupClass()
sDynamicIBOPool.cleanup();
sStreamVBOPool.cleanup();
sDynamicVBOPool.cleanup();
+ sDynamicCopyVBOPool.cleanup();
if(sPrivatePoolp)
{
@@ -911,13 +917,16 @@ S32 LLVertexBuffer::determineUsage(S32 usage)
if (ret_usage && ret_usage != GL_STREAM_DRAW_ARB)
{ //only stream_draw and dynamic_draw are supported when using VBOs, dynamic draw is the default
- if (sDisableVBOMapping)
- { //always use stream draw if VBO mapping is disabled
- ret_usage = GL_STREAM_DRAW_ARB;
- }
- else
+ if (ret_usage != GL_DYNAMIC_COPY_ARB)
{
- ret_usage = GL_DYNAMIC_DRAW_ARB;
+ if (sDisableVBOMapping)
+ { //always use stream draw if VBO mapping is disabled
+ ret_usage = GL_STREAM_DRAW_ARB;
+ }
+ else
+ {
+ ret_usage = GL_DYNAMIC_DRAW_ARB;
+ }
}
}
@@ -1067,10 +1076,15 @@ void LLVertexBuffer::genBuffer(U32 size)
{
mMappedData = sStreamVBOPool.allocate(mGLBuffer, mSize);
}
- else
+ else if (mUsage == GL_DYNAMIC_DRAW_ARB)
{
mMappedData = sDynamicVBOPool.allocate(mGLBuffer, mSize);
}
+ else
+ {
+ mMappedData = sDynamicCopyVBOPool.allocate(mGLBuffer, mSize);
+ }
+
sGLCount++;
}
@@ -1820,6 +1834,8 @@ void LLVertexBuffer::unmapBuffer()
if (mMappedData && mVertexLocked)
{
+ llassert(mUsage != GL_DYNAMIC_COPY_ARB);
+
LLFastTimer t(FTM_VBO_UNMAP);
bindGLBuffer(true);
updated_all = mIndexLocked; //both vertex and index buffers done updating
@@ -2094,22 +2110,15 @@ bool LLVertexBuffer::bindGLBuffer(bool force_bind)
if (useVBOs() && (force_bind || (mGLBuffer && (mGLBuffer != sGLRenderBuffer || !sVBOActive))))
{
- LLFastTimer t(FTM_BIND_GL_BUFFER);
- /*if (sMapped)
- {
- llerrs << "VBO bound while another VBO mapped!" << llendl;
- }*/
+ //LLFastTimer t(FTM_BIND_GL_BUFFER); <-- this timer is showing up as a hotspot (irony)
+
glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer);
sGLRenderBuffer = mGLBuffer;
sBindCount++;
sVBOActive = true;
- if (mGLArray)
- {
- llassert(sGLRenderArray == mGLArray);
- //mCachedRenderBuffer = mGLBuffer;
- }
-
+ llassert(!mGLArray || sGLRenderArray == mGLArray);
+
ret = true;
}
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index 11fa4ab6a0..a3400ae80c 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -125,9 +125,10 @@ public:
static LLVBOPool sStreamVBOPool;
static LLVBOPool sDynamicVBOPool;
+ static LLVBOPool sDynamicCopyVBOPool;
static LLVBOPool sStreamIBOPool;
static LLVBOPool sDynamicIBOPool;
-
+
static std::list<U32> sAvailableVAOName;
static U32 sCurVAOName;
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index a7e225843c..6b3127decf 100755
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -53,6 +53,7 @@
#include "llviewershadermgr.h"
#include "llvoavatar.h"
+extern BOOL gGLDebugLoggingEnabled;
#define LL_MAX_INDICES_COUNT 1000000
@@ -1166,6 +1167,15 @@ static LLFastTimer::DeclareTimer FTM_FACE_GEOM_COLOR("Color");
static LLFastTimer::DeclareTimer FTM_FACE_GEOM_EMISSIVE("Emissive");
static LLFastTimer::DeclareTimer FTM_FACE_GEOM_WEIGHTS("Weights");
static LLFastTimer::DeclareTimer FTM_FACE_GEOM_BINORMAL("Binormal");
+
+static LLFastTimer::DeclareTimer FTM_FACE_GEOM_FEEDBACK("Face Feedback");
+static LLFastTimer::DeclareTimer FTM_FACE_GEOM_FEEDBACK_POSITION("Feedback Position");
+static LLFastTimer::DeclareTimer FTM_FACE_GEOM_FEEDBACK_NORMAL("Feedback Normal");
+static LLFastTimer::DeclareTimer FTM_FACE_GEOM_FEEDBACK_TEXTURE("Feedback Texture");
+static LLFastTimer::DeclareTimer FTM_FACE_GEOM_FEEDBACK_COLOR("Feedback Color");
+static LLFastTimer::DeclareTimer FTM_FACE_GEOM_FEEDBACK_EMISSIVE("Feedback Emissive");
+static LLFastTimer::DeclareTimer FTM_FACE_GEOM_FEEDBACK_BINORMAL("Feedback Binormal");
+
static LLFastTimer::DeclareTimer FTM_FACE_GEOM_INDEX("Index");
static LLFastTimer::DeclareTimer FTM_FACE_GEOM_INDEX_TAIL("Tail");
static LLFastTimer::DeclareTimer FTM_FACE_POSITION_STORE("Pos");
@@ -1389,12 +1399,14 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
#ifdef GL_TRANSFORM_FEEDBACK_BUFFER
if (use_transform_feedback &&
+ mVertexBuffer->getUsage() == GL_DYNAMIC_COPY_ARB &&
gTransformPositionProgram.mProgramObject && //transform shaders are loaded
mVertexBuffer->useVBOs() && //target buffer is in VRAM
!rebuild_weights && //TODO: add support for weights
!volume.isUnique()) //source volume is NOT flexi
{ //use transform feedback to pack vertex buffer
-
+ //gGLDebugLoggingEnabled = TRUE;
+ LLFastTimer t(FTM_FACE_GEOM_FEEDBACK);
LLVertexBuffer* buff = (LLVertexBuffer*) vf.mVertexBuffer.get();
if (vf.mVertexBuffer.isNull() || buff->getNumVerts() != vf.mNumVertices)
@@ -1411,7 +1423,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (rebuild_pos)
{
- LLFastTimer t(FTM_FACE_GEOM_POSITION);
+ LLFastTimer t(FTM_FACE_GEOM_FEEDBACK_POSITION);
gTransformPositionProgram.bind();
mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_VERTEX, mGeomIndex, mGeomCount);
@@ -1436,7 +1448,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (rebuild_color)
{
- LLFastTimer t(FTM_FACE_GEOM_COLOR);
+ LLFastTimer t(FTM_FACE_GEOM_FEEDBACK_COLOR);
gTransformColorProgram.bind();
mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_COLOR, mGeomIndex, mGeomCount);
@@ -1452,7 +1464,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (rebuild_emissive)
{
- LLFastTimer t(FTM_FACE_GEOM_EMISSIVE);
+ LLFastTimer t(FTM_FACE_GEOM_FEEDBACK_EMISSIVE);
gTransformColorProgram.bind();
mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_EMISSIVE, mGeomIndex, mGeomCount);
@@ -1473,7 +1485,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (rebuild_normal)
{
- LLFastTimer t(FTM_FACE_GEOM_NORMAL);
+ LLFastTimer t(FTM_FACE_GEOM_FEEDBACK_NORMAL);
gTransformNormalProgram.bind();
mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_NORMAL, mGeomIndex, mGeomCount);
@@ -1486,7 +1498,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (rebuild_binormal)
{
- LLFastTimer t(FTM_FACE_GEOM_BINORMAL);
+ LLFastTimer t(FTM_FACE_GEOM_FEEDBACK_BINORMAL);
gTransformBinormalProgram.bind();
mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_BINORMAL, mGeomIndex, mGeomCount);
@@ -1499,7 +1511,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (rebuild_tcoord)
{
- LLFastTimer t(FTM_FACE_GEOM_TEXTURE);
+ LLFastTimer t(FTM_FACE_GEOM_FEEDBACK_TEXTURE);
gTransformTexCoordProgram.bind();
mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TEXCOORD0, mGeomIndex, mGeomCount);
@@ -1522,13 +1534,13 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
}
glBindBufferARB(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
-
gGL.popMatrix();
if (cur_shader)
{
cur_shader->bind();
}
+ //gGLDebugLoggingEnabled = FALSE;
}
else
#endif
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 5b65687090..ae48898e82 100755
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -588,7 +588,7 @@ void LLMeshRepoThread::run()
if (!fetchMeshLOD(req.mMeshParams, req.mLOD, count))//failed, resubmit
{
mMutex->lock();
- mLODReqQ.push(req) ;
+ mLODReqQ.push(req);
mMutex->unlock();
}
}
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index b853112f74..6a18534484 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -99,6 +99,8 @@ static LLFastTimer::DeclareTimer FTM_GEN_TRIANGLES("Generate Triangles");
static LLFastTimer::DeclareTimer FTM_GEN_VOLUME("Generate Volumes");
static LLFastTimer::DeclareTimer FTM_VOLUME_TEXTURES("Volume Textures");
+extern BOOL gGLDebugLoggingEnabled;
+
// Implementation class of LLMediaDataClientObject. See llmediadataclient.h
class LLMediaDataClientObjectImpl : public LLMediaDataClientObject
{
@@ -1067,7 +1069,9 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bo
break;
}
volume->genBinormals(i);
+ //gGLDebugLoggingEnabled = TRUE;
LLFace::cacheFaceInVRAM(face);
+ //gGLDebugLoggingEnabled = FALSE;
}
}
@@ -4836,6 +4840,16 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
U32 buffer_usage = group->mBufferUsage;
+ static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback");
+
+ if (use_transform_feedback &&
+ gTransformPositionProgram.mProgramObject && //transform shaders are loaded
+ buffer_usage == GL_DYNAMIC_DRAW_ARB && //target buffer is in VRAM
+ !(mask & LLVertexBuffer::MAP_WEIGHT4)) //TODO: add support for weights
+ {
+ buffer_usage = GL_DYNAMIC_COPY_ARB;
+ }
+
#if LL_DARWIN
// HACK from Leslie:
// Disable VBO usage for alpha on Mac OS X because it kills the framerate
@@ -4895,6 +4909,8 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
//NEVER use more than 16 texture index channels (workaround for prevalent driver bug)
texture_index_channels = llmin(texture_index_channels, 16);
+ bool flexi = false;
+
while (face_iter != faces.end())
{
//pull off next face
@@ -4921,6 +4937,8 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
U32 index_count = facep->getIndicesCount();
U32 geom_count = facep->getGeomCount();
+ flexi = flexi || facep->getViewerObject()->getVolume()->isUnique();
+
//sum up vertices needed for this render batch
std::vector<LLFace*>::iterator i = face_iter;
++i;
@@ -4989,6 +5007,9 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
}
++i;
+
+ flexi = flexi || facep->getViewerObject()->getVolume()->isUnique();
+
index_count += facep->getIndicesCount();
geom_count += facep->getGeomCount();
@@ -5018,10 +5039,18 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
++i;
index_count += facep->getIndicesCount();
geom_count += facep->getGeomCount();
+
+ flexi = flexi || facep->getViewerObject()->getVolume()->isUnique();
}
}
}
+
+ if (flexi && buffer_usage && buffer_usage != GL_STREAM_DRAW_ARB)
+ {
+ buffer_usage = GL_STREAM_DRAW_ARB;
+ }
+
//create vertex buffer
LLVertexBuffer* buffer = NULL;