davep avatar davep committed 24118e6

MAINT-616 Fix for corrupted mipmaps. Cleanup based on code review feedback.

Comments (0)

Files changed (14)

indra/llrender/llcubemap.cpp

 		{
 			U32 texname = 0;
 			
-			LLImageGL::generateTextures(LLTexUnit::TT_CUBE_MAP, 1, &texname);
+			LLImageGL::generateTextures(LLTexUnit::TT_CUBE_MAP, GL_RGB8, 1, &texname);
 
 			for (int i = 0; i < 6; i++)
 			{

indra/llrender/llgl.h

 	virtual void updateGL() = 0;
 };
 
-const U32 FENCE_WAIT_TIME_NANOSECONDS = 10000;  //1 ms
+const U32 FENCE_WAIT_TIME_NANOSECONDS = 1000;  //1 ms
 
 class LLGLFence
 {

indra/llrender/llimagegl.cpp

 S32 LLImageGL::sBoundTextureMemoryInBytes		= 0;
 S32 LLImageGL::sCurBoundTextureMemory	= 0;
 S32 LLImageGL::sCount					= 0;
-std::list<U32> LLImageGL::sDeadTextureList[LLTexUnit::TT_NONE];
+LLImageGL::dead_texturelist_t LLImageGL::sDeadTextureList[LLTexUnit::TT_NONE];
 U32 LLImageGL::sCurTexName = 1;
 
 BOOL LLImageGL::sGlobalUseAnisotropic	= FALSE;
 
 				if (gGLManager.mHasFramebufferObject)
 				{
+					gGL.getTexUnit(0)->unbind(mBindTarget);
+					gGL.getTexUnit(0)->bind(this);
+
 					glGenerateMipmap(LLTexUnit::getInternalType(mBindTarget));
 				}
 			}
 }
 
 // static
-void LLImageGL::generateTextures(LLTexUnit::eTextureType type, S32 numTextures, U32 *textures)
+void LLImageGL::generateTextures(LLTexUnit::eTextureType type, U32 format, S32 numTextures, U32 *textures)
 {
+	bool empty = true;
+
+	dead_texturelist_t::iterator iter = sDeadTextureList[type].find(format);
+	
+	if (iter != sDeadTextureList[type].end())
+	{
+		empty = iter->second.empty();
+	}
+	
 	for (S32 i = 0; i < numTextures; ++i)
 	{
-		if (!sDeadTextureList[type].empty())
+		if (!empty)
 		{
-			textures[i] = sDeadTextureList[type].front();
-			sDeadTextureList[type].pop_front();
+			textures[i] = iter->second.front();
+			iter->second.pop_front();
+			empty = iter->second.empty();
 		}
 		else
 		{
 }
 
 // static
-void LLImageGL::deleteTextures(LLTexUnit::eTextureType type, S32 numTextures, U32 *textures, bool immediate)
+void LLImageGL::deleteTextures(LLTexUnit::eTextureType type, U32 format, S32 numTextures, U32 *textures, bool immediate)
 {
 	if (gGLManager.mInited)
 	{
-		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 (format == 0)
+		{ //unknown internal format, 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, 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);
+				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
+				{
+					glTexImage2D(LLTexUnit::getInternalType(type), 0, format, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+				}
+				sDeadTextureList[type][format].push_back(textures[i]);
 			}
-			else
-			{
-				glTexImage2D(LLTexUnit::getInternalType(type), 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
-			}
-			sDeadTextureList[type].push_back(textures[i]);
 		}
 	}
 	
 
 	if(mTexName)
 	{
-		LLImageGL::deleteTextures(mBindTarget, 1, (reinterpret_cast<GLuint*>(&mTexName))) ;
+		LLImageGL::deleteTextures(mBindTarget, mFormatInternal, 1, (reinterpret_cast<GLuint*>(&mTexName))) ;
 	}
 	
 
-	LLImageGL::generateTextures(mBindTarget, 1, &mTexName);
+	LLImageGL::generateTextures(mBindTarget, mFormatInternal, 1, &mTexName);
 	stop_glerror();
 	if (!mTexName)
 	{
 	}
 	else
 	{
-		LLImageGL::generateTextures(mBindTarget, 1, &mTexName);
+		LLImageGL::generateTextures(mBindTarget, mFormatInternal, 1, &mTexName);
 		stop_glerror();
 		{
 			llverify(gGL.getTexUnit(0)->bind(this));
 			decTextureCounter(mTextureMemory, mComponents, mCategory) ;
 		}
 
-		LLImageGL::deleteTextures(mBindTarget,1, &old_name);
+		LLImageGL::deleteTextures(mBindTarget, mFormatInternal, 1, &old_name);
 
 		stop_glerror();
 	}
 			mTextureMemory = 0;
 		}
 		
-		LLImageGL::deleteTextures(mBindTarget, 1, &mTexName);			
+		LLImageGL::deleteTextures(mBindTarget,  mFormatInternal, 1, &mTexName);			
 		mTexName = 0;
 		mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel.
 		mGLTextureCreated = FALSE ;

indra/llrender/llimagegl.h

 	friend class LLTexUnit;
 public:
 	static U32 sCurTexName;
-	static std::list<U32> sDeadTextureList[LLTexUnit::TT_NONE];
+
+	//previously used but now available texture names
+	// sDeadTextureList[<usage>][<internal format>]
+	typedef std::map<U32, std::list<U32> > dead_texturelist_t;
+	static dead_texturelist_t 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 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 deleteDeadTextures();
 
 	// Size calculation

indra/llrender/llrendertarget.cpp

 LLRenderTarget::LLRenderTarget() :
 	mResX(0),
 	mResY(0),
-	mTex(0),
 	mFBO(0),
 	mDepth(0),
 	mStencil(0),
 	}
 
 	U32 tex;
-	LLImageGL::generateTextures(mUsage, 1, &tex);
+	LLImageGL::generateTextures(mUsage, color_fmt, 1, &tex);
 	gGL.getTexUnit(0)->bindManual(mUsage, tex);
 
 	stop_glerror();
 	}
 
 	mTex.push_back(tex);
+	mInternalFormat.push_back(color_fmt);
 
 	if (gDebugGL)
 	{ //bind and unbind to validate target
 	}
 	else
 	{
-		LLImageGL::generateTextures(mUsage, 1, &mDepth);
+		LLImageGL::generateTextures(mUsage, GL_DEPTH_COMPONENT24, 1, &mDepth);
 		gGL.getTexUnit(0)->bindManual(mUsage, mDepth);
 		
 		U32 internal_type = LLTexUnit::getInternalType(mUsage);
 		}
 		else
 		{
-			LLImageGL::deleteTextures(mUsage, 1, &mDepth, true);
+			LLImageGL::deleteTextures(mUsage, 0, 1, &mDepth, true);
 			stop_glerror();
 		}
 		mDepth = 0;
 	if (mTex.size() > 0)
 	{
 		sBytesAllocated -= mResX*mResY*4*mTex.size();
-		LLImageGL::deleteTextures(mUsage, mTex.size(), &mTex[0], true);
+		LLImageGL::deleteTextures(mUsage, mInternalFormat[0], mTex.size(), &mTex[0], true);
 		mTex.clear();
+		mInternalFormat.clear();
 	}
 	
 	mResX = mResY = 0;

indra/llrender/llrendertarget.h

 	U32 mResX;
 	U32 mResY;
 	std::vector<U32> mTex;
+	std::vector<U32> mInternalFormat;
 	U32 mFBO;
 	U32 mDepth;
 	bool mStencil;

indra/llrender/llvertexbuffer.cpp

 #include "llglslshader.h"
 #include "llmemory.h"
 
-#define LL_VBO_POOLING 1
-
 //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)
 	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)
 {
 	llassert(vbo_block_size(size) == size);
 	
 	volatile U8* ret = NULL;
 
-#if LL_VBO_POOLING
-
 	U32 i = vbo_block_index(size);
 
 	if (mFreeList.size() <= i)
 	{
 		mFreeList.resize(i+1);
-		mMissCount.resize(i+1);
 	}
 
 	if (mFreeList[i].empty() || for_seed)
 	{
 		//make a new buffer
-		{
-			LLFastTimer t(FTM_VBO_GEN_BUFFER);
-			name = genBuffer();
-		}
+		name = genBuffer();
+		
 		glBindBufferARB(mType, name);
 
 		if (!for_seed && i < LL_VBO_POOL_SEED_COUNT)
 		}
 		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);
 		}
 
 
 		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;
 }
 {
 	llassert(vbo_block_size(size) == size);
 
-#if 0 && LL_VBO_POOLING
-
-	U32 i = vbo_block_index(size);
-
-	llassert(mFreeList.size() > i);
-
-	Record rec;
-	rec.mGLName = name;
-	rec.mClientData = buffer;
-	
-	if (buffer == NULL)
-	{
-		glDeleteBuffersARB(1, &rec.mGLName);
-	}
-	else
-	{
-		if (mType == GL_ARRAY_BUFFER_ARB)
-		{
-			sBytesPooled += size;
-		}
-		else
-		{
-			sIndexBytesPooled += size;
-		}
-		mFreeList[i].push_back(rec);
-	}
-#else //no pooling
 	deleteBuffer(name);
 	ll_aligned_free_16((U8*) buffer);
 
 	{
 		LLVertexBuffer::sAllocatedIndexBytes -= size;
 	}
-#endif
 }
 
 void LLVBOPool::seedPool()

indra/newview/app_settings/settings.xml

       <key>Type</key>
       <string>Boolean</string>
       <key>Value</key>
-      <integer>0</integer>
+      <integer>1</integer>
     </map>
   <key>RenderDebugNormalScale</key>
   <map>

indra/newview/app_settings/shaders/class1/transform/binormalV.glsl

 
 ATTRIBUTE vec3 binormal;
 
-VARYING vec3 binormal_out;
+VARYING vec4 binormal_out;
 
 void main()
 {
-	binormal_out = normal_matrix * binormal;
+	binormal_out = vec4(normal_matrix * binormal, 0.0);
 }
 

indra/newview/llfloatermodelpreview.cpp

 	sInstance = this;
 	mLastMouseX = 0;
 	mLastMouseY = 0;
-	mGLName = 0;
 	mStatusLock = new LLMutex(NULL);
 	mModelPreview = NULL;
 
 		delete mModelPreview;
 	}
 
-	if (mGLName)
-	{
-		LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, 1, &mGLName );
-	}
-
 	delete mStatusLock;
 	mStatusLock = NULL;
 }

indra/newview/llfloatermodelpreview.h

 	S32				mLastMouseX;
 	S32				mLastMouseY;
 	LLRect			mPreviewRect;
-	U32				mGLName;
 	static S32		sUploadAmount;
 	
 	std::set<LLPointer<DecompRequest> > mCurRequest;

indra/newview/llvoavatar.cpp

 		}
 		if (mBakedTextureDatas[i].mMaskTexName)
 		{
-			LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, 1, (GLuint*)&(mBakedTextureDatas[i].mMaskTexName));
+			LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_ALPHA8, 1, (GLuint*)&(mBakedTextureDatas[i].mMaskTexName));
 			mBakedTextureDatas[i].mMaskTexName = 0 ;
 		}
 	}
 			}
 
 			U32 gl_name;
-			LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, 1, &gl_name );
+			LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_ALPHA8, 1, &gl_name );
 			stop_glerror();
 
 			gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, gl_name);
 						maskData->mLastDiscardLevel = discard_level;
 						if (self->mBakedTextureDatas[baked_index].mMaskTexName)
 						{
-							LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, 1, &(self->mBakedTextureDatas[baked_index].mMaskTexName));
+							LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_ALPHA8, 1, &(self->mBakedTextureDatas[baked_index].mMaskTexName));
 						}
 						self->mBakedTextureDatas[baked_index].mMaskTexName = gl_name;
 						found_texture_id = true;

indra/newview/llvoavatarself.cpp

 		 namep; 
 		 namep = sScratchTexNames.getNextData() )
 	{
-		LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, 1, (U32 *)namep );
+		LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, 0, 1, (U32 *)namep );
 		stop_glerror();
 	}
 

indra/newview/pipeline.cpp

 	
 	if (mNoiseMap)
 	{
-		LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, 1, &mNoiseMap);
+		LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_RGB16F_ARB, 1, &mNoiseMap);
 		mNoiseMap = 0;
 	}
 
 	if (mTrueNoiseMap)
 	{
-		LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, 1, &mTrueNoiseMap);
+		LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_RGB16F_ARB, 1, &mTrueNoiseMap);
 		mTrueNoiseMap = 0;
 	}
 
 	if (mLightFunc)
 	{
-		LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, 1, &mLightFunc);
+		LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_R8, 1, &mLightFunc);
 		mLightFunc = 0;
 	}
 
 				noise[i].mV[2] = ll_frand()*scaler+1.f-scaler/2.f;
 			}
 
-			LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, 1, &mNoiseMap);
+			LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_RGB16F_ARB, 1, &mNoiseMap);
 			
 			gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap);
 			LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB, GL_FLOAT, noise, false);
 				noise[i] = ll_frand()*2.0-1.0;
 			}
 
-			LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, 1, &mTrueNoiseMap);
+			LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_RGB16F_ARB, 1, &mTrueNoiseMap);
 			gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mTrueNoiseMap);
 			LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB,GL_FLOAT, noise, false);
 			gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
 				}
 			}
 
-			LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, 1, &mLightFunc);
+			LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_R8, 1, &mLightFunc);
 			gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc);
 			LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_R8, lightResX, lightResY, GL_RED, GL_UNSIGNED_BYTE, lg, false);
 			gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.