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.cpp574
1 files changed, 313 insertions, 261 deletions
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 50b0c1a7dd..79d1beb33a 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -148,7 +148,7 @@ U32 wpo2(U32 i)
return r;
}
-U8* LLVBOPool::allocate(U32& name, U32 size)
+volatile U8* LLVBOPool::allocate(U32& name, U32 size)
{
llassert(nhpo2(size) == size);
@@ -159,20 +159,25 @@ U8* LLVBOPool::allocate(U32& name, U32 size)
mFreeList.resize(i+1);
}
- U8* ret = NULL;
+ volatile U8* ret = NULL;
if (mFreeList[i].empty())
{
//make a new buffer
glGenBuffersARB(1, &name);
glBindBufferARB(mType, name);
- glBufferDataARB(mType, size, 0, mUsage);
LLVertexBuffer::sAllocatedBytes += size;
- if (LLVertexBuffer::sDisableVBOMapping)
+ 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);
}
else
@@ -188,7 +193,7 @@ 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);
@@ -202,8 +207,15 @@ void LLVBOPool::release(U32 name, U8* buffer, U32 size)
sBytesPooled += size;
+ if (!LLVertexBuffer::sDisableVBOMapping && mUsage == GL_DYNAMIC_DRAW_ARB)
+ {
+ glDeleteBuffersARB(1, &rec.mGLName);
+ }
+ else
+ {
mFreeList[i].push_back(rec);
}
+}
void LLVBOPool::cleanup()
{
@@ -221,7 +233,7 @@ void LLVBOPool::cleanup()
if (r.mClientData)
{
- ll_aligned_free_16(r.mClientData);
+ ll_aligned_free_16((void*) r.mClientData);
}
l.pop_front();
@@ -276,7 +288,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
if (LLGLSLShader::sNoFixedFunction)
{
for (U32 i = 0; i < TYPE_MAX; ++i)
- {
+ {
S32 loc = i;
U32 mask = 1 << i;
@@ -299,14 +311,14 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
}
else
{
-
- GLenum array[] =
- {
- GL_VERTEX_ARRAY,
- GL_NORMAL_ARRAY,
- GL_TEXTURE_COORD_ARRAY,
- GL_COLOR_ARRAY,
- };
+
+ GLenum array[] =
+ {
+ GL_VERTEX_ARRAY,
+ GL_NORMAL_ARRAY,
+ GL_TEXTURE_COORD_ARRAY,
+ GL_COLOR_ARRAY,
+ };
GLenum mask[] =
{
@@ -318,94 +330,94 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
- for (U32 i = 0; i < 4; ++i)
- {
- if (sLastMask & mask[i])
- { //was enabled
+ for (U32 i = 0; i < 4; ++i)
+ {
+ if (sLastMask & mask[i])
+ { //was enabled
if (!(data_mask & mask[i]))
- { //needs to be disabled
- glDisableClientState(array[i]);
- }
- else if (gDebugGL)
+ { //needs to be disabled
+ glDisableClientState(array[i]);
+ }
+ else if (gDebugGL)
{ //needs to be enabled, make sure it was (DEBUG)
if (!glIsEnabled(array[i]))
- {
+ {
+ if (gDebugSession)
+ {
+ error = TRUE;
+ gFailLog << "Bad client state! " << array[i] << " disabled." << std::endl;
+ }
+ else
+ {
+ llerrs << "Bad client state! " << array[i] << " disabled." << llendl;
+ }
+ }
+ }
+ }
+ else
+ { //was disabled
+ if (data_mask & mask[i])
+ { //needs to be enabled
+ glEnableClientState(array[i]);
+ }
+ else if (gDebugGL && glIsEnabled(array[i]))
+ { //needs to be disabled, make sure it was (DEBUG TEMPORARY)
if (gDebugSession)
{
error = TRUE;
- gFailLog << "Bad client state! " << array[i] << " disabled." << std::endl;
+ gFailLog << "Bad client state! " << array[i] << " enabled." << std::endl;
}
else
{
- llerrs << "Bad client state! " << array[i] << " disabled." << llendl;
+ llerrs << "Bad client state! " << array[i] << " enabled." << llendl;
}
}
}
}
- else
- { //was disabled
- if (data_mask & mask[i])
- { //needs to be enabled
- glEnableClientState(array[i]);
- }
- else if (gDebugGL && glIsEnabled(array[i]))
- { //needs to be disabled, make sure it was (DEBUG TEMPORARY)
- if (gDebugSession)
- {
- error = TRUE;
- gFailLog << "Bad client state! " << array[i] << " enabled." << std::endl;
- }
- else
- {
- llerrs << "Bad client state! " << array[i] << " enabled." << llendl;
- }
- }
- }
- }
-
- U32 map_tc[] =
- {
- MAP_TEXCOORD1,
- MAP_TEXCOORD2,
- MAP_TEXCOORD3
- };
+
+ U32 map_tc[] =
+ {
+ MAP_TEXCOORD1,
+ MAP_TEXCOORD2,
+ MAP_TEXCOORD3
+ };
- for (U32 i = 0; i < 3; i++)
- {
- if (sLastMask & map_tc[i])
+ for (U32 i = 0; i < 3; i++)
{
- if (!(data_mask & map_tc[i]))
+ if (sLastMask & map_tc[i])
+ {
+ if (!(data_mask & map_tc[i]))
{ //disable
+ glClientActiveTextureARB(GL_TEXTURE1_ARB+i);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ }
+ }
+ else if (data_mask & map_tc[i])
+ {
glClientActiveTextureARB(GL_TEXTURE1_ARB+i);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTextureARB(GL_TEXTURE0_ARB);
}
}
- else if (data_mask & map_tc[i])
+
+ if (sLastMask & MAP_BINORMAL)
{
- glClientActiveTextureARB(GL_TEXTURE1_ARB+i);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ if (!(data_mask & MAP_BINORMAL))
+ {
+ glClientActiveTextureARB(GL_TEXTURE2_ARB);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ }
}
- }
-
- if (sLastMask & MAP_BINORMAL)
- {
- if (!(data_mask & MAP_BINORMAL))
+ else if (data_mask & MAP_BINORMAL)
{
glClientActiveTextureARB(GL_TEXTURE2_ARB);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTextureARB(GL_TEXTURE0_ARB);
}
}
- else if (data_mask & MAP_BINORMAL)
- {
- glClientActiveTextureARB(GL_TEXTURE2_ARB);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glClientActiveTextureARB(GL_TEXTURE0_ARB);
- }
- }
-
+
sLastMask = data_mask;
}
}
@@ -441,8 +453,8 @@ void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, con
}
else
{
- glVertexPointer(3, GL_FLOAT, 0, pos[0].mV);
- glNormalPointer(GL_FLOAT, 0, norm[0].mV);
+ glVertexPointer(3, GL_FLOAT, 0, pos[0].mV);
+ glNormalPointer(GL_FLOAT, 0, norm[0].mV);
}
glDrawArrays(sGLMode[mode], 0, count);
@@ -529,14 +541,14 @@ void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_of
llerrs << "Bad texture index found in vertex data stream." << llendl;
}
}
+ }
}
}
-}
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);
@@ -551,15 +563,15 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
}
else
{
- if (mGLIndices != sGLRenderIndices)
- {
- llerrs << "Wrong index buffer bound." << llendl;
- }
+ if (mGLIndices != sGLRenderIndices)
+ {
+ llerrs << "Wrong index buffer bound." << llendl;
+ }
- if (mGLBuffer != sGLRenderBuffer)
- {
- llerrs << "Wrong vertex buffer bound." << llendl;
- }
+ if (mGLBuffer != sGLRenderBuffer)
+ {
+ llerrs << "Wrong vertex buffer bound." << llendl;
+ }
}
if (gDebugGL && !mGLArray && useVBOs())
@@ -591,7 +603,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);
@@ -610,15 +622,15 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
}
else
{
- if (mGLIndices != sGLRenderIndices)
- {
- llerrs << "Wrong index buffer bound." << llendl;
- }
+ if (mGLIndices != sGLRenderIndices)
+ {
+ llerrs << "Wrong index buffer bound." << llendl;
+ }
- if (mGLBuffer != sGLRenderBuffer)
- {
- llerrs << "Wrong vertex buffer bound." << llendl;
- }
+ if (mGLBuffer != sGLRenderBuffer)
+ {
+ llerrs << "Wrong vertex buffer bound." << llendl;
+ }
}
if (mode >= LLRender::NUM_MODES)
@@ -637,7 +649,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);
@@ -658,9 +670,9 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
{
BOOL uvb = useVBOs();
if (mGLBuffer != sGLRenderBuffer || uvb != sVBOActive)
- {
- llerrs << "Wrong vertex buffer bound." << llendl;
- }
+ {
+ llerrs << "Wrong vertex buffer bound." << llendl;
+ }
}
if (mode >= LLRender::NUM_MODES)
@@ -682,7 +694,7 @@ void LLVertexBuffer::initClass(bool use_vbo, bool no_vbo_mapping)
sDisableVBOMapping = sEnableVBOs && no_vbo_mapping ;
if(!sPrivatePoolp)
- {
+ {
sPrivatePoolp = LLPrivateMemoryPoolManager::getInstance()->newPool(LLPrivateMemoryPool::STATIC) ;
}
@@ -788,9 +800,26 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
if (mUsage && mUsage != 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
+ mUsage = GL_STREAM_DRAW_ARB;
+ }
+ else
+ {
mUsage = GL_DYNAMIC_DRAW_ARB;
}
+ }
+
+ if (mUsage == GL_DYNAMIC_DRAW_ARB && !sDisableVBOMapping)
+ {
+ mMappable = TRUE;
+ }
+ else
+ {
+ mMappable = FALSE;
+ }
+
//zero out offsets
for (U32 i = 0; i < TYPE_MAX; i++)
{
@@ -1001,7 +1030,7 @@ void LLVertexBuffer::createGLBuffer(U32 size)
void LLVertexBuffer::createGLIndices(U32 size)
{
LLMemType mt2(LLMemType::MTYPE_VERTEX_CREATE_INDICES);
-
+
if (mGLIndices)
{
destroyGLIndices();
@@ -1043,7 +1072,7 @@ void LLVertexBuffer::destroyGLBuffer()
}
else
{
- FREE_MEM(sPrivatePoolp, mMappedData) ;
+ FREE_MEM(sPrivatePoolp, (void*) mMappedData) ;
mMappedData = NULL;
mEmpty = TRUE;
}
@@ -1064,7 +1093,7 @@ void LLVertexBuffer::destroyGLIndices()
}
else
{
- FREE_MEM(sPrivatePoolp, mMappedIndexData) ;
+ FREE_MEM(sPrivatePoolp, (void*) mMappedIndexData) ;
mMappedIndexData = NULL;
mEmpty = TRUE;
}
@@ -1093,8 +1122,8 @@ void LLVertexBuffer::updateNumVerts(S32 nverts)
createGLBuffer(needed_size);
}
- mNumVerts = nverts;
- }
+ mNumVerts = nverts;
+}
void LLVertexBuffer::updateNumIndices(S32 nindices)
{
@@ -1107,15 +1136,15 @@ void LLVertexBuffer::updateNumIndices(S32 nindices)
if (needed_size > mIndicesSize || needed_size <= mIndicesSize/2)
{
createGLIndices(needed_size);
- }
-
- mNumIndices = nindices;
}
+ mNumIndices = nindices;
+}
+
void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
{
LLMemType mt2(LLMemType::MTYPE_VERTEX_ALLOCATE_BUFFER);
-
+
stop_glerror();
if (nverts < 0 || nindices < 0 ||
@@ -1133,21 +1162,21 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
flush();
if (gGLManager.mHasVertexArrayObject && useVBOs() && (LLRender::sGLCoreProfile || sUseVAO))
- {
+ {
#if GL_ARB_vertex_array_object
glGenVertexArrays(1, &mGLArray);
#endif
setupVertexArray();
}
}
- }
-
+}
+
static LLFastTimer::DeclareTimer FTM_SETUP_VERTEX_ARRAY("Setup VAO");
void LLVertexBuffer::setupVertexArray()
{
if (!mGLArray)
-{
+ {
return;
}
@@ -1173,7 +1202,7 @@ void LLVertexBuffer::setupVertexArray()
4, //TYPE_CLOTHWEIGHT,
1, //TYPE_TEXTURE_INDEX
};
-
+
U32 attrib_type[] =
{
GL_FLOAT, //TYPE_VERTEX,
@@ -1190,7 +1219,7 @@ void LLVertexBuffer::setupVertexArray()
GL_FLOAT, //TYPE_CLOTHWEIGHT,
GL_FLOAT, //TYPE_TEXTURE_INDEX
};
-
+
U32 attrib_normalized[] =
{
GL_FALSE, //TYPE_VERTEX,
@@ -1217,21 +1246,21 @@ void LLVertexBuffer::setupVertexArray()
{
glEnableVertexAttribArrayARB(i);
glVertexAttribPointerARB(i, attrib_size[i], attrib_type[i], attrib_normalized[i], sTypeSize[i], (void*) mOffsets[i]);
- }
- else
- {
+ }
+ else
+ {
glDisableVertexAttribArrayARB(i);
- }
- }
+ }
+ }
//draw a dummy triangle to set index array pointer
//glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_SHORT, NULL);
unbind();
- }
+}
void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices)
- {
+{
llassert(newnverts >= 0);
llassert(newnindices >= 0);
@@ -1239,9 +1268,9 @@ void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices)
updateNumVerts(newnverts);
updateNumIndices(newnindices);
-
+
if (useVBOs())
- {
+ {
flush();
if (mGLArray)
@@ -1283,8 +1312,11 @@ 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);
@@ -1299,7 +1331,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)
{
@@ -1324,7 +1356,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);
}
}
@@ -1341,19 +1373,20 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
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,
@@ -1377,6 +1410,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);
@@ -1404,7 +1438,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();
@@ -1417,7 +1451,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
//check the availability of memory
LLMemory::logMemoryInfo(TRUE) ;
- if(!sDisableVBOMapping)
+ if(mMappable)
{
//--------------------
//print out more debug info before crash
@@ -1449,7 +1483,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;
}
@@ -1459,7 +1493,11 @@ 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);
@@ -1474,7 +1512,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)
{
@@ -1496,7 +1534,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);
}
}
@@ -1525,19 +1563,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,
@@ -1549,6 +1588,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);
@@ -1570,6 +1610,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);
}
@@ -1588,7 +1629,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
log_glerror();
LLMemory::logMemoryInfo(TRUE) ;
- if(!sDisableVBOMapping)
+ if(mMappable)
{
GLint buff;
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
@@ -1610,7 +1651,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;
}
@@ -1620,6 +1661,13 @@ 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);
@@ -1632,10 +1680,11 @@ void LLVertexBuffer::unmapBuffer()
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())
{
@@ -1645,7 +1694,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();
}
@@ -1654,7 +1703,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();
}
}
@@ -1672,6 +1721,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
@@ -1699,8 +1749,9 @@ void LLVertexBuffer::unmapBuffer()
if (mMappedIndexData && mIndexLocked)
{
+ LLFastTimer t(FTM_IBO_UNMAP);
bindGLIndices();
- if(sDisableVBOMapping)
+ if(!mMappable)
{
if (!mMappedIndexRegions.empty())
{
@@ -1709,7 +1760,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();
}
@@ -1718,7 +1769,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();
}
}
@@ -1735,6 +1786,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
@@ -1764,9 +1816,9 @@ void LLVertexBuffer::unmapBuffer()
if(updated_all)
{
- mEmpty = FALSE;
- }
+ mEmpty = FALSE;
}
+}
//----------------------------------------------------------------------------
@@ -1779,7 +1831,7 @@ 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)
{
@@ -1795,7 +1847,7 @@ template <class T,S32 type> struct VertexBufferStrider
{
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)
{
@@ -1874,7 +1926,7 @@ bool LLVertexBuffer::bindGLArray()
{
if (mGLArray && sGLRenderArray != mGLArray)
{
-{
+ {
LLFastTimer t(FTM_BIND_GL_ARRAY);
#if GL_ARB_vertex_array_object
glBindVertexArray(mGLArray);
@@ -1895,22 +1947,22 @@ bool LLVertexBuffer::bindGLArray()
static LLFastTimer::DeclareTimer FTM_BIND_GL_BUFFER("Bind Buffer");
bool LLVertexBuffer::bindGLBuffer(bool force_bind)
- {
+{
bindGLArray();
bool ret = false;
if (useVBOs() && (force_bind || (mGLBuffer && (mGLBuffer != sGLRenderBuffer || !sVBOActive))))
- {
+ {
LLFastTimer t(FTM_BIND_GL_BUFFER);
- /*if (sMapped)
- {
- llerrs << "VBO bound while another VBO mapped!" << llendl;
- }*/
- glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer);
+ /*if (sMapped)
+ {
+ llerrs << "VBO bound while another VBO mapped!" << llendl;
+ }*/
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer);
sGLRenderBuffer = mGLBuffer;
- sBindCount++;
- sVBOActive = TRUE;
+ sBindCount++;
+ sVBOActive = TRUE;
if (mGLArray)
{
@@ -1922,7 +1974,7 @@ bool LLVertexBuffer::bindGLBuffer(bool force_bind)
}
return ret;
- }
+}
static LLFastTimer::DeclareTimer FTM_BIND_GL_INDICES("Bind Indices");
@@ -1932,23 +1984,23 @@ bool LLVertexBuffer::bindGLIndices(bool force_bind)
bool ret = false;
if (useVBOs() && (force_bind || (mGLIndices && (mGLIndices != sGLRenderIndices || !sIBOActive))))
- {
+ {
LLFastTimer t(FTM_BIND_GL_INDICES);
- /*if (sMapped)
- {
- llerrs << "VBO bound while another VBO mapped!" << llendl;
- }*/
- glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mGLIndices);
+ /*if (sMapped)
+ {
+ llerrs << "VBO bound while another VBO mapped!" << llendl;
+ }*/
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mGLIndices);
sGLRenderIndices = mGLIndices;
- stop_glerror();
- sBindCount++;
- sIBOActive = TRUE;
+ stop_glerror();
+ sBindCount++;
+ sIBOActive = TRUE;
ret = true;
}
return ret;
- }
-
+}
+
void LLVertexBuffer::flush()
{
if (useVBOs())
@@ -1973,85 +2025,85 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
{
U32 required_mask = 0;
for (U32 i = 0; i < LLVertexBuffer::TYPE_TEXTURE_INDEX; ++i)
- {
- if (shader->getAttribLocation(i) > -1)
{
+ if (shader->getAttribLocation(i) > -1)
+ {
U32 required = 1 << i;
if ((data_mask & required) == 0)
- {
+ {
llwarns << "Missing attribute: " << LLShaderMgr::instance()->mReservedAttribs[i] << llendl;
}
required_mask |= required;
}
- }
+ }
if ((data_mask & required_mask) != required_mask)
- {
+ {
llerrs << "Shader consumption mismatches data provision." << llendl;
}
- }
- }
+ }
+ }
if (useVBOs())
- {
+ {
if (mGLArray)
- {
+ {
bindGLArray();
setup = FALSE; //do NOT perform pointer setup if using VAO
- }
- else
- {
+ }
+ else
+ {
if (bindGLBuffer())
{
setup = TRUE;
- }
+ }
if (bindGLIndices())
{
setup = TRUE;
- }
}
+ }
BOOL error = FALSE;
if (gDebugGL && !mGLArray)
{
- GLint buff;
- glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
- if ((GLuint)buff != mGLBuffer)
+ GLint buff;
+ glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
+ if ((GLuint)buff != mGLBuffer)
+ {
+ if (gDebugSession)
{
- if (gDebugSession)
- {
- error = TRUE;
+ error = TRUE;
gFailLog << "Invalid GL vertex buffer bound: " << buff << std::endl;
- }
- else
- {
- llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
- }
}
+ else
+ {
+ llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
+ }
+ }
if (mGLIndices)
+ {
+ glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
+ if ((GLuint)buff != mGLIndices)
{
- glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
- if ((GLuint)buff != mGLIndices)
+ if (gDebugSession)
{
- if (gDebugSession)
- {
- error = TRUE;
+ error = TRUE;
gFailLog << "Invalid GL index buffer bound: " << buff << std::endl;
- }
- else
- {
- llerrs << "Invalid GL index buffer bound: " << buff << llendl;
- }
+ }
+ else
+ {
+ llerrs << "Invalid GL index buffer bound: " << buff << llendl;
}
}
}
+ }
-
- }
- else
- {
+
+ }
+ else
+ {
if (sGLRenderArray)
{
#if GL_ARB_vertex_array_object
@@ -2060,7 +2112,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
sGLRenderArray = 0;
sGLRenderIndices = 0;
sIBOActive = FALSE;
- }
+ }
if (mGLBuffer)
{
@@ -2081,10 +2133,10 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
{
if (sIBOActive)
{
- glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
- sBindCount++;
- sIBOActive = FALSE;
- }
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
+ sBindCount++;
+ sIBOActive = FALSE;
+ }
sGLRenderIndices = mGLIndices;
}
@@ -2092,9 +2144,9 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
if (!mGLArray)
{
- setupClientArrays(data_mask);
+ setupClientArrays(data_mask);
}
-
+
if (mGLBuffer)
{
if (data_mask && setup)
@@ -2110,7 +2162,7 @@ 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)
{
@@ -2190,7 +2242,7 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
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);
- }
+ }
if (data_mask & MAP_VERTEX)
{
S32 loc = TYPE_VERTEX;
@@ -2200,56 +2252,56 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
}
else
{
- if (data_mask & MAP_NORMAL)
- {
- glNormalPointer(GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_NORMAL], (void*)(base + mOffsets[TYPE_NORMAL]));
- }
- if (data_mask & MAP_TEXCOORD3)
- {
- glClientActiveTextureARB(GL_TEXTURE3_ARB);
- glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], (void*)(base + mOffsets[TYPE_TEXCOORD3]));
- glClientActiveTextureARB(GL_TEXTURE0_ARB);
- }
- if (data_mask & MAP_TEXCOORD2)
- {
- glClientActiveTextureARB(GL_TEXTURE2_ARB);
- glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], (void*)(base + mOffsets[TYPE_TEXCOORD2]));
- glClientActiveTextureARB(GL_TEXTURE0_ARB);
- }
- if (data_mask & MAP_TEXCOORD1)
- {
- glClientActiveTextureARB(GL_TEXTURE1_ARB);
- glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1]));
- glClientActiveTextureARB(GL_TEXTURE0_ARB);
- }
- if (data_mask & MAP_BINORMAL)
- {
- glClientActiveTextureARB(GL_TEXTURE2_ARB);
- glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL]));
- glClientActiveTextureARB(GL_TEXTURE0_ARB);
- }
- if (data_mask & MAP_TEXCOORD0)
- {
- glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0]));
- }
- if (data_mask & MAP_COLOR)
- {
- glColorPointer(4, GL_UNSIGNED_BYTE, LLVertexBuffer::sTypeSize[TYPE_COLOR], (void*)(base + mOffsets[TYPE_COLOR]));
- }
+ if (data_mask & MAP_NORMAL)
+ {
+ glNormalPointer(GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_NORMAL], (void*)(base + mOffsets[TYPE_NORMAL]));
+ }
+ if (data_mask & MAP_TEXCOORD3)
+ {
+ glClientActiveTextureARB(GL_TEXTURE3_ARB);
+ glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], (void*)(base + mOffsets[TYPE_TEXCOORD3]));
+ glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ }
+ if (data_mask & MAP_TEXCOORD2)
+ {
+ glClientActiveTextureARB(GL_TEXTURE2_ARB);
+ glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], (void*)(base + mOffsets[TYPE_TEXCOORD2]));
+ glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ }
+ if (data_mask & MAP_TEXCOORD1)
+ {
+ glClientActiveTextureARB(GL_TEXTURE1_ARB);
+ glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1]));
+ glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ }
+ if (data_mask & MAP_BINORMAL)
+ {
+ glClientActiveTextureARB(GL_TEXTURE2_ARB);
+ glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL]));
+ glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ }
+ if (data_mask & MAP_TEXCOORD0)
+ {
+ glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0]));
+ }
+ if (data_mask & MAP_COLOR)
+ {
+ glColorPointer(4, GL_UNSIGNED_BYTE, LLVertexBuffer::sTypeSize[TYPE_COLOR], (void*)(base + mOffsets[TYPE_COLOR]));
+ }
if (data_mask & MAP_VERTEX)
- {
+ {
glVertexPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0));
}
}
llglassertok();
- }
+}
LLVertexBuffer::MappedRegion::MappedRegion(S32 type, S32 index, S32 count)
: mType(type), mIndex(index), mCount(count)
- {
+{
llassert(mType == LLVertexBuffer::TYPE_INDEX ||
mType < LLVertexBuffer::TYPE_TEXTURE_INDEX);
- }
+}