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.cpp270
1 files changed, 209 insertions, 61 deletions
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 4a0b964e61..8fd1193780 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -25,7 +25,6 @@
*/
#include "linden_common.h"
-#include "llmemory.h"
#include <boost/static_assert.hpp>
#include "llsys.h"
@@ -35,6 +34,9 @@
#include "llmemtype.h"
#include "llrender.h"
#include "llvector4a.h"
+#include "llglslshader.h"
+#include "llmemory.h"
+
//============================================================================
@@ -44,6 +46,7 @@ LLVBOPool LLVertexBuffer::sDynamicVBOPool;
LLVBOPool LLVertexBuffer::sStreamIBOPool;
LLVBOPool LLVertexBuffer::sDynamicIBOPool;
+LLPrivateMemoryPool* LLVertexBuffer::sPrivatePoolp = NULL ;
U32 LLVertexBuffer::sBindCount = 0;
U32 LLVertexBuffer::sSetCount = 0;
S32 LLVertexBuffer::sCount = 0;
@@ -65,6 +68,60 @@ S32 LLVertexBuffer::sWeight4Loc = -1;
std::vector<U32> LLVertexBuffer::sDeleteList;
+const U32 FENCE_WAIT_TIME_NANOSECONDS = 10000; //1 ms
+
+class LLGLSyncFence : public LLGLFence
+{
+public:
+#ifdef GL_ARB_sync
+ GLsync mSync;
+#endif
+
+ LLGLSyncFence()
+ {
+#ifdef GL_ARB_sync
+ mSync = 0;
+#endif
+ }
+
+ ~LLGLSyncFence()
+ {
+#ifdef GL_ARB_sync
+ if (mSync)
+ {
+ glDeleteSync(mSync);
+ }
+#endif
+ }
+
+ void placeFence()
+ {
+#ifdef GL_ARB_sync
+ if (mSync)
+ {
+ glDeleteSync(mSync);
+ }
+ mSync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+#endif
+ }
+
+ 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
+ }
+
+
+};
+
S32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] =
{
sizeof(LLVector4), // TYPE_VERTEX,
@@ -240,7 +297,8 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, const std::vector<LLVector3>& norm)
{
U32 count = pos.size();
- llassert(norm.size() >= pos.size());
+ llassert_always(norm.size() >= pos.size());
+ llassert_always(count > 0) ;
unbind();
@@ -309,6 +367,7 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT,
idx);
stop_glerror();
+ placeFence();
}
void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
@@ -340,6 +399,7 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
glDrawElements(sGLMode[mode], count, GL_UNSIGNED_SHORT,
((U16*) getIndicesPointer()) + indices_offset);
stop_glerror();
+ placeFence();
}
void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
@@ -365,6 +425,7 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
stop_glerror();
glDrawArrays(sGLMode[mode], first, count);
stop_glerror();
+ placeFence();
}
//static
@@ -383,6 +444,11 @@ void LLVertexBuffer::initClass(bool use_vbo, bool no_vbo_mapping)
}
sDisableVBOMapping = sEnableVBOs && no_vbo_mapping ;
+
+ if(!sPrivatePoolp)
+ {
+ sPrivatePoolp = LLPrivateMemoryPoolManager::getInstance()->newPool(LLPrivateMemoryPool::STATIC) ;
+ }
}
//static
@@ -412,7 +478,11 @@ void LLVertexBuffer::cleanupClass()
unbind();
clientCopy(); // deletes GL buffers
- //llassert_always(!sCount) ;
+ if(sPrivatePoolp)
+ {
+ LLPrivateMemoryPoolManager::getInstance()->deletePool(sPrivatePoolp) ;
+ sPrivatePoolp = NULL ;
+ }
}
void LLVertexBuffer::clientCopy(F64 max_time)
@@ -444,9 +514,11 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
mFilthy(FALSE),
mEmpty(TRUE),
mResized(FALSE),
- mDynamicSize(FALSE)
+ mDynamicSize(FALSE),
+ mFence(NULL)
{
LLMemType mt2(LLMemType::MTYPE_VERTEX_CONSTRUCTOR);
+ mFence = NULL;
if (!sEnableVBOs)
{
mUsage = 0 ;
@@ -527,9 +599,40 @@ LLVertexBuffer::~LLVertexBuffer()
destroyGLIndices();
sCount--;
+ if (mFence)
+ {
+ delete mFence;
+ }
+
+ mFence = NULL;
+
llassert_always(!mMappedData && !mMappedIndexData) ;
};
+void LLVertexBuffer::placeFence() const
+{
+ /*if (!mFence && useVBOs())
+ {
+ if (gGLManager.mHasSync)
+ {
+ mFence = new LLGLSyncFence();
+ }
+ }
+
+ if (mFence)
+ {
+ mFence->placeFence();
+ }*/
+}
+
+void LLVertexBuffer::waitFence() const
+{
+ /*if (mFence)
+ {
+ mFence->wait();
+ }*/
+}
+
//----------------------------------------------------------------------------
void LLVertexBuffer::genBuffer()
@@ -629,7 +732,7 @@ void LLVertexBuffer::createGLBuffer()
{
static int gl_buffer_idx = 0;
mGLBuffer = ++gl_buffer_idx;
- mMappedData = (U8*) ll_aligned_malloc_16(size);
+ mMappedData = (U8*)ALLOCATE_MEM(sPrivatePoolp, size);
}
}
@@ -663,7 +766,7 @@ void LLVertexBuffer::createGLIndices()
}
else
{
- mMappedIndexData = (U8*) ll_aligned_malloc_16(size);
+ mMappedIndexData = (U8*)ALLOCATE_MEM(sPrivatePoolp, size);
static int gl_buffer_idx = 0;
mGLIndices = ++gl_buffer_idx;
}
@@ -686,7 +789,7 @@ void LLVertexBuffer::destroyGLBuffer()
}
else
{
- ll_aligned_free_16(mMappedData);
+ FREE_MEM(sPrivatePoolp, mMappedData) ;
mMappedData = NULL;
mEmpty = TRUE;
}
@@ -715,7 +818,7 @@ void LLVertexBuffer::destroyGLIndices()
}
else
{
- ll_aligned_free_16(mMappedIndexData);
+ FREE_MEM(sPrivatePoolp, mMappedIndexData) ;
mMappedIndexData = NULL;
mEmpty = TRUE;
}
@@ -848,8 +951,8 @@ void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices)
{
if (!useVBOs())
{
- ll_aligned_free_16(mMappedData);
- mMappedData = (U8*) ll_aligned_malloc_16(newsize);
+ FREE_MEM(sPrivatePoolp, mMappedData);
+ mMappedData = (U8*)ALLOCATE_MEM(sPrivatePoolp, newsize);
}
mResized = TRUE;
}
@@ -869,8 +972,8 @@ void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices)
{
if (!useVBOs())
{
- ll_aligned_free_16(mMappedIndexData);
- mMappedIndexData = (U8*) ll_aligned_malloc_16(new_index_size);
+ FREE_MEM(sPrivatePoolp, mMappedIndexData) ;
+ mMappedIndexData = (U8*)ALLOCATE_MEM(sPrivatePoolp, new_index_size);
}
mResized = TRUE;
}
@@ -892,17 +995,11 @@ BOOL LLVertexBuffer::useVBOs() const
{
//it's generally ineffective to use VBO for things that are streaming on apple
-#if LL_DARWIN
- if (!mUsage || mUsage == GL_STREAM_DRAW_ARB)
- {
- return FALSE;
- }
-#else
if (!mUsage)
{
return FALSE;
}
-#endif
+
return TRUE;
}
@@ -911,8 +1008,8 @@ void LLVertexBuffer::freeClientBuffer()
{
if(useVBOs() && sDisableVBOMapping && (mMappedData || mMappedIndexData))
{
- ll_aligned_free_16(mMappedData) ;
- ll_aligned_free_16(mMappedIndexData) ;
+ FREE_MEM(sPrivatePoolp, mMappedData) ;
+ FREE_MEM(sPrivatePoolp, mMappedIndexData) ;
mMappedData = NULL ;
mMappedIndexData = NULL ;
}
@@ -922,7 +1019,7 @@ void LLVertexBuffer::allocateClientVertexBuffer()
{
if(!mMappedData)
{
- mMappedData = (U8*)ll_aligned_malloc_16(getSize());
+ mMappedData = (U8*)ALLOCATE_MEM(sPrivatePoolp, getSize());
}
}
@@ -930,7 +1027,7 @@ void LLVertexBuffer::allocateClientIndexBuffer()
{
if(!mMappedIndexData)
{
- mMappedIndexData = (U8*)ll_aligned_malloc_16(getIndicesSize());
+ mMappedIndexData = (U8*)ALLOCATE_MEM(sPrivatePoolp, getIndicesSize());
}
}
@@ -967,8 +1064,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
if (useVBOs())
{
-
- if (sDisableVBOMapping || gGLManager.mHasMapBufferRange)
+ if (sDisableVBOMapping || gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange)
{
if (count == -1)
{
@@ -1008,6 +1104,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_VERTICES);
setBuffer(0, type);
mVertexLocked = TRUE;
+ sMappedCount++;
stop_glerror();
if(sDisableVBOMapping)
@@ -1018,29 +1115,50 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
else
{
U8* src = NULL;
-#ifdef GL_ARB_map_buffer_range
+ waitFence();
if (gGLManager.mHasMapBufferRange)
{
if (map_range)
{
+#ifdef GL_ARB_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, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_INVALIDATE_RANGE_BIT);
+ src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER_ARB, offset, length,
+ GL_MAP_WRITE_BIT |
+ GL_MAP_FLUSH_EXPLICIT_BIT |
+ GL_MAP_INVALIDATE_RANGE_BIT);
+#endif
}
else
{
- src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER_ARB, 0, mSize, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
+#ifdef GL_ARB_map_buffer_range
+ src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER_ARB, 0, mSize,
+ GL_MAP_WRITE_BIT |
+ GL_MAP_FLUSH_EXPLICIT_BIT);
+#endif
+ }
+ }
+ else if (gGLManager.mHasFlushBufferRange)
+ {
+ if (map_range)
+ {
+ glBufferParameteriAPPLE(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE);
+ glBufferParameteriAPPLE(GL_ARRAY_BUFFER_ARB, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE);
+ src = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+ }
+ else
+ {
+ src = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
}
}
else
-#else
- llassert_always(!gGLManager.mHasMapBufferRange);
-#endif
{
map_range = false;
src = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
}
+ llassert(src != NULL);
+
mMappedData = LL_NEXT_ALIGNED_ADDRESS<U8>(src);
mAlignedOffset = mMappedData - src;
@@ -1051,12 +1169,9 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
{
log_glerror();
- //check the availability of memory
- U32 avail_phy_mem, avail_vir_mem;
- LLMemoryInfo::getAvailableMemoryKB(avail_phy_mem, avail_vir_mem) ;
- llinfos << "Available physical mwmory(KB): " << avail_phy_mem << llendl ;
- llinfos << "Available virtual memory(KB): " << avail_vir_mem << llendl;
-
+ //check the availability of memory
+ LLMemory::logMemoryInfo(TRUE) ;
+
if(!sDisableVBOMapping)
{
//--------------------
@@ -1082,7 +1197,6 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
llerrs << "memory allocation for vertex data failed." << llendl ;
}
}
- sMappedCount++;
}
}
else
@@ -1090,7 +1204,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran
map_range = false;
}
- if (map_range && !sDisableVBOMapping)
+ if (map_range && gGLManager.mHasMapBufferRange && !sDisableVBOMapping)
{
return mMappedData;
}
@@ -1114,7 +1228,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
if (useVBOs())
{
- if (sDisableVBOMapping || gGLManager.mHasMapBufferRange)
+ if (sDisableVBOMapping || gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange)
{
if (count == -1)
{
@@ -1152,6 +1266,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
setBuffer(0, TYPE_INDEX);
mIndexLocked = TRUE;
+ sMappedCount++;
stop_glerror();
if(sDisableVBOMapping)
@@ -1162,29 +1277,51 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
else
{
U8* src = NULL;
-#ifdef GL_ARB_map_buffer_range
+ waitFence();
if (gGLManager.mHasMapBufferRange)
{
if (map_range)
{
+#ifdef GL_ARB_map_buffer_range
S32 offset = sizeof(U16)*index;
S32 length = sizeof(U16)*count;
- src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_INVALIDATE_RANGE_BIT);
+ src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length,
+ GL_MAP_WRITE_BIT |
+ GL_MAP_FLUSH_EXPLICIT_BIT |
+ GL_MAP_INVALIDATE_RANGE_BIT);
+#endif
+ }
+ else
+ {
+#ifdef GL_ARB_map_buffer_range
+ src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, sizeof(U16)*mNumIndices,
+ GL_MAP_WRITE_BIT |
+ GL_MAP_FLUSH_EXPLICIT_BIT);
+#endif
+ }
+ }
+ else if (gGLManager.mHasFlushBufferRange)
+ {
+ if (map_range)
+ {
+ glBufferParameteriAPPLE(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE);
+ glBufferParameteriAPPLE(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE);
+ src = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
}
else
{
- src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, sizeof(U16)*mNumIndices, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
+ src = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
}
}
else
-#else
- llassert_always(!gGLManager.mHasMapBufferRange);
-#endif
{
map_range = false;
src = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
}
+ llassert(src != NULL);
+
+
mMappedIndexData = src; //LL_NEXT_ALIGNED_ADDRESS<U8>(src);
mAlignedIndexOffset = mMappedIndexData - src;
stop_glerror();
@@ -1194,6 +1331,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
if (!mMappedIndexData)
{
log_glerror();
+ LLMemory::logMemoryInfo(TRUE) ;
if(!sDisableVBOMapping)
{
@@ -1211,15 +1349,13 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
llerrs << "memory allocation for Index data failed. " << llendl ;
}
}
-
- sMappedCount++;
}
else
{
map_range = false;
}
- if (map_range && !sDisableVBOMapping)
+ if (map_range && gGLManager.mHasMapBufferRange && !sDisableVBOMapping)
{
return mMappedIndexData;
}
@@ -1268,8 +1404,7 @@ void LLVertexBuffer::unmapBuffer(S32 type)
}
else
{
-#ifdef GL_ARB_map_buffer_range
- if (gGLManager.mHasMapBufferRange)
+ if (gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange)
{
if (!mMappedVertexRegions.empty())
{
@@ -1279,16 +1414,22 @@ void LLVertexBuffer::unmapBuffer(S32 type)
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;
- glFlushMappedBufferRange(GL_ARRAY_BUFFER_ARB, offset, length);
+ if (gGLManager.mHasMapBufferRange)
+ {
+#ifdef GL_ARB_map_buffer_range
+ glFlushMappedBufferRange(GL_ARRAY_BUFFER_ARB, offset, length);
+#endif
+ }
+ else if (gGLManager.mHasFlushBufferRange)
+ {
+ glFlushMappedBufferRangeAPPLE(GL_ARRAY_BUFFER_ARB, offset, length);
+ }
stop_glerror();
}
mMappedVertexRegions.clear();
}
}
-#else
- llassert_always(!gGLManager.mHasMapBufferRange);
-#endif
stop_glerror();
glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
stop_glerror();
@@ -1326,8 +1467,7 @@ void LLVertexBuffer::unmapBuffer(S32 type)
}
else
{
-#ifdef GL_ARB_map_buffer_range
- if (gGLManager.mHasMapBufferRange)
+ if (gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange)
{
if (!mMappedIndexRegions.empty())
{
@@ -1336,16 +1476,24 @@ void LLVertexBuffer::unmapBuffer(S32 type)
const MappedRegion& region = mMappedIndexRegions[i];
S32 offset = region.mIndex >= 0 ? sizeof(U16)*region.mIndex : 0;
S32 length = sizeof(U16)*region.mCount;
- glFlushMappedBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length);
+ if (gGLManager.mHasMapBufferRange)
+ {
+#ifdef GL_ARB_map_buffer_range
+ glFlushMappedBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length);
+#endif
+ }
+ else if (gGLManager.mHasFlushBufferRange)
+ {
+#ifdef GL_APPLE_flush_buffer_range
+ glFlushMappedBufferRangeAPPLE(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length);
+#endif
+ }
stop_glerror();
}
mMappedIndexRegions.clear();
}
}
-#else
- llassert_always(!gGLManager.mHasMapBufferRange);
-#endif
stop_glerror();
glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
stop_glerror();