diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 9354373dba7d993f40eefabb6259bbd3a31bd0cb..d1eb4c8be0bc1f791d5d8b41bf7f6063002b65f4 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -313,6 +313,7 @@ LLGLManager::LLGLManager() :
 	mIsDisabled(FALSE),
 
 	mHasMultitexture(FALSE),
+	mHasATIMemInfo(FALSE),
 	mNumTextureUnits(1),
 	mHasMipMapGeneration(FALSE),
 	mHasCompressedTextures(FALSE),
@@ -497,6 +498,14 @@ bool LLGLManager::initGL()
 	// This is called here because it depends on the setting of mIsGF2or4MX, and sets up mHasMultitexture.
 	initExtensions();
 
+	if (mHasATIMemInfo)
+	{ //ask the gl how much vram is free at startup and attempt to use no more than half of that
+		S32 meminfo[4];
+		glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo);
+
+		mVRAM = meminfo[0]/1024;
+	}
+
 	if (mHasMultitexture)
 	{
 		GLint num_tex_units;		
@@ -659,6 +668,7 @@ void LLGLManager::initExtensions()
 	mHasTextureRectangle = FALSE;
 #else // LL_MESA_HEADLESS
 	mHasMultitexture = glh_init_extensions("GL_ARB_multitexture");
+	mHasATIMemInfo = ExtensionExists("GL_ATI_meminfo", 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");
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index df110613e3a04da9fc2a20b7fb9704f6272bcfc8..f4be067f2ea43142616fc7e2f1fb64d544af1a40 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -76,6 +76,7 @@ class LLGLManager
 
 	// Extensions used by everyone
 	BOOL mHasMultitexture;
+	BOOL mHasATIMemInfo;
 	S32	 mNumTextureUnits;
 	BOOL mHasMipMapGeneration;
 	BOOL mHasCompressedTextures;
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index afc268d7a52c560b45c1e5948160106fe7ca733d..6022153020dd2ca8903d5f88bb5dfad61f1a831f 100644
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -1,4 +1,4 @@
-version 26
+version 27
 
 // NOTE: This is mostly identical to featuretable_mac.txt with a few differences
 // Should be combined into one table
@@ -465,6 +465,10 @@ list ATI
 RenderUseStreamVBO			1	0
 RenderAvatarVP				1	0
 
+// Disable vertex buffer objects by default for ATI cards with little video memory
+list ATIVramLT256
+RenderVBOEnable				1	0
+
 /// Tweaked NVIDIA
 
 list NVIDIA_GeForce_FX_5100
diff --git a/indra/newview/featuretable_xp.txt b/indra/newview/featuretable_xp.txt
index d87c3db1119e0fc708055b8c0e8971a75bed32cd..6976bcf10210c8b4e91c76a103d7ed0c49095b56 100644
--- a/indra/newview/featuretable_xp.txt
+++ b/indra/newview/featuretable_xp.txt
@@ -1,4 +1,4 @@
-version 26
+version 27
 
 // NOTE: This is mostly identical to featuretable_mac.txt with a few differences
 // Should be combined into one table
@@ -458,6 +458,10 @@ list ATI
 RenderUseStreamVBO			1	0
 RenderAvatarVP				1	0
 
+// Disable vertex buffer objects by default for ATI cards with little video memory
+list ATIVramLT256
+RenderVBOEnable				1	0
+
 /// Tweaked NVIDIA
 
 list NVIDIA_GeForce_FX_5100
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index d328567a0e0f4f2e7e919fffebdaad9618af947a..54689ea808a6ed40e4987394e971b6822edcfc71 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -440,7 +440,11 @@ bool LLAppViewerWin32::initHardwareTest()
 		LL_WARNS("AppInit") << " Someone took over my exception handler (post hardware probe)!" << LL_ENDL;
 	}
 
-	gGLManager.mVRAM = gDXHardware.getVRAM();
+	if (gGLManager.mVRAM == 0)
+	{
+		gGLManager.mVRAM = gDXHardware.getVRAM();
+	}
+
 	LL_INFOS("AppInit") << "Detected VRAM: " << gGLManager.mVRAM << LL_ENDL;
 
 	return true;
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index edfc4538a1dab95b499dbca94f121f18221339ae..9f0b34becc51d9f3edd880d146d272977d81882d 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -729,6 +729,10 @@ void LLFeatureManager::applyBaseMasks()
 	{
 		maskFeatures("ATI");
 	}
+	if (gGLManager.mHasATIMemInfo && gGLManager.mVRAM < 256)
+	{
+		maskFeatures("ATIVramLT256");
+	}
 	if (gGLManager.mATIOldDriver)
 	{
 		maskFeatures("ATIOldDriver");
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index d5008c12b04ed851474612250214ae9fcad8eebe..1c573eab004729d637cfe7a8ba74ad27462ef4e6 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -457,6 +457,23 @@ class LLDebugText
 				addText(xpos, ypos, "Shaders Disabled");
 				ypos += y_inc;
 			}
+
+			if (gGLManager.mHasATIMemInfo)
+			{
+				S32 meminfo[4];
+				glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo);
+
+				addText(xpos, ypos, llformat("%.2f MB Texture Memory Free", meminfo[0]/1024.f));
+				ypos += y_inc;
+
+				if (gGLManager.mHasVertexBufferObject)
+				{
+					glGetIntegerv(GL_VBO_FREE_MEMORY_ATI, meminfo);
+					addText(xpos, ypos, llformat("%.2f MB VBO Memory Free", meminfo[0]/1024.f));
+					ypos += y_inc;
+				}
+			}
+
 			addText(xpos, ypos, llformat("%d MB Vertex Data", LLVertexBuffer::sAllocatedBytes/(1024*1024)));
 			ypos += y_inc;