glGenerateMipmap now does not force textures to become render targets.

For textures that are not already render targets, use the CPU to filter them and mark them as dirty.

I tested it by modifying the "mip_map_2d" demo to call glGenerateMipmap instead of generating the mipmaps itself. I also used the debugger to force it to take the render target path and verified that it still worked.

We've been having problems with the display being reset when video memory pressure is heavy with one of our demos. This patch made a noticable improvement on Vista but I don't think it will necessarily help on XP.

Review URL: http://codereview.appspot.com/3262041

git-svn-id: https://angleproject.googlecode.com/svn/trunk@490 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/Texture.cpp b/src/libGLESv2/Texture.cpp
index c9701d7..b7dc370 100644
--- a/src/libGLESv2/Texture.cpp
+++ b/src/libGLESv2/Texture.cpp
@@ -10,6 +10,8 @@
 
 #include "libGLESv2/Texture.h"
 
+#include <d3dx9tex.h>
+
 #include <algorithm>
 
 #include "common/debug.h"
@@ -1137,6 +1139,11 @@
     return mBaseTexture ? mBaseTexture->GetLevelCount() : 0;
 }
 
+bool Texture::isRenderable() const
+{
+    return mIsRenderable;
+}
+
 Texture2D::Texture2D(GLuint id) : Texture(id)
 {
     mTexture = NULL;
@@ -1623,28 +1630,50 @@
         mImageArray[i].height = std::max(mImageArray[0].height >> i, 1);
     }
 
-    needRenderTarget();
-
-    if (mTexture == NULL)
+    if (isRenderable())
     {
-        return;
-    }
-
-    for (unsigned int i = 1; i <= q; i++)
-    {
-        IDirect3DSurface9 *upper = NULL;
-        IDirect3DSurface9 *lower = NULL;
-
-        mTexture->GetSurfaceLevel(i-1, &upper);
-        mTexture->GetSurfaceLevel(i, &lower);
-
-        if (upper != NULL && lower != NULL)
+        if (mTexture == NULL)
         {
-            getBlitter()->boxFilter(upper, lower);
+            ERR(" failed because mTexture was null.");
+            return;
         }
 
-        if (upper != NULL) upper->Release();
-        if (lower != NULL) lower->Release();
+        for (unsigned int i = 1; i <= q; i++)
+        {
+            IDirect3DSurface9 *upper = NULL;
+            IDirect3DSurface9 *lower = NULL;
+
+            mTexture->GetSurfaceLevel(i-1, &upper);
+            mTexture->GetSurfaceLevel(i, &lower);
+
+            if (upper != NULL && lower != NULL)
+            {
+                getBlitter()->boxFilter(upper, lower);
+            }
+
+            if (upper != NULL) upper->Release();
+            if (lower != NULL) lower->Release();
+        }
+    }
+    else
+    {
+        for (unsigned int i = 1; i <= q; i++)
+        {
+            createSurface(mImageArray[i].width, mImageArray[i].height, mImageArray[i].format, mType, &mImageArray[i]);
+            if (mImageArray[i].surface == NULL)
+            {
+                return error(GL_OUT_OF_MEMORY);
+            }
+
+            if (FAILED(D3DXLoadSurfaceFromSurface(mImageArray[i].surface, NULL, NULL, mImageArray[i - 1].surface, NULL, NULL, D3DX_FILTER_BOX, 0)))
+            {
+                ERR(" failed to load filter %d to %d.", i - 1, i);
+            }
+
+            mImageArray[i].dirty = true;
+        }
+
+        mDirtyMetaData = true;
     }
 }
 
@@ -2271,28 +2300,52 @@
         }
     }
 
-    needRenderTarget();
-
-    if (mTexture == NULL)
+    if (isRenderable())
     {
-        return;
-    }
-
-    for (unsigned int f = 0; f < 6; f++)
-    {
-        for (unsigned int i = 1; i <= q; i++)
+        if (mTexture == NULL)
         {
-            IDirect3DSurface9 *upper = getCubeMapSurface(f, i-1);
-            IDirect3DSurface9 *lower = getCubeMapSurface(f, i);
-
-            if (upper != NULL && lower != NULL)
-            {
-                getBlitter()->boxFilter(upper, lower);
-            }
-
-            if (upper != NULL) upper->Release();
-            if (lower != NULL) lower->Release();
+            return;
         }
+
+        for (unsigned int f = 0; f < 6; f++)
+        {
+            for (unsigned int i = 1; i <= q; i++)
+            {
+                IDirect3DSurface9 *upper = getCubeMapSurface(f, i-1);
+                IDirect3DSurface9 *lower = getCubeMapSurface(f, i);
+
+                if (upper != NULL && lower != NULL)
+                {
+                    getBlitter()->boxFilter(upper, lower);
+                }
+
+                if (upper != NULL) upper->Release();
+                if (lower != NULL) lower->Release();
+            }
+        }
+    }
+    else
+    {
+        for (unsigned int f = 0; f < 6; f++)
+        {
+            for (unsigned int i = 1; i <= q; i++)
+            {
+                createSurface(mImageArray[f][i].width, mImageArray[f][i].height, mImageArray[f][i].format, mType, &mImageArray[f][i]);
+                if (mImageArray[f][i].surface == NULL)
+                {
+                    return error(GL_OUT_OF_MEMORY);
+                }
+
+                if (FAILED(D3DXLoadSurfaceFromSurface(mImageArray[f][i].surface, NULL, NULL, mImageArray[f][i - 1].surface, NULL, NULL, D3DX_FILTER_BOX, 0)))
+                {
+                    ERR(" failed to load filter %d to %d.", i - 1, i);
+                }
+
+                mImageArray[f][i].dirty = true;
+            }
+        }
+
+        mDirtyMetaData = true;
     }
 }