diff options
author | Dave Parks <davep@lindenlab.com> | 2012-05-15 16:42:04 -0500 |
---|---|---|
committer | Dave Parks <davep@lindenlab.com> | 2012-05-15 16:42:04 -0500 |
commit | 89b0b6ac7198653d989dea78ee1c3d3f4f61161f (patch) | |
tree | 03184fb7c5723a766182a2fcfa0b86340e3761e1 /indra/llrender | |
parent | f1f9b1c3b73b245fef3c976a9a1d71009bdbf3e0 (diff) |
MAINT-616 Different VBO Pooling scheme -- populate VBO pool with buffers that are likely to be requested, but never reuse a previously used buffer.
Diffstat (limited to 'indra/llrender')
-rw-r--r-- | indra/llrender/llvertexbuffer.cpp | 79 | ||||
-rw-r--r-- | indra/llrender/llvertexbuffer.h | 16 |
2 files changed, 85 insertions, 10 deletions
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 1b179bdbb1..7b12304967 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -38,7 +38,7 @@ #include "llglslshader.h" #include "llmemory.h" -#define LL_VBO_POOLING 0 +#define LL_VBO_POOLING 1 //Next Highest Power Of Two //helper function, returns first number > v that is a power of 2, or v if v is already a power of 2 @@ -67,6 +67,7 @@ U32 wpo2(U32 i) 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? @@ -79,6 +80,7 @@ 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); //============================================================================ @@ -169,8 +171,15 @@ public: }; +LLVBOPool::LLVBOPool(U32 vboUsage, U32 vboType) +: mUsage(vboUsage), mType(vboType) +{ + mMissCount.resize(LL_VBO_POOL_SEED_COUNT); + std::fill(mMissCount.begin(), mMissCount.end(), 0); +} + -volatile U8* LLVBOPool::allocate(U32& name, U32 size) +volatile U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed) { llassert(vbo_block_size(size) == size); @@ -183,14 +192,20 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size) if (mFreeList.size() <= i) { mFreeList.resize(i+1); + mMissCount.resize(i+1); } - if (mFreeList[i].empty()) + if (mFreeList[i].empty() || for_seed) { //make a new buffer glGenBuffersARB(1, &name); glBindBufferARB(mType, name); + if (!for_seed && i < LL_VBO_POOL_SEED_COUNT) + { //record this miss + mMissCount[i]++; + } + if (mType == GL_ARRAY_BUFFER_ARB) { LLVertexBuffer::sAllocatedBytes += size; @@ -211,6 +226,25 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size) } 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 { @@ -263,7 +297,7 @@ void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size) { llassert(vbo_block_size(size) == size); -#if LL_VBO_POOLING +#if 0 && LL_VBO_POOLING U32 i = vbo_block_index(size); @@ -304,6 +338,31 @@ void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size) #endif } +void LLVBOPool::seedPool() +{ + U32 dummy_name = 0; + + if (mFreeList.size() < LL_VBO_POOL_SEED_COUNT) + { + mFreeList.resize(LL_VBO_POOL_SEED_COUNT); + } + + 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; @@ -339,6 +398,9 @@ void LLVBOPool::cleanup() size *= 2; } + + //reset miss counts + std::fill(mMissCount.begin(), mMissCount.end(), 0); } @@ -374,6 +436,15 @@ U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] = //static +void LLVertexBuffer::seedPools() +{ + sStreamVBOPool.seedPool(); + sDynamicVBOPool.seedPool(); + sStreamIBOPool.seedPool(); + sDynamicIBOPool.seedPool(); +} + +//static void LLVertexBuffer::setupClientArrays(U32 data_mask) { if (sLastMask != data_mask) diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index 7477dec3ad..a64daa1a90 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -57,20 +57,20 @@ public: static U32 sBytesPooled; static U32 sIndexBytesPooled; - LLVBOPool(U32 vboUsage, U32 vboType) - : mUsage(vboUsage) - , mType(vboType) - {} - + LLVBOPool(U32 vboUsage, U32 vboType); + const U32 mUsage; const U32 mType; //size MUST be a power of 2 - volatile U8* allocate(U32& name, U32 size); + volatile U8* allocate(U32& name, U32 size, bool for_seed = false); //size MUST be the size provided to allocate that returned the given name void release(U32 name, volatile U8* buffer, U32 size); + //batch allocate buffers to be provided to the application on demand + void seedPool(); + //destroy all records in mFreeList void cleanup(); @@ -83,6 +83,8 @@ public: typedef std::list<Record> record_list_t; std::vector<record_list_t> mFreeList; + std::vector<U32> mMissCount; + }; class LLGLFence @@ -129,6 +131,8 @@ public: static bool sUseVAO; static bool sPreferStreamDraw; + static void seedPools(); + static void initClass(bool use_vbo, bool no_vbo_mapping); static void cleanupClass(); static void setupClientArrays(U32 data_mask); |