From eefd0296db800b32f9f3595530e38d2cabfada5a Mon Sep 17 00:00:00 2001
From: Rye Mutt <rye@alchemyviewer.org>
Date: Wed, 11 Mar 2020 08:21:39 -0400
Subject: [PATCH] Fix 64bit issues in texture memory management and allow
 3072mb of texmem usage

---
 indra/llimage/llimage.cpp             |  4 ++--
 indra/llimage/llimage.h               |  4 ++--
 indra/llrender/llgltexture.cpp        |  2 +-
 indra/llrender/llgltexture.h          |  2 +-
 indra/llrender/llimagegl.cpp          | 20 +++++++++---------
 indra/llrender/llimagegl.h            | 12 +++++------
 indra/newview/lltextureinfo.cpp       |  2 +-
 indra/newview/llviewertexture.cpp     | 13 +++++++-----
 indra/newview/llviewertexture.h       |  6 +++---
 indra/newview/llviewertexturelist.cpp | 29 +++++++++++++++++++--------
 10 files changed, 55 insertions(+), 39 deletions(-)

diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 7a0c8cd8f57..e3fbe6c5049 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -793,7 +793,7 @@ U8* LLImageBase::allocateDataSize(S32 width, S32 height, S32 ncomponents, S32 si
 // LLImageRaw
 //---------------------------------------------------------------------------
 
-S32 LLImageRaw::sGlobalRawMemory = 0;
+S64 LLImageRaw::sGlobalRawMemory = 0;
 S32 LLImageRaw::sRawImageCount = 0;
 
 LLImageRaw::LLImageRaw()
@@ -1908,7 +1908,7 @@ bool LLImageRaw::createFromFile(const std::string &filename, bool j2c_lowest_mip
 //---------------------------------------------------------------------------
 
 //static
-S32 LLImageFormatted::sGlobalFormattedMemory = 0;
+S64 LLImageFormatted::sGlobalFormattedMemory = 0;
 
 LLImageFormatted::LLImageFormatted(S8 codec)
 	: LLImageBase(),
diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h
index 9f8d0612939..03c66bf1f50 100644
--- a/indra/llimage/llimage.h
+++ b/indra/llimage/llimage.h
@@ -272,7 +272,7 @@ class LLImageRaw : public LLImageBase
 	void setDataAndSize(U8 *data, S32 width, S32 height, S8 components) ;
 
 public:
-	static S32 sGlobalRawMemory;
+	static S64 sGlobalRawMemory;
 	static S32 sRawImageCount;
 
 private:
@@ -351,7 +351,7 @@ class LLImageFormatted : public LLImageBase
 	S8 mLevels;			// Number of resolution levels in that image. Min is 1. 0 means unknown.
 	
 public:
-	static S32 sGlobalFormattedMemory;
+	static S64 sGlobalFormattedMemory;
 };
 
 #endif
diff --git a/indra/llrender/llgltexture.cpp b/indra/llrender/llgltexture.cpp
index 8223811c95f..66a216ea141 100644
--- a/indra/llrender/llgltexture.cpp
+++ b/indra/llrender/llgltexture.cpp
@@ -307,7 +307,7 @@ LLTexUnit::eTextureAddressMode LLGLTexture::getAddressMode(void) const
 	return mGLTexturep->getAddressMode() ;
 }
 
-S32Bytes LLGLTexture::getTextureMemory() const
+S64Bytes LLGLTexture::getTextureMemory() const
 {
 	llassert(mGLTexturep.notNull()) ;
 
diff --git a/indra/llrender/llgltexture.h b/indra/llrender/llgltexture.h
index 78aab68d8e5..b9cb5db7b74 100644
--- a/indra/llrender/llgltexture.h
+++ b/indra/llrender/llgltexture.h
@@ -141,7 +141,7 @@ class LLGLTexture : public LLTexture
 	S32        getDiscardLevel() const;
 	S8         getComponents() const;
 	BOOL       getBoundRecently() const;
-	S32Bytes   getTextureMemory() const ;
+	S64Bytes   getTextureMemory() const ;
 	LLGLenum   getPrimaryFormat() const;
 	BOOL       getIsAlphaMask() const ;
 	LLTexUnit::eTextureType getTarget(void) const ;
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 0080eef6791..7cc749dfbf7 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -51,9 +51,9 @@ U32 wpo2(U32 i);
 
 U32 LLImageGL::sUniqueCount				= 0;
 U32 LLImageGL::sBindCount				= 0;
-S32Bytes LLImageGL::sGlobalTextureMemory(0);
-S32Bytes LLImageGL::sBoundTextureMemory(0);
-S32Bytes LLImageGL::sCurBoundTextureMemory(0);
+S64Bytes LLImageGL::sGlobalTextureMemory(0);
+S64Bytes LLImageGL::sBoundTextureMemory(0);
+S64Bytes LLImageGL::sCurBoundTextureMemory(0);
 S32 LLImageGL::sCount					= 0;
 
 BOOL LLImageGL::sGlobalUseAnisotropic	= FALSE;
@@ -265,11 +265,11 @@ void LLImageGL::updateStats(F32 current_time)
 	LL_RECORD_BLOCK_TIME(FTM_IMAGE_UPDATE_STATS);
 	sLastFrameTime = current_time;
 	sBoundTextureMemory = sCurBoundTextureMemory;
-	sCurBoundTextureMemory = S32Bytes(0);
+	sCurBoundTextureMemory = S64Bytes(0);
 }
 
 //static
-S32 LLImageGL::updateBoundTexMem(const S32Bytes mem, const S32 ncomponents, S32 category)
+S64 LLImageGL::updateBoundTexMem(const S64Bytes mem, const S32 ncomponents, S32 category)
 {
 	LLImageGL::sCurBoundTextureMemory += mem ;
 	return LLImageGL::sCurBoundTextureMemory.value();
@@ -442,7 +442,7 @@ void LLImageGL::init(BOOL usemipmaps)
 	// so that it is obvious by visual inspection if we forgot to
 	// init a field.
 
-	mTextureMemory = (S32Bytes)0;
+	mTextureMemory = S64Bytes(0);
 	mLastBindTime = 0.f;
 
 	mPickMask = NULL;
@@ -610,7 +610,7 @@ void LLImageGL::forceUpdateBindStats(void) const
 	mLastBindTime = sLastFrameTime;
 }
 
-BOOL LLImageGL::updateBindStats(S32Bytes tex_mem) const
+BOOL LLImageGL::updateBindStats(S64Bytes tex_mem) const
 {	
 	if (mTexName != 0)
 	{
@@ -1525,7 +1525,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
 	}
 
 	disclaimMem(mTextureMemory);
-	mTextureMemory = (S32Bytes)getMipBytes(discard_level);
+	mTextureMemory = S64Bytes(getMipBytes(discard_level));
 	claimMem(mTextureMemory);
 	sGlobalTextureMemory += mTextureMemory;
 	mTexelsInGLTexture = getWidth() * getHeight() ;
@@ -1660,11 +1660,11 @@ void LLImageGL::destroyGLTexture()
 {
 	if (mTexName != 0)
 	{
-		if(mTextureMemory != S32Bytes(0))
+		if(mTextureMemory != S64Bytes(0))
 		{
 			sGlobalTextureMemory -= mTextureMemory;
 			disclaimMem(mTextureMemory);
-			mTextureMemory = (S32Bytes)0;
+			mTextureMemory = (S64Bytes)0;
 		}
 		
 		LLImageGL::deleteTextures(1, &mTexName);			
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index b722c761d3d..04177dc9133 100644
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -56,7 +56,7 @@ class LLImageGL : public LLRefCount, public LLTrace::MemTrackable<LLImageGL>
 	static S32 dataFormatBytes(S32 dataformat, S32 width, S32 height);
 	static S32 dataFormatComponents(S32 dataformat);
 
-	BOOL updateBindStats(S32Bytes tex_mem) const ;
+	BOOL updateBindStats(S64Bytes tex_mem) const ;
 	F32 getTimePassedSinceLastBound();
 	void forceUpdateBindStats(void) const;
 
@@ -69,7 +69,7 @@ class LLImageGL : public LLRefCount, public LLTrace::MemTrackable<LLImageGL>
 	static void dirtyTexOptions();
 
 	// Sometimes called externally for textures not using LLImageGL (should go away...)	
-	static S32 updateBoundTexMem(const S32Bytes mem, const S32 ncomponents, S32 category) ;
+	static S64 updateBoundTexMem(const S64Bytes mem, const S32 ncomponents, S32 category) ;
 	
 	static bool checkSize(S32 width, S32 height);
 
@@ -188,7 +188,7 @@ class LLImageGL : public LLRefCount, public LLTrace::MemTrackable<LLImageGL>
 
 public:
 	// Various GL/Rendering options
-	S32Bytes mTextureMemory;
+	S64Bytes mTextureMemory;
 	mutable F32  mLastBindTime;	// last time this was bound, by discard level
 	
 private:
@@ -250,9 +250,9 @@ class LLImageGL : public LLRefCount, public LLTrace::MemTrackable<LLImageGL>
 	static F32 sLastFrameTime;
 
 	// Global memory statistics
-	static S32Bytes sGlobalTextureMemory;	// Tracks main memory texmem
-	static S32Bytes sBoundTextureMemory;	// Tracks bound texmem for last completed frame
-	static S32Bytes sCurBoundTextureMemory;		// Tracks bound texmem for current frame
+	static S64Bytes sGlobalTextureMemory;	// Tracks main memory texmem
+	static S64Bytes sBoundTextureMemory;	// Tracks bound texmem for last completed frame
+	static S64Bytes sCurBoundTextureMemory;		// Tracks bound texmem for current frame
 	static U32 sBindCount;					// Tracks number of texture binds for current frame
 	static U32 sUniqueCount;				// Tracks number of unique texture binds for current frame
 	static BOOL sGlobalUseAnisotropic;
diff --git a/indra/newview/lltextureinfo.cpp b/indra/newview/lltextureinfo.cpp
index e79bb62a52f..1e392926cc9 100644
--- a/indra/newview/lltextureinfo.cpp
+++ b/indra/newview/lltextureinfo.cpp
@@ -104,7 +104,7 @@ void LLTextureInfo::setRequestSize(const LLUUID& id, U32 size)
 	{
 		addRequest(id);
 	}
-	mTextures[id]->mSize = (U32Bytes)size;
+	mTextures[id]->mSize = U32Bytes(size);
 }
 
 void LLTextureInfo::setRequestOffset(const LLUUID& id, U32 offset)
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index c900071ce27..31878332339 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -64,8 +64,11 @@
 
 // extern
 const S32Megabytes gMinVideoRam(32);
+#if defined(_WIN64) || defined(__amd64__) || defined(__x86_64__)
+const S32Megabytes gMaxVideoRam(3072);
+#else
 const S32Megabytes gMaxVideoRam(512);
-
+#endif
 
 // statics
 LLPointer<LLViewerTexture>        LLViewerTexture::sNullImagep = NULL;
@@ -89,11 +92,11 @@ S32 LLViewerTexture::sAuxCount = 0;
 LLFrameTimer LLViewerTexture::sEvaluationTimer;
 F32 LLViewerTexture::sDesiredDiscardBias = 0.f;
 F32 LLViewerTexture::sDesiredDiscardScale = 1.1f;
-S32Bytes LLViewerTexture::sBoundTextureMemory;
-S32Bytes LLViewerTexture::sTotalTextureMemory;
+S64Bytes LLViewerTexture::sBoundTextureMemory;
+S64Bytes LLViewerTexture::sTotalTextureMemory;
 S32Megabytes LLViewerTexture::sMaxBoundTextureMemory;
 S32Megabytes LLViewerTexture::sMaxTotalTextureMem;
-S32Bytes LLViewerTexture::sMaxDesiredTextureMem;
+S64Bytes LLViewerTexture::sMaxDesiredTextureMem;
 S8  LLViewerTexture::sCameraMovingDiscardBias = 0;
 F32 LLViewerTexture::sCameraMovingBias = 0.0f;
 S32 LLViewerTexture::sMaxSculptRez = 128; //max sculpt image size
@@ -581,7 +584,7 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity
 		sTotalTextureMemory >= sMaxTotalTextureMem)
 	{
 		//when texture memory overflows, lower down the threshold to release the textures more aggressively.
-		sMaxDesiredTextureMem = llmin(sMaxDesiredTextureMem * 0.75f, F32Bytes(gMaxVideoRam));
+		sMaxDesiredTextureMem = llmin(sMaxDesiredTextureMem * 0.75, F64Bytes(gMaxVideoRam));
 	
 		// If we are using more texture memory than we should,
 		// scale up the desired discard level
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index ba155af6230..da59e6e16f3 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -222,11 +222,11 @@ class LLViewerTexture : public LLGLTexture
 	static LLFrameTimer sEvaluationTimer;
 	static F32 sDesiredDiscardBias;
 	static F32 sDesiredDiscardScale;
-	static S32Bytes sBoundTextureMemory;
-	static S32Bytes sTotalTextureMemory;
+	static S64Bytes sBoundTextureMemory;
+	static S64Bytes sTotalTextureMemory;
 	static S32Megabytes sMaxBoundTextureMemory;
 	static S32Megabytes sMaxTotalTextureMem;
-	static S32Bytes sMaxDesiredTextureMem ;
+	static S64Bytes sMaxDesiredTextureMem ;
 	static S8  sCameraMovingDiscardBias;
 	static F32 sCameraMovingBias;
 	static S32 sMaxSculptRez ;
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index 06524847d17..ada50e2c0cb 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -102,8 +102,8 @@ void LLViewerTextureList::init()
 {			
 	mInitialized = TRUE ;
 	sNumImages = 0;
-	mMaxResidentTexMemInMegaBytes = (U32Bytes)0;
-	mMaxTotalTextureMemInMegaBytes = (U32Bytes)0;
+	mMaxResidentTexMemInMegaBytes = S32Megabytes(0);
+	mMaxTotalTextureMemInMegaBytes = S32Megabytes(0);
 	
 	// Update how much texture RAM we're allowed to use.
 	updateMaxResidentTexMem(S32Megabytes(0)); // 0 = use current
@@ -1375,15 +1375,15 @@ S32Megabytes LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended, fl
 	{
 		if (!get_recommended)
 		{
-			max_texmem = (S32Megabytes)512;
+			max_texmem = S32Megabytes(512);
 		}
 		else if (gSavedSettings.getBOOL("NoHardwareProbe")) //did not do hardware detection at startup
 		{
-			max_texmem = (S32Megabytes)512;
+			max_texmem = S32Megabytes(512);
 		}
 		else
 		{
-			max_texmem = (S32Megabytes)128;
+			max_texmem = S32Megabytes(128);
 		}
 
 		LL_WARNS() << "VRAM amount not detected, defaulting to " << max_texmem << " MB" << LL_ENDL;
@@ -1412,11 +1412,11 @@ void LLViewerTextureList::updateMaxResidentTexMem(S32Megabytes mem)
 	S32Megabytes cur_mem(gSavedSettings.getS32("TextureMemory"));
 	F32 mem_multiplier = gSavedSettings.getF32("RenderTextureMemoryMultiple");
 	S32Megabytes default_mem = getMaxVideoRamSetting(true, mem_multiplier); // recommended default
-	if (mem == (S32Bytes)0)
+	if (mem == (S32Megabytes)0)
 	{
-		mem = cur_mem > (S32Bytes)0 ? cur_mem : default_mem;
+		mem = cur_mem > (S32Megabytes)0 ? cur_mem : default_mem;
 	}
-	else if (mem < (S32Bytes)0)
+	else if (mem < (S32Megabytes)0)
 	{
 		mem = default_mem;
 	}
@@ -1435,11 +1435,22 @@ void LLViewerTextureList::updateMaxResidentTexMem(S32Megabytes mem)
 	S32Megabytes fb_mem = llmax(VIDEO_CARD_FRAMEBUFFER_MEM, vb_mem/4);
 	mMaxResidentTexMemInMegaBytes = (vb_mem - fb_mem) ; //in MB
 	
+#if defined(_WIN64) || defined(__amd64__) || defined(__x86_64__)
+	if (mMaxResidentTexMemInMegaBytes > gMaxVideoRam / 2)
+	{
+		mMaxTotalTextureMemInMegaBytes = gMaxVideoRam + (S32Megabytes) (mMaxResidentTexMemInMegaBytes * 0.25f);
+	}
+	else
+	{
+		mMaxTotalTextureMemInMegaBytes = mMaxResidentTexMemInMegaBytes * 2;
+	}
+#else
 	mMaxTotalTextureMemInMegaBytes = mMaxResidentTexMemInMegaBytes * 2;
 	if (mMaxResidentTexMemInMegaBytes > (S32Megabytes)640)
 	{
 		mMaxTotalTextureMemInMegaBytes -= (mMaxResidentTexMemInMegaBytes / 4);
 	}
+#endif
 
 	//system mem
 	S32Megabytes system_ram = gSysMemory.getPhysicalMemoryKB();
@@ -1456,6 +1467,8 @@ void LLViewerTextureList::updateMaxResidentTexMem(S32Megabytes mem)
 	
 	LL_INFOS() << "Total Video Memory set to: " << vb_mem << " MB" << LL_ENDL;
 	LL_INFOS() << "Available Texture Memory set to: " << (vb_mem - fb_mem) << " MB" << LL_ENDL;
+	LL_INFOS() << "Total Texture Memory set to: " << mMaxTotalTextureMemInMegaBytes << " MB" << LL_ENDL;
+	LL_INFOS() << "Maxiumum Resident Texture Memory set to: " << mMaxResidentTexMemInMegaBytes << " MB" << LL_ENDL;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-- 
GitLab