diff options
Diffstat (limited to 'indra/llrender')
| -rw-r--r-- | indra/llrender/llcubemap.cpp | 2 | ||||
| -rw-r--r-- | indra/llrender/llgl.cpp | 79 | ||||
| -rw-r--r-- | indra/llrender/llgl.h | 26 | ||||
| -rw-r--r-- | indra/llrender/llglheaders.h | 13 | ||||
| -rw-r--r-- | indra/llrender/llglslshader.cpp | 9 | ||||
| -rw-r--r-- | indra/llrender/llglslshader.h | 4 | ||||
| -rw-r--r-- | indra/llrender/llimagegl.cpp | 62 | ||||
| -rw-r--r-- | indra/llrender/llimagegl.h | 10 | ||||
| -rw-r--r-- | indra/llrender/llrendertarget.cpp | 8 | ||||
| -rw-r--r-- | indra/llrender/llvertexbuffer.cpp | 121 | ||||
| -rw-r--r-- | indra/llrender/llvertexbuffer.h | 25 | 
11 files changed, 273 insertions, 86 deletions
| diff --git a/indra/llrender/llcubemap.cpp b/indra/llrender/llcubemap.cpp index 45a3b18179..32e4c0d18e 100644 --- a/indra/llrender/llcubemap.cpp +++ b/indra/llrender/llcubemap.cpp @@ -81,7 +81,7 @@ void LLCubeMap::initGL()  		{  			U32 texname = 0; -			LLImageGL::generateTextures(1, &texname); +			LLImageGL::generateTextures(LLTexUnit::TT_CUBE_MAP, 1, &texname);  			for (int i = 0; i < 6; i++)  			{ diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index 639d967853..3946c43929 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -249,6 +249,12 @@ PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample = NULL;  PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv = NULL;  PFNGLSAMPLEMASKIPROC glSampleMaski = NULL; +//transform feedback (4.0 core) +PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback = NULL; +PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback = NULL; +PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings = NULL; +PFNGLBINDBUFFERRANGEPROC glBindBufferRange = NULL; +  //GL_ARB_debug_output  PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControlARB = NULL;  PFNGLDEBUGMESSAGEINSERTARBPROC glDebugMessageInsertARB = NULL; @@ -421,6 +427,7 @@ LLGLManager::LLGLManager() :  	mHasDrawBuffers(FALSE),  	mHasTextureRectangle(FALSE),  	mHasTextureMultisample(FALSE), +	mHasTransformFeedback(FALSE),  	mMaxSampleMaskWords(0),  	mMaxColorTextureSamples(0),  	mMaxDepthTextureSamples(0), @@ -969,6 +976,7 @@ void LLGLManager::initExtensions()  	mHasTextureRectangle = ExtensionExists("GL_ARB_texture_rectangle", gGLHExts.mSysExts);  	mHasTextureMultisample = ExtensionExists("GL_ARB_texture_multisample", gGLHExts.mSysExts);  	mHasDebugOutput = ExtensionExists("GL_ARB_debug_output", gGLHExts.mSysExts); +	mHasTransformFeedback = mGLVersion >= 4.f ? TRUE : FALSE;  #if !LL_DARWIN  	mHasPointParameters = !mIsATI && ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts);  #endif @@ -1208,7 +1216,14 @@ void LLGLManager::initExtensions()  		glTexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC) GLH_EXT_GET_PROC_ADDRESS("glTexImage3DMultisample");  		glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC) GLH_EXT_GET_PROC_ADDRESS("glGetMultisamplefv");  		glSampleMaski = (PFNGLSAMPLEMASKIPROC) GLH_EXT_GET_PROC_ADDRESS("glSampleMaski"); -	}	 +	} +	if (mHasTransformFeedback) +	{ +		glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC) GLH_EXT_GET_PROC_ADDRESS("glBeginTransformFeedback"); +		glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC) GLH_EXT_GET_PROC_ADDRESS("glEndTransformFeedback"); +		glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC) GLH_EXT_GET_PROC_ADDRESS("glTransformFeedbackVaryings"); +		glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC) GLH_EXT_GET_PROC_ADDRESS("glBindBufferRange"); +	}  	if (mHasDebugOutput)  	{  		glDebugMessageControlARB = (PFNGLDEBUGMESSAGECONTROLARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDebugMessageControlARB"); @@ -2433,3 +2448,65 @@ LLGLSquashToFarClip::~LLGLSquashToFarClip()  	gGL.matrixMode(LLRender::MM_MODELVIEW);  } + +	 +LLGLSyncFence::LLGLSyncFence() +{ +#ifdef GL_ARB_sync +	mSync = 0; +#endif +} + +LLGLSyncFence::~LLGLSyncFence() +{ +#ifdef GL_ARB_sync +	if (mSync) +	{ +		glDeleteSync(mSync); +	} +#endif +} + +void LLGLSyncFence::placeFence() +{ +#ifdef GL_ARB_sync +	if (mSync) +	{ +		glDeleteSync(mSync); +	} +	mSync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); +#endif +} + +bool LLGLSyncFence::isCompleted() +{ +	bool ret = true; +#ifdef GL_ARB_sync +	if (mSync) +	{ +		GLenum status = glClientWaitSync(mSync, 0, 1); +		if (status == GL_TIMEOUT_EXPIRED) +		{ +			ret = false; +		} +	} +#endif +	return ret; +} + +void LLGLSyncFence::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 +} + + + diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index 9c3a47bd50..c26b75eff7 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -104,6 +104,7 @@ public:  	BOOL mHasDepthClamp;  	BOOL mHasTextureRectangle;  	BOOL mHasTextureMultisample; +	BOOL mHasTransformFeedback;  	S32 mMaxSampleMaskWords;  	S32 mMaxColorTextureSamples;  	S32 mMaxDepthTextureSamples; @@ -418,6 +419,31 @@ public:  	virtual void updateGL() = 0;  }; +const U32 FENCE_WAIT_TIME_NANOSECONDS = 10000;  //1 ms + +class LLGLFence +{ +public: +	virtual void placeFence() = 0; +	virtual bool isCompleted() = 0; +	virtual void wait() = 0; +}; + +class LLGLSyncFence : public LLGLFence +{ +public: +#ifdef GL_ARB_sync +	GLsync mSync; +#endif +	 +	LLGLSyncFence(); +	virtual ~LLGLSyncFence(); + +	void placeFence(); +	bool isCompleted(); +	void wait(); +}; +  extern LLMatrix4 gGLObliqueProjectionInverse;  #include "llglstates.h" diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index d61ec707f0..a0727b8686 100644 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -528,6 +528,13 @@ extern PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample;  extern PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv;  extern PFNGLSAMPLEMASKIPROC glSampleMaski; +//transform feedback (4.0 core) +extern PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback; +extern PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback; +extern PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings; +extern PFNGLBINDBUFFERRANGEPROC glBindBufferRange; + +  #elif LL_WINDOWS  //----------------------------------------------------------------------------  // LL_WINDOWS @@ -759,6 +766,12 @@ extern PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample;  extern PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv;  extern PFNGLSAMPLEMASKIPROC glSampleMaski; +//transform feedback (4.0 core) +extern PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback; +extern PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback; +extern PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings; +extern PFNGLBINDBUFFERRANGEPROC glBindBufferRange; +  //GL_ARB_debug_output  extern PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControlARB;  extern PFNGLDEBUGMESSAGEINSERTARBPROC glDebugMessageInsertARB; diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 4b7e639aed..149e8cc548 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -129,7 +129,9 @@ void LLGLSLShader::unload()  }  BOOL LLGLSLShader::createShader(vector<string> * attributes, -								vector<string> * uniforms) +								vector<string> * uniforms, +								U32 varying_count, +								const char** varyings)  {  	//reloading, reset matrix hash values  	for (U32 i = 0; i < LLRender::NUM_MATRIX_MODES; ++i) @@ -172,6 +174,11 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,  		mFeatures.mIndexedTextureChannels = llmin(mFeatures.mIndexedTextureChannels, 1);  	} +	if (varying_count > 0 && varyings) +	{ +		glTransformFeedbackVaryings(mProgramObject, varying_count, varyings, GL_INTERLEAVED_ATTRIBS); +	} +  	// Map attributes and uniforms  	if (success)  	{ diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index 7873fe3c4e..5c68cb46eb 100644 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -76,7 +76,9 @@ public:  	void unload();  	BOOL createShader(std::vector<std::string> * attributes, -						std::vector<std::string> * uniforms); +						std::vector<std::string> * uniforms, +						U32 varying_count = 0, +						const char** varyings = NULL);  	BOOL attachObject(std::string object);  	void attachObject(GLhandleARB object);  	void attachObjects(GLhandleARB* objects = NULL, S32 count = 0); diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 17131c9d8a..3bdee6cade 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -51,7 +51,8 @@ S32 LLImageGL::sGlobalTextureMemoryInBytes		= 0;  S32 LLImageGL::sBoundTextureMemoryInBytes		= 0;  S32 LLImageGL::sCurBoundTextureMemory	= 0;  S32 LLImageGL::sCount					= 0; -std::list<U32> LLImageGL::sDeadTextureList; +std::list<U32> LLImageGL::sDeadTextureList[LLTexUnit::TT_NONE]; +U32 LLImageGL::sCurTexName = 1;  BOOL LLImageGL::sGlobalUseAnisotropic	= FALSE;  F32 LLImageGL::sLastFrameTime			= 0.f; @@ -1093,23 +1094,49 @@ BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_  }  // static -void LLImageGL::generateTextures(S32 numTextures, U32 *textures) +void LLImageGL::generateTextures(LLTexUnit::eTextureType type, S32 numTextures, U32 *textures)  { -	glGenTextures(numTextures, (GLuint*)textures); +	for (S32 i = 0; i < numTextures; ++i) +	{ +		if (!sDeadTextureList[type].empty()) +		{ +			textures[i] = sDeadTextureList[type].front(); +			sDeadTextureList[type].pop_front(); +		} +		else +		{ +			textures[i] = sCurTexName++; +		} +	}  }  // static -void LLImageGL::deleteTextures(S32 numTextures, U32 *textures, bool immediate) +void LLImageGL::deleteTextures(LLTexUnit::eTextureType type, S32 numTextures, U32 *textures, bool immediate)  { -	for (S32 i = 0; i < numTextures; i++) -	{ -		sDeadTextureList.push_back(textures[i]); -	} +	for (S32 i = 0; i < numTextures; ++i) +	{ //remove texture from VRAM by setting its size to zero +		gGL.getTexUnit(0)->bindManual(type, textures[i]); -	if (immediate) +		if (type == LLTexUnit::TT_CUBE_MAP) +		{ +			glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); +			glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); +			glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); +			glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); +			glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); +			glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); +		} +		else +		{ +			glTexImage2D(LLTexUnit::getInternalType(type), 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); +		} +		sDeadTextureList[type].push_back(textures[i]); +	} +	 +	/*if (immediate)  	{  		LLImageGL::deleteDeadTextures(); -	} +	}*/  }  // static @@ -1234,10 +1261,11 @@ BOOL LLImageGL::createGLTexture()  	if(mTexName)  	{ -		glDeleteTextures(1, (reinterpret_cast<GLuint*>(&mTexName))) ; +		LLImageGL::deleteTextures(mBindTarget, 1, (reinterpret_cast<GLuint*>(&mTexName))) ;  	} -	glGenTextures(1, (GLuint*)&mTexName); + +	LLImageGL::generateTextures(mBindTarget, 1, &mTexName);  	stop_glerror();  	if (!mTexName)  	{ @@ -1350,7 +1378,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_  	}  	else  	{ -		LLImageGL::generateTextures(1, &mTexName); +		LLImageGL::generateTextures(mBindTarget, 1, &mTexName);  		stop_glerror();  		{  			llverify(gGL.getTexUnit(0)->bind(this)); @@ -1400,7 +1428,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_  			decTextureCounter(mTextureMemory, mComponents, mCategory) ;  		} -		LLImageGL::deleteTextures(1, &old_name); +		LLImageGL::deleteTextures(mBindTarget,1, &old_name);  		stop_glerror();  	} @@ -1533,7 +1561,7 @@ void LLImageGL::deleteDeadTextures()  {  	bool reset = false; -	while (!sDeadTextureList.empty()) +	/*while (!sDeadTextureList.empty())  	{  		GLuint tex = sDeadTextureList.front();  		sDeadTextureList.pop_front(); @@ -1555,7 +1583,7 @@ void LLImageGL::deleteDeadTextures()  		glDeleteTextures(1, &tex);  		stop_glerror(); -	} +	}*/  	if (reset)  	{ @@ -1577,7 +1605,7 @@ void LLImageGL::destroyGLTexture()  			mTextureMemory = 0;  		} -		LLImageGL::deleteTextures(1, &mTexName);			 +		LLImageGL::deleteTextures(mBindTarget, 1, &mTexName);			  		mTexName = 0;  		mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel.  		mGLTextureCreated = FALSE ; diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index e23005fe29..8c9cea111e 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -45,8 +45,12 @@ class LLImageGL : public LLRefCount  {  	friend class LLTexUnit;  public: -	static std::list<U32> sDeadTextureList; +	static U32 sCurTexName; +	static std::list<U32> sDeadTextureList[LLTexUnit::TT_NONE]; +	// These 2 functions replace glGenTextures() and glDeleteTextures() +	static void generateTextures(LLTexUnit::eTextureType type, S32 numTextures, U32 *textures); +	static void deleteTextures(LLTexUnit::eTextureType type, S32 numTextures, U32 *textures, bool immediate = false);  	static void deleteDeadTextures();  	// Size calculation @@ -96,10 +100,6 @@ public:  	void setComponents(S32 ncomponents) { mComponents = (S8)ncomponents ;}  	void setAllowCompression(bool allow) { mAllowCompression = allow; } -	// These 3 functions currently wrap glGenTextures(), glDeleteTextures(), and glTexImage2D()  -	// for tracking purposes and will be deprecated in the future -	static void generateTextures(S32 numTextures, U32 *textures); -	static void deleteTextures(S32 numTextures, U32 *textures, bool immediate = false);  	static void setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels, bool allow_compression = true);  	BOOL createGLTexture() ; diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index 780f1dc484..f0dd6f3bd6 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -135,7 +135,7 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)  	}  	U32 tex; -	LLImageGL::generateTextures(1, &tex); +	LLImageGL::generateTextures(mUsage, 1, &tex);  	gGL.getTexUnit(0)->bindManual(mUsage, tex);  	stop_glerror(); @@ -217,7 +217,7 @@ bool LLRenderTarget::allocateDepth()  	}  	else  	{ -		LLImageGL::generateTextures(1, &mDepth); +		LLImageGL::generateTextures(mUsage, 1, &mDepth);  		gGL.getTexUnit(0)->bindManual(mUsage, mDepth);  		U32 internal_type = LLTexUnit::getInternalType(mUsage); @@ -294,7 +294,7 @@ void LLRenderTarget::release()  		}  		else  		{ -			LLImageGL::deleteTextures(1, &mDepth, true); +			LLImageGL::deleteTextures(mUsage, 1, &mDepth, true);  			stop_glerror();  		}  		mDepth = 0; @@ -326,7 +326,7 @@ void LLRenderTarget::release()  	if (mTex.size() > 0)  	{  		sBytesAllocated -= mResX*mResY*4*mTex.size(); -		LLImageGL::deleteTextures(mTex.size(), &mTex[0], true); +		LLImageGL::deleteTextures(mUsage, mTex.size(), &mTex[0], true);  		mTex.clear();  	} diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 7b12304967..6a218e7734 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -93,6 +93,11 @@ LLVBOPool LLVertexBuffer::sDynamicIBOPool(GL_DYNAMIC_DRAW_ARB, GL_ELEMENT_ARRAY_  U32 LLVBOPool::sBytesPooled = 0;  U32 LLVBOPool::sIndexBytesPooled = 0; +U32 LLVBOPool::sCurGLName = 1; + +std::list<U32> LLVertexBuffer::sAvailableVAOName; +U32 LLVertexBuffer::sCurVAOName = 1; +  U32 LLVertexBuffer::sAllocatedIndexBytes = 0;  U32 LLVertexBuffer::sIndexCount = 0; @@ -117,59 +122,38 @@ bool LLVertexBuffer::sUseStreamDraw = true;  bool LLVertexBuffer::sUseVAO = false;  bool LLVertexBuffer::sPreferStreamDraw = false; -const U32 FENCE_WAIT_TIME_NANOSECONDS = 10000;  //1 ms -class LLGLSyncFence : public LLGLFence +U32 LLVBOPool::genBuffer()  { -public: -#ifdef GL_ARB_sync -	GLsync mSync; -#endif -	 -	LLGLSyncFence() -	{ -#ifdef GL_ARB_sync -		mSync = 0; -#endif -	} +	U32 ret = 0; -	virtual ~LLGLSyncFence() +	if (mGLNamePool.empty())  	{ -#ifdef GL_ARB_sync -		if (mSync) -		{ -			glDeleteSync(mSync); -		} -#endif +		ret = sCurGLName++;  	} - -	void placeFence() +	else  	{ -#ifdef GL_ARB_sync -		if (mSync) -		{ -			glDeleteSync(mSync); -		} -		mSync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); -#endif +		ret = mGLNamePool.front(); +		mGLNamePool.pop_front();  	} -	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 -	} +	return ret; +} + +void LLVBOPool::deleteBuffer(U32 name) +{ +	LLVertexBuffer::unbind(); +	glBindBufferARB(mType, name); +	glBufferDataARB(mType, 0, NULL, mUsage); + +	llassert(std::find(mGLNamePool.begin(), mGLNamePool.end(), name) == mGLNamePool.end()); + +	mGLNamePool.push_back(name); + +	LLVertexBuffer::unbind(); +} -};  LLVBOPool::LLVBOPool(U32 vboUsage, U32 vboType)  : mUsage(vboUsage), mType(vboType) @@ -178,6 +162,9 @@ LLVBOPool::LLVBOPool(U32 vboUsage, U32 vboType)  	std::fill(mMissCount.begin(), mMissCount.end(), 0);  } +static LLFastTimer::DeclareTimer FTM_VBO_GEN_BUFFER("gen buffers"); +static LLFastTimer::DeclareTimer FTM_VBO_BUFFER_DATA("glBufferData"); +  volatile U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)  { @@ -198,7 +185,10 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)  	if (mFreeList[i].empty() || for_seed)  	{  		//make a new buffer -		glGenBuffersARB(1, &name); +		{ +			LLFastTimer t(FTM_VBO_GEN_BUFFER); +			name = genBuffer(); +		}  		glBindBufferARB(mType, name);  		if (!for_seed && i < LL_VBO_POOL_SEED_COUNT) @@ -222,6 +212,7 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)  		}  		else  		{ //always use a true hint of static draw when allocating non-client-backed buffers +			LLFastTimer t(FTM_VBO_BUFFER_DATA);  			glBufferDataARB(mType, size, 0, GL_STATIC_DRAW_ARB);  		} @@ -324,7 +315,7 @@ void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size)  		mFreeList[i].push_back(rec);  	}  #else //no pooling -	glDeleteBuffersARB(1, &name); +	deleteBuffer(name);  	ll_aligned_free_16((U8*) buffer);  	if (mType == GL_ARRAY_BUFFER_ARB) @@ -375,8 +366,8 @@ void LLVBOPool::cleanup()  		{  			Record& r = l.front(); -			glDeleteBuffersARB(1, &r.mGLName); - +			deleteBuffer(r.mGLName); +			  			if (r.mClientData)  			{  				ll_aligned_free_16((void*) r.mClientData); @@ -434,6 +425,30 @@ U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] =  	GL_LINE_LOOP,  }; +//static +U32 LLVertexBuffer::getVAOName() +{ +	U32 ret = 0; + +	if (!sAvailableVAOName.empty()) +	{ +		ret = sAvailableVAOName.front(); +		sAvailableVAOName.pop_front(); +	} +	else +	{ +		glGenVertexArrays(1, &ret); +	} + +	return ret;		 +} + +//static +void LLVertexBuffer::releaseVAOName(U32 name) +{ +	sAvailableVAOName.push_back(name); +} +  //static  void LLVertexBuffer::seedPools() @@ -1052,7 +1067,7 @@ LLVertexBuffer::~LLVertexBuffer()  	if (mGLArray)  	{  #if GL_ARB_vertex_array_object -		glDeleteVertexArrays(1, &mGLArray); +		releaseVAOName(mGLArray);  #endif  	} @@ -1337,7 +1352,7 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)  		if (gGLManager.mHasVertexArrayObject && useVBOs() && (LLRender::sGLCoreProfile || sUseVAO))  		{  #if GL_ARB_vertex_array_object -			glGenVertexArrays(1, &mGLArray); +			mGLArray = getVAOName();  #endif  			setupVertexArray();  		} @@ -2207,6 +2222,14 @@ void LLVertexBuffer::flush()  	}  } +// bind for transform feedback (quick 'n dirty) +void LLVertexBuffer::bindForFeedback(U32 channel, U32 type, U32 index, U32 count) +{ +	U32 offset = mOffsets[type] + sTypeSize[type]*index; +	U32 size= (sTypeSize[type]*count); +	glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, channel, mGLBuffer, offset, size); +} +  // Set for rendering  void LLVertexBuffer::setBuffer(U32 data_mask)  { diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index a64daa1a90..11fa4ab6a0 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -57,6 +57,8 @@ public:  	static U32 sBytesPooled;  	static U32 sIndexBytesPooled; +	static U32 sCurGLName; +  	LLVBOPool(U32 vboUsage, U32 vboType);  	const U32 mUsage; @@ -74,6 +76,9 @@ public:  	//destroy all records in mFreeList  	void cleanup(); +	U32 genBuffer(); +	void deleteBuffer(U32 name); +  	class Record  	{  	public: @@ -81,18 +86,14 @@ public:  		volatile U8* mClientData;  	}; +	std::list<U32> mGLNamePool; +  	typedef std::list<Record> record_list_t;  	std::vector<record_list_t> mFreeList;  	std::vector<U32> mMissCount;  }; -class LLGLFence -{ -public: -	virtual void placeFence() = 0; -	virtual void wait() = 0; -};  //============================================================================  // base class  @@ -127,15 +128,22 @@ public:  	static LLVBOPool sStreamIBOPool;  	static LLVBOPool sDynamicIBOPool; +	static std::list<U32> sAvailableVAOName; +	static U32 sCurVAOName; +  	static bool	sUseStreamDraw;  	static bool sUseVAO;  	static bool	sPreferStreamDraw;  	static void seedPools(); +	static U32 getVAOName(); +	static void releaseVAOName(U32 name); +  	static void initClass(bool use_vbo, bool no_vbo_mapping);  	static void cleanupClass();  	static void setupClientArrays(U32 data_mask); +	static void pushPositions(U32 mode, const LLVector4a* pos, U32 count);  	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); @@ -212,7 +220,6 @@ protected:  	void 	destroyGLIndices();  	void	updateNumVerts(S32 nverts);  	void	updateNumIndices(S32 nindices);  -	bool	useVBOs() const;  	void	unmapBuffer();  public: @@ -222,6 +229,8 @@ public:  	volatile U8*		mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range);  	volatile U8*		mapIndexBuffer(S32 index, S32 count, bool map_range); +	void bindForFeedback(U32 channel, U32 type, U32 index, U32 count); +  	// set for rendering  	virtual void	setBuffer(U32 data_mask); 	// calls  setupVertexBuffer() if data_mask is not 0  	void flush(); //flush pending data to GL memory @@ -244,12 +253,14 @@ public:  	bool getNormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);  	bool getBinormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);  	bool getColorStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false); +	bool getTextureIndexStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);  	bool getEmissiveStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);  	bool getWeightStrider(LLStrider<F32>& strider, S32 index=0, S32 count = -1, bool map_range = false);  	bool getWeight4Strider(LLStrider<LLVector4>& strider, S32 index=0, S32 count = -1, bool map_range = false);  	bool getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index=0, S32 count = -1, bool map_range = false); +	bool useVBOs() const;  	bool isEmpty() const					{ return mEmpty; }  	bool isLocked() const					{ return mVertexLocked || mIndexLocked; }  	S32 getNumVerts() const					{ return mNumVerts; } | 
