diff options
Diffstat (limited to 'indra/llrender')
| -rw-r--r-- | indra/llrender/llcubemap.cpp | 12 | ||||
| -rw-r--r-- | indra/llrender/llgl.cpp | 44 | ||||
| -rw-r--r-- | indra/llrender/llgl.h | 2 | ||||
| -rw-r--r-- | indra/llrender/llglheaders.h | 39 | ||||
| -rw-r--r-- | indra/llrender/llglslshader.cpp | 7 | ||||
| -rw-r--r-- | indra/llrender/llglslshader.h | 7 | ||||
| -rw-r--r-- | indra/llrender/llimagegl.cpp | 12 | ||||
| -rw-r--r-- | indra/llrender/llrender.cpp | 29 | ||||
| -rw-r--r-- | indra/llrender/llrender.h | 2 | ||||
| -rw-r--r-- | indra/llrender/llrendertarget.cpp | 47 | ||||
| -rw-r--r-- | indra/llrender/llrendertarget.h | 14 | ||||
| -rw-r--r-- | indra/llrender/llvertexbuffer.cpp | 219 | ||||
| -rw-r--r-- | indra/llrender/llvertexbuffer.h | 12 | 
13 files changed, 373 insertions, 73 deletions
| diff --git a/indra/llrender/llcubemap.cpp b/indra/llrender/llcubemap.cpp index fb22d7f1f5..1b10354c22 100644 --- a/indra/llrender/llcubemap.cpp +++ b/indra/llrender/llcubemap.cpp @@ -259,7 +259,7 @@ void LLCubeMap::setMatrix(S32 stage)  	if (mMatrixStage < 0) return; -	if (stage > 0) +	//if (stage > 0)  	{  		gGL.getTexUnit(stage)->activate();  	} @@ -278,17 +278,17 @@ void LLCubeMap::setMatrix(S32 stage)  	glLoadMatrixf((F32 *)trans.mMatrix);  	glMatrixMode(GL_MODELVIEW); -	if (stage > 0) +	/*if (stage > 0)  	{  		gGL.getTexUnit(0)->activate(); -	} +	}*/  }  void LLCubeMap::restoreMatrix()  {  	if (mMatrixStage < 0) return; -	if (mMatrixStage > 0) +	//if (mMatrixStage > 0)  	{  		gGL.getTexUnit(mMatrixStage)->activate();  	} @@ -296,10 +296,10 @@ void LLCubeMap::restoreMatrix()  	glPopMatrix();  	glMatrixMode(GL_MODELVIEW); -	if (mMatrixStage > 0) +	/*if (mMatrixStage > 0)  	{  		gGL.getTexUnit(0)->activate(); -	} +	}*/  }  void LLCubeMap::setReflection (void) diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index e44c58efab..39f59c0bd8 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"); @@ -1354,6 +1379,8 @@ void LLGLState::checkStates(const std::string& msg)  	glGetIntegerv(GL_BLEND_SRC, &src);  	glGetIntegerv(GL_BLEND_DST, &dst); +	stop_glerror(); +  	BOOL error = FALSE;  	if (src != GL_SRC_ALPHA || dst != GL_ONE_MINUS_SRC_ALPHA) @@ -1374,7 +1401,9 @@ void LLGLState::checkStates(const std::string& msg)  	{  		LLGLenum state = iter->first;  		LLGLboolean cur_state = iter->second; +		stop_glerror();  		LLGLboolean gl_state = glIsEnabled(state); +		stop_glerror();  		if(cur_state != gl_state)  		{  			dumpStates(); @@ -1399,11 +1428,11 @@ void LLGLState::checkStates(const std::string& msg)  void LLGLState::checkTextureChannels(const std::string& msg)  { +#if 0  	if (!gDebugGL)  	{  		return;  	} -  	stop_glerror();  	GLint activeTexture; @@ -1569,6 +1598,7 @@ void LLGLState::checkTextureChannels(const std::string& msg)  			LL_GL_ERRS << "GL texture state corruption detected.  " << msg << LL_ENDL;  		}  	} +#endif  }  void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask) @@ -1685,7 +1715,7 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)  		}  	} -	if (glIsEnabled(GL_TEXTURE_2D)) +	/*if (glIsEnabled(GL_TEXTURE_2D))  	{  		if (!(data_mask & 0x0008))  		{ @@ -1708,7 +1738,7 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)  				gFailLog << "GL does not have GL_TEXTURE_2D enabled on channel 1." << std::endl;  			}  		} -	} +	}*/  	glClientActiveTextureARB(GL_TEXTURE0_ARB);  	gGL.getTexUnit(0)->activate(); 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/llglslshader.cpp b/indra/llrender/llglslshader.cpp index ad2c662dfc..80c93bb0d2 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -49,6 +49,11 @@ using std::make_pair;  using std::string;  GLhandleARB LLGLSLShader::sCurBoundShader = 0; +bool LLGLSLShader::sNoFixedFunction = false; + +//UI shader -- declared here so llui_libtest will link properly +LLGLSLShader	gUIProgram; +LLGLSLShader	gSolidColorProgram;  BOOL shouldChange(const LLVector4& v1, const LLVector4& v2)  { @@ -376,6 +381,7 @@ BOOL LLGLSLShader::link(BOOL suppress_errors)  void LLGLSLShader::bind()  { +	gGL.flush();  	if (gGLManager.mHasShaderObjects)  	{  		glUseProgramObjectARB(mProgramObject); @@ -390,6 +396,7 @@ void LLGLSLShader::bind()  void LLGLSLShader::unbind()  { +	gGL.flush();  	if (gGLManager.mHasShaderObjects)  	{  		stop_glerror(); diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index 4922eb6d67..621e0b82ee 100644 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -67,6 +67,7 @@ public:  	LLGLSLShader();  	static GLhandleARB sCurBoundShader; +	static bool sNoFixedFunction;  	void unload();  	BOOL createShader(std::vector<std::string> * attributes, @@ -141,4 +142,10 @@ public:  	std::string mName;  }; +//UI shader (declared here so llui_libtest will link properly) +extern LLGLSLShader			gUIProgram; +//output vec4(color.rgb,color.a*tex0[tc0].a) +extern LLGLSLShader			gSolidColorProgram; + +  #endif diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 60a5962234..9ca3a23d52 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -1414,6 +1414,8 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre  void LLImageGL::deleteDeadTextures()  { +	bool reset = false; +  	while (!sDeadTextureList.empty())  	{  		GLuint tex = sDeadTextureList.front(); @@ -1426,12 +1428,22 @@ void LLImageGL::deleteDeadTextures()  			{  				tex_unit->unbind(tex_unit->getCurrType());  				stop_glerror(); + +				if (i > 0) +				{ +					reset = true; +				}  			}  		}  		glDeleteTextures(1, &tex);  		stop_glerror();  	} + +	if (reset) +	{ +		gGL.getTexUnit(0)->activate(); +	}  }  void LLImageGL::destroyGLTexture() diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 1d82dda30f..70df1dd1d1 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -46,6 +46,7 @@ S32	gGLViewport[4];  U32 LLRender::sUICalls = 0;  U32 LLRender::sUIVerts = 0; +U32 LLTexUnit::sWhiteTexture = 0;  static const U32 LL_NUM_TEXTURE_LAYERS = 32;   static const U32 LL_NUM_LIGHT_UNITS = 8; @@ -126,7 +127,8 @@ void LLTexUnit::refreshState(void)  	// Per apple spec, don't call glEnable/glDisable when index exceeds max texture units  	// http://www.mailinglistarchive.com/html/mac-opengl@lists.apple.com/2008-07/msg00653.html  	// -	bool enableDisable = (mIndex < gGLManager.mNumTextureUnits) && mCurrTexType != LLTexUnit::TT_MULTISAMPLE_TEXTURE; +	bool enableDisable = !LLGLSLShader::sNoFixedFunction &&  +		(mIndex < gGLManager.mNumTextureUnits) && mCurrTexType != LLTexUnit::TT_MULTISAMPLE_TEXTURE;  	if (mCurrTexType != TT_NONE)  	{ @@ -184,7 +186,8 @@ void LLTexUnit::enable(eTextureType type)  		mCurrTexType = type;  		gGL.flush(); -		if (type != LLTexUnit::TT_MULTISAMPLE_TEXTURE && +		if (!LLGLSLShader::sNoFixedFunction &&  +			type != LLTexUnit::TT_MULTISAMPLE_TEXTURE &&  			mIndex < gGLManager.mNumTextureUnits)  		{  			glEnable(sGLTextureType[type]); @@ -201,7 +204,8 @@ void LLTexUnit::disable(void)  		activate();  		unbind(mCurrTexType);  		gGL.flush(); -		if (mCurrTexType != LLTexUnit::TT_MULTISAMPLE_TEXTURE && +		if (!LLGLSLShader::sNoFixedFunction && +			mCurrTexType != LLTexUnit::TT_MULTISAMPLE_TEXTURE &&  			mIndex < gGLManager.mNumTextureUnits)  		{  			glDisable(sGLTextureType[mCurrTexType]); @@ -403,7 +407,14 @@ void LLTexUnit::unbind(eTextureType type)  		activate();  		mCurrTexture = 0; -		glBindTexture(sGLTextureType[type], 0); +		if (LLGLSLShader::sNoFixedFunction && type == LLTexUnit::TT_TEXTURE) +		{ +			glBindTexture(sGLTextureType[type], sWhiteTexture); +		} +		else +		{ +			glBindTexture(sGLTextureType[type], 0); +		}  		stop_glerror();  	}  } @@ -474,6 +485,11 @@ void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions optio  void LLTexUnit::setTextureBlendType(eTextureBlendType type)  { +	if (LLGLSLShader::sNoFixedFunction) +	{ //texture blend type means nothing when using shaders +		return; +	} +  	if (mIndex < 0) return;  	// Do nothing if it's already correctly set. @@ -594,6 +610,11 @@ GLint LLTexUnit::getTextureSourceType(eTextureBlendSrc src, bool isAlpha)  void LLTexUnit::setTextureCombiner(eTextureBlendOp op, eTextureBlendSrc src1, eTextureBlendSrc src2, bool isAlpha)  { +	if (LLGLSLShader::sNoFixedFunction) +	{ //register combiners do nothing when not using fixed function +		return; +	}	 +  	if (mIndex < 0) return;  	activate(); diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index 41e7b35341..9eedebe2ce 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -52,6 +52,8 @@ class LLTexUnit  {  	friend class LLRender;  public: +	static U32 sWhiteTexture; +  	typedef enum  	{  		TT_TEXTURE = 0,			// Standard 2D Texture diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index b6463309e1..8c0d3592df 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -72,11 +72,11 @@ LLRenderTarget::~LLRenderTarget()  	release();  } -void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, S32 samples) +bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, S32 samples)  {  	stop_glerror(); -	  	release(); +	stop_glerror();  	mResX = resx;  	mResY = resy; @@ -103,9 +103,11 @@ void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, boo  	{  		if (depth)  		{ -			stop_glerror(); -			allocateDepth(); -			stop_glerror(); +			if (!allocateDepth()) +			{ +				llwarns << "Failed to allocate depth buffer for render target." << llendl; +				return false; +			}  		}  		glGenFramebuffers(1, (GLuint *) &mFBO); @@ -131,14 +133,14 @@ void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, boo  		stop_glerror();  	} -	addColorAttachment(color_fmt); +	return addColorAttachment(color_fmt);  } -void LLRenderTarget::addColorAttachment(U32 color_fmt) +bool LLRenderTarget::addColorAttachment(U32 color_fmt)  {  	if (color_fmt == 0)  	{ -		return; +		return true;  	}  	U32 offset = mTex.size(); @@ -158,14 +160,26 @@ void LLRenderTarget::addColorAttachment(U32 color_fmt)  #ifdef GL_ARB_texture_multisample  	if (mSamples > 1)  	{ +		clear_glerror();  		glTexImage2DMultisample(LLTexUnit::getInternalType(mUsage), mSamples, color_fmt, mResX, mResY, GL_TRUE); +		if (glGetError() != GL_NO_ERROR) +		{ +			llwarns << "Could not allocate multisample color buffer for render target." << llendl; +			return false; +		}  	}  	else  #else  	llassert_always(mSamples <= 1);  #endif  	{ +		clear_glerror();  		LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL); +		if (glGetError() != GL_NO_ERROR) +		{ +			llwarns << "Could not allocate color buffer for render target." << llendl; +			return false; +		}  	}  	stop_glerror(); @@ -217,15 +231,18 @@ void LLRenderTarget::addColorAttachment(U32 color_fmt)  		flush();  	} +	return true;  } -void LLRenderTarget::allocateDepth() +bool LLRenderTarget::allocateDepth()  {  	if (mStencil)  	{  		//use render buffers where stencil buffers are in play  		glGenRenderbuffers(1, (GLuint *) &mDepth);  		glBindRenderbuffer(GL_RENDERBUFFER, mDepth); +		stop_glerror(); +		clear_glerror();  		glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, mResX, mResY);  		glBindRenderbuffer(GL_RENDERBUFFER, 0);  	} @@ -237,17 +254,29 @@ void LLRenderTarget::allocateDepth()  		{  			U32 internal_type = LLTexUnit::getInternalType(mUsage);  			gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); +			stop_glerror(); +			clear_glerror();  			LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT32, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);  		}  #ifdef GL_ARB_texture_multisample  		else  		{ +			stop_glerror(); +			clear_glerror();  			glTexImage2DMultisample(LLTexUnit::getInternalType(mUsage), mSamples, GL_DEPTH_COMPONENT32, mResX, mResY, GL_TRUE);  		}  #else  		llassert_always(mSamples <= 1);  #endif  	} + +	if (glGetError() != GL_NO_ERROR) +	{ +		llwarns << "Unable to allocate depth buffer for render target." << llendl; +		return false; +	} + +	return true;  }  void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target) diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h index 094b58b562..dea1de12d8 100644 --- a/indra/llrender/llrendertarget.h +++ b/indra/llrender/llrendertarget.h @@ -66,30 +66,30 @@ public:  	static bool sUseFBO;   	LLRenderTarget(); -	virtual ~LLRenderTarget(); +	~LLRenderTarget();  	//allocate resources for rendering  	//must be called before use  	//multiple calls will release previously allocated resources -	void allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, bool use_fbo = false, S32 samples = 0); +	bool allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, bool use_fbo = false, S32 samples = 0);  	//add color buffer attachment  	//limit of 4 color attachments per render target -	virtual void addColorAttachment(U32 color_fmt); +	bool addColorAttachment(U32 color_fmt);  	//allocate a depth texture -	virtual void allocateDepth(); +	bool allocateDepth();  	//share depth buffer with provided render target -	virtual void shareDepthBuffer(LLRenderTarget& target); +	void shareDepthBuffer(LLRenderTarget& target);  	//free any allocated resources  	//safe to call redundantly -	virtual void release(); +	void release();  	//bind target for rendering  	//applies appropriate viewport -	virtual void bindTarget(); +	void bindTarget();  	//unbind target for rendering  	static void unbindTarget(); diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 4a0b964e61..1180afa631 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -35,6 +35,8 @@  #include "llmemtype.h"  #include "llrender.h"  #include "llvector4a.h" +#include "llglslshader.h" +  //============================================================================ @@ -65,6 +67,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 +365,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 +397,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 +423,7 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const  	stop_glerror();  	glDrawArrays(sGLMode[mode], first, count);  	stop_glerror(); +	placeFence();  }  //static @@ -444,9 +503,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 +588,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 +984,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 +1053,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 +1093,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 +1104,50 @@ 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); +#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); +#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,51 @@ 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); +#endif +					} +					else +					{ +#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); +#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*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, sizeof(U16)*mNumIndices, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT); +						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 +1340,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 +1395,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 +1405,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 +1458,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 +1467,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; | 
