summaryrefslogtreecommitdiff
path: root/indra/llrender/llvertexbuffer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llrender/llvertexbuffer.cpp')
-rw-r--r--indra/llrender/llvertexbuffer.cpp762
1 files changed, 481 insertions, 281 deletions
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 3948145580..dfbd8cd4ee 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -31,7 +31,6 @@
#include "llvertexbuffer.h"
// #include "llrender.h"
#include "llglheaders.h"
-#include "llmemtype.h"
#include "llrender.h"
#include "llvector4a.h"
#include "llshadermgr.h"
@@ -49,138 +48,198 @@ U32 nhpo2(U32 v)
return r;
}
+//which power of 2 is i?
+//assumes i is a power of 2 > 0
+U32 wpo2(U32 i)
+{
+ llassert(i > 0);
+ llassert(nhpo2(i) == i);
+
+ U32 r = 0;
+
+ while (i >>= 1) ++r;
+
+ return r;
+}
+
+
+const U32 LL_VBO_BLOCK_SIZE = 2048;
+const U32 LL_VBO_POOL_MAX_SEED_SIZE = 256*1024;
+
+U32 vbo_block_size(U32 size)
+{ //what block size will fit size?
+ U32 mod = size % LL_VBO_BLOCK_SIZE;
+ return mod == 0 ? size : size + (LL_VBO_BLOCK_SIZE-mod);
+}
+
+U32 vbo_block_index(U32 size)
+{
+ return vbo_block_size(size)/LL_VBO_BLOCK_SIZE;
+}
+
+const U32 LL_VBO_POOL_SEED_COUNT = vbo_block_index(LL_VBO_POOL_MAX_SEED_SIZE);
+
//============================================================================
//static
-LLVBOPool LLVertexBuffer::sStreamVBOPool;
-LLVBOPool LLVertexBuffer::sDynamicVBOPool;
-LLVBOPool LLVertexBuffer::sStreamIBOPool;
-LLVBOPool LLVertexBuffer::sDynamicIBOPool;
+LLVBOPool LLVertexBuffer::sStreamVBOPool(GL_STREAM_DRAW_ARB, GL_ARRAY_BUFFER_ARB);
+LLVBOPool LLVertexBuffer::sDynamicVBOPool(GL_DYNAMIC_DRAW_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);
+
U32 LLVBOPool::sBytesPooled = 0;
+U32 LLVBOPool::sIndexBytesPooled = 0;
+U32 LLVBOPool::sCurGLName = 1;
-LLPrivateMemoryPool* LLVertexBuffer::sPrivatePoolp = NULL ;
+std::list<U32> LLVertexBuffer::sAvailableVAOName;
+U32 LLVertexBuffer::sCurVAOName = 1;
+
+U32 LLVertexBuffer::sAllocatedIndexBytes = 0;
+U32 LLVertexBuffer::sIndexCount = 0;
+
+LLPrivateMemoryPool* LLVertexBuffer::sPrivatePoolp = NULL;
U32 LLVertexBuffer::sBindCount = 0;
U32 LLVertexBuffer::sSetCount = 0;
S32 LLVertexBuffer::sCount = 0;
S32 LLVertexBuffer::sGLCount = 0;
S32 LLVertexBuffer::sMappedCount = 0;
-BOOL LLVertexBuffer::sDisableVBOMapping = FALSE ;
-BOOL LLVertexBuffer::sEnableVBOs = TRUE;
+bool LLVertexBuffer::sDisableVBOMapping = false;
+bool LLVertexBuffer::sEnableVBOs = true;
U32 LLVertexBuffer::sGLRenderBuffer = 0;
U32 LLVertexBuffer::sGLRenderArray = 0;
U32 LLVertexBuffer::sGLRenderIndices = 0;
U32 LLVertexBuffer::sLastMask = 0;
-BOOL LLVertexBuffer::sVBOActive = FALSE;
-BOOL LLVertexBuffer::sIBOActive = FALSE;
+bool LLVertexBuffer::sVBOActive = false;
+bool LLVertexBuffer::sIBOActive = false;
U32 LLVertexBuffer::sAllocatedBytes = 0;
-BOOL LLVertexBuffer::sMapped = FALSE;
-BOOL LLVertexBuffer::sUseStreamDraw = TRUE;
-BOOL LLVertexBuffer::sUseVAO = FALSE;
-BOOL LLVertexBuffer::sPreferStreamDraw = FALSE;
+U32 LLVertexBuffer::sVertexCount = 0;
+bool LLVertexBuffer::sMapped = false;
+bool LLVertexBuffer::sUseStreamDraw = true;
+bool LLVertexBuffer::sUseVAO = false;
+bool LLVertexBuffer::sPreferStreamDraw = false;
-const U32 FENCE_WAIT_TIME_NANOSECONDS = 10000; //1 ms
-class LLGLSyncFence : public LLGLFence
+U32 LLVBOPool::genBuffer()
{
-public:
-#ifdef GL_ARB_sync
- GLsync mSync;
-#endif
-
- LLGLSyncFence()
- {
-#ifdef GL_ARB_sync
- mSync = 0;
-#endif
- }
+ U32 ret = 0;
- ~LLGLSyncFence()
+ if (mGLNamePool.empty())
{
-#ifdef GL_ARB_sync
- if (mSync)
- {
- glDeleteSync(mSync);
- }
-#endif
+ ret = sCurGLName++;
}
-
- void placeFence()
+ else
{
-#ifdef GL_ARB_sync
- if (mSync)
- {
- glDeleteSync(mSync);
- }
- mSync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
-#endif
+ ret = mGLNamePool.front();
+ mGLNamePool.pop_front();
}
- void wait()
- {
-#ifdef GL_ARB_sync
- if (mSync)
- {
- while (glClientWaitSync(mSync, 0, FENCE_WAIT_TIME_NANOSECONDS) == GL_TIMEOUT_EXPIRED)
- { //track the number of times we've waited here
- static S32 waits = 0;
- waits++;
- }
- }
-#endif
- }
+ return ret;
+}
+void LLVBOPool::deleteBuffer(U32 name)
+{
+ if (gGLManager.mInited)
+ {
+ LLVertexBuffer::unbind();
-};
+ glBindBufferARB(mType, name);
+ glBufferDataARB(mType, 0, NULL, mUsage);
+ llassert(std::find(mGLNamePool.begin(), mGLNamePool.end(), name) == mGLNamePool.end());
-//which power of 2 is i?
-//assumes i is a power of 2 > 0
-U32 wpo2(U32 i)
-{
- llassert(i > 0);
- llassert(nhpo2(i) == i);
+ mGLNamePool.push_back(name);
- U32 r = 0;
+ glBindBufferARB(mType, 0);
+ }
+}
- while (i >>= 1) ++r;
- return r;
+LLVBOPool::LLVBOPool(U32 vboUsage, U32 vboType)
+: mUsage(vboUsage), mType(vboType)
+{
+ mMissCount.resize(LL_VBO_POOL_SEED_COUNT);
+ std::fill(mMissCount.begin(), mMissCount.end(), 0);
}
-U8* LLVBOPool::allocate(U32& name, U32 size)
+volatile U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
{
- llassert(nhpo2(size) == size);
+ llassert(vbo_block_size(size) == size);
+
+ volatile U8* ret = NULL;
- U32 i = wpo2(size);
+ U32 i = vbo_block_index(size);
if (mFreeList.size() <= i)
{
mFreeList.resize(i+1);
}
- U8* ret = NULL;
-
- if (mFreeList[i].empty())
+ if (mFreeList[i].empty() || for_seed)
{
//make a new buffer
- glGenBuffersARB(1, &name);
+ name = genBuffer();
+
glBindBufferARB(mType, name);
- glBufferDataARB(mType, size, 0, mUsage);
- LLVertexBuffer::sAllocatedBytes += size;
- if (LLVertexBuffer::sDisableVBOMapping)
+ if (!for_seed && i < LL_VBO_POOL_SEED_COUNT)
+ { //record this miss
+ mMissCount[i]++;
+ }
+
+ if (mType == GL_ARRAY_BUFFER_ARB)
{
+ LLVertexBuffer::sAllocatedBytes += size;
+ }
+ else
+ {
+ LLVertexBuffer::sAllocatedIndexBytes += size;
+ }
+
+ if (LLVertexBuffer::sDisableVBOMapping || mUsage != GL_DYNAMIC_DRAW_ARB)
+ {
+ glBufferDataARB(mType, size, 0, mUsage);
ret = (U8*) ll_aligned_malloc_16(size);
}
+ else
+ { //always use a true hint of static draw when allocating non-client-backed buffers
+ glBufferDataARB(mType, size, 0, GL_STATIC_DRAW_ARB);
+ }
+
glBindBufferARB(mType, 0);
+
+ if (for_seed)
+ { //put into pool for future use
+ llassert(mFreeList.size() > i);
+
+ Record rec;
+ rec.mGLName = name;
+ rec.mClientData = ret;
+
+ if (mType == GL_ARRAY_BUFFER_ARB)
+ {
+ sBytesPooled += size;
+ }
+ else
+ {
+ sIndexBytesPooled += size;
+ }
+ mFreeList[i].push_back(rec);
+ }
}
else
{
name = mFreeList[i].front().mGLName;
ret = mFreeList[i].front().mClientData;
- sBytesPooled -= size;
+ if (mType == GL_ARRAY_BUFFER_ARB)
+ {
+ sBytesPooled -= size;
+ }
+ else
+ {
+ sIndexBytesPooled -= size;
+ }
mFreeList[i].pop_front();
}
@@ -188,26 +247,52 @@ U8* LLVBOPool::allocate(U32& name, U32 size)
return ret;
}
-void LLVBOPool::release(U32 name, U8* buffer, U32 size)
+void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size)
{
- llassert(nhpo2(size) == size);
+ llassert(vbo_block_size(size) == size);
- U32 i = wpo2(size);
+ deleteBuffer(name);
+ ll_aligned_free_16((U8*) buffer);
- llassert(mFreeList.size() > i);
+ if (mType == GL_ARRAY_BUFFER_ARB)
+ {
+ LLVertexBuffer::sAllocatedBytes -= size;
+ }
+ else
+ {
+ LLVertexBuffer::sAllocatedIndexBytes -= size;
+ }
+}
- Record rec;
- rec.mGLName = name;
- rec.mClientData = buffer;
+void LLVBOPool::seedPool()
+{
+ U32 dummy_name = 0;
- sBytesPooled += size;
+ if (mFreeList.size() < LL_VBO_POOL_SEED_COUNT)
+ {
+ mFreeList.resize(LL_VBO_POOL_SEED_COUNT);
+ }
- mFreeList[i].push_back(rec);
+ for (U32 i = 0; i < LL_VBO_POOL_SEED_COUNT; i++)
+ {
+ if (mMissCount[i] > mFreeList[i].size())
+ {
+ U32 size = i*LL_VBO_BLOCK_SIZE;
+
+ S32 count = mMissCount[i] - mFreeList[i].size();
+ for (U32 j = 0; j < count; ++j)
+ {
+ allocate(dummy_name, size, true);
+ }
+ }
+ }
}
+
+
void LLVBOPool::cleanup()
{
- U32 size = 1;
+ U32 size = LL_VBO_BLOCK_SIZE;
for (U32 i = 0; i < mFreeList.size(); ++i)
{
@@ -217,21 +302,32 @@ void LLVBOPool::cleanup()
{
Record& r = l.front();
- glDeleteBuffersARB(1, &r.mGLName);
-
+ deleteBuffer(r.mGLName);
+
if (r.mClientData)
{
- ll_aligned_free_16(r.mClientData);
+ ll_aligned_free_16((void*) r.mClientData);
}
l.pop_front();
- LLVertexBuffer::sAllocatedBytes -= size;
- sBytesPooled -= size;
+ if (mType == GL_ARRAY_BUFFER_ARB)
+ {
+ sBytesPooled -= size;
+ LLVertexBuffer::sAllocatedBytes -= size;
+ }
+ else
+ {
+ sIndexBytesPooled -= size;
+ LLVertexBuffer::sAllocatedIndexBytes -= size;
+ }
}
- size *= 2;
+ size += LL_VBO_BLOCK_SIZE;
}
+
+ //reset miss counts
+ std::fill(mMissCount.begin(), mMissCount.end(), 0);
}
@@ -265,13 +361,54 @@ U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] =
GL_LINE_LOOP,
};
+//static
+U32 LLVertexBuffer::getVAOName()
+{
+ U32 ret = 0;
+
+ if (!sAvailableVAOName.empty())
+ {
+ ret = sAvailableVAOName.front();
+ sAvailableVAOName.pop_front();
+ }
+ else
+ {
+#ifdef GL_ARB_vertex_array_object
+ glGenVertexArrays(1, &ret);
+#endif
+ }
+
+ return ret;
+}
+
+//static
+void LLVertexBuffer::releaseVAOName(U32 name)
+{
+ sAvailableVAOName.push_back(name);
+}
+
+
+//static
+void LLVertexBuffer::seedPools()
+{
+ sStreamVBOPool.seedPool();
+ sDynamicVBOPool.seedPool();
+ sStreamIBOPool.seedPool();
+ sDynamicIBOPool.seedPool();
+}
//static
void LLVertexBuffer::setupClientArrays(U32 data_mask)
{
if (sLastMask != data_mask)
{
- BOOL error = FALSE;
+ bool error = false;
+
+ if (gGLManager.mGLSLVersionMajor < 2 && gGLManager.mGLSLVersionMinor < 30)
+ {
+ //make sure texture index is disabled
+ data_mask = data_mask & ~MAP_TEXTURE_INDEX;
+ }
if (LLGLSLShader::sNoFixedFunction)
{
@@ -332,7 +469,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
{
if (gDebugSession)
{
- error = TRUE;
+ error = true;
gFailLog << "Bad client state! " << array[i] << " disabled." << std::endl;
}
else
@@ -352,7 +489,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
{ //needs to be disabled, make sure it was (DEBUG TEMPORARY)
if (gDebugSession)
{
- error = TRUE;
+ error = true;
gFailLog << "Bad client state! " << array[i] << " enabled." << std::endl;
}
else
@@ -417,8 +554,21 @@ void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, con
gGL.syncMatrices();
U32 count = pos.size();
- llassert_always(norm.size() >= pos.size());
- llassert_always(count > 0) ;
+
+ llassert(norm.size() >= pos.size());
+ llassert(count > 0);
+
+ if( count == 0 )
+ {
+ llwarns << "Called drawArrays with 0 vertices" << llendl;
+ return;
+ }
+
+ if( norm.size() < pos.size() )
+ {
+ llwarns << "Called drawArrays with #" << norm.size() << " normals and #" << pos.size() << " vertices" << llendl;
+ return;
+ }
unbind();
@@ -536,7 +686,7 @@ void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_of
void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const
{
validateRange(start, end, count, indices_offset);
-
+ mMappable = false;
gGL.syncMatrices();
llassert(mNumVerts >= 0);
@@ -591,7 +741,7 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
{
llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
-
+ mMappable = false;
gGL.syncMatrices();
llassert(mNumIndices >= 0);
@@ -637,7 +787,7 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
{
llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
-
+ mMappable = false;
gGL.syncMatrices();
llassert(mNumVerts >= 0);
@@ -677,23 +827,13 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
//static
void LLVertexBuffer::initClass(bool use_vbo, bool no_vbo_mapping)
{
- sEnableVBOs = use_vbo && gGLManager.mHasVertexBufferObject ;
- sDisableVBOMapping = sEnableVBOs && no_vbo_mapping ;
+ sEnableVBOs = use_vbo && gGLManager.mHasVertexBufferObject;
+ sDisableVBOMapping = sEnableVBOs && no_vbo_mapping;
- if(!sPrivatePoolp)
+ if (!sPrivatePoolp)
{
- sPrivatePoolp = LLPrivateMemoryPoolManager::getInstance()->newPool(LLPrivateMemoryPool::STATIC) ;
+ sPrivatePoolp = LLPrivateMemoryPoolManager::getInstance()->newPool(LLPrivateMemoryPool::STATIC);
}
-
- sStreamVBOPool.mType = GL_ARRAY_BUFFER_ARB;
- sStreamVBOPool.mUsage= GL_STREAM_DRAW_ARB;
- sStreamIBOPool.mType = GL_ELEMENT_ARRAY_BUFFER_ARB;
- sStreamIBOPool.mUsage= GL_STREAM_DRAW_ARB;
-
- sDynamicVBOPool.mType = GL_ARRAY_BUFFER_ARB;
- sDynamicVBOPool.mUsage= GL_DYNAMIC_DRAW_ARB;
- sDynamicIBOPool.mType = GL_ELEMENT_ARRAY_BUFFER_ARB;
- sDynamicIBOPool.mUsage= GL_DYNAMIC_DRAW_ARB;
}
//static
@@ -706,18 +846,18 @@ void LLVertexBuffer::unbind()
#endif
sGLRenderArray = 0;
sGLRenderIndices = 0;
- sIBOActive = FALSE;
+ sIBOActive = false;
}
if (sVBOActive)
{
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
- sVBOActive = FALSE;
+ sVBOActive = false;
}
if (sIBOActive)
{
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
- sIBOActive = FALSE;
+ sIBOActive = false;
}
sGLRenderBuffer = 0;
@@ -729,7 +869,6 @@ void LLVertexBuffer::unbind()
//static
void LLVertexBuffer::cleanupClass()
{
- LLMemType mt2(LLMemType::MTYPE_VERTEX_CLEANUP_CLASS);
unbind();
sStreamIBOPool.cleanup();
@@ -739,69 +878,85 @@ void LLVertexBuffer::cleanupClass()
if(sPrivatePoolp)
{
- LLPrivateMemoryPoolManager::getInstance()->deletePool(sPrivatePoolp) ;
- sPrivatePoolp = NULL ;
+ LLPrivateMemoryPoolManager::getInstance()->deletePool(sPrivatePoolp);
+ sPrivatePoolp = NULL;
}
}
//----------------------------------------------------------------------------
-LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
- LLRefCount(),
-
- mNumVerts(0),
- mNumIndices(0),
- mUsage(usage),
- mGLBuffer(0),
- mGLArray(0),
- mGLIndices(0),
- mMappedData(NULL),
- mMappedIndexData(NULL),
- mVertexLocked(FALSE),
- mIndexLocked(FALSE),
- mFinal(FALSE),
- mEmpty(TRUE),
- mFence(NULL)
+S32 LLVertexBuffer::determineUsage(S32 usage)
{
- LLMemType mt2(LLMemType::MTYPE_VERTEX_CONSTRUCTOR);
- mFence = NULL;
+ S32 ret_usage = usage;
+
if (!sEnableVBOs)
{
- mUsage = 0 ;
+ ret_usage = 0;
}
-
- if (mUsage == GL_STREAM_DRAW_ARB && !sUseStreamDraw)
+
+ if (ret_usage == GL_STREAM_DRAW_ARB && !sUseStreamDraw)
{
- mUsage = 0;
+ ret_usage = 0;
}
- if (mUsage == GL_DYNAMIC_DRAW_ARB && sPreferStreamDraw)
+ if (ret_usage == GL_DYNAMIC_DRAW_ARB && sPreferStreamDraw)
{
- mUsage = GL_STREAM_DRAW_ARB;
+ ret_usage = GL_STREAM_DRAW_ARB;
}
-
- if (mUsage == 0 && LLRender::sGLCoreProfile)
+
+ if (ret_usage == 0 && LLRender::sGLCoreProfile)
{ //MUST use VBOs for all rendering
- mUsage = GL_STREAM_DRAW_ARB;
+ ret_usage = GL_STREAM_DRAW_ARB;
}
-
- if (mUsage && mUsage != GL_STREAM_DRAW_ARB)
+
+ 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
- mUsage = 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;
+ }
}
-
+
+ return ret_usage;
+}
+
+LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
+ LLRefCount(),
+
+ mNumVerts(0),
+ mNumIndices(0),
+ mAlignedOffset(0),
+ mAlignedIndexOffset(0),
+ mSize(0),
+ mIndicesSize(0),
+ mTypeMask(typemask),
+ mUsage(LLVertexBuffer::determineUsage(usage)),
+ mGLBuffer(0),
+ mGLIndices(0),
+ mGLArray(0),
+ mMappedData(NULL),
+ mMappedIndexData(NULL),
+ mMappedDataUsingVBOs(false),
+ mMappedIndexDataUsingVBOs(false),
+ mVertexLocked(false),
+ mIndexLocked(false),
+ mFinal(false),
+ mEmpty(true),
+ mMappable(false),
+ mFence(NULL)
+{
+ mMappable = (mUsage == GL_DYNAMIC_DRAW_ARB && !sDisableVBOMapping);
+
//zero out offsets
for (U32 i = 0; i < TYPE_MAX; i++)
{
mOffsets[i] = 0;
}
- mTypeMask = typemask;
- mSize = 0;
- mIndicesSize = 0;
- mAlignedOffset = 0;
- mAlignedIndexOffset = 0;
-
sCount++;
}
@@ -853,14 +1008,13 @@ S32 LLVertexBuffer::getSize() const
//virtual
LLVertexBuffer::~LLVertexBuffer()
{
- LLMemType mt2(LLMemType::MTYPE_VERTEX_DESTRUCTOR);
destroyGLBuffer();
destroyGLIndices();
if (mGLArray)
{
#if GL_ARB_vertex_array_object
- glDeleteVertexArrays(1, &mGLArray);
+ releaseVAOName(mGLArray);
#endif
}
@@ -873,7 +1027,10 @@ LLVertexBuffer::~LLVertexBuffer()
mFence = NULL;
- llassert_always(!mMappedData && !mMappedIndexData) ;
+ sVertexCount -= mNumVerts;
+ sIndexCount -= mNumIndices;
+
+ llassert_always(!mMappedData && !mMappedIndexData);
};
void LLVertexBuffer::placeFence() const
@@ -904,7 +1061,7 @@ void LLVertexBuffer::waitFence() const
void LLVertexBuffer::genBuffer(U32 size)
{
- mSize = nhpo2(size);
+ mSize = vbo_block_size(size);
if (mUsage == GL_STREAM_DRAW_ARB)
{
@@ -920,7 +1077,7 @@ void LLVertexBuffer::genBuffer(U32 size)
void LLVertexBuffer::genIndices(U32 size)
{
- mIndicesSize = nhpo2(size);
+ mIndicesSize = vbo_block_size(size);
if (mUsage == GL_STREAM_DRAW_ARB)
{
@@ -970,8 +1127,6 @@ void LLVertexBuffer::releaseIndices()
void LLVertexBuffer::createGLBuffer(U32 size)
{
- LLMemType mt2(LLMemType::MTYPE_VERTEX_CREATE_VERTICES);
-
if (mGLBuffer)
{
destroyGLBuffer();
@@ -982,9 +1137,11 @@ void LLVertexBuffer::createGLBuffer(U32 size)
return;
}
- mEmpty = TRUE;
+ mEmpty = true;
- if (useVBOs())
+ mMappedDataUsingVBOs = useVBOs();
+
+ if (mMappedDataUsingVBOs)
{
genBuffer(size);
}
@@ -999,8 +1156,6 @@ void LLVertexBuffer::createGLBuffer(U32 size)
void LLVertexBuffer::createGLIndices(U32 size)
{
- LLMemType mt2(LLMemType::MTYPE_VERTEX_CREATE_INDICES);
-
if (mGLIndices)
{
destroyGLIndices();
@@ -1011,12 +1166,14 @@ void LLVertexBuffer::createGLIndices(U32 size)
return;
}
- mEmpty = TRUE;
+ mEmpty = true;
//pad by 16 bytes for aligned copies
size += 16;
- if (useVBOs())
+ mMappedIndexDataUsingVBOs = useVBOs();
+
+ if (mMappedIndexDataUsingVBOs)
{
//pad by another 16 bytes for VBO pointer adjustment
size += 16;
@@ -1033,18 +1190,17 @@ void LLVertexBuffer::createGLIndices(U32 size)
void LLVertexBuffer::destroyGLBuffer()
{
- LLMemType mt2(LLMemType::MTYPE_VERTEX_DESTROY_BUFFER);
if (mGLBuffer)
{
- if (useVBOs())
+ if (mMappedDataUsingVBOs)
{
releaseBuffer();
}
else
{
- FREE_MEM(sPrivatePoolp, mMappedData) ;
+ FREE_MEM(sPrivatePoolp, (void*) mMappedData);
mMappedData = NULL;
- mEmpty = TRUE;
+ mEmpty = true;
}
}
@@ -1054,18 +1210,17 @@ void LLVertexBuffer::destroyGLBuffer()
void LLVertexBuffer::destroyGLIndices()
{
- LLMemType mt2(LLMemType::MTYPE_VERTEX_DESTROY_INDICES);
if (mGLIndices)
{
- if (useVBOs())
+ if (mMappedIndexDataUsingVBOs)
{
releaseIndices();
}
else
{
- FREE_MEM(sPrivatePoolp, mMappedIndexData) ;
+ FREE_MEM(sPrivatePoolp, (void*) mMappedIndexData);
mMappedIndexData = NULL;
- mEmpty = TRUE;
+ mEmpty = true;
}
}
@@ -1075,14 +1230,12 @@ void LLVertexBuffer::destroyGLIndices()
void LLVertexBuffer::updateNumVerts(S32 nverts)
{
- LLMemType mt2(LLMemType::MTYPE_VERTEX_UPDATE_VERTS);
-
llassert(nverts >= 0);
- if (nverts >= 65535)
+ if (nverts > 65536)
{
llwarns << "Vertex buffer overflow!" << llendl;
- nverts = 65535;
+ nverts = 65536;
}
U32 needed_size = calcOffsets(mTypeMask, mOffsets, nverts);
@@ -1092,13 +1245,13 @@ void LLVertexBuffer::updateNumVerts(S32 nverts)
createGLBuffer(needed_size);
}
+ sVertexCount -= mNumVerts;
mNumVerts = nverts;
+ sVertexCount += mNumVerts;
}
void LLVertexBuffer::updateNumIndices(S32 nindices)
{
- LLMemType mt2(LLMemType::MTYPE_VERTEX_UPDATE_INDICES);
-
llassert(nindices >= 0);
U32 needed_size = sizeof(U16) * nindices;
@@ -1108,13 +1261,13 @@ void LLVertexBuffer::updateNumIndices(S32 nindices)
createGLIndices(needed_size);
}
+ sIndexCount -= mNumIndices;
mNumIndices = nindices;
+ sIndexCount += mNumIndices;
}
void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
{
- LLMemType mt2(LLMemType::MTYPE_VERTEX_ALLOCATE_BUFFER);
-
stop_glerror();
if (nverts < 0 || nindices < 0 ||
@@ -1134,7 +1287,7 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
if (gGLManager.mHasVertexArrayObject && useVBOs() && (LLRender::sGLCoreProfile || sUseVAO))
{
#if GL_ARB_vertex_array_object
- glGenVertexArrays(1, &mGLArray);
+ mGLArray = getVAOName();
#endif
setupVertexArray();
}
@@ -1187,7 +1340,24 @@ void LLVertexBuffer::setupVertexArray()
GL_FLOAT, //TYPE_WEIGHT,
GL_FLOAT, //TYPE_WEIGHT4,
GL_FLOAT, //TYPE_CLOTHWEIGHT,
- GL_FLOAT, //TYPE_TEXTURE_INDEX
+ GL_UNSIGNED_INT, //TYPE_TEXTURE_INDEX
+ };
+
+ bool attrib_integer[] =
+ {
+ false, //TYPE_VERTEX,
+ false, //TYPE_NORMAL,
+ false, //TYPE_TEXCOORD0,
+ false, //TYPE_TEXCOORD1,
+ false, //TYPE_TEXCOORD2,
+ false, //TYPE_TEXCOORD3,
+ false, //TYPE_COLOR,
+ false, //TYPE_EMISSIVE,
+ false, //TYPE_BINORMAL,
+ false, //TYPE_WEIGHT,
+ false, //TYPE_WEIGHT4,
+ false, //TYPE_CLOTHWEIGHT,
+ true, //TYPE_TEXTURE_INDEX
};
U32 attrib_normalized[] =
@@ -1215,7 +1385,21 @@ void LLVertexBuffer::setupVertexArray()
if (mTypeMask & (1 << i))
{
glEnableVertexAttribArrayARB(i);
- glVertexAttribPointerARB(i, attrib_size[i], attrib_type[i], attrib_normalized[i], sTypeSize[i], (void*) mOffsets[i]);
+
+ if (attrib_integer[i])
+ {
+#if !LL_DARWIN
+ //glVertexattribIPointer requires GLSL 1.30 or later
+ if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30)
+ {
+ glVertexAttribIPointer(i, attrib_size[i], attrib_type[i], sTypeSize[i], (void*) mOffsets[i]);
+ }
+#endif
+ }
+ else
+ {
+ glVertexAttribPointerARB(i, attrib_size[i], attrib_type[i], attrib_normalized[i], sTypeSize[i], (void*) mOffsets[i]);
+ }
}
else
{
@@ -1234,8 +1418,6 @@ void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices)
llassert(newnverts >= 0);
llassert(newnindices >= 0);
- LLMemType mt2(LLMemType::MTYPE_VERTEX_RESIZE_BUFFER);
-
updateNumVerts(newnverts);
updateNumIndices(newnindices);
@@ -1250,16 +1432,10 @@ void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices)
}
}
-BOOL LLVertexBuffer::useVBOs() const
+bool LLVertexBuffer::useVBOs() const
{
//it's generally ineffective to use VBO for things that are streaming on apple
-
- if (!mUsage)
- {
- return FALSE;
- }
-
- return TRUE;
+ return (mUsage != 0);
}
//----------------------------------------------------------------------------
@@ -1282,11 +1458,13 @@ bool expand_region(LLVertexBuffer::MappedRegion& region, S32 index, S32 count)
return true;
}
+static LLFastTimer::DeclareTimer FTM_VBO_MAP_BUFFER_RANGE("VBO Map Range");
+static LLFastTimer::DeclareTimer FTM_VBO_MAP_BUFFER("VBO Map");
+
// Map for data access
-U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range)
+volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range)
{
bindGLBuffer(true);
- LLMemType mt2(LLMemType::MTYPE_VERTEX_MAP_BUFFER);
if (mFinal)
{
llerrs << "LLVertexBuffer::mapVeretxBuffer() called on a finalized buffer." << llendl;
@@ -1298,7 +1476,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
if (useVBOs())
{
- if (sDisableVBOMapping || gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange)
+ if (!mMappable || gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange)
{
if (count == -1)
{
@@ -1323,7 +1501,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
if (!mapped)
{
//not already mapped, map new region
- MappedRegion region(type, !sDisableVBOMapping && map_range ? -1 : index, count);
+ MappedRegion region(type, mMappable && map_range ? -1 : index, count);
mMappedVertexRegions.push_back(region);
}
}
@@ -1335,24 +1513,24 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
if (!mVertexLocked)
{
- LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_VERTICES);
- mVertexLocked = TRUE;
+ mVertexLocked = true;
sMappedCount++;
stop_glerror();
- if(sDisableVBOMapping)
+ if(!mMappable)
{
map_range = false;
}
else
{
- U8* src = NULL;
+ volatile U8* src = NULL;
waitFence();
if (gGLManager.mHasMapBufferRange)
{
if (map_range)
{
#ifdef GL_ARB_map_buffer_range
+ LLFastTimer t(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,
@@ -1376,6 +1554,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
}
}
+ LLFastTimer t(FTM_VBO_MAP_BUFFER);
src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER_ARB, 0, mSize,
GL_MAP_WRITE_BIT |
GL_MAP_FLUSH_EXPLICIT_BIT);
@@ -1403,7 +1582,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
llassert(src != NULL);
- mMappedData = LL_NEXT_ALIGNED_ADDRESS<U8>(src);
+ mMappedData = LL_NEXT_ALIGNED_ADDRESS<volatile U8>(src);
mAlignedOffset = mMappedData - src;
stop_glerror();
@@ -1413,17 +1592,17 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
{
log_glerror();
- //check the availability of memory
- LLMemory::logMemoryInfo(TRUE) ;
+ //check the availability of memory
+ LLMemory::logMemoryInfo(true);
- if(!sDisableVBOMapping)
+ if(mMappable)
{
//--------------------
//print out more debug info before crash
- llinfos << "vertex buffer size: (num verts : num indices) = " << getNumVerts() << " : " << getNumIndices() << llendl ;
- GLint size ;
- glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size) ;
- llinfos << "GL_ARRAY_BUFFER_ARB size is " << size << llendl ;
+ llinfos << "vertex buffer size: (num verts : num indices) = " << getNumVerts() << " : " << getNumIndices() << llendl;
+ GLint size;
+ glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size);
+ llinfos << "GL_ARRAY_BUFFER_ARB size is " << size << llendl;
//--------------------
GLint buff;
@@ -1438,7 +1617,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
}
else
{
- llerrs << "memory allocation for vertex data failed." << llendl ;
+ llerrs << "memory allocation for vertex data failed." << llendl;
}
}
}
@@ -1448,7 +1627,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
map_range = false;
}
- if (map_range && gGLManager.mHasMapBufferRange && !sDisableVBOMapping)
+ if (map_range && gGLManager.mHasMapBufferRange && mMappable)
{
return mMappedData;
}
@@ -1458,9 +1637,12 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
}
}
-U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
+
+static LLFastTimer::DeclareTimer FTM_VBO_MAP_INDEX_RANGE("IBO Map Range");
+static LLFastTimer::DeclareTimer FTM_VBO_MAP_INDEX("IBO Map");
+
+volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
{
- LLMemType mt2(LLMemType::MTYPE_VERTEX_MAP_BUFFER);
bindGLIndices(true);
if (mFinal)
{
@@ -1473,7 +1655,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
if (useVBOs())
{
- if (sDisableVBOMapping || gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange)
+ if (!mMappable || gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange)
{
if (count == -1)
{
@@ -1495,7 +1677,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
if (!mapped)
{
//not already mapped, map new region
- MappedRegion region(TYPE_INDEX, !sDisableVBOMapping && map_range ? -1 : index, count);
+ MappedRegion region(TYPE_INDEX, mMappable && map_range ? -1 : index, count);
mMappedIndexRegions.push_back(region);
}
}
@@ -1507,9 +1689,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
if (!mIndexLocked)
{
- LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_INDICES);
-
- mIndexLocked = TRUE;
+ mIndexLocked = true;
sMappedCount++;
stop_glerror();
@@ -1524,19 +1704,20 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
}
}
- if(sDisableVBOMapping)
+ if(!mMappable)
{
map_range = false;
}
else
{
- U8* src = NULL;
+ volatile U8* src = NULL;
waitFence();
if (gGLManager.mHasMapBufferRange)
{
if (map_range)
{
#ifdef GL_ARB_map_buffer_range
+ LLFastTimer t(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,
@@ -1548,6 +1729,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
else
{
#ifdef GL_ARB_map_buffer_range
+ LLFastTimer t(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);
@@ -1569,6 +1751,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
}
else
{
+ LLFastTimer t(FTM_VBO_MAP_INDEX);
map_range = false;
src = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
}
@@ -1585,9 +1768,9 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
if (!mMappedIndexData)
{
log_glerror();
- LLMemory::logMemoryInfo(TRUE) ;
+ LLMemory::logMemoryInfo(true);
- if(!sDisableVBOMapping)
+ if(mMappable)
{
GLint buff;
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
@@ -1600,7 +1783,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
}
else
{
- llerrs << "memory allocation for Index data failed. " << llendl ;
+ llerrs << "memory allocation for Index data failed. " << llendl;
}
}
}
@@ -1609,7 +1792,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
map_range = false;
}
- if (map_range && gGLManager.mHasMapBufferRange && !sDisableVBOMapping)
+ if (map_range && gGLManager.mHasMapBufferRange && mMappable)
{
return mMappedIndexData;
}
@@ -1619,22 +1802,29 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
}
}
+static LLFastTimer::DeclareTimer FTM_VBO_UNMAP("VBO Unmap");
+static LLFastTimer::DeclareTimer FTM_VBO_FLUSH_RANGE("Flush VBO Range");
+
+
+static LLFastTimer::DeclareTimer FTM_IBO_UNMAP("IBO Unmap");
+static LLFastTimer::DeclareTimer FTM_IBO_FLUSH_RANGE("Flush IBO Range");
+
void LLVertexBuffer::unmapBuffer()
{
- LLMemType mt2(LLMemType::MTYPE_VERTEX_UNMAP_BUFFER);
if (!useVBOs())
{
- return ; //nothing to unmap
+ return; //nothing to unmap
}
- bool updated_all = false ;
+ bool updated_all = false;
if (mMappedData && mVertexLocked)
{
+ LLFastTimer t(FTM_VBO_UNMAP);
bindGLBuffer(true);
updated_all = mIndexLocked; //both vertex and index buffers done updating
- if(sDisableVBOMapping)
+ if(!mMappable)
{
if (!mMappedVertexRegions.empty())
{
@@ -1644,7 +1834,7 @@ void LLVertexBuffer::unmapBuffer()
const MappedRegion& region = mMappedVertexRegions[i];
S32 offset = region.mIndex >= 0 ? mOffsets[region.mType]+sTypeSize[region.mType]*region.mIndex : 0;
S32 length = sTypeSize[region.mType]*region.mCount;
- glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, offset, length, mMappedData+offset);
+ glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, offset, length, (U8*) mMappedData+offset);
stop_glerror();
}
@@ -1653,7 +1843,7 @@ void LLVertexBuffer::unmapBuffer()
else
{
stop_glerror();
- glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, getSize(), mMappedData);
+ glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, getSize(), (U8*) mMappedData);
stop_glerror();
}
}
@@ -1671,6 +1861,7 @@ void LLVertexBuffer::unmapBuffer()
S32 length = sTypeSize[region.mType]*region.mCount;
if (gGLManager.mHasMapBufferRange)
{
+ LLFastTimer t(FTM_VBO_FLUSH_RANGE);
#ifdef GL_ARB_map_buffer_range
glFlushMappedBufferRange(GL_ARRAY_BUFFER_ARB, offset, length);
#endif
@@ -1692,14 +1883,15 @@ void LLVertexBuffer::unmapBuffer()
mMappedData = NULL;
}
- mVertexLocked = FALSE ;
+ mVertexLocked = false;
sMappedCount--;
}
if (mMappedIndexData && mIndexLocked)
{
+ LLFastTimer t(FTM_IBO_UNMAP);
bindGLIndices();
- if(sDisableVBOMapping)
+ if(!mMappable)
{
if (!mMappedIndexRegions.empty())
{
@@ -1708,7 +1900,7 @@ void LLVertexBuffer::unmapBuffer()
const MappedRegion& region = mMappedIndexRegions[i];
S32 offset = region.mIndex >= 0 ? sizeof(U16)*region.mIndex : 0;
S32 length = sizeof(U16)*region.mCount;
- glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length, mMappedIndexData+offset);
+ glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length, (U8*) mMappedIndexData+offset);
stop_glerror();
}
@@ -1717,7 +1909,7 @@ void LLVertexBuffer::unmapBuffer()
else
{
stop_glerror();
- glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, getIndicesSize(), mMappedIndexData);
+ glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, getIndicesSize(), (U8*) mMappedIndexData);
stop_glerror();
}
}
@@ -1734,6 +1926,7 @@ void LLVertexBuffer::unmapBuffer()
S32 length = sizeof(U16)*region.mCount;
if (gGLManager.mHasMapBufferRange)
{
+ LLFastTimer t(FTM_IBO_FLUSH_RANGE);
#ifdef GL_ARB_map_buffer_range
glFlushMappedBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length);
#endif
@@ -1754,16 +1947,16 @@ void LLVertexBuffer::unmapBuffer()
glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
stop_glerror();
- mMappedIndexData = NULL ;
+ mMappedIndexData = NULL;
}
- mIndexLocked = FALSE ;
+ mIndexLocked = false;
sMappedCount--;
}
if(updated_all)
{
- mEmpty = FALSE;
+ mEmpty = false;
}
}
@@ -1778,39 +1971,39 @@ template <class T,S32 type> struct VertexBufferStrider
{
if (type == LLVertexBuffer::TYPE_INDEX)
{
- U8* ptr = vbo.mapIndexBuffer(index, count, map_range);
+ volatile U8* ptr = vbo.mapIndexBuffer(index, count, map_range);
if (ptr == NULL)
{
llwarns << "mapIndexBuffer failed!" << llendl;
- return FALSE;
+ return false;
}
strider = (T*)ptr;
strider.setStride(0);
- return TRUE;
+ return true;
}
else if (vbo.hasDataType(type))
{
S32 stride = LLVertexBuffer::sTypeSize[type];
- U8* ptr = vbo.mapVertexBuffer(type, index, count, map_range);
+ volatile U8* ptr = vbo.mapVertexBuffer(type, index, count, map_range);
if (ptr == NULL)
{
llwarns << "mapVertexBuffer failed!" << llendl;
- return FALSE;
+ return false;
}
strider = (T*)ptr;
strider.setStride(stride);
- return TRUE;
+ return true;
}
else
{
llerrs << "VertexBufferStrider could not find valid vertex data." << llendl;
}
- return FALSE;
+ return false;
}
};
@@ -1909,7 +2102,7 @@ bool LLVertexBuffer::bindGLBuffer(bool force_bind)
glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer);
sGLRenderBuffer = mGLBuffer;
sBindCount++;
- sVBOActive = TRUE;
+ sVBOActive = true;
if (mGLArray)
{
@@ -1941,7 +2134,7 @@ bool LLVertexBuffer::bindGLIndices(bool force_bind)
sGLRenderIndices = mGLIndices;
stop_glerror();
sBindCount++;
- sIBOActive = TRUE;
+ sIBOActive = true;
ret = true;
}
@@ -1956,14 +2149,23 @@ void LLVertexBuffer::flush()
}
}
+// bind for transform feedback (quick 'n dirty)
+void LLVertexBuffer::bindForFeedback(U32 channel, U32 type, U32 index, U32 count)
+{
+#ifdef GL_TRANSFORM_FEEDBACK_BUFFER
+ U32 offset = mOffsets[type] + sTypeSize[type]*index;
+ U32 size= (sTypeSize[type]*count);
+ glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, channel, mGLBuffer, offset, size);
+#endif
+}
+
// Set for rendering
void LLVertexBuffer::setBuffer(U32 data_mask)
{
flush();
- LLMemType mt2(LLMemType::MTYPE_VERTEX_SET_BUFFER);
//set up pointers if the data mask is different ...
- BOOL setup = (sLastMask != data_mask);
+ bool setup = (sLastMask != data_mask);
if (gDebugGL && data_mask != 0)
{ //make sure data requirements are fulfilled
@@ -1997,21 +2199,17 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
if (mGLArray)
{
bindGLArray();
- setup = FALSE; //do NOT perform pointer setup if using VAO
+ setup = false; //do NOT perform pointer setup if using VAO
}
else
{
- if (bindGLBuffer())
- {
- setup = TRUE;
- }
- if (bindGLIndices())
- {
- setup = TRUE;
- }
+ const bool bindBuffer = bindGLBuffer();
+ const bool bindIndices = bindGLIndices();
+
+ setup = setup || bindBuffer || bindIndices;
}
- BOOL error = FALSE;
+ bool error = false;
if (gDebugGL && !mGLArray)
{
GLint buff;
@@ -2020,7 +2218,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
{
if (gDebugSession)
{
- error = TRUE;
+ error = true;
gFailLog << "Invalid GL vertex buffer bound: " << buff << std::endl;
}
else
@@ -2036,7 +2234,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
{
if (gDebugSession)
{
- error = TRUE;
+ error = true;
gFailLog << "Invalid GL index buffer bound: " << buff << std::endl;
}
else
@@ -2058,7 +2256,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
#endif
sGLRenderArray = 0;
sGLRenderIndices = 0;
- sIBOActive = FALSE;
+ sIBOActive = false;
}
if (mGLBuffer)
@@ -2067,13 +2265,13 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
{
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
sBindCount++;
- sVBOActive = FALSE;
- setup = TRUE; // ... or a VBO is deactivated
+ sVBOActive = false;
+ setup = true; // ... or a VBO is deactivated
}
if (sGLRenderBuffer != mGLBuffer)
{
sGLRenderBuffer = mGLBuffer;
- setup = TRUE; // ... or a client memory pointer changed
+ setup = true; // ... or a client memory pointer changed
}
}
if (mGLIndices)
@@ -2082,7 +2280,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
{
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
sBindCount++;
- sIBOActive = FALSE;
+ sIBOActive = false;
}
sGLRenderIndices = mGLIndices;
@@ -2107,14 +2305,13 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
// virtual (default)
void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
{
- LLMemType mt2(LLMemType::MTYPE_VERTEX_SETUP_VERTEX_BUFFER);
stop_glerror();
- U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData;
+ volatile U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData;
- /*if ((data_mask & mTypeMask) != data_mask)
+ if (gDebugGL && ((data_mask & mTypeMask) != data_mask))
{
llerrs << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl;
- }*/
+ }
if (LLGLSLShader::sNoFixedFunction)
{
@@ -2170,25 +2367,28 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
{
S32 loc = TYPE_WEIGHT;
void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT]);
- glVertexAttribPointerARB(loc, 1, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], ptr);
+ 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, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], ptr);
+ 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, TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], ptr);
+ glVertexAttribPointerARB(loc, 4, GL_FLOAT, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], ptr);
}
- if (data_mask & MAP_TEXTURE_INDEX)
+ if (data_mask & MAP_TEXTURE_INDEX &&
+ (gGLManager.mGLSLVersionMajor >= 2 || gGLManager.mGLSLVersionMinor >= 30)) //indexed texture rendering requires GLSL 1.30 or later
{
+#if !LL_DARWIN
S32 loc = TYPE_TEXTURE_INDEX;
void *ptr = (void*) (base + mOffsets[TYPE_VERTEX] + 12);
- glVertexAttribPointerARB(loc, 1, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
+ glVertexAttribIPointer(loc, 1, GL_UNSIGNED_INT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
+#endif
}
if (data_mask & MAP_VERTEX)
{