diff options
Diffstat (limited to 'indra/llrender')
| -rw-r--r-- | indra/llrender/llgl.cpp | 27 | ||||
| -rw-r--r--[-rwxr-xr-x] | indra/llrender/llimagegl.cpp | 43 | ||||
| -rw-r--r--[-rwxr-xr-x] | indra/llrender/llimagegl.h | 7 | ||||
| -rw-r--r-- | indra/llrender/llrendertarget.cpp | 4 | ||||
| -rw-r--r-- | indra/llrender/llvertexbuffer.cpp | 157 | ||||
| -rw-r--r-- | indra/llrender/llvertexbuffer.h | 4 | 
6 files changed, 200 insertions, 42 deletions
| diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index 197bc2b422..628a8d6131 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -94,6 +94,10 @@ void APIENTRY gl_debug_callback(GLenum source,  	llwarns << "Severity: " << std::hex << severity << llendl;  	llwarns << "Message: " << message << llendl;  	llwarns << "-----------------------" << llendl; +	if (severity == GL_DEBUG_SEVERITY_HIGH_ARB) +	{ +		llerrs << "Halting on GL Error" << llendl; +	}  }  #endif @@ -572,6 +576,15 @@ bool LLGLManager::initGL()  #endif  	} +	if (mGLVersion >= 2.1f && LLImageGL::sCompressTextures) +	{ //use texture compression +		glHint(GL_TEXTURE_COMPRESSION_HINT, GL_NICEST); +	} +	else +	{ //GL version is < 3.0, always disable texture compression +		LLImageGL::sCompressTextures = false; +	} +	  	// Trailing space necessary to keep "nVidia Corpor_ati_on" cards  	// from being recognized as ATI.  	if (mGLVendor.substr(0,4) == "ATI ") @@ -592,11 +605,8 @@ bool LLGLManager::initGL()  #endif // LL_WINDOWS  #if (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS -		// release 7277 is a point at which we verify that ATI OpenGL -		// drivers get pretty stable with SL, ~Catalyst 8.2, -		// for both Win32 and Linux. -		if (mDriverVersionRelease < 7277 && -		    mDriverVersionRelease != 0) // 0 == Undetectable driver version - these get to pretend to be new ATI drivers, though that decision may be revisited. +		// count any pre OpenGL 3.0 implementation as an old driver +		if (mGLVersion < 3.f)   		{  			mATIOldDriver = TRUE;  		} @@ -735,6 +745,11 @@ bool LLGLManager::initGL()  	}  #endif +	if (mIsIntel && mGLVersion <= 3.f) +	{ //never try to use framebuffer objects on older intel drivers (crashy) +		mHasFramebufferObject = FALSE; +	} +  	if (mHasFramebufferObject)  	{  		glGetIntegerv(GL_MAX_SAMPLES, &mMaxSamples); @@ -1897,7 +1912,7 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)  	glClientActiveTextureARB(GL_TEXTURE0_ARB);  	gGL.getTexUnit(0)->activate(); -	if (gGLManager.mHasVertexShader) +	if (gGLManager.mHasVertexShader && LLGLSLShader::sNoFixedFunction)  	{	//make sure vertex attribs are all disabled  		GLint count;  		glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &count); diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 2c13fead97..c04a3f6b41 100755..100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -56,6 +56,7 @@ BOOL LLImageGL::sGlobalUseAnisotropic	= FALSE;  F32 LLImageGL::sLastFrameTime			= 0.f;  BOOL LLImageGL::sAllowReadBackRaw       = FALSE ;  LLImageGL* LLImageGL::sDefaultGLTexture = NULL ; +bool LLImageGL::sCompressTextures = false;  std::set<LLImageGL*> LLImageGL::sImageList; @@ -409,6 +410,8 @@ void LLImageGL::init(BOOL usemipmaps)  	mDiscardLevelInAtlas = -1 ;  	mTexelsInAtlas = 0 ;  	mTexelsInGLTexture = 0 ; + +	mAllowCompression = true;  	mTarget = GL_TEXTURE_2D;  	mBindTarget = LLTexUnit::TT_TEXTURE; @@ -637,7 +640,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)  						stop_glerror();  					} -					LLImageGL::setManualImage(mTarget, gl_level, mFormatInternal, w, h, mFormatPrimary, GL_UNSIGNED_BYTE, (GLvoid*)data_in); +					LLImageGL::setManualImage(mTarget, gl_level, mFormatInternal, w, h, mFormatPrimary, GL_UNSIGNED_BYTE, (GLvoid*)data_in, mAllowCompression);  					if (gl_level == 0)  					{  						analyzeAlpha(data_in, w, h); @@ -679,7 +682,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)  					LLImageGL::setManualImage(mTarget, 0, mFormatInternal,  								 w, h,   								 mFormatPrimary, mFormatType, -								 data_in); +								 data_in, mAllowCompression);  					analyzeAlpha(data_in, w, h);  					stop_glerror(); @@ -737,7 +740,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)  							stop_glerror();  						} -						LLImageGL::setManualImage(mTarget, m, mFormatInternal, w, h, mFormatPrimary, mFormatType, cur_mip_data); +						LLImageGL::setManualImage(mTarget, m, mFormatInternal, w, h, mFormatPrimary, mFormatType, cur_mip_data, mAllowCompression);  						if (m == 0)  						{  							analyzeAlpha(data_in, w, h); @@ -795,7 +798,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)  			}  			LLImageGL::setManualImage(mTarget, 0, mFormatInternal, w, h, -						 mFormatPrimary, mFormatType, (GLvoid *)data_in); +						 mFormatPrimary, mFormatType, (GLvoid *)data_in, mAllowCompression);  			analyzeAlpha(data_in, w, h);  			updatePickMask(w, h, data_in); @@ -1042,7 +1045,7 @@ void LLImageGL::deleteTextures(S32 numTextures, U32 *textures, bool immediate)  }  // static -void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels) +void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels, bool allow_compression)  {  	bool use_scratch = false;  	U32* scratch = NULL; @@ -1105,6 +1108,36 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt  		}  	} +	if (LLImageGL::sCompressTextures && allow_compression) +	{ +		switch (intformat) +		{ +			case GL_RGB:  +			case GL_RGB8: +				intformat = GL_COMPRESSED_RGB;  +				break; +			case GL_RGBA: +			case GL_RGBA8: +				intformat = GL_COMPRESSED_RGBA;  +				break; +			case GL_LUMINANCE: +			case GL_LUMINANCE8: +				intformat = GL_COMPRESSED_LUMINANCE; +				break; +			case GL_LUMINANCE_ALPHA: +			case GL_LUMINANCE8_ALPHA8: +				intformat = GL_COMPRESSED_LUMINANCE_ALPHA; +				break; +			case GL_ALPHA: +			case GL_ALPHA8: +				intformat = GL_COMPRESSED_ALPHA; +				break; +			default: +				llwarns << "Could not compress format: " << std::hex << intformat << llendl; +				break; +		} +	} +  	stop_glerror();  	glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, use_scratch ? scratch : pixels);  	stop_glerror(); diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index e515d6b324..f34b9fa91a 100755..100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -94,12 +94,13 @@ public:  	void setSize(S32 width, S32 height, S32 ncomponents);  	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); +	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() ;  	BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE, @@ -210,6 +211,8 @@ private:  	U32      mTexelsInAtlas ;  	U32      mTexelsInGLTexture; +	bool mAllowCompression; +  protected:  	LLGLenum mTarget;		// Normally GL_TEXTURE2D, sometimes something else (ex. cube maps)  	LLTexUnit::eTextureType mBindTarget;	// Normally TT_TEXTURE, sometimes something else (ex. cube maps) @@ -245,7 +248,7 @@ public:  	static BOOL sGlobalUseAnisotropic;  	static LLImageGL* sDefaultGLTexture ;	  	static BOOL sAutomatedTest; - +	static bool sCompressTextures;			//use GL texture compression  #if DEBUG_MISS  	BOOL mMissed; // Missed on last bind?  	BOOL getMissed() const { return mMissed; }; diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index ef2a7395da..780f1dc484 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -143,7 +143,7 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)  	{  		clear_glerror(); -		LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL); +		LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL, false);  		if (glGetError() != GL_NO_ERROR)  		{  			llwarns << "Could not allocate color buffer for render target." << llendl; @@ -223,7 +223,7 @@ bool LLRenderTarget::allocateDepth()  		U32 internal_type = LLTexUnit::getInternalType(mUsage);  		stop_glerror();  		clear_glerror(); -		LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT24, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); +		LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT24, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL, false);  		gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);  	} diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 8b5503229f..b4899209c4 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -38,6 +38,8 @@  #include "llglslshader.h"  #include "llmemory.h" +#define LL_VBO_POOLING 0 +  //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) @@ -49,6 +51,35 @@ U32 nhpo2(U32 v)  	return r;  } +//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; +} + + +const U32 LL_VBO_BLOCK_SIZE = 2048; + +U32 vbo_block_size(U32 size) +{ //what block size will fit size? +	U32 mod = size % LL_VBO_BLOCK_SIZE; +	return mod == 0 ? size : size + (LL_VBO_BLOCK_SIZE-mod); +} + +U32 vbo_block_index(U32 size) +{ +	return vbo_block_size(size)/LL_VBO_BLOCK_SIZE; +} + +  //============================================================================ @@ -57,7 +88,11 @@ LLVBOPool LLVertexBuffer::sStreamVBOPool(GL_STREAM_DRAW_ARB, GL_ARRAY_BUFFER_ARB  LLVBOPool LLVertexBuffer::sDynamicVBOPool(GL_DYNAMIC_DRAW_ARB, GL_ARRAY_BUFFER_ARB);  LLVBOPool LLVertexBuffer::sStreamIBOPool(GL_STREAM_DRAW_ARB, GL_ELEMENT_ARRAY_BUFFER_ARB);  LLVBOPool LLVertexBuffer::sDynamicIBOPool(GL_DYNAMIC_DRAW_ARB, GL_ELEMENT_ARRAY_BUFFER_ARB); +  U32 LLVBOPool::sBytesPooled = 0; +U32 LLVBOPool::sIndexBytesPooled = 0; +U32 LLVertexBuffer::sAllocatedIndexBytes = 0; +U32 LLVertexBuffer::sIndexCount = 0;  LLPrivateMemoryPool* LLVertexBuffer::sPrivatePoolp = NULL;  U32 LLVertexBuffer::sBindCount = 0; @@ -74,6 +109,7 @@ U32 LLVertexBuffer::sLastMask = 0;  bool LLVertexBuffer::sVBOActive = false;  bool LLVertexBuffer::sIBOActive = false;  U32 LLVertexBuffer::sAllocatedBytes = 0; +U32 LLVertexBuffer::sVertexCount = 0;  bool LLVertexBuffer::sMapped = false;  bool LLVertexBuffer::sUseStreamDraw = true;  bool LLVertexBuffer::sUseVAO = false; @@ -134,39 +170,35 @@ 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; -} -  volatile U8* LLVBOPool::allocate(U32& name, U32 size)  { -	llassert(nhpo2(size) == size); +	llassert(vbo_block_size(size) == size); +	 +	volatile U8* ret = NULL; + +#if LL_VBO_POOLING -	U32 i = wpo2(size); +	U32 i = vbo_block_index(size);  	if (mFreeList.size() <= i)  	{  		mFreeList.resize(i+1);  	} -	volatile U8* ret = NULL; -  	if (mFreeList[i].empty())  	{  		//make a new buffer  		glGenBuffersARB(1, &name);  		glBindBufferARB(mType, name); -		LLVertexBuffer::sAllocatedBytes += size; + +		if (mType == GL_ARRAY_BUFFER_ARB) +		{ +			LLVertexBuffer::sAllocatedBytes += size; +		} +		else +		{ +			LLVertexBuffer::sAllocatedIndexBytes += size; +		}  		if (LLVertexBuffer::sDisableVBOMapping || mUsage != GL_DYNAMIC_DRAW_ARB)  		{ @@ -185,19 +217,55 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size)  		name = mFreeList[i].front().mGLName;  		ret = mFreeList[i].front().mClientData; -		sBytesPooled -= size; +		if (mType == GL_ARRAY_BUFFER_ARB) +		{ +			sBytesPooled -= size; +		} +		else +		{ +			sIndexBytesPooled -= size; +		}  		mFreeList[i].pop_front();  	} +#else //no pooling + +	glGenBuffersARB(1, &name); +	glBindBufferARB(mType, name); + +	if (mType == GL_ARRAY_BUFFER_ARB) +	{ +		LLVertexBuffer::sAllocatedBytes += size; +	} +	else +	{ +		LLVertexBuffer::sAllocatedIndexBytes += size; +	} + +	if (LLVertexBuffer::sDisableVBOMapping || mUsage != GL_DYNAMIC_DRAW_ARB) +	{ +		glBufferDataARB(mType, size, 0, mUsage); +		ret = (U8*) ll_aligned_malloc_16(size); +	} +	else +	{ //always use a true hint of static draw when allocating non-client-backed buffers +		glBufferDataARB(mType, size, 0, GL_STATIC_DRAW_ARB); +	} + +	glBindBufferARB(mType, 0); + +#endif  	return ret;  }  void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size)  { -	llassert(nhpo2(size) == size); +	llassert(vbo_block_size(size) == size); -	U32 i = wpo2(size); +#if LL_VBO_POOLING + +	U32 i = vbo_block_index(size);  	llassert(mFreeList.size() > i); @@ -211,9 +279,29 @@ void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size)  	}  	else  	{ -		sBytesPooled += size; +		if (mType == GL_ARRAY_BUFFER_ARB) +		{ +			sBytesPooled += size; +		} +		else +		{ +			sIndexBytesPooled += size; +		}  		mFreeList[i].push_back(rec);  	} +#else //no pooling +	glDeleteBuffersARB(1, &name); +	ll_aligned_free_16((U8*) buffer); + +	if (mType == GL_ARRAY_BUFFER_ARB) +	{ +		LLVertexBuffer::sAllocatedBytes -= size; +	} +	else +	{ +		LLVertexBuffer::sAllocatedIndexBytes -= size; +	} +#endif  }  void LLVBOPool::cleanup() @@ -237,8 +325,16 @@ void LLVBOPool::cleanup()  			l.pop_front(); -			LLVertexBuffer::sAllocatedBytes -= size; -			sBytesPooled -= size; +			if (mType == GL_ARRAY_BUFFER_ARB) +			{ +				sBytesPooled -= size; +				LLVertexBuffer::sAllocatedBytes -= size; +			} +			else +			{ +				sIndexBytesPooled -= size; +				LLVertexBuffer::sAllocatedIndexBytes -= size; +			}  		}  		size *= 2; @@ -898,6 +994,9 @@ LLVertexBuffer::~LLVertexBuffer()  	mFence = NULL; +	sVertexCount -= mNumVerts; +	sIndexCount -= mNumIndices; +  	llassert_always(!mMappedData && !mMappedIndexData);  }; @@ -929,7 +1028,7 @@ void LLVertexBuffer::waitFence() const  void LLVertexBuffer::genBuffer(U32 size)  { -	mSize = nhpo2(size); +	mSize = vbo_block_size(size);  	if (mUsage == GL_STREAM_DRAW_ARB)  	{ @@ -945,7 +1044,7 @@ void LLVertexBuffer::genBuffer(U32 size)  void LLVertexBuffer::genIndices(U32 size)  { -	mIndicesSize = nhpo2(size); +	mIndicesSize = vbo_block_size(size);  	if (mUsage == GL_STREAM_DRAW_ARB)  	{ @@ -1121,7 +1220,9 @@ void LLVertexBuffer::updateNumVerts(S32 nverts)  		createGLBuffer(needed_size);  	} +	sVertexCount -= mNumVerts;  	mNumVerts = nverts; +	sVertexCount += mNumVerts;  }  void LLVertexBuffer::updateNumIndices(S32 nindices) @@ -1137,7 +1238,9 @@ void LLVertexBuffer::updateNumIndices(S32 nindices)  		createGLIndices(needed_size);  	} +	sIndexCount -= mNumIndices;  	mNumIndices = nindices; +	sIndexCount += mNumIndices;  }  void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create) diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index d859199663..7477dec3ad 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -55,6 +55,7 @@ class LLVBOPool  {  public:  	static U32 sBytesPooled; +	static U32 sIndexBytesPooled;  	LLVBOPool(U32 vboUsage, U32 vboType)  		: mUsage(vboUsage) @@ -332,6 +333,9 @@ public:  	static bool sIBOActive;  	static U32 sLastMask;  	static U32 sAllocatedBytes; +	static U32 sAllocatedIndexBytes; +	static U32 sVertexCount; +	static U32 sIndexCount;  	static U32 sBindCount;  	static U32 sSetCount;  }; | 
