diff options
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llrender/llgl.cpp | 33 | ||||
| -rw-r--r-- | indra/llrender/llgl.h | 2 | ||||
| -rw-r--r-- | indra/llrender/llglheaders.h | 39 | ||||
| -rw-r--r-- | indra/llrender/llvertexbuffer.cpp | 221 | ||||
| -rw-r--r-- | indra/llrender/llvertexbuffer.h | 12 | ||||
| -rw-r--r-- | indra/newview/featuretable.txt | 6 | ||||
| -rw-r--r-- | indra/newview/featuretable_linux.txt | 6 | ||||
| -rw-r--r-- | indra/newview/featuretable_mac.txt | 13 | ||||
| -rw-r--r-- | indra/newview/featuretable_xp.txt | 6 | ||||
| -rw-r--r-- | indra/newview/lldrawable.cpp | 5 | ||||
| -rw-r--r-- | indra/newview/llface.cpp | 64 | ||||
| -rw-r--r-- | indra/newview/llfeaturemanager.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/llvovolume.cpp | 38 | 
13 files changed, 348 insertions, 101 deletions
| diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index c224ab0e9b..e07ff0015c 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -128,9 +128,21 @@ PFNGLGETBUFFERPARAMETERIVARBPROC	glGetBufferParameterivARB = NULL;  PFNGLGETBUFFERPOINTERVARBPROC		glGetBufferPointervARB = NULL;  // GL_ARB_map_buffer_range -PFNGLMAPBUFFERRANGEPROC			glMapBufferRange; -PFNGLFLUSHMAPPEDBUFFERRANGEPROC	glFlushMappedBufferRange; - +PFNGLMAPBUFFERRANGEPROC			glMapBufferRange = NULL; +PFNGLFLUSHMAPPEDBUFFERRANGEPROC	glFlushMappedBufferRange = NULL; + +// GL_ARB_sync +PFNGLFENCESYNCPROC				glFenceSync = NULL; +PFNGLISSYNCPROC					glIsSync = NULL; +PFNGLDELETESYNCPROC				glDeleteSync = NULL; +PFNGLCLIENTWAITSYNCPROC			glClientWaitSync = NULL; +PFNGLWAITSYNCPROC				glWaitSync = NULL; +PFNGLGETINTEGER64VPROC			glGetInteger64v = NULL; +PFNGLGETSYNCIVPROC				glGetSynciv = NULL; + +// GL_APPLE_flush_buffer_range +PFNGLBUFFERPARAMETERIAPPLEPROC	glBufferParameteriAPPLE = NULL; +PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC glFlushMappedBufferRangeAPPLE = NULL;  // vertex object prototypes  PFNGLNEWOBJECTBUFFERATIPROC			glNewObjectBufferATI = NULL; @@ -334,9 +346,10 @@ LLGLManager::LLGLManager() :  	mHasFramebufferObject(FALSE),  	mMaxSamples(0),  	mHasBlendFuncSeparate(FALSE), - +	mHasSync(FALSE),  	mHasVertexBufferObject(FALSE),  	mHasMapBufferRange(FALSE), +	mHasFlushBufferRange(FALSE),  	mHasPBuffer(FALSE),  	mHasShaderObjects(FALSE),  	mHasVertexShader(FALSE), @@ -774,7 +787,9 @@ void LLGLManager::initExtensions()  	mHasOcclusionQuery = ExtensionExists("GL_ARB_occlusion_query", gGLHExts.mSysExts);  	mHasOcclusionQuery2 = ExtensionExists("GL_ARB_occlusion_query2", gGLHExts.mSysExts);  	mHasVertexBufferObject = ExtensionExists("GL_ARB_vertex_buffer_object", gGLHExts.mSysExts); +	mHasSync = ExtensionExists("GL_ARB_sync", gGLHExts.mSysExts);  	mHasMapBufferRange = ExtensionExists("GL_ARB_map_buffer_range", gGLHExts.mSysExts); +	mHasFlushBufferRange = ExtensionExists("GL_APPLE_flush_buffer_range", gGLHExts.mSysExts);  	mHasDepthClamp = ExtensionExists("GL_ARB_depth_clamp", gGLHExts.mSysExts) || ExtensionExists("GL_NV_depth_clamp", gGLHExts.mSysExts);  	// mask out FBO support when packed_depth_stencil isn't there 'cause we need it for LLRenderTarget -Brad  #ifdef GL_ARB_framebuffer_object @@ -969,6 +984,16 @@ void LLGLManager::initExtensions()  			mHasVertexBufferObject = FALSE;  		}  	} +	if (mHasSync) +	{ +		glFenceSync = (PFNGLFENCESYNCPROC) GLH_EXT_GET_PROC_ADDRESS("glFenceSync");
 +		glIsSync = (PFNGLISSYNCPROC) GLH_EXT_GET_PROC_ADDRESS("glIsSync");
 +		glDeleteSync = (PFNGLDELETESYNCPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteSync");
 +		glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC) GLH_EXT_GET_PROC_ADDRESS("glClientWaitSync");
 +		glWaitSync = (PFNGLWAITSYNCPROC) GLH_EXT_GET_PROC_ADDRESS("glWaitSync");
 +		glGetInteger64v = (PFNGLGETINTEGER64VPROC) GLH_EXT_GET_PROC_ADDRESS("glGetInteger64v");
 +		glGetSynciv = (PFNGLGETSYNCIVPROC) GLH_EXT_GET_PROC_ADDRESS("glGetSynciv"); +	}  	if (mHasMapBufferRange)  	{  		glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC) GLH_EXT_GET_PROC_ADDRESS("glMapBufferRange"); diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index d1bee00161..d736133f3f 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -88,7 +88,9 @@ public:  	// ARB Extensions  	BOOL mHasVertexBufferObject; +	BOOL mHasSync;  	BOOL mHasMapBufferRange; +	BOOL mHasFlushBufferRange;  	BOOL mHasPBuffer;  	BOOL mHasShaderObjects;  	BOOL mHasVertexShader; diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index f35f329f00..851a75629e 100644 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -68,6 +68,19 @@ extern PFNGLUNMAPBUFFERARBPROC		glUnmapBufferARB;  extern PFNGLGETBUFFERPARAMETERIVARBPROC	glGetBufferParameterivARB;  extern PFNGLGETBUFFERPOINTERVARBPROC	glGetBufferPointervARB; +// GL_ARB_sync +extern PFNGLFENCESYNCPROC				glFenceSync; +extern PFNGLISSYNCPROC					glIsSync; +extern PFNGLDELETESYNCPROC				glDeleteSync; +extern PFNGLCLIENTWAITSYNCPROC			glClientWaitSync; +extern PFNGLWAITSYNCPROC				glWaitSync; +extern PFNGLGETINTEGER64VPROC			glGetInteger64v; +extern PFNGLGETSYNCIVPROC				glGetSynciv; + +// GL_APPLE_flush_buffer_range +extern PFNGLBUFFERPARAMETERIAPPLEPROC	glBufferParameteriAPPLE; +extern PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC glFlushMappedBufferRangeAPPLE; +  // GL_ARB_map_buffer_range  extern PFNGLMAPBUFFERRANGEPROC			glMapBufferRange;  extern PFNGLFLUSHMAPPEDBUFFERRANGEPROC	glFlushMappedBufferRange; @@ -310,6 +323,19 @@ extern PFNGLUNMAPBUFFERARBPROC		glUnmapBufferARB;  extern PFNGLGETBUFFERPARAMETERIVARBPROC	glGetBufferParameterivARB;  extern PFNGLGETBUFFERPOINTERVARBPROC	glGetBufferPointervARB; +// GL_ARB_sync +extern PFNGLFENCESYNCPROC				glFenceSync; +extern PFNGLISSYNCPROC					glIsSync; +extern PFNGLDELETESYNCPROC				glDeleteSync; +extern PFNGLCLIENTWAITSYNCPROC			glClientWaitSync; +extern PFNGLWAITSYNCPROC				glWaitSync; +extern PFNGLGETINTEGER64VPROC			glGetInteger64v; +extern PFNGLGETSYNCIVPROC				glGetSynciv; + +// GL_APPLE_flush_buffer_range +extern PFNGLBUFFERPARAMETERIAPPLEPROC	glBufferParameteriAPPLE; +extern PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC glFlushMappedBufferRangeAPPLE; +  // GL_ARB_map_buffer_range  extern PFNGLMAPBUFFERRANGEPROC			glMapBufferRange;  extern PFNGLFLUSHMAPPEDBUFFERRANGEPROC	glFlushMappedBufferRange; @@ -519,6 +545,19 @@ extern PFNGLUNMAPBUFFERARBPROC		glUnmapBufferARB;  extern PFNGLGETBUFFERPARAMETERIVARBPROC	glGetBufferParameterivARB;  extern PFNGLGETBUFFERPOINTERVARBPROC	glGetBufferPointervARB; +// GL_ARB_sync +extern PFNGLFENCESYNCPROC				glFenceSync; +extern PFNGLISSYNCPROC					glIsSync; +extern PFNGLDELETESYNCPROC				glDeleteSync; +extern PFNGLCLIENTWAITSYNCPROC			glClientWaitSync; +extern PFNGLWAITSYNCPROC				glWaitSync; +extern PFNGLGETINTEGER64VPROC			glGetInteger64v; +extern PFNGLGETSYNCIVPROC				glGetSynciv; + +// GL_APPLE_flush_buffer_range +extern PFNGLBUFFERPARAMETERIAPPLEPROC	glBufferParameteriAPPLE; +extern PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC glFlushMappedBufferRangeAPPLE; +  // GL_ARB_map_buffer_range  extern PFNGLMAPBUFFERRANGEPROC			glMapBufferRange;  extern PFNGLFLUSHMAPPEDBUFFERRANGEPROC	glFlushMappedBufferRange; diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 4a0b964e61..82c5efe0ac 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -65,6 +65,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, @@ -309,6 +363,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 +395,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 +421,7 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const  	stop_glerror();  	glDrawArrays(sGLMode[mode], first, count);  	stop_glerror(); +	placeFence();  }  //static @@ -444,9 +501,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 +586,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() @@ -892,17 +982,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;  } @@ -967,8 +1051,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 +1091,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 +1102,52 @@ 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 |  +							GL_MAP_UNSYNCHRONIZED_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 | +							GL_MAP_UNSYNCHRONIZED_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; @@ -1082,7 +1189,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 +1196,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 +1220,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 +1258,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)  			setBuffer(0, TYPE_INDEX);  			mIndexLocked = TRUE; +			sMappedCount++;  			stop_glerror();	  			if(sDisableVBOMapping) @@ -1162,29 +1269,53 @@ 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 | +							GL_MAP_UNSYNCHRONIZED_BIT); +#endif  					}  					else  					{ -						src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, sizeof(U16)*mNumIndices, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT); +#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 | +							GL_MAP_UNSYNCHRONIZED_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*) 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(); @@ -1211,15 +1342,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 +1397,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 +1407,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 +1460,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 +1469,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(); diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index aa5df305a6..cc5d11e1c2 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -70,6 +70,12 @@ protected:  	}  }; +class LLGLFence +{ +public: +	virtual void placeFence() = 0; +	virtual void wait() = 0; +};  //============================================================================  // base class  @@ -270,6 +276,12 @@ protected:  	std::vector<MappedRegion> mMappedVertexRegions;  	std::vector<MappedRegion> mMappedIndexRegions; +	mutable LLGLFence* mFence; + +	void placeFence() const; +	void waitFence() const; + +  public:  	static S32 sCount;  	static S32 sGLCount; diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index 22c79a4cbd..d2d0227f62 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -1,4 +1,4 @@ -version 30 +version 31  // NOTE: This is mostly identical to featuretable_mac.txt with a few differences  // Should be combined into one table @@ -244,9 +244,9 @@ RenderDeferredSSAO			0	0  RenderShadowDetail			0	0  // -// No GL_ARB_map_buffer_range +// GL_ARB_map_buffer_range exists  // -list NoMapBufferRange +list MapBufferRange  RenderVBOMappingDisable		1	0 diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt index 649f5ebd18..d9b4083016 100644 --- a/indra/newview/featuretable_linux.txt +++ b/indra/newview/featuretable_linux.txt @@ -1,4 +1,4 @@ -version 25 +version 26  // NOTE: This is mostly identical to featuretable_mac.txt with a few differences  // Should be combined into one table @@ -242,9 +242,9 @@ RenderDeferredSSAO			0	0  RenderShadowDetail			0	0  // -// No GL_ARB_map_buffer_range +// GL_ARB_map_buffer_range exists  // -list NoMapBufferRange +list MapBufferRange  RenderVBOMappingDisable		1	0 diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index ee08e78af5..f0b1f532a9 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -1,4 +1,4 @@ -version 26 +version 28  // NOTE: This is mostly identical to featuretable_mac.txt with a few differences  // Should be combined into one table @@ -48,7 +48,7 @@ RenderTransparentWater			1	1  RenderTreeLODFactor				1	1.0  RenderUseImpostors				1	1  RenderVBOEnable					1	1 -RenderVBOMappingDisable		1	1 +RenderVBOMappingDisable		1	0  RenderVolumeLODFactor			1	2.0  UseStartScreen				1	1  UseOcclusion					1	1 @@ -63,7 +63,7 @@ RenderDeferred				1	1  RenderDeferredSSAO			1	1  RenderShadowDetail			1	2  WatchdogDisabled				1	1 -RenderUseStreamVBO			1	1 +RenderUseStreamVBO			1	0  RenderFSAASamples			1	16  // @@ -244,13 +244,6 @@ RenderDeferredSSAO			0	0  RenderShadowDetail			0	0  // -// No GL_ARB_map_buffer_range -// -list NoMapBufferRange -RenderVBOMappingDisable		1	0 - - -//  // "Default" setups for safe, low, medium, high  //  list safe diff --git a/indra/newview/featuretable_xp.txt b/indra/newview/featuretable_xp.txt index ba74f9a6c2..6477dab35a 100644 --- a/indra/newview/featuretable_xp.txt +++ b/indra/newview/featuretable_xp.txt @@ -1,4 +1,4 @@ -version 30 +version 31  // NOTE: This is mostly identical to featuretable_mac.txt with a few differences  // Should be combined into one table @@ -244,9 +244,9 @@ RenderDeferredSSAO			0	0  RenderShadowDetail			0	0  // -// No GL_ARB_map_buffer_range +// GL_ARB_map_buffer_range exists  // -list NoMapBufferRange +list MapBufferRange  RenderVBOMappingDisable		1	0 diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index debac9dcbf..a5168fd897 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -1524,6 +1524,11 @@ BOOL LLDrawable::isAnimating() const  		return TRUE;  	} +	if (!LLVertexBuffer::sUseStreamDraw && mVObjp->isFlexible()) +	{ +		return TRUE; +	} +  	return FALSE;  } diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index b6566fcbd0..59c6e904a1 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1064,6 +1064,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  	S32 num_vertices = (S32)vf.mNumVertices;  	S32 num_indices = (S32) vf.mNumIndices; +	bool map_range = gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange; +  	if (mVertexBuffer.notNull())  	{  		if (num_indices + (S32) mIndicesIndex > mVertexBuffer->getNumIndices()) @@ -1182,7 +1184,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  	// INDICES  	if (full_rebuild)  	{ -		mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex, mIndicesCount, true); +		mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex, mIndicesCount, map_range);  		__m128i* dst = (__m128i*) indicesp.get();  		__m128i* src = (__m128i*) vf.mIndices; @@ -1201,7 +1203,10 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			indicesp[i] = vf.mIndices[i]+index_offset;  		} -		mVertexBuffer->setBuffer(0); +		if (map_range) +		{ +			mVertexBuffer->setBuffer(0); +		}  	}  	LLMatrix4a mat_normal; @@ -1422,11 +1427,14 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  				}  			} -			mVertexBuffer->setBuffer(0); +			if (map_range) +			{ +				mVertexBuffer->setBuffer(0); +			}  		}  		else  		{ //either bump mapped or in atlas, just do the whole expensive loop -			mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount, true); +			mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount, map_range);  			std::vector<LLVector2> bump_tc; @@ -1566,12 +1574,14 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  				}  			} -			mVertexBuffer->setBuffer(0); - +			if (map_range) +			{ +				mVertexBuffer->setBuffer(0); +			}  			if (do_bump)  			{ -				mVertexBuffer->getTexCoord1Strider(tex_coords2, mGeomIndex, mGeomCount, true); +				mVertexBuffer->getTexCoord1Strider(tex_coords2, mGeomIndex, mGeomCount, map_range);  				for (S32 i = 0; i < num_vertices; i++)  				{ @@ -1601,14 +1611,17 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  					*tex_coords2++ = tc;  				} -				mVertexBuffer->setBuffer(0); +				if (map_range) +				{ +					mVertexBuffer->setBuffer(0); +				}  			}  		}  	}  	if (rebuild_pos)  	{ -		mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount, true); +		mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount, map_range);  		vertices = (LLVector4a*) vert.get();  		LLMatrix4a mat_vert; @@ -1637,12 +1650,15 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		}  		while (index_dst < index_end); -		mVertexBuffer->setBuffer(0); +		if (map_range) +		{ +			mVertexBuffer->setBuffer(0); +		}  	}  	if (rebuild_normal)  	{ -		mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount, true); +		mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount, map_range);  		normals = (LLVector4a*) norm.get();  		for (S32 i = 0; i < num_vertices; i++) @@ -1653,12 +1669,15 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			normals[i] = normal;  		} -		mVertexBuffer->setBuffer(0); +		if (map_range) +		{ +			mVertexBuffer->setBuffer(0); +		}  	}  	if (rebuild_binormal)  	{ -		mVertexBuffer->getBinormalStrider(binorm, mGeomIndex, mGeomCount, true); +		mVertexBuffer->getBinormalStrider(binorm, mGeomIndex, mGeomCount, map_range);  		binormals = (LLVector4a*) binorm.get();  		for (S32 i = 0; i < num_vertices; i++) @@ -1669,20 +1688,26 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			binormals[i] = binormal;  		} -		mVertexBuffer->setBuffer(0); +		if (map_range) +		{ +			mVertexBuffer->setBuffer(0); +		}  	}  	if (rebuild_weights && vf.mWeights)  	{ -		mVertexBuffer->getWeight4Strider(wght, mGeomIndex, mGeomCount, true); +		mVertexBuffer->getWeight4Strider(wght, mGeomIndex, mGeomCount, map_range);  		weights = (LLVector4a*) wght.get();  		LLVector4a::memcpyNonAliased16((F32*) weights, (F32*) vf.mWeights, num_vertices*4*sizeof(F32)); -		mVertexBuffer->setBuffer(0); +		if (map_range) +		{ +			mVertexBuffer->setBuffer(0); +		}  	}  	if (rebuild_color)  	{ -		mVertexBuffer->getColorStrider(colors, mGeomIndex, mGeomCount, true); +		mVertexBuffer->getColorStrider(colors, mGeomIndex, mGeomCount, map_range);  		LLVector4a src; @@ -1703,7 +1728,10 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			dst[i] = src;  		} -		mVertexBuffer->setBuffer(0); +		if (map_range) +		{ +			mVertexBuffer->setBuffer(0); +		}  	}  	if (rebuild_tcoord) diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index 83844048d1..0ea0e41dfa 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -769,6 +769,10 @@ void LLFeatureManager::applyBaseMasks()  	{  		maskFeatures("TexUnit8orLess");  	} +	if (gGLManager.mHasMapBufferRange) +	{ +		maskFeatures("MapBufferRange"); +	}  	// now mask by gpu string  	// Replaces ' ' with '_' in mGPUString to deal with inability for parser to handle spaces diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index e6da8eb89d..40afabdb65 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4361,6 +4361,8 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)  		group->mBuilt = 1.f; +		std::set<LLVertexBuffer*> mapped_buffers; +  		for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)  		{  			LLFastTimer t(FTM_VOLUME_GEOM_PARTIAL); @@ -4375,35 +4377,31 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)  				for (S32 i = 0; i < drawablep->getNumFaces(); ++i)  				{  					LLFace* face = drawablep->getFace(i); -					if (face && face->getVertexBuffer()) +					if (face)  					{ -						face->getGeometryVolume(*volume, face->getTEOffset(),  -							vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex()); +						LLVertexBuffer* buff = face->getVertexBuffer(); +						if (buff) +						{ +							face->getGeometryVolume(*volume, face->getTEOffset(),  +								vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex()); + +							if (buff->isLocked()) +							{ +								mapped_buffers.insert(buff); +							} +						}  					}  				} - +				  				drawablep->clearState(LLDrawable::REBUILD_ALL);  			}  		} -		//unmap all the buffers -		for (LLSpatialGroup::buffer_map_t::iterator i = group->mBufferMap.begin(); i != group->mBufferMap.end(); ++i) +		for (std::set<LLVertexBuffer*>::iterator iter = mapped_buffers.begin(); iter != mapped_buffers.end(); ++iter)  		{ -			LLSpatialGroup::buffer_texture_map_t& map = i->second; -			for (LLSpatialGroup::buffer_texture_map_t::iterator j = map.begin(); j != map.end(); ++j) -			{ -				LLSpatialGroup::buffer_list_t& list = j->second; -				for (LLSpatialGroup::buffer_list_t::iterator k = list.begin(); k != list.end(); ++k) -				{ -					LLVertexBuffer* buffer = *k; -					if (buffer->isLocked()) -					{ -						buffer->setBuffer(0); -					} -				} -			} +			(*iter)->setBuffer(0);  		} -		 +  		// don't forget alpha  		if(group != NULL &&   		   !group->mVertexBuffer.isNull() &&  | 
