Accept ImageIndex in TextureD3D::subImage and getImage.

This paves the way for setting data on the TextureStorage directly
instead of working through the Image objects.

BUG=angle:741

Change-Id: I3be3d5f9b2e45707c1630b74ad3f4789e034c3fd
Reviewed-on: https://chromium-review.googlesource.com/218311
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Tested-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libGLESv2/ImageIndex.cpp b/src/libGLESv2/ImageIndex.cpp
new file mode 100644
index 0000000..9806786
--- /dev/null
+++ b/src/libGLESv2/ImageIndex.cpp
@@ -0,0 +1,57 @@
+//
+// Copyright 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// ImageIndex.cpp: Implementation for ImageIndex methods.
+
+#include "libGLESv2/ImageIndex.h"
+#include "libGLESv2/Texture.h"
+#include "common/utilities.h"
+
+namespace gl
+{
+
+ImageIndex::ImageIndex(const ImageIndex &other)
+    : type(other.type),
+      mipIndex(other.mipIndex),
+      layerIndex(other.layerIndex)
+{}
+
+ImageIndex &ImageIndex::operator=(const ImageIndex &other)
+{
+    type = other.type;
+    mipIndex = other.mipIndex;
+    layerIndex = other.layerIndex;
+    return *this;
+}
+
+ImageIndex ImageIndex::Make2D(GLint mipIndex)
+{
+    return ImageIndex(GL_TEXTURE_2D, mipIndex, 0);
+}
+
+ImageIndex ImageIndex::MakeCube(GLenum target, GLint mipIndex)
+{
+    ASSERT(gl::IsCubemapTextureTarget(target));
+    return ImageIndex(target, mipIndex, TextureCubeMap::targetToLayerIndex(target));
+}
+
+ImageIndex ImageIndex::Make2DArray(GLint mipIndex, GLint layerIndex)
+{
+    return ImageIndex(GL_TEXTURE_2D_ARRAY, mipIndex, layerIndex);
+}
+
+ImageIndex ImageIndex::Make3D(GLint mipIndex, GLint layerIndex)
+{
+    return ImageIndex(GL_TEXTURE_3D, mipIndex, layerIndex);
+}
+
+ImageIndex::ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn)
+    : type(typeIn),
+      mipIndex(mipIndexIn),
+      layerIndex(layerIndexIn)
+{}
+
+}
diff --git a/src/libGLESv2/ImageIndex.h b/src/libGLESv2/ImageIndex.h
new file mode 100644
index 0000000..342a293
--- /dev/null
+++ b/src/libGLESv2/ImageIndex.h
@@ -0,0 +1,37 @@
+//
+// Copyright 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// ImageIndex.h: A helper struct for indexing into an Image array
+
+#ifndef LIBGLESV2_IMAGE_INDEX_H_
+#define LIBGLESV2_IMAGE_INDEX_H_
+
+#include "angle_gl.h"
+
+namespace gl
+{
+
+struct ImageIndex
+{
+    GLenum type;
+    GLint mipIndex;
+    GLint layerIndex;
+
+    ImageIndex(const ImageIndex &other);
+    ImageIndex &operator=(const ImageIndex &other);
+
+    static ImageIndex Make2D(GLint mipIndex);
+    static ImageIndex MakeCube(GLenum target, GLint mipIndex);
+    static ImageIndex Make2DArray(GLint mipIndex, GLint layerIndex);
+    static ImageIndex Make3D(GLint mipIndex, GLint layerIndex = 0);
+
+  private:
+    ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn);
+};
+
+}
+
+#endif // LIBGLESV2_IMAGE_INDEX_H_
diff --git a/src/libGLESv2/Texture.cpp b/src/libGLESv2/Texture.cpp
index 396dbb5..826002d 100644
--- a/src/libGLESv2/Texture.cpp
+++ b/src/libGLESv2/Texture.cpp
@@ -12,6 +12,7 @@
 #include "libGLESv2/main.h"
 #include "libGLESv2/Context.h"
 #include "libGLESv2/formatutils.h"
+#include "libGLESv2/ImageIndex.h"
 #include "libGLESv2/Renderbuffer.h"
 #include "libGLESv2/renderer/Image.h"
 #include "libGLESv2/renderer/d3d/TextureStorage.h"
@@ -115,25 +116,25 @@
 
 GLsizei Texture::getWidth(const ImageIndex &index) const
 {
-    rx::Image *image = mTexture->getImage(index.mipIndex, index.layerIndex);
+    rx::Image *image = mTexture->getImage(index);
     return image->getWidth();
 }
 
 GLsizei Texture::getHeight(const ImageIndex &index) const
 {
-    rx::Image *image = mTexture->getImage(index.mipIndex, index.layerIndex);
+    rx::Image *image = mTexture->getImage(index);
     return image->getHeight();
 }
 
 GLenum Texture::getInternalFormat(const ImageIndex &index) const
 {
-    rx::Image *image = mTexture->getImage(index.mipIndex, index.layerIndex);
+    rx::Image *image = mTexture->getImage(index);
     return image->getInternalFormat();
 }
 
 GLenum Texture::getActualFormat(const ImageIndex &index) const
 {
-    rx::Image *image = mTexture->getImage(index.mipIndex, index.layerIndex);
+    rx::Image *image = mTexture->getImage(index);
     return image->getActualFormat();
 }
 
diff --git a/src/libGLESv2/Texture.h b/src/libGLESv2/Texture.h
index c75bb45..94dd3bc 100644
--- a/src/libGLESv2/Texture.h
+++ b/src/libGLESv2/Texture.h
@@ -240,54 +240,6 @@
     bool isLevelComplete(int level) const;
 };
 
-struct ImageIndex
-{
-    GLenum type;
-    GLint mipIndex;
-    GLint layerIndex;
-
-    ImageIndex(const ImageIndex &other)
-        : type(other.type),
-          mipIndex(other.mipIndex),
-          layerIndex(other.layerIndex)
-    {}
-
-    ImageIndex &operator=(const ImageIndex &other)
-    {
-        type = other.type;
-        mipIndex = other.mipIndex;
-        layerIndex = other.layerIndex;
-        return *this;
-    }
-
-    static ImageIndex Make2D(GLint mipIndex)
-    {
-        return ImageIndex(GL_TEXTURE_2D, mipIndex, 0);
-    }
-
-    static ImageIndex MakeCube(GLenum target, GLint mipIndex)
-    {
-        return ImageIndex(target, mipIndex, TextureCubeMap::targetToLayerIndex(target));
-    }
-
-    static ImageIndex Make2DArray(GLint mipIndex, GLint layerIndex)
-    {
-        return ImageIndex(GL_TEXTURE_2D_ARRAY, mipIndex, layerIndex);
-    }
-
-    static ImageIndex Make3D(GLint mipIndex, GLint layerIndex = 0)
-    {
-        return ImageIndex(GL_TEXTURE_3D, mipIndex, layerIndex);
-    }
-
-  private:
-      ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn)
-        : type(typeIn),
-          mipIndex(mipIndexIn),
-          layerIndex(layerIndexIn)
-    {}
-};
-
 }
 
 #endif   // LIBGLESV2_TEXTURE_H_
diff --git a/src/libGLESv2/renderer/TextureImpl.h b/src/libGLESv2/renderer/TextureImpl.h
index 9ac3ec1..da561bd 100644
--- a/src/libGLESv2/renderer/TextureImpl.h
+++ b/src/libGLESv2/renderer/TextureImpl.h
@@ -13,6 +13,8 @@
 
 #include "angle_gl.h"
 
+#include "libGLESv2/ImageIndex.h"
+
 namespace egl
 {
 class Surface;
@@ -42,7 +44,9 @@
     // higher level code should not rely on it.
     virtual TextureStorageInterface *getNativeTexture() = 0;
 
+    // Deprecated in favour of the ImageIndex method
     virtual Image *getImage(int level, int layer) const = 0;
+    virtual Image *getImage(const gl::ImageIndex &index) const = 0;
     virtual GLsizei getLayerCount(int level) const = 0;
 
     virtual void setUsage(GLenum usage) = 0;
diff --git a/src/libGLESv2/renderer/d3d/TextureD3D.cpp b/src/libGLESv2/renderer/d3d/TextureD3D.cpp
index 5e29e4b..06803ea 100644
--- a/src/libGLESv2/renderer/d3d/TextureD3D.cpp
+++ b/src/libGLESv2/renderer/d3d/TextureD3D.cpp
@@ -121,7 +121,7 @@
 }
 
 bool TextureD3D::subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
-                       GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels, Image *image)
+                          GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels, const gl::ImageIndex &index)
 {
     const void *pixelData = pixels;
 
@@ -138,6 +138,9 @@
 
     if (pixelData != NULL)
     {
+        Image *image = getImage(index);
+        ASSERT(image);
+
         image->loadData(xoffset, yoffset, zoffset, width, height, depth, unpack.alignment, type, pixelData);
         mDirtyImages = true;
     }
@@ -238,6 +241,14 @@
     return mImageArray[level];
 }
 
+Image *TextureD3D_2D::getImage(const gl::ImageIndex &index) const
+{
+    ASSERT(index.mipIndex < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+    ASSERT(index.layerIndex == 0);
+    ASSERT(index.type == GL_TEXTURE_2D);
+    return mImageArray[index.mipIndex];
+}
+
 GLsizei TextureD3D_2D::getLayerCount(int level) const
 {
     ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
@@ -343,7 +354,8 @@
         }
     }
 
-    if (!fastUnpacked && TextureD3D::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels, mImageArray[level]))
+    gl::ImageIndex index = gl::ImageIndex::Make2D(level);
+    if (!fastUnpacked && TextureD3D::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels, index))
     {
         commitRect(level, xoffset, yoffset, width, height);
     }
@@ -759,6 +771,13 @@
     return mImageArray[layer][level];
 }
 
+Image *TextureD3D_Cube::getImage(const gl::ImageIndex &index) const
+{
+    ASSERT(index.mipIndex < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+    ASSERT(index.layerIndex < 6);
+    return mImageArray[index.layerIndex][index.mipIndex];
+}
+
 GLsizei TextureD3D_Cube::getLayerCount(int level) const
 {
     ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
@@ -808,7 +827,8 @@
 
     int faceIndex = gl::TextureCubeMap::targetToLayerIndex(target);
 
-    if (TextureD3D::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels, mImageArray[faceIndex][level]))
+    gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level);
+    if (TextureD3D::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels, index))
     {
         commitRect(faceIndex, level, xoffset, yoffset, width, height);
     }
@@ -1251,6 +1271,14 @@
     return mImageArray[level];
 }
 
+Image *TextureD3D_3D::getImage(const gl::ImageIndex &index) const
+{
+    ASSERT(index.mipIndex < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+    ASSERT(index.layerIndex == 0);
+    ASSERT(index.type == GL_TEXTURE_3D);
+    return mImageArray[index.mipIndex];
+}
+
 GLsizei TextureD3D_3D::getLayerCount(int level) const
 {
     ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
@@ -1356,7 +1384,8 @@
         }
     }
 
-    if (!fastUnpacked && TextureD3D::subImage(xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels, mImageArray[level]))
+    gl::ImageIndex index = gl::ImageIndex::Make3D(level);
+    if (!fastUnpacked && TextureD3D::subImage(xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels, index))
     {
         commitRect(level, xoffset, yoffset, zoffset, width, height, depth);
     }
@@ -1740,6 +1769,14 @@
     return mImageArray[level][layer];
 }
 
+Image *TextureD3D_2DArray::getImage(const gl::ImageIndex &index) const
+{
+    ASSERT(index.mipIndex < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+    ASSERT(index.layerIndex < mLayerCounts[index.mipIndex]);
+    ASSERT(index.type == GL_TEXTURE_2D_ARRAY);
+    return mImageArray[index.mipIndex][index.layerIndex];
+}
+
 GLsizei TextureD3D_2DArray::getLayerCount(int level) const
 {
     ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
@@ -1818,7 +1855,8 @@
         int layer = zoffset + i;
         const void *layerPixels = pixels ? (reinterpret_cast<const unsigned char*>(pixels) + (inputDepthPitch * i)) : NULL;
 
-        if (TextureD3D::subImage(xoffset, yoffset, zoffset, width, height, 1, format, type, unpack, layerPixels, mImageArray[level][layer]))
+        gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, layer);
+        if (TextureD3D::subImage(xoffset, yoffset, zoffset, width, height, 1, format, type, unpack, layerPixels, index))
         {
             commitRect(level, xoffset, yoffset, layer, width, height);
         }
diff --git a/src/libGLESv2/renderer/d3d/TextureD3D.h b/src/libGLESv2/renderer/d3d/TextureD3D.h
index e8fbe84..1ede45e 100644
--- a/src/libGLESv2/renderer/d3d/TextureD3D.h
+++ b/src/libGLESv2/renderer/d3d/TextureD3D.h
@@ -58,7 +58,7 @@
   protected:
     void setImage(const gl::PixelUnpackState &unpack, GLenum type, const void *pixels, Image *image);
     bool subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
-                  GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels, Image *image);
+                  GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels, const gl::ImageIndex &index);
     void setCompressedImage(GLsizei imageSize, const void *pixels, Image *image);
     bool subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
                             GLenum format, GLsizei imageSize, const void *pixels, Image *image);
@@ -94,6 +94,7 @@
     virtual ~TextureD3D_2D();
 
     virtual Image *getImage(int level, int layer) const;
+    virtual Image *getImage(const gl::ImageIndex &index) const;
     virtual GLsizei getLayerCount(int level) const;
 
     GLsizei getWidth(GLint level) const;
@@ -149,6 +150,7 @@
     virtual ~TextureD3D_Cube();
 
     virtual Image *getImage(int level, int layer) const;
+    virtual Image *getImage(const gl::ImageIndex &index) const;
     virtual GLsizei getLayerCount(int level) const;
 
     virtual bool hasDirtyImages() const { return mDirtyImages; }
@@ -206,6 +208,7 @@
     virtual ~TextureD3D_3D();
 
     virtual Image *getImage(int level, int layer) const;
+    virtual Image *getImage(const gl::ImageIndex &index) const;
     virtual GLsizei getLayerCount(int level) const;
 
     GLsizei getWidth(GLint level) const;
@@ -262,6 +265,7 @@
     virtual ~TextureD3D_2DArray();
 
     virtual Image *getImage(int level, int layer) const;
+    virtual Image *getImage(const gl::ImageIndex &index) const;
     virtual GLsizei getLayerCount(int level) const;
 
     GLsizei getWidth(GLint level) const;