diff options
| -rw-r--r-- | indra/llrender/llvertexbuffer.cpp | 458 | ||||
| -rw-r--r-- | indra/llrender/llvertexbuffer.h | 69 | ||||
| -rw-r--r-- | indra/newview/lldrawpoolavatar.cpp | 6 | ||||
| -rw-r--r-- | indra/newview/lldrawpooltree.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/llface.cpp | 13 | ||||
| -rw-r--r-- | indra/newview/llfloatermodelpreview.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llspatialpartition.cpp | 10 | ||||
| -rw-r--r-- | indra/newview/llviewerdisplay.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/llviewerwindow.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llvoavatar.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/llvowlsky.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/pipeline.cpp | 26 | 
12 files changed, 257 insertions, 345 deletions
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 4484a880cc..ad99bd1807 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -38,6 +38,17 @@  #include "llglslshader.h"  #include "llmemory.h" +//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 +U32 nhpo2(U32 v) +{ +	U32 r = 1; +	while (r < v) { +		r *= 2; +	} +	return r; +} +  //============================================================================ @@ -46,6 +57,7 @@ LLVBOPool LLVertexBuffer::sStreamVBOPool;  LLVBOPool LLVertexBuffer::sDynamicVBOPool;  LLVBOPool LLVertexBuffer::sStreamIBOPool;  LLVBOPool LLVertexBuffer::sDynamicIBOPool; +U32 LLVBOPool::sBytesPooled = 0;  LLPrivateMemoryPool* LLVertexBuffer::sPrivatePoolp = NULL ;  U32 LLVertexBuffer::sBindCount = 0; @@ -66,7 +78,6 @@ BOOL LLVertexBuffer::sMapped = FALSE;  BOOL LLVertexBuffer::sUseStreamDraw = TRUE;  BOOL LLVertexBuffer::sUseVAO = FALSE;  BOOL LLVertexBuffer::sPreferStreamDraw = FALSE; -std::vector<U32> LLVertexBuffer::sDeleteList;  const U32 FENCE_WAIT_TIME_NANOSECONDS = 10000;  //1 ms @@ -122,6 +133,107 @@ public:  }; + +//which power of 2 is i? +//assumes i is a power of 2 > 0 +U32 wpo2(U32 i) +{ +	llassert(i > 0); +	llassert(nhpo2(i) == i); + +	U32 r = 0; + +	while (i >>= 1) ++r; + +	return r; +} + +U8* LLVBOPool::allocate(U32& name, U32 size) +{ +	llassert(nhpo2(size) == size); + +	U32 i = wpo2(size); + +	if (mFreeList.size() <= i) +	{ +		mFreeList.resize(i+1); +	} + +	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) +		{ +			ret = (U8*) ll_aligned_malloc_16(size); +		} +		glBindBufferARB(mType, 0); +	} +	else +	{ +		name = mFreeList[i].front().mGLName; +		ret = mFreeList[i].front().mClientData; + +		sBytesPooled -= size; + +		mFreeList[i].pop_front(); +	} + +	return ret; +} + +void LLVBOPool::release(U32 name, U8* buffer, U32 size) +{ +	llassert(nhpo2(size) == size); + +	U32 i = wpo2(size); + +	llassert(mFreeList.size() > i); + +	Record rec; +	rec.mGLName = name; +	rec.mClientData = buffer; + +	sBytesPooled += size; + +	mFreeList[i].push_back(rec); +} + +void LLVBOPool::cleanup() +{ +	U32 size = 1; + +	for (U32 i = 0; i < mFreeList.size(); ++i) +	{ +		record_list_t& l = mFreeList[i]; + +		while (!l.empty()) +		{ +			Record& r = l.front(); + +			glDeleteBuffersARB(1, &r.mGLName); + +			if (r.mClientData) +			{ +				ll_aligned_free_16(r.mClientData); +			} + +			l.pop_front(); + +			LLVertexBuffer::sAllocatedBytes -= size; +		} + +		size *= 2; +	} +} + +  //NOTE: each component must be AT LEAST 4 bytes in size to avoid a performance penalty on AMD hardware  S32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] =  { @@ -374,16 +486,16 @@ void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVecto  void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_offset) const  { -	if (start >= (U32) mRequestedNumVerts || -	    end >= (U32) mRequestedNumVerts) +	if (start >= (U32) mNumVerts || +	    end >= (U32) mNumVerts)  	{ -		llerrs << "Bad vertex buffer draw range: [" << start << ", " << end << "] vs " << mRequestedNumVerts << llendl; +		llerrs << "Bad vertex buffer draw range: [" << start << ", " << end << "] vs " << mNumVerts << llendl;  	} -	llassert(mRequestedNumIndices >= 0); +	llassert(mNumIndices >= 0); -	if (indices_offset >= (U32) mRequestedNumIndices || -	    indices_offset + count > (U32) mRequestedNumIndices) +	if (indices_offset >= (U32) mNumIndices || +	    indices_offset + count > (U32) mNumIndices)  	{  		llerrs << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl;  	} @@ -407,7 +519,7 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi  	gGL.syncMatrices(); -	llassert(mRequestedNumVerts >= 0); +	llassert(mNumVerts >= 0);  	llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);  	if (mGLArray) @@ -462,9 +574,9 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const  	gGL.syncMatrices(); -	llassert(mRequestedNumIndices >= 0); -	if (indices_offset >= (U32) mRequestedNumIndices || -	    indices_offset + count > (U32) mRequestedNumIndices) +	llassert(mNumIndices >= 0); +	if (indices_offset >= (U32) mNumIndices || +	    indices_offset + count > (U32) mNumIndices)  	{  		llerrs << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl;  	} @@ -508,9 +620,9 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const  	gGL.syncMatrices(); -	llassert(mRequestedNumVerts >= 0); -	if (first >= (U32) mRequestedNumVerts || -	    first + count > (U32) mRequestedNumVerts) +	llassert(mNumVerts >= 0); +	if (first >= (U32) mNumVerts || +	    first + count > (U32) mNumVerts)  	{  		llerrs << "Bad vertex buffer draw range: [" << first << ", " << first+count << "]" << llendl;  	} @@ -546,23 +658,22 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const  void LLVertexBuffer::initClass(bool use_vbo, bool no_vbo_mapping)  {  	sEnableVBOs = use_vbo && gGLManager.mHasVertexBufferObject ; -	if(sEnableVBOs) -	{ -		//llassert_always(glBindBufferARB) ; //double check the extention for VBO is loaded. - -		llinfos << "VBO is enabled." << llendl ; -	} -	else -	{ -		llinfos << "VBO is disabled." << llendl ; -	} -  	sDisableVBOMapping = sEnableVBOs && no_vbo_mapping ;  	if(!sPrivatePoolp)  	{   		sPrivatePoolp = LLPrivateMemoryPoolManager::getInstance()->newPool(LLPrivateMemoryPool::STATIC) ;  	} + +	sStreamVBOPool.mType = GL_ARRAY_BUFFER_ARB; +	sStreamVBOPool.mUsage= GL_STREAM_DRAW_ARB; +	sStreamIBOPool.mType = GL_ELEMENT_ARRAY_BUFFER_ARB; +	sStreamIBOPool.mUsage= GL_STREAM_DRAW_ARB; + +	sDynamicVBOPool.mType = GL_ARRAY_BUFFER_ARB; +	sDynamicVBOPool.mUsage= GL_DYNAMIC_DRAW_ARB; +	sDynamicIBOPool.mType = GL_ELEMENT_ARRAY_BUFFER_ARB; +	sDynamicIBOPool.mUsage= GL_DYNAMIC_DRAW_ARB;  }  //static  @@ -600,7 +711,11 @@ void LLVertexBuffer::cleanupClass()  {  	LLMemType mt2(LLMemType::MTYPE_VERTEX_CLEANUP_CLASS);  	unbind(); -	clientCopy(); // deletes GL buffers +	 +	sStreamIBOPool.cleanup(); +	sDynamicIBOPool.cleanup(); +	sStreamVBOPool.cleanup(); +	sDynamicVBOPool.cleanup();  	if(sPrivatePoolp)  	{ @@ -609,15 +724,6 @@ void LLVertexBuffer::cleanupClass()  	}  } -void LLVertexBuffer::clientCopy(F64 max_time) -{ -	if (!sDeleteList.empty()) -	{ -		glDeleteBuffersARB(sDeleteList.size(), (GLuint*) &(sDeleteList[0])); -		sDeleteList.clear(); -	} -} -  //----------------------------------------------------------------------------  LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : @@ -625,8 +731,6 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :  	mNumVerts(0),  	mNumIndices(0), -	mRequestedNumVerts(-1), -	mRequestedNumIndices(-1),  	mUsage(usage),  	mGLBuffer(0),  	mGLArray(0), @@ -636,10 +740,7 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :  	mVertexLocked(FALSE),  	mIndexLocked(FALSE),  	mFinal(FALSE), -	mFilthy(FALSE),  	mEmpty(TRUE), -	mResized(FALSE), -	mDynamicSize(FALSE),  	mFence(NULL)  {  	LLMemType mt2(LLMemType::MTYPE_VERTEX_CONSTRUCTOR); @@ -664,6 +765,11 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :  		mUsage = GL_STREAM_DRAW_ARB;  	} +	if (mUsage && mUsage != GL_STREAM_DRAW_ARB) +	{ //only stream_draw and dynamic_draw are supported when using VBOs, dynamic draw is the default +		mUsage = GL_DYNAMIC_DRAW_ARB; +	} +		  	//zero out offsets  	for (U32 i = 0; i < TYPE_MAX; i++)  	{ @@ -672,6 +778,7 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :  	mTypeMask = typemask;  	mSize = 0; +	mIndicesSize = 0;  	mAlignedOffset = 0;  	mAlignedIndexOffset = 0; @@ -775,39 +882,35 @@ void LLVertexBuffer::waitFence() const  //---------------------------------------------------------------------------- -void LLVertexBuffer::genBuffer() +void LLVertexBuffer::genBuffer(U32 size)  { +	mSize = nhpo2(size); +  	if (mUsage == GL_STREAM_DRAW_ARB)  	{ -		mGLBuffer = sStreamVBOPool.allocate(); -	} -	else if (mUsage == GL_DYNAMIC_DRAW_ARB) -	{ -		mGLBuffer = sDynamicVBOPool.allocate(); +		mMappedData = sStreamVBOPool.allocate(mGLBuffer, mSize);  	}  	else  	{ -		BOOST_STATIC_ASSERT(sizeof(mGLBuffer) == sizeof(GLuint)); -		glGenBuffersARB(1, (GLuint*)&mGLBuffer); +		mMappedData = sDynamicVBOPool.allocate(mGLBuffer, mSize);  	} +	  	sGLCount++;  } -void LLVertexBuffer::genIndices() +void LLVertexBuffer::genIndices(U32 size)  { +	mIndicesSize = nhpo2(size); +  	if (mUsage == GL_STREAM_DRAW_ARB)  	{ -		mGLIndices = sStreamIBOPool.allocate(); -	} -	else if (mUsage == GL_DYNAMIC_DRAW_ARB) -	{ -		mGLIndices = sDynamicIBOPool.allocate(); +		mMappedIndexData = sStreamIBOPool.allocate(mGLIndices, mIndicesSize);  	}  	else  	{ -		BOOST_STATIC_ASSERT(sizeof(mGLBuffer) == sizeof(GLuint)); -		glGenBuffersARB(1, (GLuint*)&mGLIndices); +		mMappedIndexData = sDynamicIBOPool.allocate(mGLIndices, mIndicesSize);  	} +	  	sGLCount++;  } @@ -815,16 +918,16 @@ void LLVertexBuffer::releaseBuffer()  {  	if (mUsage == GL_STREAM_DRAW_ARB)  	{ -		sStreamVBOPool.release(mGLBuffer); -	} -	else if (mUsage == GL_DYNAMIC_DRAW_ARB) -	{ -		sDynamicVBOPool.release(mGLBuffer); +		sStreamVBOPool.release(mGLBuffer, mMappedData, mSize);  	}  	else  	{ -		sDeleteList.push_back(mGLBuffer); +		sDynamicVBOPool.release(mGLBuffer, mMappedData, mSize);  	} +	 +	mGLBuffer = 0; +	mMappedData = NULL; +  	sGLCount--;  } @@ -832,24 +935,23 @@ void LLVertexBuffer::releaseIndices()  {  	if (mUsage == GL_STREAM_DRAW_ARB)  	{ -		sStreamIBOPool.release(mGLIndices); +		sStreamIBOPool.release(mGLIndices, mMappedIndexData, mIndicesSize);  	}  	else if (mUsage == GL_DYNAMIC_DRAW_ARB)  	{ -		sDynamicIBOPool.release(mGLIndices); -	} -	else -	{ -		sDeleteList.push_back(mGLIndices); +		sDynamicIBOPool.release(mGLIndices, mMappedIndexData, mIndicesSize);  	} + +	mGLIndices = 0; +	mMappedIndexData = NULL; +	  	sGLCount--;  } -void LLVertexBuffer::createGLBuffer() +void LLVertexBuffer::createGLBuffer(U32 size)  {  	LLMemType mt2(LLMemType::MTYPE_VERTEX_CREATE_VERTICES); -	U32 size = getSize();  	if (mGLBuffer)  	{  		destroyGLBuffer(); @@ -864,23 +966,21 @@ void LLVertexBuffer::createGLBuffer()  	if (useVBOs())  	{ -		mMappedData = NULL; -		genBuffer(); -		mResized = TRUE; +		genBuffer(size);  	}  	else  	{  		static int gl_buffer_idx = 0;  		mGLBuffer = ++gl_buffer_idx;  		mMappedData = (U8*)ALLOCATE_MEM(sPrivatePoolp, size); +		mSize = size;  	}  } -void LLVertexBuffer::createGLIndices() +void LLVertexBuffer::createGLIndices(U32 size)  {  	LLMemType mt2(LLMemType::MTYPE_VERTEX_CREATE_INDICES); -	U32 size = getIndicesSize(); - +	  	if (mGLIndices)  	{  		destroyGLIndices(); @@ -900,15 +1000,14 @@ void LLVertexBuffer::createGLIndices()  	{  		//pad by another 16 bytes for VBO pointer adjustment  		size += 16; -		mMappedIndexData = NULL; -		genIndices(); -		mResized = TRUE; +		genIndices(size);  	}  	else  	{  		mMappedIndexData = (U8*)ALLOCATE_MEM(sPrivatePoolp, size);  		static int gl_buffer_idx = 0;  		mGLIndices = ++gl_buffer_idx; +		mIndicesSize = size;  	}  } @@ -919,12 +1018,6 @@ void LLVertexBuffer::destroyGLBuffer()  	{  		if (useVBOs())  		{ -			freeClientBuffer() ; - -			if (mMappedData || mMappedIndexData) -			{ -				llerrs << "Vertex buffer destroyed while mapped!" << llendl; -			}  			releaseBuffer();  		}  		else @@ -933,8 +1026,6 @@ void LLVertexBuffer::destroyGLBuffer()  			mMappedData = NULL;  			mEmpty = TRUE;  		} - -		sAllocatedBytes -= getSize();  	}  	mGLBuffer = 0; @@ -948,12 +1039,6 @@ void LLVertexBuffer::destroyGLIndices()  	{  		if (useVBOs())  		{ -			freeClientBuffer() ; - -			if (mMappedData || mMappedIndexData) -			{ -				llerrs << "Vertex buffer destroyed while mapped." << llendl; -			}  			releaseIndices();  		}  		else @@ -962,8 +1047,6 @@ void LLVertexBuffer::destroyGLIndices()  			mMappedIndexData = NULL;  			mEmpty = TRUE;  		} - -		sAllocatedBytes -= getIndicesSize();  	}  	mGLIndices = 0; @@ -982,23 +1065,14 @@ void LLVertexBuffer::updateNumVerts(S32 nverts)  		nverts = 65535;  	} -	mRequestedNumVerts = nverts; +	U32 needed_size = calcOffsets(mTypeMask, mOffsets, nverts); -	if (!mDynamicSize) +	if (needed_size > mSize || needed_size <= mSize/2)  	{ -		mNumVerts = nverts; -	} -	else if (mUsage == GL_STATIC_DRAW_ARB || -		nverts > mNumVerts || -		nverts < mNumVerts/2) -	{ -		if (mUsage != GL_STATIC_DRAW_ARB && nverts + nverts/4 <= 65535) -		{ -			nverts += nverts/4; -		} -		mNumVerts = nverts; +		createGLBuffer(needed_size);  	} -	mSize = calcOffsets(mTypeMask, mOffsets, mNumVerts); + +	mNumVerts = nverts;  }  void LLVertexBuffer::updateNumIndices(S32 nindices) @@ -1007,22 +1081,14 @@ void LLVertexBuffer::updateNumIndices(S32 nindices)  	llassert(nindices >= 0); -	mRequestedNumIndices = nindices; -	if (!mDynamicSize) +	U32 needed_size = sizeof(U16) * nindices; + +	if (needed_size > mIndicesSize || needed_size <= mIndicesSize/2)  	{ -		mNumIndices = nindices; +		createGLIndices(needed_size);  	} -	else if (mUsage == GL_STATIC_DRAW_ARB || -		nindices > mNumIndices || -		nindices < mNumIndices/2) -	{ -		if (mUsage != GL_STATIC_DRAW_ARB) -		{ -			nindices += nindices/4; -		} -		mNumIndices = nindices; -	} +	mNumIndices = nindices;  }  void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create) @@ -1040,15 +1106,8 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)  	updateNumVerts(nverts);  	updateNumIndices(nindices); -	if (mMappedData) -	{ -		llerrs << "LLVertexBuffer::allocateBuffer() called redundantly." << llendl; -	}  	if (create && (nverts || nindices))  	{ -		createGLBuffer(); -		createGLIndices(); -  		//actually allocate space for the vertex buffer if using VBO mapping  		flush(); @@ -1060,8 +1119,6 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)  			setupVertexArray();  		}  	} -	 -	sAllocatedBytes += getSize() + getIndicesSize();  }  void LLVertexBuffer::setupVertexArray() @@ -1151,77 +1208,13 @@ void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices)  	llassert(newnverts >= 0);  	llassert(newnindices >= 0); -	mRequestedNumVerts = newnverts; -	mRequestedNumIndices = newnindices; -  	LLMemType mt2(LLMemType::MTYPE_VERTEX_RESIZE_BUFFER); -	mDynamicSize = TRUE; -	if (mUsage == GL_STATIC_DRAW_ARB) -	{ //always delete/allocate static buffers on resize -		destroyGLBuffer(); -		destroyGLIndices(); -		allocateBuffer(newnverts, newnindices, TRUE); -		mFinal = FALSE; -	} -	else if (newnverts > mNumVerts || newnindices > mNumIndices || -			 newnverts < mNumVerts/2 || newnindices < mNumIndices/2) -	{ -		sAllocatedBytes -= getSize() + getIndicesSize(); -		 -		updateNumVerts(newnverts);		 -		updateNumIndices(newnindices); -		 -		S32 newsize = getSize(); -		S32 new_index_size = getIndicesSize(); - -		sAllocatedBytes += newsize + new_index_size; - -		if (newsize) -		{ -			if (!mGLBuffer) -			{ //no buffer exists, create a new one -				createGLBuffer(); -			} -			else -			{ -				if (!useVBOs()) -				{ -					FREE_MEM(sPrivatePoolp, mMappedData); -					mMappedData = (U8*)ALLOCATE_MEM(sPrivatePoolp, newsize); -				} -				mResized = TRUE; -			} -		} -		else if (mGLBuffer) -		{ -			destroyGLBuffer(); -		} -		 -		if (new_index_size) -		{ -			if (!mGLIndices) -			{ -				createGLIndices(); -			} -			else -			{ -				if (!useVBOs()) -				{ -					FREE_MEM(sPrivatePoolp, mMappedIndexData) ; -					mMappedIndexData = (U8*)ALLOCATE_MEM(sPrivatePoolp, new_index_size); -				} -				mResized = TRUE; -			} -		} -		else if (mGLIndices) -		{ -			destroyGLIndices(); -		} -	} - -	if (mResized && useVBOs()) +	 +	updateNumVerts(newnverts);		 +	updateNumIndices(newnindices); +	 +	if (useVBOs())  	{ -		freeClientBuffer();  		flush();  		if (mGLArray) @@ -1244,32 +1237,6 @@ BOOL LLVertexBuffer::useVBOs() const  }  //---------------------------------------------------------------------------- -void LLVertexBuffer::freeClientBuffer() -{ -	if(useVBOs() && sDisableVBOMapping && (mMappedData || mMappedIndexData)) -	{ -		FREE_MEM(sPrivatePoolp, mMappedData) ; -		FREE_MEM(sPrivatePoolp, mMappedIndexData) ; -		mMappedData = NULL ; -		mMappedIndexData = NULL ; -	} -} - -void LLVertexBuffer::allocateClientVertexBuffer() -{ -	if(!mMappedData) -	{ -		mMappedData = (U8*)ALLOCATE_MEM(sPrivatePoolp, getSize()); -	} -} - -void LLVertexBuffer::allocateClientIndexBuffer() -{ -	if(!mMappedIndexData) -	{ -		mMappedIndexData = (U8*)ALLOCATE_MEM(sPrivatePoolp, getIndicesSize());		 -	} -}  bool expand_region(LLVertexBuffer::MappedRegion& region, S32 index, S32 count)  { @@ -1350,7 +1317,6 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran  			if(sDisableVBOMapping)  			{  				map_range = false; -				allocateClientVertexBuffer() ;  			}  			else  			{ @@ -1535,7 +1501,6 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)  			if(sDisableVBOMapping)  			{  				map_range = false; -				allocateClientIndexBuffer() ;  			}  			else  			{ @@ -1772,21 +1737,7 @@ void LLVertexBuffer::unmapBuffer()  	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) -			{ -				freeClientBuffer() ; -			} -		} -		else -		{ -			mEmpty = FALSE; -		} +		mEmpty = FALSE;  	}  } @@ -1965,27 +1916,6 @@ void LLVertexBuffer::flush()  {  	if (useVBOs())  	{ -		if (mResized) -		{ -			if (mGLBuffer) -			{ -				stop_glerror(); -				bindGLBuffer(true); -				glBufferDataARB(GL_ARRAY_BUFFER_ARB, getSize(), NULL, mUsage); -				stop_glerror(); -			} -			if (mGLIndices) -			{ -				stop_glerror(); -				bindGLIndices(true); -				glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, getIndicesSize(), NULL, mUsage); -				stop_glerror(); -			} - -			mEmpty = TRUE; -			mResized = FALSE; -		} -  		unmapBuffer();  	}  } diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index b50c409c49..3e6f6a959a 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -51,24 +51,32 @@  //============================================================================  // gl name pools for dynamic and streaming buffers -class LLVBOPool : public LLGLNamePool +class LLVBOPool  { -protected: -	virtual GLuint allocateName() -	{ -		GLuint name; -		stop_glerror(); -		glGenBuffersARB(1, &name); -		stop_glerror(); -		return name; -	} +public: +	static U32 sBytesPooled; + +	U32 mUsage; +	U32 mType; -	virtual void releaseName(GLuint name) +	//size MUST be a power of 2 +	U8* allocate(U32& name, U32 size); +	 +	//size MUST be the size provided to allocate that returned the given name +	void release(U32 name, U8* buffer, U32 size); +	 +	//destroy all records in mFreeList +	void cleanup(); + +	class Record  	{ -		stop_glerror(); -		glDeleteBuffersARB(1, &name); -		stop_glerror(); -	} +	public: +		U32 mGLName; +		U8* mClientData; +	}; + +	typedef std::list<Record> record_list_t; +	std::vector<record_list_t> mFreeList;  };  class LLGLFence @@ -120,8 +128,7 @@ public:  	static void drawArrays(U32 mode, const std::vector<LLVector3>& pos, const std::vector<LLVector3>& norm);  	static void drawElements(U32 mode, const LLVector4a* pos, const LLVector2* tc, S32 num_indices, const U16* indicesp); - 	static void clientCopy(F64 max_time = 0.005); //copy data from client to GL -	static void unbind(); //unbind any bound vertex buffer + 	static void unbind(); //unbind any bound vertex buffer  	//get the size of a vertex with the given typemask  	static S32 calcVertexSize(const U32& typemask); @@ -181,25 +188,22 @@ protected:  	virtual void setupVertexBuffer(U32 data_mask); // pure virtual, called from mapBuffer()  	void setupVertexArray(); -	void	genBuffer(); -	void	genIndices(); +	void	genBuffer(U32 size); +	void	genIndices(U32 size);  	bool	bindGLBuffer(bool force_bind = false);  	bool	bindGLIndices(bool force_bind = false);  	bool	bindGLArray();  	void	releaseBuffer();  	void	releaseIndices(); -	void	createGLBuffer(); -	void	createGLIndices(); +	void	createGLBuffer(U32 size); +	void	createGLIndices(U32 size);  	void 	destroyGLBuffer();  	void 	destroyGLIndices();  	void	updateNumVerts(S32 nverts);  	void	updateNumIndices(S32 nindices);   	virtual BOOL	useVBOs() const;  	void	unmapBuffer(); -	void freeClientBuffer() ; -	void allocateClientVertexBuffer() ; -	void allocateClientIndexBuffer() ; - +		  public:  	LLVertexBuffer(U32 typemask, S32 usage); @@ -239,15 +243,13 @@ public:  	BOOL isLocked() const					{ return mVertexLocked || mIndexLocked; }  	S32 getNumVerts() const					{ return mNumVerts; }  	S32 getNumIndices() const				{ return mNumIndices; } -	S32 getRequestedVerts() const			{ return mRequestedNumVerts; } -	S32 getRequestedIndices() const			{ return mRequestedNumIndices; } - +	  	U8* getIndicesPointer() const			{ return useVBOs() ? (U8*) mAlignedIndexOffset : mMappedIndexData; }  	U8* getVerticesPointer() const			{ return useVBOs() ? (U8*) mAlignedOffset : mMappedData; }  	U32 getTypeMask() const					{ return mTypeMask; }  	bool hasDataType(S32 type) const		{ return ((1 << type) & getTypeMask()); }  	S32 getSize() const; -	S32 getIndicesSize() const				{ return mNumIndices * sizeof(U16); } +	S32 getIndicesSize() const				{ return mIndicesSize; }  	U8* getMappedData() const				{ return mMappedData; }  	U8* getMappedIndices() const			{ return mMappedIndexData; }  	S32 getOffset(S32 type) const			{ return mOffsets[type]; } @@ -265,12 +267,11 @@ public:  protected:	  	S32		mNumVerts;		// Number of vertices allocated  	S32		mNumIndices;	// Number of indices allocated -	S32		mRequestedNumVerts;  // Number of vertices requested -	S32		mRequestedNumIndices;  // Number of indices requested - +	  	ptrdiff_t mAlignedOffset;  	ptrdiff_t mAlignedIndexOffset;  	S32		mSize; +	S32		mIndicesSize;  	U32		mTypeMask;  	S32		mUsage;			// GL usage  	U32		mGLBuffer;		// GL VBO handle @@ -282,10 +283,7 @@ protected:  	BOOL	mVertexLocked;			// if TRUE, vertex buffer is being or has been written to in client memory  	BOOL	mIndexLocked;			// if TRUE, index buffer is being or has been written to in client memory  	BOOL	mFinal;			// if TRUE, buffer can not be mapped again -	BOOL	mFilthy;		// if TRUE, entire buffer must be copied (used to prevent redundant dirty flags)  	BOOL	mEmpty;			// if TRUE, client buffer is empty (or NULL). Old values have been discarded.	 -	BOOL	mResized;		// if TRUE, client buffer has been resized and GL buffer has not -	BOOL	mDynamicSize;	// if TRUE, buffer has been resized at least once (and should be padded)  	S32		mOffsets[TYPE_MAX];  	std::vector<MappedRegion> mMappedVertexRegions; @@ -305,7 +303,6 @@ public:  	static S32 sGLCount;  	static S32 sMappedCount;  	static BOOL sMapped; -	static std::vector<U32> sDeleteList;  	typedef std::list<LLVertexBuffer*> buffer_list_t;  	static BOOL sDisableVBOMapping; //disable glMapBufferARB diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index a710bdcdbd..7290a48a1a 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1277,8 +1277,8 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*  	if (buffer.isNull() ||   		buffer->getTypeMask() != data_mask || -		buffer->getRequestedVerts() != vol_face.mNumVertices || -		buffer->getRequestedIndices() != vol_face.mNumIndices || +		buffer->getNumVerts() != vol_face.mNumVertices || +		buffer->getNumIndices() != vol_face.mNumIndices ||  		(drawable && drawable->isState(LLDrawable::REBUILD_ALL)))  	{  		face->setGeomIndex(0); @@ -1366,7 +1366,7 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*  		LLMatrix4a bind_shape_matrix;  		bind_shape_matrix.loadu(skin->mBindShapeMatrix); -		for (U32 j = 0; j < buffer->getRequestedVerts(); ++j) +		for (U32 j = 0; j < buffer->getNumVerts(); ++j)  		{  			LLMatrix4a final_mat;  			final_mat.clear(); diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp index 3fe5b4d929..cdf6e1ab52 100644 --- a/indra/newview/lldrawpooltree.cpp +++ b/indra/newview/lldrawpooltree.cpp @@ -113,8 +113,8 @@ void LLDrawPoolTree::render(S32 pass)  			if(buff)  			{  				buff->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK); -				buff->drawRange(LLRender::TRIANGLES, 0, buff->getRequestedVerts()-1, buff->getRequestedIndices(), 0);  -				gPipeline.addTrianglesDrawn(buff->getRequestedIndices()); +				buff->drawRange(LLRender::TRIANGLES, 0, buff->getNumVerts()-1, buff->getNumIndices(), 0);  +				gPipeline.addTrianglesDrawn(buff->getNumIndices());  			}  		}  	} diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 36b88ebbd4..eab3dcfadd 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -362,8 +362,8 @@ void LLFace::setSize(S32 num_vertices, S32 num_indices, bool align)  {  	if (align)  	{ -		//allocate vertices in blocks of 16 for alignment -		num_vertices = (num_vertices + 0xF) & ~0xF; +		//allocate vertices in blocks of 4 for alignment +		num_vertices = (num_vertices + 0x3) & ~0x3;  	}  	if (mGeomCount != num_vertices || @@ -1073,6 +1073,11 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  	S32 num_vertices = (S32)vf.mNumVertices;  	S32 num_indices = (S32) vf.mNumIndices; +	if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCTREE)) +	{ +		updateRebuildFlags(); +	} +  	bool map_range = gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange;  	if (mVertexBuffer.notNull()) @@ -2055,7 +2060,7 @@ BOOL LLFace::verify(const U32* indices_array) const  	}  	// First, check whether the face data fits within the pool's range. -	if ((mGeomIndex + mGeomCount) > mVertexBuffer->getRequestedVerts()) +	if ((mGeomIndex + mGeomCount) > mVertexBuffer->getNumVerts())  	{  		ok = FALSE;  		llinfos << "Face references invalid vertices!" << llendl; @@ -2074,7 +2079,7 @@ BOOL LLFace::verify(const U32* indices_array) const  		llinfos << "Face has bogus indices count" << llendl;  	} -	if (mIndicesIndex + mIndicesCount > mVertexBuffer->getRequestedIndices()) +	if (mIndicesIndex + mIndicesCount > mVertexBuffer->getNumIndices())  	{  		ok = FALSE;  		llinfos << "Face references invalid indices!" << llendl; diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index d9ce72a2c2..8f6013f2d9 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -5457,7 +5457,7 @@ BOOL LLModelPreview::render()  								}  							} -							for (U32 j = 0; j < buffer->getRequestedVerts(); ++j) +							for (U32 j = 0; j < buffer->getNumVerts(); ++j)  							{  								LLMatrix4 final_mat;  								final_mat.mMatrix[0][0] = final_mat.mMatrix[1][1] = final_mat.mMatrix[2][2] = final_mat.mMatrix[3][3] = 0.f; diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index ffb0ce4056..2530f1f0d4 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -2454,7 +2454,7 @@ void pushBufferVerts(LLVertexBuffer* buffer, U32 mask)  	if (buffer)  	{  		buffer->setBuffer(mask); -		buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getRequestedVerts()-1, buffer->getRequestedIndices(), 0); +		buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);  	}  } @@ -2526,7 +2526,7 @@ void renderOctree(LLSpatialGroup* group)  	//coded by buffer usage and activity  	gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);  	LLVector4 col; -	/*if (group->mBuilt > 0.f) +	if (group->mBuilt > 0.f)  	{  		group->mBuilt -= 2.f * gFrameIntervalSeconds;  		if (group->mBufferUsage == GL_STATIC_DRAW_ARB) @@ -2595,7 +2595,7 @@ void renderOctree(LLSpatialGroup* group)  			gGL.diffuseColor4f(1,1,1,1);  		}  	} -	else*/ +	else  	{  		if (group->mBufferUsage == GL_STATIC_DRAW_ARB && !group->getData().empty()   			&& group->mSpatialPartition->mRenderByGroup) @@ -3442,11 +3442,11 @@ void renderPhysicsShapes(LLSpatialGroup* group)  						buff->setBuffer(LLVertexBuffer::MAP_VERTEX);  						gGL.diffuseColor3f(0.2f, 0.5f, 0.3f); -						buff->draw(LLRender::TRIANGLES, buff->getRequestedIndices(), 0); +						buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0);  						gGL.diffuseColor3f(0.2f, 1.f, 0.3f);  						glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); -						buff->draw(LLRender::TRIANGLES, buff->getRequestedIndices(), 0); +						buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0);  					}  				}  			} diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 1832416a4b..e0359cc61d 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -661,10 +661,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  		{   			LLMemType mt_ds(LLMemType::MTYPE_DISPLAY_SWAP); -			{ - 				LLFastTimer ftm(FTM_CLIENT_COPY); -				LLVertexBuffer::clientCopy(0.016); -			}  			if (gResizeScreenTexture)  			{ diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 2aac43d99e..f3e9bc711a 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -532,7 +532,7 @@ public:  			} -			addText(xpos, ypos, llformat("%d MB Vertex Data", LLVertexBuffer::sAllocatedBytes/(1024*1024))); +			addText(xpos, ypos, llformat("%d MB Vertex Data (%d MB Pooled)", LLVertexBuffer::sAllocatedBytes/(1024*1024), LLVBOPool::sBytesPooled/(1024*1024)));  			ypos += y_inc;  			addText(xpos, ypos, llformat("%d Vertex Buffers", LLVertexBuffer::sGLCount)); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 5687ba5064..6506938766 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -2117,8 +2117,8 @@ void LLVOAvatar::updateMeshData()  			}  			else  			{ -				if (buff->getRequestedIndices() == num_indices && -					buff->getRequestedVerts() == num_vertices) +				if (buff->getNumIndices() == num_indices && +					buff->getNumVerts() == num_vertices)  				{  					terse_update = true;  				} diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp index 14fd0a1eb1..f1c5499d84 100644 --- a/indra/newview/llvowlsky.cpp +++ b/indra/newview/llvowlsky.cpp @@ -516,9 +516,9 @@ void LLVOWLSky::drawDome(void)  		strips_segment->drawRange(  			LLRender::TRIANGLE_STRIP,  -			0, strips_segment->getRequestedVerts()-1, strips_segment->getRequestedIndices(),  +			0, strips_segment->getNumVerts()-1, strips_segment->getNumIndices(),   			0); -		gPipeline.addTrianglesDrawn(strips_segment->getRequestedIndices(), LLRender::TRIANGLE_STRIP); +		gPipeline.addTrianglesDrawn(strips_segment->getNumIndices(), LLRender::TRIANGLE_STRIP);  	}  #else diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index e4125c8dc8..5035e0197d 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -264,15 +264,7 @@ std::string gPoolNames[] =  void drawBox(const LLVector3& c, const LLVector3& r);  void drawBoxOutline(const LLVector3& pos, const LLVector3& size); - -U32 nhpo2(U32 v)  -{ -	U32 r = 1; -	while (r < v) { -		r *= 2; -	} -	return r; -} +U32 nhpo2(U32 v);  glh::matrix4f glh_copy_matrix(F32* src)  { @@ -2902,11 +2894,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)  			}  		}  	} -	{ -		LLFastTimer ftm(FTM_CLIENT_COPY); -		LLVertexBuffer::clientCopy(); -	} -	 +		  	postSort(camera);	  } @@ -6122,13 +6110,7 @@ void LLPipeline::resetVertexBuffers()  		llwarns << "VBO wipe failed." << llendl;  	} -	if (!LLVertexBuffer::sStreamIBOPool.mNameList.empty() || -		!LLVertexBuffer::sStreamVBOPool.mNameList.empty() || -		!LLVertexBuffer::sDynamicIBOPool.mNameList.empty() || -		!LLVertexBuffer::sDynamicVBOPool.mNameList.empty()) -	{ -		llwarns << "VBO name pool cleanup failed." << llendl; -	} +	llassert(LLVertexBuffer::sGLCount == 0);  	LLVertexBuffer::unbind();	 @@ -6142,6 +6124,8 @@ void LLPipeline::resetVertexBuffers()  	sBakeSunlight = gSavedSettings.getBOOL("RenderBakeSunlight");  	sNoAlpha = gSavedSettings.getBOOL("RenderNoAlpha");  	LLPipeline::sTextureBindTest = gSavedSettings.getBOOL("RenderDebugTextureBind"); + +	LLVertexBuffer::initClass(LLVertexBuffer::sEnableVBOs, LLVertexBuffer::sDisableVBOMapping);  }  void LLPipeline::renderObjects(U32 type, U32 mask, BOOL texture)  | 
