diff options
| -rw-r--r-- | indra/llrender/llgl.cpp | 3 | ||||
| -rw-r--r-- | indra/llrender/llimagegl.cpp | 84 | ||||
| -rw-r--r-- | indra/llrender/llimagegl.h | 5 | ||||
| -rw-r--r-- | indra/llrender/llrender.cpp | 18 | ||||
| -rw-r--r-- | indra/llrender/llrendertarget.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/lltextureatlas.cpp | 1 | ||||
| -rw-r--r-- | indra/newview/llvoavatar.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/llvoavatarself.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/pipeline.cpp | 6 | 
9 files changed, 78 insertions, 49 deletions
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index 3946c43929..0b56b3889c 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -946,7 +946,6 @@ void LLGLManager::initExtensions()  	mHasMultitexture = glh_init_extensions("GL_ARB_multitexture");  	mHasATIMemInfo = ExtensionExists("GL_ATI_meminfo", gGLHExts.mSysExts);  	mHasNVXMemInfo = ExtensionExists("GL_NVX_gpu_memory_info", gGLHExts.mSysExts); -	mHasMipMapGeneration = glh_init_extensions("GL_SGIS_generate_mipmap");  	mHasSeparateSpecularColor = glh_init_extensions("GL_EXT_separate_specular_color");  	mHasAnisotropic = glh_init_extensions("GL_EXT_texture_filter_anisotropic");  	glh_init_extensions("GL_ARB_texture_cube_map"); @@ -971,6 +970,8 @@ void LLGLManager::initExtensions()  							ExtensionExists("GL_EXT_packed_depth_stencil", gGLHExts.mSysExts);  #endif +	mHasMipMapGeneration = mHasFramebufferObject || mGLVersion >= 1.4f; +  	mHasDrawBuffers = ExtensionExists("GL_ARB_draw_buffers", gGLHExts.mSysExts);  	mHasBlendFuncSeparate = ExtensionExists("GL_EXT_blend_func_separate", gGLHExts.mSysExts);  	mHasTextureRectangle = ExtensionExists("GL_ARB_texture_rectangle", gGLHExts.mSysExts); diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index bb585cc49c..793fd4be31 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -42,6 +42,10 @@  //----------------------------------------------------------------------------  const F32 MIN_TEXTURE_LIFETIME = 10.f; +//which power of 2 is i? +//assumes i is a power of 2 > 0 +U32 wpo2(U32 i); +  //statics  LLGLuint LLImageGL::sCurrentBoundTextures[MAX_GL_TEXTURE_UNITS] = { 0 }; @@ -485,6 +489,7 @@ void LLImageGL::init(BOOL usemipmaps)  	mTarget = GL_TEXTURE_2D;  	mBindTarget = LLTexUnit::TT_TEXTURE;  	mHasMipMaps = false; +	mMipLevels = -1;  	mIsResident = 0; @@ -675,8 +680,24 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)  		is_compressed = true;  	} +	 +	 +	if (mUseMipMaps) +	{ +		//set has mip maps to true before binding image so tex parameters get set properly +		gGL.getTexUnit(0)->unbind(mBindTarget); +		mHasMipMaps = true; +		mTexOptionsDirty = true; +		setFilteringOption(LLTexUnit::TFO_ANISOTROPIC); +	} +	else +	{ +		mHasMipMaps = false; +	} +	  	llverify(gGL.getTexUnit(0)->bind(this)); +	  	if (mUseMipMaps)  	{  		if (data_hasmips) @@ -689,6 +710,9 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)  				S32 w = getWidth(d);  				S32 h = getHeight(d);  				S32 gl_level = d-mCurrentDiscardLevel; + +				mMipLevels = llmax(mMipLevels, gl_level); +  				if (d > mCurrentDiscardLevel)  				{  					data_in -= dataFormatBytes(mFormatPrimary, w, h); // see above comment @@ -731,10 +755,6 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)  		{  			if (mAutoGenMips)  			{ -				if (!gGLManager.mHasFramebufferObject) -				{ -					glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_GENERATE_MIPMAP_SGIS, TRUE); -				}  				stop_glerror();  				{  // 					LLFastTimer t2(FTM_TEMP4); @@ -748,6 +768,11 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)  					S32 w = getWidth(mCurrentDiscardLevel);  					S32 h = getHeight(mCurrentDiscardLevel); +					mMipLevels = wpo2(llmax(w, h)); + +					//use legacy mipmap generation mode +					glTexParameteri(mTarget, GL_GENERATE_MIPMAP, GL_TRUE); +					  					LLImageGL::setManualImage(mTarget, 0, mFormatInternal,  								 w, h,   								 mFormatPrimary, mFormatType, @@ -763,19 +788,10 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)  						stop_glerror();  					}  				} - -				if (gGLManager.mHasFramebufferObject) -				{ -					gGL.getTexUnit(0)->unbind(mBindTarget); -					gGL.getTexUnit(0)->bind(this); - -					glGenerateMipmap(LLTexUnit::getInternalType(mBindTarget)); -				}  			}  			else  			{  				// Create mips by hand -				// about 30% faster than autogen on ATI 9800, 50% slower on nVidia 4800  				// ~4x faster than gluBuild2DMipmaps  				S32 width = getWidth(mCurrentDiscardLevel);  				S32 height = getHeight(mCurrentDiscardLevel); @@ -785,6 +801,9 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)  				const U8* cur_mip_data = 0;  				S32 prev_mip_size = 0;  				S32 cur_mip_size = 0; +				 +				mMipLevels = nummips; +  				for (int m=0; m<nummips; m++)  				{  					if (m==0) @@ -849,10 +868,10 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)  		{  			llerrs << "Compressed Image has mipmaps but data does not (can not auto generate compressed mips)" << llendl;  		} -		mHasMipMaps = true;  	}  	else  	{ +		mMipLevels = 0;  		S32 w = getWidth();  		S32 h = getHeight();  		if (is_compressed) @@ -884,7 +903,6 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)  			}  		} -		mHasMipMaps = false;  	}  	stop_glerror();  	mGLTextureCreated = true; @@ -1124,35 +1142,31 @@ void LLImageGL::generateTextures(LLTexUnit::eTextureType type, U32 format, S32 n  }  // static -void LLImageGL::deleteTextures(LLTexUnit::eTextureType type, U32 format, S32 numTextures, U32 *textures, bool immediate) +void LLImageGL::deleteTextures(LLTexUnit::eTextureType type, U32 format, S32 mip_levels, S32 numTextures, U32 *textures, bool immediate)  {  	if (gGLManager.mInited)  	{ -		if (format == 0) -		{ //unknown internal format, not safe to reuse +		if (format == 0 ||  type == LLTexUnit::TT_CUBE_MAP || mip_levels == -1) +		{ //unknown internal format or unknown number of mip levels, not safe to reuse  			glDeleteTextures(numTextures, textures);  		}  		else  		{  			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 (type == LLTexUnit::TT_CUBE_MAP) -				{ -					glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, format, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); -					glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, format, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); -					glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, format, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); -					glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, format, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); -					glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, format, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); -					glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, format, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); -				} -				else +				for (S32 j = 0; j <= mip_levels; j++)  				{ -					glTexImage2D(LLTexUnit::getInternalType(type), 0, format, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); +					gGL.getTexUnit(0)->bindManual(type, textures[i]); + +					glTexImage2D(LLTexUnit::getInternalType(type), j, format, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);  				} + +				llassert(std::find(sDeadTextureList[type][format].begin(), +								   sDeadTextureList[type][format].end(), textures[i]) ==  +								   sDeadTextureList[type][format].end()); +  				sDeadTextureList[type][format].push_back(textures[i]); -			} +			}	  		}  	} @@ -1284,7 +1298,7 @@ BOOL LLImageGL::createGLTexture()  	if(mTexName)  	{ -		LLImageGL::deleteTextures(mBindTarget, mFormatInternal, 1, (reinterpret_cast<GLuint*>(&mTexName))) ; +		LLImageGL::deleteTextures(mBindTarget, mFormatInternal, mMipLevels, 1, (reinterpret_cast<GLuint*>(&mTexName))) ;  	} @@ -1451,7 +1465,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_  			decTextureCounter(mTextureMemory, mComponents, mCategory) ;  		} -		LLImageGL::deleteTextures(mBindTarget, mFormatInternal, 1, &old_name); +		LLImageGL::deleteTextures(mBindTarget, mFormatInternal, mMipLevels, 1, &old_name);  		stop_glerror();  	} @@ -1628,7 +1642,7 @@ void LLImageGL::destroyGLTexture()  			mTextureMemory = 0;  		} -		LLImageGL::deleteTextures(mBindTarget,  mFormatInternal, 1, &mTexName);			 +		LLImageGL::deleteTextures(mBindTarget,  mFormatInternal, mMipLevels, 1, &mTexName);			  		mTexName = 0;  		mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel.  		mGLTextureCreated = FALSE ; diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index 34efafb015..0d5785d3bf 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -54,7 +54,7 @@ public:  	// These 2 functions replace glGenTextures() and glDeleteTextures()  	static void generateTextures(LLTexUnit::eTextureType type, U32 format, S32 numTextures, U32 *textures); -	static void deleteTextures(LLTexUnit::eTextureType type, U32 format, S32 numTextures, U32 *textures, bool immediate = false); +	static void deleteTextures(LLTexUnit::eTextureType type, U32 format, S32 mip_levels, S32 numTextures, U32 *textures, bool immediate = false);  	static void deleteDeadTextures();  	// Size calculation @@ -220,7 +220,8 @@ protected:  	LLGLenum mTarget;		// Normally GL_TEXTURE2D, sometimes something else (ex. cube maps)  	LLTexUnit::eTextureType mBindTarget;	// Normally TT_TEXTURE, sometimes something else (ex. cube maps)  	bool mHasMipMaps; -	 +	S32 mMipLevels; +  	LLGLboolean mIsResident;  	S8 mComponents; diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 51f45ca91e..b45ff1a6b7 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -474,11 +474,25 @@ void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions optio  	}   	else if (option >= TFO_BILINEAR)  	{ -		glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR); +		if (mHasMipMaps) +		{ +			glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); +		} +		else +		{ +			glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR); +		}  	}  	else  	{ -		glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_NEAREST); +		if (mHasMipMaps) +		{ +			glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); +		} +		else +		{ +			glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_NEAREST); +		}  	}  	if (gGLManager.mHasAnisotropic) diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index ced6b013ec..99f0da330c 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -294,7 +294,7 @@ void LLRenderTarget::release()  		}  		else  		{ -			LLImageGL::deleteTextures(mUsage, 0, 1, &mDepth, true); +			LLImageGL::deleteTextures(mUsage, 0, 0, 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(mUsage, mInternalFormat[0], mTex.size(), &mTex[0], true); +		LLImageGL::deleteTextures(mUsage, mInternalFormat[0], 0, mTex.size(), &mTex[0], true);  		mTex.clear();  		mInternalFormat.clear();  	} diff --git a/indra/newview/lltextureatlas.cpp b/indra/newview/lltextureatlas.cpp index d2e4b01732..f8c1bca8ae 100644 --- a/indra/newview/lltextureatlas.cpp +++ b/indra/newview/lltextureatlas.cpp @@ -116,7 +116,6 @@ LLGLuint LLTextureAtlas::insertSubTexture(LLImageGL* source_gl_tex, S32 discard_  		return 0 ;  	} -	glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, TRUE);  	glTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, w, h,  						mGLTexturep->getPrimaryFormat(), mGLTexturep->getFormatType(), raw_image->getData()); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index cbb818a304..240caeee1c 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -896,7 +896,7 @@ void LLVOAvatar::deleteLayerSetCaches(bool clearAll)  		}  		if (mBakedTextureDatas[i].mMaskTexName)  		{ -			LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_ALPHA8, 1, (GLuint*)&(mBakedTextureDatas[i].mMaskTexName)); +			LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, 0, -1, 1, (GLuint*)&(mBakedTextureDatas[i].mMaskTexName));  			mBakedTextureDatas[i].mMaskTexName = 0 ;  		}  	} @@ -7431,7 +7431,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture  						maskData->mLastDiscardLevel = discard_level;  						if (self->mBakedTextureDatas[baked_index].mMaskTexName)  						{ -							LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_ALPHA8, 1, &(self->mBakedTextureDatas[baked_index].mMaskTexName)); +							LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, 0, -1, 1, &(self->mBakedTextureDatas[baked_index].mMaskTexName));  						}  						self->mBakedTextureDatas[baked_index].mMaskTexName = gl_name;  						found_texture_id = true; diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index fcfa0b7d15..c99e94e60c 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -2605,7 +2605,7 @@ void LLVOAvatarSelf::deleteScratchTextures()  		 namep;   		 namep = sScratchTexNames.getNextData() )  	{ -		LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, 0, 1, (U32 *)namep ); +		LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, 0, -1, 1, (U32 *)namep );  		stop_glerror();  	} diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 75f8346938..09ce17d7fa 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1047,19 +1047,19 @@ void LLPipeline::releaseGLBuffers()  	if (mNoiseMap)  	{ -		LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_RGB16F_ARB, 1, &mNoiseMap); +		LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_RGB16F_ARB, 0, 1, &mNoiseMap);  		mNoiseMap = 0;  	}  	if (mTrueNoiseMap)  	{ -		LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_RGB16F_ARB, 1, &mTrueNoiseMap); +		LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_RGB16F_ARB, 0, 1, &mTrueNoiseMap);  		mTrueNoiseMap = 0;  	}  	if (mLightFunc)  	{ -		LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_R8, 1, &mLightFunc); +		LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_R8, 0, 1, &mLightFunc);  		mLightFunc = 0;  	}  | 
