diff options
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); | 
