Reduce code duplication in generateMipmap.

Using the newly introduced image index struct, we can simplify
our code somewhat in TextureStorage.

BUG=angle:729

Change-Id: Iff274fd1df7a0dc36dd34e0cb31ad42831b4f5d5
Reviewed-on: https://chromium-review.googlesource.com/219836
Tested-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libGLESv2/renderer/d3d/TextureD3D.cpp b/src/libGLESv2/renderer/d3d/TextureD3D.cpp
index 447254e..18e9e98 100644
--- a/src/libGLESv2/renderer/d3d/TextureD3D.cpp
+++ b/src/libGLESv2/renderer/d3d/TextureD3D.cpp
@@ -210,6 +210,42 @@
     return gl::log2(std::max(std::max(getBaseLevelWidth(), getBaseLevelHeight()), getBaseLevelDepth())) + 1;
 }
 
+void TextureD3D::generateMipmaps()
+{
+    // Set up proper image sizes.
+    initMipmapsImages();
+
+    // We know that all layers have the same dimension, for the texture to be complete
+    GLint layerCount = static_cast<GLint>(getLayerCount(0));
+    GLint mipCount = mipLevels();
+
+    // The following will create and initialize the storage, or update it if it exists
+    TextureStorage *storage = getNativeTexture();
+
+    bool renderableStorage = (storage && storage->isRenderTarget());
+
+    for (GLint layer = 0; layer < layerCount; ++layer)
+    {
+        for (GLint mip = 1; mip < mipCount; ++mip)
+        {
+            ASSERT(getLayerCount(mip) == layerCount);
+
+            gl::ImageIndex sourceIndex = getImageIndex(mip - 1, layer);
+            gl::ImageIndex destIndex = getImageIndex(mip, layer);
+
+            if (renderableStorage)
+            {
+                // GPU-side mipmapping
+                storage->generateMipmap(sourceIndex, destIndex);
+            }
+            else
+            {
+                // CPU-side mipmapping
+                mRenderer->generateMipmap(getImage(destIndex), getImage(sourceIndex));
+            }
+        }
+    }
+}
 
 TextureD3D_2D::TextureD3D_2D(Renderer *renderer)
     : TextureD3D(renderer),
@@ -489,7 +525,7 @@
     }
 }
 
-void TextureD3D_2D::generateMipmaps()
+void TextureD3D_2D::initMipmapsImages()
 {
     // Purge array levels 1 through q and reset them to represent the generated mipmap levels.
     int levelCount = mipLevels();
@@ -499,22 +535,6 @@
                       std::max(getBaseLevelWidth() >> level, 1),
                       std::max(getBaseLevelHeight() >> level, 1));
     }
-
-    if (mTexStorage && mTexStorage->isRenderTarget())
-    {
-        mTexStorage->generateMipmaps();
-        for (int level = 1; level < levelCount; level++)
-        {
-            mImageArray[level]->markClean();
-        }
-    }
-    else
-    {
-        for (int level = 1; level < levelCount; level++)
-        {
-            mRenderer->generateMipmap(mImageArray[level], mImageArray[level - 1]);
-        }
-    }
 }
 
 unsigned int TextureD3D_2D::getRenderTargetSerial(const gl::ImageIndex &index)
@@ -994,7 +1014,7 @@
 }
 
 
-void TextureD3D_Cube::generateMipmaps()
+void TextureD3D_Cube::initMipmapsImages()
 {
     // Purge array levels 1 through q and reset them to represent the generated mipmap levels.
     int levelCount = mipLevels();
@@ -1006,29 +1026,6 @@
             redefineImage(faceIndex, level, mImageArray[faceIndex][0]->getInternalFormat(), faceLevelSize, faceLevelSize);
         }
     }
-
-    if (mTexStorage && mTexStorage->isRenderTarget())
-    {
-        mTexStorage->generateMipmaps();
-
-        for (int faceIndex = 0; faceIndex < 6; faceIndex++)
-        {
-            for (int level = 1; level < levelCount; level++)
-            {
-                mImageArray[faceIndex][level]->markClean();
-            }
-        }
-    }
-    else
-    {
-        for (int faceIndex = 0; faceIndex < 6; faceIndex++)
-        {
-            for (int level = 1; level < levelCount; level++)
-            {
-                mRenderer->generateMipmap(mImageArray[faceIndex][level], mImageArray[faceIndex][level - 1]);
-            }
-        }
-    }
 }
 
 unsigned int TextureD3D_Cube::getRenderTargetSerial(const gl::ImageIndex &index)
@@ -1502,7 +1499,7 @@
 }
 
 
-void TextureD3D_3D::generateMipmaps()
+void TextureD3D_3D::initMipmapsImages()
 {
     // Purge array levels 1 through q and reset them to represent the generated mipmap levels.
     int levelCount = mipLevels();
@@ -1513,23 +1510,6 @@
                       std::max(getBaseLevelHeight() >> level, 1),
                       std::max(getBaseLevelDepth() >> level, 1));
     }
-
-    if (mTexStorage && mTexStorage->isRenderTarget())
-    {
-        mTexStorage->generateMipmaps();
-
-        for (int level = 1; level < levelCount; level++)
-        {
-            mImageArray[level]->markClean();
-        }
-    }
-    else
-    {
-        for (int level = 1; level < levelCount; level++)
-        {
-            mRenderer->generateMipmap(mImageArray[level], mImageArray[level - 1]);
-        }
-    }
 }
 
 unsigned int TextureD3D_3D::getRenderTargetSerial(const gl::ImageIndex &index)
@@ -1994,7 +1974,7 @@
 }
 
 
-void TextureD3D_2DArray::generateMipmaps()
+void TextureD3D_2DArray::initMipmapsImages()
 {
     int baseWidth = getBaseLevelWidth();
     int baseHeight = getBaseLevelHeight();
@@ -2007,29 +1987,6 @@
     {
         redefineImage(level, baseFormat, std::max(baseWidth >> level, 1), std::max(baseHeight >> level, 1), baseDepth);
     }
-
-    if (mTexStorage && mTexStorage->isRenderTarget())
-    {
-        mTexStorage->generateMipmaps();
-
-        for (int level = 1; level < levelCount; level++)
-        {
-            for (int layer = 0; layer < mLayerCounts[level]; layer++)
-            {
-                mImageArray[level][layer]->markClean();
-            }
-        }
-    }
-    else
-    {
-        for (int level = 1; level < levelCount; level++)
-        {
-            for (int layer = 0; layer < mLayerCounts[level]; layer++)
-            {
-                mRenderer->generateMipmap(mImageArray[level][layer], mImageArray[level - 1][layer]);
-            }
-        }
-    }
 }
 
 unsigned int TextureD3D_2DArray::getRenderTargetSerial(const gl::ImageIndex &index)