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.cpp295
1 files changed, 173 insertions, 122 deletions
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 03befe6818..2417f88050 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -214,11 +214,6 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
{
llassert(mRequestedNumVerts >= 0);
- if(mDirty)
- {
- postUpdate() ;
- }
-
if (start >= (U32) mRequestedNumVerts ||
end >= (U32) mRequestedNumVerts)
{
@@ -259,11 +254,6 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
{
llassert(mRequestedNumIndices >= 0);
- if(mDirty)
- {
- postUpdate() ;
- }
-
if (indices_offset >= (U32) mRequestedNumIndices ||
indices_offset + count > (U32) mRequestedNumIndices)
{
@@ -296,11 +286,6 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
{
llassert(mRequestedNumVerts >= 0);
- if(mDirty)
- {
- postUpdate() ;
- }
-
if (first >= (U32) mRequestedNumVerts ||
first + count > (U32) mRequestedNumVerts)
{
@@ -327,7 +312,7 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
void LLVertexBuffer::initClass(bool use_vbo, bool no_vbo_mapping)
{
sEnableVBOs = use_vbo;
- sDisableVBOMapping = no_vbo_mapping ;
+ sDisableVBOMapping = sEnableVBOs && no_vbo_mapping ;
LLGLNamePool::registerPool(&sDynamicVBOPool);
LLGLNamePool::registerPool(&sDynamicIBOPool);
LLGLNamePool::registerPool(&sStreamVBOPool);
@@ -384,13 +369,14 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
mGLBuffer(0),
mGLIndices(0),
mMappedData(NULL),
- mMappedIndexData(NULL), mLocked(FALSE),
+ mMappedIndexData(NULL),
+ mVertexLocked(FALSE),
+ mIndexLocked(FALSE),
mFinal(FALSE),
mFilthy(FALSE),
mEmpty(TRUE),
mResized(FALSE),
- mDynamicSize(FALSE),
- mDirty(FALSE)
+ mDynamicSize(FALSE)
{
LLMemType mt2(LLMemType::MTYPE_VERTEX_CONSTRUCTOR);
if (!sEnableVBOs)
@@ -443,6 +429,8 @@ LLVertexBuffer::~LLVertexBuffer()
destroyGLBuffer();
destroyGLIndices();
sCount--;
+
+ llassert_always(!mMappedData && !mMappedIndexData) ;
};
//----------------------------------------------------------------------------
@@ -859,85 +847,58 @@ void LLVertexBuffer::freeClientBuffer()
}
}
-void LLVertexBuffer::preUpdate()
+void LLVertexBuffer::allocateClientVertexBuffer()
{
- if(!useVBOs() || !sDisableVBOMapping)
- {
- return ;
- }
-
if(!mMappedData)
{
U32 size = getSize() ;
mMappedData = new U8[size];
memset(mMappedData, 0, size);
}
+}
+void LLVertexBuffer::allocateClientIndexBuffer()
+{
if(!mMappedIndexData)
{
U32 size = getIndicesSize();
mMappedIndexData = new U8[size];
memset(mMappedIndexData, 0, size);
}
-
- mDirty = TRUE ;
-}
-
-void LLVertexBuffer::postUpdate() const
-{
- if(!useVBOs() || !sDisableVBOMapping)
- {
- return ;
- }
-
- llassert_always(mMappedData && mMappedIndexData) ;
-
- //release the existing buffers
- glBufferDataARB(GL_ARRAY_BUFFER_ARB, 0, NULL, mUsage);
- glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, NULL, mUsage);
-
- //update to the new buffers
- glBufferDataARB(GL_ARRAY_BUFFER_ARB, getSize(), mMappedData, mUsage);
- glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, getIndicesSize(), mMappedIndexData, mUsage);
-
- mDirty = FALSE ;
}
// Map for data access
-U8* LLVertexBuffer::mapBuffer(S32 access)
+U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 access)
{
LLMemType mt2(LLMemType::MTYPE_VERTEX_MAP_BUFFER);
if (mFinal)
{
- llerrs << "LLVertexBuffer::mapBuffer() called on a finalized buffer." << llendl;
+ llerrs << "LLVertexBuffer::mapVeretxBuffer() called on a finalized buffer." << llendl;
}
if (!useVBOs() && !mMappedData && !mMappedIndexData)
{
- llerrs << "LLVertexBuffer::mapBuffer() called on unallocated buffer." << llendl;
+ llerrs << "LLVertexBuffer::mapVertexBuffer() called on unallocated buffer." << llendl;
}
- if(useVBOs() && sDisableVBOMapping)
- {
- preUpdate() ;
- return mMappedData ;
- }
-
- if (!mLocked && useVBOs())
+ if (!mVertexLocked && useVBOs())
{
{
LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_VERTICES);
- setBuffer(0);
- mLocked = TRUE;
+ setBuffer(0, type);
+ mVertexLocked = TRUE;
stop_glerror();
- mMappedData = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
- stop_glerror();
- }
- {
- LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_INDICES);
- mMappedIndexData = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+
+ if(sDisableVBOMapping)
+ {
+ allocateClientVertexBuffer() ;
+ }
+ else
+ {
+ mMappedData = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+ }
stop_glerror();
}
-
+
if (!mMappedData)
{
log_glerror();
@@ -945,23 +906,67 @@ U8* LLVertexBuffer::mapBuffer(S32 access)
//check the availability of memory
LLMemory::logMemoryInfo(TRUE) ;
- //--------------------
- //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 ;
- //--------------------
+ if(!sDisableVBOMapping)
+ {
+ //--------------------
+ //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 ;
+ //--------------------
- 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)
+ {
+ llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
+ }
+
+
+ llerrs << "glMapBuffer returned NULL (no vertex data)" << llendl;
+ }
+ else
{
- llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
+ llerrs << "memory allocation for vertex data failed." << llendl ;
}
+ }
+ sMappedCount++;
+ }
+
+ return mMappedData;
+}
-
- llerrs << "glMapBuffer returned NULL (no vertex data)" << llendl;
+U8* LLVertexBuffer::mapIndexBuffer(S32 access)
+{
+ LLMemType mt2(LLMemType::MTYPE_VERTEX_MAP_BUFFER);
+ if (mFinal)
+ {
+ llerrs << "LLVertexBuffer::mapIndexBuffer() called on a finalized buffer." << llendl;
+ }
+ if (!useVBOs() && !mMappedData && !mMappedIndexData)
+ {
+ llerrs << "LLVertexBuffer::mapIndexBuffer() called on unallocated buffer." << llendl;
+ }
+
+ if (!mIndexLocked && useVBOs())
+ {
+ {
+ LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_INDICES);
+
+ setBuffer(0, TYPE_INDEX);
+ mIndexLocked = TRUE;
+ stop_glerror();
+
+ if(sDisableVBOMapping)
+ {
+ allocateClientIndexBuffer() ;
+ }
+ else
+ {
+ mMappedIndexData = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+ }
+ stop_glerror();
}
if (!mMappedIndexData)
@@ -969,61 +974,99 @@ U8* LLVertexBuffer::mapBuffer(S32 access)
log_glerror();
LLMemory::logMemoryInfo(TRUE) ;
- GLint buff;
- glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
- if ((GLuint)buff != mGLIndices)
+ if(!sDisableVBOMapping)
{
- llerrs << "Invalid GL index buffer bound: " << buff << llendl;
- }
+ GLint buff;
+ glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
+ if ((GLuint)buff != mGLIndices)
+ {
+ llerrs << "Invalid GL index buffer bound: " << buff << llendl;
+ }
- llerrs << "glMapBuffer returned NULL (no index data)" << llendl;
+ llerrs << "glMapBuffer returned NULL (no index data)" << llendl;
+ }
+ else
+ {
+ llerrs << "memory allocation for Index data failed. " << llendl ;
+ }
}
sMappedCount++;
}
-
- return mMappedData;
+
+ return mMappedIndexData ;
}
-void LLVertexBuffer::unmapBuffer()
+void LLVertexBuffer::unmapBuffer(S32 type)
{
LLMemType mt2(LLMemType::MTYPE_VERTEX_UNMAP_BUFFER);
- if (mMappedData || mMappedIndexData)
+ if (!useVBOs())
+ {
+ return ; //nothing to unmap
+ }
+
+ bool updated_all = false ;
+ if (mMappedData && mVertexLocked && type != TYPE_INDEX)
{
- if(sDisableVBOMapping && useVBOs())
+ updated_all = (mIndexLocked && type < 0) ; //both vertex and index buffers done updating
+
+ if(sDisableVBOMapping)
{
- return ;
+ stop_glerror();
+ glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, getSize(), mMappedData);
+ stop_glerror();
}
- else if (useVBOs() && mLocked)
+ else
{
stop_glerror();
glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
stop_glerror();
+
+ mMappedData = NULL;
+ }
+
+ mVertexLocked = FALSE ;
+ sMappedCount--;
+ }
+
+ if(mMappedIndexData && mIndexLocked && (type < 0 || type == TYPE_INDEX))
+ {
+ if(sDisableVBOMapping)
+ {
+ stop_glerror();
+ glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, getIndicesSize(), mMappedIndexData);
+ stop_glerror();
+ }
+ else
+ {
+ stop_glerror();
glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
stop_glerror();
- /*if (!sMapped)
- {
- llerrs << "Redundantly unmapped VBO!" << llendl;
- }
- sMapped = FALSE;*/
- sMappedCount--;
-
- if (mUsage == GL_STATIC_DRAW_ARB)
- { //static draw buffers can only be mapped a single time
- //throw out client data (we won't be using it again)
- mEmpty = TRUE;
- mFinal = TRUE;
- }
- else
+ mMappedIndexData = NULL ;
+ }
+
+ mIndexLocked = FALSE ;
+ sMappedCount--;
+ }
+
+ if(updated_all)
+ {
+ if(mUsage == GL_STATIC_DRAW_ARB)
+ {
+ //static draw buffers can only be mapped a single time
+ //throw out client data (we won't be using it again)
+ mEmpty = TRUE;
+ mFinal = TRUE;
+
+ if(sDisableVBOMapping)
{
- mEmpty = FALSE;
+ freeClientBuffer() ;
}
-
- mMappedIndexData = NULL;
- mMappedData = NULL;
-
- mLocked = FALSE;
+ }
+ else
+ {
+ mEmpty = FALSE;
}
}
}
@@ -1037,15 +1080,16 @@ template <class T,S32 type> struct VertexBufferStrider
strider_t& strider,
S32 index)
{
- if (vbo.mapBuffer() == NULL)
- {
- llwarns << "mapBuffer failed!" << llendl;
- return FALSE;
- }
-
if (type == LLVertexBuffer::TYPE_INDEX)
{
S32 stride = sizeof(T);
+
+ if (vbo.mapIndexBuffer() == NULL)
+ {
+ llwarns << "mapIndexBuffer failed!" << llendl;
+ return FALSE;
+ }
+
strider = (T*)(vbo.getMappedIndices() + index*stride);
strider.setStride(0);
return TRUE;
@@ -1053,6 +1097,13 @@ template <class T,S32 type> struct VertexBufferStrider
else if (vbo.hasDataType(type))
{
S32 stride = vbo.getStride();
+
+ if (vbo.mapVertexBuffer(type) == NULL)
+ {
+ llwarns << "mapVertexBuffer failed!" << llendl;
+ return FALSE;
+ }
+
strider = (T*)(vbo.getMappedData() + vbo.getOffset(type) + index*stride);
strider.setStride(stride);
return TRUE;
@@ -1133,7 +1184,7 @@ void LLVertexBuffer::setStride(S32 type, S32 new_stride)
//----------------------------------------------------------------------------
// Set for rendering
-void LLVertexBuffer::setBuffer(U32 data_mask)
+void LLVertexBuffer::setBuffer(U32 data_mask, S32 type)
{
LLMemType mt2(LLMemType::MTYPE_VERTEX_SET_BUFFER);
//set up pointers if the data mask is different ...
@@ -1240,13 +1291,13 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
}
}
- if (mGLBuffer && !sDisableVBOMapping)
+ if (mGLBuffer)
{
stop_glerror();
glBufferDataARB(GL_ARRAY_BUFFER_ARB, getSize(), NULL, mUsage);
stop_glerror();
}
- if (mGLIndices && !sDisableVBOMapping)
+ if (mGLIndices)
{
stop_glerror();
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, getIndicesSize(), NULL, mUsage);
@@ -1274,7 +1325,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
{
ll_fail("LLVertexBuffer::mapBuffer failed");
}
- unmapBuffer();
+ unmapBuffer(type);
}
else
{