Tracks sized internal formats for textures.

TRAC #21609

Signed-off-by: Daniel Koch

Author:    Shannon Woods <shannon.woods@transgaming.com>

git-svn-id: https://angleproject.googlecode.com/svn/trunk@1301 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index 1363ed6..414bfa9 100644
--- a/src/libGLESv2/Context.cpp
+++ b/src/libGLESv2/Context.cpp
@@ -2507,7 +2507,7 @@
         return error(GL_INVALID_OPERATION);
     }
 
-    GLsizei outputPitch = ComputePitch(width, format, type, mState.packAlignment);
+    GLsizei outputPitch = ComputePitch(width, ConvertSizedInternalFormat(format, type), mState.packAlignment);
     // sized query sanity check
     if (bufSize)
     {
diff --git a/src/libGLESv2/Framebuffer.cpp b/src/libGLESv2/Framebuffer.cpp
index 76d4283..2372257 100644
--- a/src/libGLESv2/Framebuffer.cpp
+++ b/src/libGLESv2/Framebuffer.cpp
@@ -301,13 +301,14 @@
         }
         else if (IsInternalTextureTarget(mColorbufferType))
         {
-            GLenum internalformat = colorbuffer->getInternalFormat();
+            GLint internalformat = colorbuffer->getInternalFormat();
+            GLenum format = gl::ExtractFormat(internalformat);
             D3DFORMAT d3dformat = colorbuffer->getD3DFormat();
 
-            if (IsCompressed(internalformat) ||
-                internalformat == GL_ALPHA ||
-                internalformat == GL_LUMINANCE ||
-                internalformat == GL_LUMINANCE_ALPHA)
+            if (IsCompressed(format) ||
+                format == GL_ALPHA ||
+                format == GL_LUMINANCE ||
+                format == GL_LUMINANCE_ALPHA)
             {
                 return GL_FRAMEBUFFER_UNSUPPORTED;
             }
diff --git a/src/libGLESv2/Texture.cpp b/src/libGLESv2/Texture.cpp
index 4a17c4f..0ba8b5c 100644
--- a/src/libGLESv2/Texture.cpp
+++ b/src/libGLESv2/Texture.cpp
@@ -28,49 +28,47 @@
 {
 unsigned int TextureStorage::mCurrentTextureSerial = 1;
 
-static D3DFORMAT ConvertTextureFormatType(GLenum format, GLenum type)
+static D3DFORMAT ConvertTextureFormatType(GLint internalformat)
 {
-    if (IsDepthTexture(format))
+    switch (internalformat)
     {
+      case GL_DEPTH_COMPONENT16:
+      case GL_DEPTH_COMPONENT32_OES:
+      case GL_DEPTH24_STENCIL8_OES:
         return D3DFMT_INTZ;
-    }
-    else if (format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
-             format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
-    {
+      case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+      case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
         return D3DFMT_DXT1;
-    }
-    else if (format == GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE)
-    {
+      case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
         return D3DFMT_DXT3;
-    }
-    else if (format == GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE)
-    {
+      case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
         return D3DFMT_DXT5;
-    }
-    else if (type == GL_FLOAT)
-    {
+      case GL_RGBA32F_EXT:
+      case GL_RGB32F_EXT:
+      case GL_ALPHA32F_EXT:
+      case GL_LUMINANCE32F_EXT:
+      case GL_LUMINANCE_ALPHA32F_EXT:
         return D3DFMT_A32B32G32R32F;
-    }
-    else if (type == GL_HALF_FLOAT_OES)
-    {
+      case GL_RGBA16F_EXT:
+      case GL_RGB16F_EXT:
+      case GL_ALPHA16F_EXT:
+      case GL_LUMINANCE16F_EXT:
+      case GL_LUMINANCE_ALPHA16F_EXT:
         return D3DFMT_A16B16G16R16F;
-    }
-    else if (type == GL_UNSIGNED_BYTE)
-    {
-        if (format == GL_LUMINANCE && getContext()->supportsLuminanceTextures())
+      case GL_LUMINANCE8_EXT:
+        if (getContext()->supportsLuminanceTextures())
         {
             return D3DFMT_L8;
         }
-        else if (format == GL_LUMINANCE_ALPHA && getContext()->supportsLuminanceAlphaTextures())
+        break;
+      case GL_LUMINANCE8_ALPHA8_EXT:
+        if (getContext()->supportsLuminanceAlphaTextures())
         {
             return D3DFMT_A8L8;
         }
-        else if (format == GL_RGB)
-        {
-            return D3DFMT_X8R8G8B8;
-        }
-
-        return D3DFMT_A8R8G8B8;
+        break;
+      case GL_RGB8_OES:
+        return D3DFMT_X8R8G8B8;
     }
 
     return D3DFMT_A8R8G8B8;
@@ -141,8 +139,7 @@
 {
     mWidth = 0; 
     mHeight = 0;
-    mFormat = GL_NONE;
-    mType = GL_UNSIGNED_BYTE;
+    mInternalFormat = GL_NONE;
 
     mSurface = NULL;
 
@@ -160,20 +157,18 @@
     }
 }
 
-bool Image::redefine(GLenum format, GLsizei width, GLsizei height, GLenum type, bool forceRelease)
+bool Image::redefine(GLint internalformat, GLsizei width, GLsizei height, bool forceRelease)
 {
     if (mWidth != width ||
         mHeight != height ||
-        mFormat != format ||
-        mType != type ||
+        mInternalFormat != internalformat ||
         forceRelease)
     {
         mWidth = width;
         mHeight = height;
-        mFormat = format;
-        mType = type;
+        mInternalFormat = internalformat;
         // compute the d3d format that will be used
-        mD3DFormat = ConvertTextureFormatType(mFormat, mType);
+        mD3DFormat = ConvertTextureFormatType(internalformat);
 
         if (mSurface)
         {
@@ -205,7 +200,7 @@
         int levelToFetch = 0;
         GLsizei requestWidth = mWidth;
         GLsizei requestHeight = mHeight;
-        MakeValidSize(true, IsCompressed(mFormat), &requestWidth, &requestHeight, &levelToFetch);
+        MakeValidSize(true, IsCompressed(mInternalFormat), &requestWidth, &requestHeight, &levelToFetch);
 
         HRESULT result = getDevice()->CreateTexture(requestWidth, requestHeight, levelToFetch + 1, NULL, d3dFormat,
                                                     poolToUse, &newTexture, NULL);
@@ -318,7 +313,7 @@
 
 // Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input
 // into the target pixel rectangle.
-void Image::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum type,
+void Image::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
                      GLint unpackAlignment, const void *input)
 {
     RECT lockRect =
@@ -334,120 +329,84 @@
         return;
     }
 
-    GLsizei inputPitch = ComputePitch(width, mFormat, type, unpackAlignment);
 
-    switch (type)
+    GLsizei inputPitch = ComputePitch(width, mInternalFormat, unpackAlignment);
+
+    switch (mInternalFormat)
     {
-      case GL_UNSIGNED_BYTE:
-        switch (mFormat)
+      case GL_ALPHA8_EXT:
+        if (supportsSSE2())
         {
-          case GL_ALPHA:
-            if (supportsSSE2())
-            {
-                loadAlphaDataSSE2(width, height, inputPitch, input, locked.Pitch, locked.pBits);
-            }
-            else
-            {
-                loadAlphaData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
-            }
-            break;
-          case GL_LUMINANCE:
-            loadLuminanceData(width, height, inputPitch, input, locked.Pitch, locked.pBits, getD3DFormat() == D3DFMT_L8);
-            break;
-          case GL_LUMINANCE_ALPHA:
-            loadLuminanceAlphaData(width, height, inputPitch, input, locked.Pitch, locked.pBits, getD3DFormat() == D3DFMT_A8L8);
-            break;
-          case GL_RGB:
-            loadRGBUByteData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
-            break;
-          case GL_RGBA:
-            if (supportsSSE2())
-            {
-                loadRGBAUByteDataSSE2(width, height, inputPitch, input, locked.Pitch, locked.pBits);
-            }
-            else
-            {
-                loadRGBAUByteData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
-            }
-            break;
-          case GL_BGRA_EXT:
-            loadBGRAData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
-            break;
-          default: UNREACHABLE();
+            loadAlphaDataSSE2(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+        }
+        else
+        {
+            loadAlphaData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
         }
         break;
-      case GL_UNSIGNED_SHORT_5_6_5:
-        switch (mFormat)
+      case GL_LUMINANCE8_EXT:
+        loadLuminanceData(width, height, inputPitch, input, locked.Pitch, locked.pBits, getD3DFormat() == D3DFMT_L8);
+        break;
+      case GL_ALPHA32F_EXT:
+        loadAlphaFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+        break;
+      case GL_LUMINANCE32F_EXT:
+        loadLuminanceFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+        break;
+      case GL_ALPHA16F_EXT:
+        loadAlphaHalfFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+        break;
+      case GL_LUMINANCE16F_EXT:
+        loadLuminanceHalfFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+        break;
+      case GL_LUMINANCE8_ALPHA8_EXT:
+        loadLuminanceAlphaData(width, height, inputPitch, input, locked.Pitch, locked.pBits, getD3DFormat() == D3DFMT_A8L8);
+        break;
+      case GL_LUMINANCE_ALPHA32F_EXT:
+        loadLuminanceAlphaFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+        break;
+      case GL_LUMINANCE_ALPHA16F_EXT:
+        loadLuminanceAlphaHalfFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+        break;
+      case GL_RGB8_OES:
+        loadRGBUByteData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+        break;
+      case GL_RGB565:
+        loadRGB565Data(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+        break;
+      case GL_RGBA8_OES:
+        if (supportsSSE2())
         {
-          case GL_RGB:
-            loadRGB565Data(width, height, inputPitch, input, locked.Pitch, locked.pBits);
-            break;
-          default: UNREACHABLE();
+            loadRGBAUByteDataSSE2(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+        }
+        else
+        {
+            loadRGBAUByteData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
         }
         break;
-      case GL_UNSIGNED_SHORT_4_4_4_4:
-        switch (mFormat)
-        {
-          case GL_RGBA:
-            loadRGBA4444Data(width, height, inputPitch, input, locked.Pitch, locked.pBits);
-            break;
-          default: UNREACHABLE();
-        }
+      case GL_RGBA4:
+        loadRGBA4444Data(width, height, inputPitch, input, locked.Pitch, locked.pBits);
         break;
-      case GL_UNSIGNED_SHORT_5_5_5_1:
-        switch (mFormat)
-        {
-          case GL_RGBA:
-            loadRGBA5551Data(width, height, inputPitch, input, locked.Pitch, locked.pBits);
-            break;
-          default: UNREACHABLE();
-        }
+      case GL_RGB5_A1:
+        loadRGBA5551Data(width, height, inputPitch, input, locked.Pitch, locked.pBits);
         break;
-      case GL_FLOAT:
-        switch (mFormat)
-        {
-          // float textures are converted to RGBA, not BGRA, as they're stored that way in D3D
-          case GL_ALPHA:
-            loadAlphaFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
-            break;
-          case GL_LUMINANCE:
-            loadLuminanceFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
-            break;
-          case GL_LUMINANCE_ALPHA:
-            loadLuminanceAlphaFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
-            break;
-          case GL_RGB:
-            loadRGBFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
-            break;
-          case GL_RGBA:
-            loadRGBAFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
-            break;
-          default: UNREACHABLE();
-        }
+      case GL_BGRA8_EXT:
+        loadBGRAData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
         break;
-      case GL_HALF_FLOAT_OES:
-        switch (mFormat)
-        {
-          // float textures are converted to RGBA, not BGRA, as they're stored that way in D3D
-          case GL_ALPHA:
-            loadAlphaHalfFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
-            break;
-          case GL_LUMINANCE:
-            loadLuminanceHalfFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
-            break;
-          case GL_LUMINANCE_ALPHA:
-            loadLuminanceAlphaHalfFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
-            break;
-          case GL_RGB:
-            loadRGBHalfFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
-            break;
-          case GL_RGBA:
-            loadRGBAHalfFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
-            break;
-          default: UNREACHABLE();
-        }
+      // float textures are converted to RGBA, not BGRA, as they're stored that way in D3D
+      case GL_RGB32F_EXT:
+        loadRGBFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
         break;
-      default: UNREACHABLE();
+      case GL_RGB16F_EXT:
+        loadRGBHalfFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+        break;
+      case GL_RGBA32F_EXT:
+        loadRGBAFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+        break;
+      case GL_RGBA16F_EXT:
+        loadRGBAHalfFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+        break;
+      default: UNREACHABLE(); 
     }
 
     unlock();
@@ -849,8 +808,8 @@
         return;
     }
 
-    GLsizei inputSize = ComputeCompressedSize(width, height, mFormat);
-    GLsizei inputPitch = ComputeCompressedPitch(width, mFormat);
+    GLsizei inputSize = ComputeCompressedSize(width, height, mInternalFormat);
+    GLsizei inputPitch = ComputeCompressedPitch(width, mInternalFormat);
     int rows = inputSize / inputPitch;
     for (int i = 0; i < rows; ++i)
     {
@@ -1246,7 +1205,7 @@
 {
     if (pixels != NULL)
     {
-        image->loadData(0, 0, image->getWidth(), image->getHeight(), image->getType(), unpackAlignment, pixels);
+        image->loadData(0, 0, image->getWidth(), image->getHeight(), unpackAlignment, pixels);
         mDirtyImages = true;
     }
 }
@@ -1264,7 +1223,7 @@
 {
     if (pixels != NULL)
     {
-        image->loadData(xoffset, yoffset, width, height, type, unpackAlignment, pixels);
+        image->loadData(xoffset, yoffset, width, height, unpackAlignment, pixels);
         mDirtyImages = true;
     }
 
@@ -1524,7 +1483,7 @@
 GLenum Texture2D::getInternalFormat(GLint level) const
 {
     if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
-        return mImageArray[level].getFormat();
+        return mImageArray[level].getInternalFormat();
     else
         return GL_NONE;
 }
@@ -1537,11 +1496,11 @@
         return D3DFMT_UNKNOWN;
 }
 
-void Texture2D::redefineImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLenum type)
+void Texture2D::redefineImage(GLint level, GLint internalformat, GLsizei width, GLsizei height)
 {
     releaseTexImage();
 
-    bool redefined = mImageArray[level].redefine(format, width, height, type, false);
+    bool redefined = mImageArray[level].redefine(internalformat, width, height, false);
 
     if (mTexStorage && redefined)
     {
@@ -1558,7 +1517,8 @@
 
 void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
 {
-    redefineImage(level, format, width, height, type);
+    GLint internalformat = ConvertSizedInternalFormat(format, type);
+    redefineImage(level, internalformat, width, height);
 
     Texture::setImage(unpackAlignment, pixels, &mImageArray[level]);
 }
@@ -1567,22 +1527,22 @@
 {
     releaseTexImage();
 
-    GLenum format;
+    GLint internalformat;
 
     switch(surface->getFormat())
     {
       case D3DFMT_A8R8G8B8:
-        format = GL_RGBA;
+        internalformat = GL_RGBA8_OES;
         break;
       case D3DFMT_X8R8G8B8:
-        format = GL_RGB;
+        internalformat = GL_RGB8_OES;
         break;
       default:
         UNIMPLEMENTED();
         return;
     }
 
-    mImageArray[0].redefine(format, surface->getWidth(), surface->getHeight(), GL_UNSIGNED_BYTE, true);
+    mImageArray[0].redefine(internalformat, surface->getWidth(), surface->getHeight(), true);
 
     delete mTexStorage;
     mTexStorage = new TextureStorage2D(surface->getOffscreenTexture());
@@ -1607,14 +1567,15 @@
 
         for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
         {
-            mImageArray[i].redefine(GL_RGBA, 0, 0, GL_UNSIGNED_BYTE, true);
+            mImageArray[i].redefine(GL_RGBA8_OES, 0, 0, true);
         }
     }
 }
 
 void Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
 {
-    redefineImage(level, format, width, height, GL_UNSIGNED_BYTE);
+    // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
+    redefineImage(level, format, width, height);
 
     Texture::setCompressedImage(imageSize, pixels, &mImageArray[level]);
 }
@@ -1664,7 +1625,8 @@
         return error(GL_OUT_OF_MEMORY);
     }
 
-    redefineImage(level, format, width, height, GL_UNSIGNED_BYTE);
+    GLint internalformat = ConvertSizedInternalFormat(format, GL_UNSIGNED_BYTE);
+    redefineImage(level, internalformat, width, height);
    
     if (!mImageArray[level].isRenderableFormat())
     {
@@ -1742,7 +1704,9 @@
 
             if (dest)
             {
-                getBlitter()->copy(renderTarget, sourceRect, mImageArray[0].getFormat(), xoffset, yoffset, dest);
+                getBlitter()->copy(renderTarget, sourceRect, 
+                                   gl::ExtractFormat(mImageArray[0].getInternalFormat()),
+                                   xoffset, yoffset, dest);
                 dest->Release();
             }
         }
@@ -1753,9 +1717,7 @@
 
 void Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
 {
-    GLenum format = gl::ExtractFormat(internalformat);
-    GLenum type = gl::ExtractType(internalformat);
-    D3DFORMAT d3dfmt = ConvertTextureFormatType(format, type);
+    D3DFORMAT d3dfmt = ConvertTextureFormatType(internalformat);
     DWORD d3dusage = GetTextureUsage(d3dfmt, mUsage, false);
 
     delete mTexStorage;
@@ -1764,14 +1726,14 @@
 
     for (int level = 0; level < levels; level++)
     {
-        mImageArray[level].redefine(format, width, height, type, true);
+        mImageArray[level].redefine(internalformat, width, height, true);
         width = std::max(1, width >> 1);
         height = std::max(1, height >> 1);
     }
 
     for (int level = levels; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
     {
-        mImageArray[level].redefine(GL_NONE, 0, 0, GL_UNSIGNED_BYTE, true);
+        mImageArray[level].redefine(GL_NONE, 0, 0, true);
     }
 
     if (mTexStorage->isManaged())
@@ -1814,8 +1776,8 @@
       default: UNREACHABLE();
     }
 
-    if ((getInternalFormat(0) == GL_FLOAT && !getContext()->supportsFloat32LinearFilter()) ||
-        (getInternalFormat(0) == GL_HALF_FLOAT_OES && !getContext()->supportsFloat16LinearFilter()))
+    if ((gl::ExtractType(getInternalFormat(0)) == GL_FLOAT && !getContext()->supportsFloat32LinearFilter()) ||
+        (gl::ExtractType(getInternalFormat(0)) == GL_HALF_FLOAT_OES && !getContext()->supportsFloat16LinearFilter()))
     {
         if (mMagFilter != GL_NEAREST || (mMinFilter != GL_NEAREST && mMinFilter != GL_NEAREST_MIPMAP_NEAREST))
         {
@@ -1873,12 +1835,7 @@
 
     for (int level = 1; level <= q; level++)
     {
-        if (mImageArray[level].getFormat() != mImageArray[0].getFormat())
-        {
-            return false;
-        }
-
-        if (mImageArray[level].getType() != mImageArray[0].getType())
+        if (mImageArray[level].getInternalFormat() != mImageArray[0].getInternalFormat())
         {
             return false;
         }
@@ -2013,10 +1970,9 @@
     unsigned int q = log2(std::max(mImageArray[0].getWidth(), mImageArray[0].getHeight()));
     for (unsigned int i = 1; i <= q; i++)
     {
-        redefineImage(i, mImageArray[0].getFormat(), 
+        redefineImage(i, mImageArray[0].getInternalFormat(), 
                          std::max(mImageArray[0].getWidth() >> i, 1),
-                         std::max(mImageArray[0].getHeight() >> i, 1),
-                         mImageArray[0].getType());
+                         std::max(mImageArray[0].getHeight() >> i, 1));
     }
 
     if (mTexStorage && mTexStorage->isRenderTarget())
@@ -2267,7 +2223,7 @@
 GLenum TextureCubeMap::getInternalFormat(GLenum target, GLint level) const
 {
     if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
-        return mImageArray[faceIndex(target)][level].getFormat();
+        return mImageArray[faceIndex(target)][level].getInternalFormat();
     else
         return GL_NONE;
 }
@@ -2312,7 +2268,8 @@
 
 void TextureCubeMap::setCompressedImage(GLenum face, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
 {
-    redefineImage(faceIndex(face), level, format, width, height, GL_UNSIGNED_BYTE);
+    // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
+    redefineImage(faceIndex(face), level, format, width, height);
 
     Texture::setCompressedImage(imageSize, pixels, &mImageArray[faceIndex(face)][level]);
 }
@@ -2377,8 +2334,8 @@
         return false;
     }
 
-    if ((getInternalFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0) == GL_FLOAT && !getContext()->supportsFloat32LinearFilter()) ||
-        (getInternalFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0) == GL_HALF_FLOAT_OES && !getContext()->supportsFloat16LinearFilter()))
+    if ((gl::ExtractType(getInternalFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0)) == GL_FLOAT && !getContext()->supportsFloat32LinearFilter()) ||
+        (gl::ExtractType(getInternalFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0) == GL_HALF_FLOAT_OES) && !getContext()->supportsFloat16LinearFilter()))
     {
         if (mMagFilter != GL_NEAREST || (mMinFilter != GL_NEAREST && mMinFilter != GL_NEAREST_MIPMAP_NEAREST))
         {
@@ -2424,8 +2381,7 @@
     {
         if (mImageArray[face][0].getWidth() != mImageArray[0][0].getWidth() ||
             mImageArray[face][0].getWidth() != mImageArray[0][0].getHeight() ||
-            mImageArray[face][0].getFormat() != mImageArray[0][0].getFormat() ||
-            mImageArray[face][0].getType() != mImageArray[0][0].getType())
+            mImageArray[face][0].getInternalFormat() != mImageArray[0][0].getInternalFormat())
         {
             return false;
         }
@@ -2454,12 +2410,7 @@
     {
         for (int level = 1; level <= q; level++)
         {
-            if (mImageArray[face][level].getFormat() != mImageArray[0][0].getFormat())
-            {
-                return false;
-            }
-
-            if (mImageArray[face][level].getType() != mImageArray[0][0].getType())
+            if (mImageArray[face][level].getInternalFormat() != mImageArray[0][0].getInternalFormat())
             {
                 return false;
             }
@@ -2579,7 +2530,8 @@
 
 void TextureCubeMap::setImage(int faceIndex, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
 {
-    redefineImage(faceIndex, level, format, width, height, type);
+    GLint internalformat = ConvertSizedInternalFormat(format, type);
+    redefineImage(faceIndex, level, internalformat, width, height);
 
     Texture::setImage(unpackAlignment, pixels, &mImageArray[faceIndex][level]);
 }
@@ -2595,9 +2547,9 @@
     return face - GL_TEXTURE_CUBE_MAP_POSITIVE_X;
 }
 
-void TextureCubeMap::redefineImage(int face, GLint level, GLenum format, GLsizei width, GLsizei height, GLenum type)
+void TextureCubeMap::redefineImage(int face, GLint level, GLint internalformat, GLsizei width, GLsizei height)
 {
-    bool redefined = mImageArray[face][level].redefine(format, width, height, type, false);
+    bool redefined = mImageArray[face][level].redefine(internalformat, width, height, false);
 
     if (mTexStorage && redefined)
     {
@@ -2627,7 +2579,8 @@
     }
 
     unsigned int faceindex = faceIndex(target);
-    redefineImage(faceindex, level, format, width, height, GL_UNSIGNED_BYTE);
+    GLint internalformat = gl::ConvertSizedInternalFormat(format, GL_UNSIGNED_BYTE);
+    redefineImage(faceindex, level, internalformat, width, height);
 
     if (!mImageArray[faceindex][level].isRenderableFormat())
     {
@@ -2711,7 +2664,7 @@
 
             if (dest)
             {
-                getBlitter()->copy(renderTarget, sourceRect, mImageArray[0][0].getFormat(), xoffset, yoffset, dest);
+                getBlitter()->copy(renderTarget, sourceRect, gl::ExtractFormat(mImageArray[0][0].getInternalFormat()), xoffset, yoffset, dest);
                 dest->Release();
             }
         }
@@ -2722,9 +2675,7 @@
 
 void TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size)
 {
-    GLenum format = gl::ExtractFormat(internalformat);
-    GLenum type = gl::ExtractType(internalformat);
-    D3DFORMAT d3dfmt = ConvertTextureFormatType(format, type);
+    D3DFORMAT d3dfmt = ConvertTextureFormatType(internalformat);
     DWORD d3dusage = GetTextureUsage(d3dfmt, mUsage, false);
 
     delete mTexStorage;
@@ -2735,7 +2686,7 @@
     {
         for (int face = 0; face < 6; face++)
         {
-            mImageArray[face][level].redefine(format, size, size, type, true);
+            mImageArray[face][level].redefine(internalformat, size, size, true);
             size = std::max(1, size >> 1);
         }
     }
@@ -2744,7 +2695,7 @@
     {
         for (int face = 0; face < 6; face++)
         {
-            mImageArray[face][level].redefine(GL_NONE, 0, 0, GL_UNSIGNED_BYTE, true);
+            mImageArray[face][level].redefine(GL_NONE, 0, 0, true);
         }
     }
 
@@ -2784,10 +2735,9 @@
     {
         for (unsigned int i = 1; i <= q; i++)
         {
-            redefineImage(f, i, mImageArray[f][0].getFormat(),
+            redefineImage(f, i, mImageArray[f][0].getInternalFormat(),
                                 std::max(mImageArray[f][0].getWidth() >> i, 1),
-                                std::max(mImageArray[f][0].getWidth() >> i, 1),
-                                mImageArray[f][0].getType());
+                                std::max(mImageArray[f][0].getWidth() >> i, 1));
         }
     }
 
diff --git a/src/libGLESv2/Texture.h b/src/libGLESv2/Texture.h
index 34f9664..7d7378f 100644
--- a/src/libGLESv2/Texture.h
+++ b/src/libGLESv2/Texture.h
@@ -49,7 +49,7 @@
     Image();
     ~Image();
 
-    bool redefine(GLenum format, GLsizei width, GLsizei height, GLenum type, bool forceRelease);
+    bool redefine(GLint internalformat, GLsizei width, GLsizei height, bool forceRelease);
     void markDirty() {mDirty = true;}
     void markClean() {mDirty = false;}
 
@@ -58,15 +58,14 @@
 
     GLsizei getWidth() const {return mWidth;}
     GLsizei getHeight() const {return mHeight;}
-    GLenum getFormat() const {return mFormat;}
-    GLenum getType() const {return mType;}
+    GLenum getInternalFormat() const {return mInternalFormat;}
     bool isDirty() const {return mSurface && mDirty;}
     IDirect3DSurface9 *getSurface();
 
     void setManagedSurface(IDirect3DSurface9 *surface);
     void updateSurface(IDirect3DSurface9 *dest, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
 
-    void loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum type,
+    void loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
                   GLint unpackAlignment, const void *input);
 
     void loadAlphaData(GLsizei width, GLsizei height,
@@ -126,8 +125,7 @@
 
     GLsizei mWidth;
     GLsizei mHeight;
-    GLenum mFormat;
-    GLenum mType;
+    GLint mInternalFormat;
 
     bool mDirty;
 
@@ -321,7 +319,7 @@
 
     bool isMipmapComplete() const;
 
-    void redefineImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLenum type);
+    void redefineImage(GLint level, GLint internalformat, GLsizei width, GLsizei height);
     void commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
 
     Image mImageArray[IMPLEMENTATION_MAX_TEXTURE_LEVELS];
@@ -416,7 +414,7 @@
 
     void setImage(int faceIndex, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
     void commitRect(int faceIndex, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
-    void redefineImage(int faceIndex, GLint level, GLenum format, GLsizei width, GLsizei height, GLenum type);
+    void redefineImage(int faceIndex, GLint level, GLint internalformat, GLsizei width, GLsizei height);
 
     Image mImageArray[6][IMPLEMENTATION_MAX_TEXTURE_LEVELS];
 
diff --git a/src/libGLESv2/libGLESv2.cpp b/src/libGLESv2/libGLESv2.cpp
index 62bf20f..3e9a7a2 100644
--- a/src/libGLESv2/libGLESv2.cpp
+++ b/src/libGLESv2/libGLESv2.cpp
@@ -148,8 +148,9 @@
         return error(GL_INVALID_ENUM, false);
     }
 }
+
 bool validateSubImageParams2D(bool compressed, GLsizei width, GLsizei height,
-                              GLint xoffset, GLint yoffset, GLint level, GLenum format,
+                              GLint xoffset, GLint yoffset, GLint level, GLenum format, GLenum type,
                               gl::Texture2D *texture)
 {
     if (!texture)
@@ -162,9 +163,13 @@
         return error(GL_INVALID_OPERATION, false);
     }
 
-    if (format != GL_NONE && format != texture->getInternalFormat(level))
+    if (format != GL_NONE)
     {
-        return error(GL_INVALID_OPERATION, false);
+        GLenum internalformat = gl::ConvertSizedInternalFormat(format, type);
+        if (internalformat != texture->getInternalFormat(level))
+        {
+            return error(GL_INVALID_OPERATION, false);
+        }
     }
 
     if (compressed)
@@ -186,7 +191,7 @@
 }
 
 bool validateSubImageParamsCube(bool compressed, GLsizei width, GLsizei height,
-                                GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format,
+                                GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format, GLenum type,
                                 gl::TextureCubeMap *texture)
 {
     if (!texture)
@@ -199,9 +204,13 @@
         return error(GL_INVALID_OPERATION, false);
     }
 
-    if (format != GL_NONE && format != texture->getInternalFormat(target, level))
+    if (format != GL_NONE)
     {
-        return error(GL_INVALID_OPERATION, false);
+        GLenum internalformat = gl::ConvertSizedInternalFormat(format, type);
+        if (internalformat != texture->getInternalFormat(target, level))
+        {
+            return error(GL_INVALID_OPERATION, false);
+        }
     }
 
     if (compressed)
@@ -1218,7 +1227,7 @@
             if (target == GL_TEXTURE_2D)
             {
                 gl::Texture2D *texture = context->getTexture2D();
-                if (validateSubImageParams2D(true, width, height, xoffset, yoffset, level, format, texture))
+                if (validateSubImageParams2D(true, width, height, xoffset, yoffset, level, format, GL_NONE, texture))
                 {
                     texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
                 }
@@ -1226,7 +1235,7 @@
             else if (gl::IsCubemapTextureTarget(target))
             {
                 gl::TextureCubeMap *texture = context->getTextureCubeMap();
-                if (validateSubImageParamsCube(true, width, height, xoffset, yoffset, target, level, format, texture))
+                if (validateSubImageParamsCube(true, width, height, xoffset, yoffset, target, level, format, GL_NONE, texture))
                 {
                     texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
                 }
@@ -1319,8 +1328,7 @@
             switch (internalformat)
             {
               case GL_ALPHA:
-                if (colorbufferFormat != GL_ALPHA &&
-                    colorbufferFormat != GL_RGBA &&
+                if (colorbufferFormat != GL_ALPHA8_EXT &&
                     colorbufferFormat != GL_RGBA4 &&
                     colorbufferFormat != GL_RGB5_A1 &&
                     colorbufferFormat != GL_RGBA8_OES)
@@ -1329,11 +1337,17 @@
                 }
                 break;
               case GL_LUMINANCE:
-              case GL_RGB:
-                if (colorbufferFormat != GL_RGB &&
-                    colorbufferFormat != GL_RGB565 &&
+                if (colorbufferFormat != GL_RGB565 &&
                     colorbufferFormat != GL_RGB8_OES &&
-                    colorbufferFormat != GL_RGBA &&
+                    colorbufferFormat != GL_RGBA4 &&
+                    colorbufferFormat != GL_RGB5_A1 &&
+                    colorbufferFormat != GL_RGBA8_OES)
+                {
+                    return error(GL_INVALID_OPERATION);
+                }
+              case GL_RGB:
+                if (colorbufferFormat != GL_RGB565 &&
+                    colorbufferFormat != GL_RGB8_OES &&
                     colorbufferFormat != GL_RGBA4 &&
                     colorbufferFormat != GL_RGB5_A1 &&
                     colorbufferFormat != GL_RGBA8_OES)
@@ -1343,8 +1357,7 @@
                 break;
               case GL_LUMINANCE_ALPHA:
               case GL_RGBA:
-                if (colorbufferFormat != GL_RGBA &&
-                    colorbufferFormat != GL_RGBA4 &&
+                if (colorbufferFormat != GL_RGBA4 &&
                     colorbufferFormat != GL_RGB5_A1 &&
                     colorbufferFormat != GL_RGBA8_OES)
                  {
@@ -1498,22 +1511,22 @@
             {
                 gl::Texture2D *tex2d = context->getTexture2D();
 
-                if (!validateSubImageParams2D(false, width, height, xoffset, yoffset, level, GL_NONE, tex2d))
+                if (!validateSubImageParams2D(false, width, height, xoffset, yoffset, level, GL_NONE, GL_NONE, tex2d))
                 {
                     return; // error already registered by validateSubImageParams
                 }
-                textureFormat = tex2d->getInternalFormat(level);
+                textureFormat = gl::ExtractFormat(tex2d->getInternalFormat(level));
                 texture = tex2d;
             }
             else if (gl::IsCubemapTextureTarget(target))
             {
                 gl::TextureCubeMap *texcube = context->getTextureCubeMap();
 
-                if (!validateSubImageParamsCube(false, width, height, xoffset, yoffset, target, level, GL_NONE, texcube))
+                if (!validateSubImageParamsCube(false, width, height, xoffset, yoffset, target, level, GL_NONE, GL_NONE, texcube))
                 {
                     return; // error already registered by validateSubImageParams
                 }
-                textureFormat = texcube->getInternalFormat(target, level);
+                textureFormat = gl::ExtractFormat(texcube->getInternalFormat(target, level));
                 texture = texcube;
             }
             else UNREACHABLE();
@@ -1522,8 +1535,7 @@
             switch (textureFormat)
             {
               case GL_ALPHA:
-                if (colorbufferFormat != GL_ALPHA &&
-                    colorbufferFormat != GL_RGBA &&
+                if (colorbufferFormat != GL_ALPHA8_EXT &&
                     colorbufferFormat != GL_RGBA4 &&
                     colorbufferFormat != GL_RGB5_A1 &&
                     colorbufferFormat != GL_RGBA8_OES)
@@ -1532,9 +1544,7 @@
                 }
                 break;
               case GL_LUMINANCE:
-              case GL_RGB:
-                if (colorbufferFormat != GL_RGB &&
-                    colorbufferFormat != GL_RGB565 &&
+                if (colorbufferFormat != GL_RGB565 &&
                     colorbufferFormat != GL_RGB8_OES &&
                     colorbufferFormat != GL_RGBA &&
                     colorbufferFormat != GL_RGBA4 &&
@@ -1544,10 +1554,19 @@
                     return error(GL_INVALID_OPERATION);
                 }
                 break;
+              case GL_RGB:
+                if (colorbufferFormat != GL_RGB565 &&
+                    colorbufferFormat != GL_RGB8_OES &&
+                    colorbufferFormat != GL_RGBA4 &&
+                    colorbufferFormat != GL_RGB5_A1 &&
+                    colorbufferFormat != GL_RGBA8_OES)
+                {
+                    return error(GL_INVALID_OPERATION);
+                }
+                break;
               case GL_LUMINANCE_ALPHA:
               case GL_RGBA:
-                if (colorbufferFormat != GL_RGBA &&
-                    colorbufferFormat != GL_RGBA4 &&
+                if (colorbufferFormat != GL_RGBA4 &&
                     colorbufferFormat != GL_RGB5_A1 &&
                     colorbufferFormat != GL_RGBA8_OES)
                 {
@@ -5910,7 +5929,7 @@
             if (target == GL_TEXTURE_2D)
             {
                 gl::Texture2D *texture = context->getTexture2D();
-                if (validateSubImageParams2D(false, width, height, xoffset, yoffset, level, format, texture))
+                if (validateSubImageParams2D(false, width, height, xoffset, yoffset, level, format, type, texture))
                 {
                     texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
                 }
@@ -5918,7 +5937,7 @@
             else if (gl::IsCubemapTextureTarget(target))
             {
                 gl::TextureCubeMap *texture = context->getTextureCubeMap();
-                if (validateSubImageParamsCube(false, width, height, xoffset, yoffset, target, level, format, texture))
+                if (validateSubImageParamsCube(false, width, height, xoffset, yoffset, target, level, format, type, texture))
                 {
                     texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
                 }
diff --git a/src/libGLESv2/utilities.cpp b/src/libGLESv2/utilities.cpp
index d0a7beb..1dae681 100644
--- a/src/libGLESv2/utilities.cpp
+++ b/src/libGLESv2/utilities.cpp
@@ -229,22 +229,22 @@
     return -1;
 }
 
-GLsizei ComputePitch(GLsizei width, GLenum format, GLenum type, GLint alignment)
+GLsizei ComputePitch(GLsizei width, GLint internalformat, GLint alignment)
 {
     ASSERT(alignment > 0 && isPow2(alignment));
 
-    GLsizei rawPitch = ComputePixelSize(format, type) * width;
+    GLsizei rawPitch = ComputePixelSize(internalformat) * width;
     return (rawPitch + alignment - 1) & ~(alignment - 1);
 }
 
-GLsizei ComputeCompressedPitch(GLsizei width, GLenum format)
+GLsizei ComputeCompressedPitch(GLsizei width, GLenum internalformat)
 {
-    return ComputeCompressedSize(width, 1, format);
+    return ComputeCompressedSize(width, 1, internalformat);
 }
 
-GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format)
+GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum internalformat)
 {
-    switch (format)
+    switch (internalformat)
     {
       case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
       case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
@@ -277,7 +277,10 @@
 bool IsDepthTexture(GLenum format)
 {
     if (format == GL_DEPTH_COMPONENT ||
-        format == GL_DEPTH_STENCIL_OES)
+        format == GL_DEPTH_STENCIL_OES ||
+        format == GL_DEPTH_COMPONENT16 ||
+        format == GL_DEPTH_COMPONENT32_OES ||
+        format == GL_DEPTH24_STENCIL8_OES)
     {
         return true;
     }
@@ -286,54 +289,29 @@
 }
 
 // Returns the size, in bytes, of a single texel in an Image
-int ComputePixelSize(GLenum format, GLenum type)
+int ComputePixelSize(GLint internalformat)
 {
-    switch (type)
+    switch (internalformat)
     {
-      case GL_UNSIGNED_BYTE:
-        switch (format)
-        {
-          case GL_ALPHA:           return sizeof(unsigned char);
-          case GL_LUMINANCE:       return sizeof(unsigned char);
-          case GL_LUMINANCE_ALPHA: return sizeof(unsigned char) * 2;
-          case GL_RGB:             return sizeof(unsigned char) * 3;
-          case GL_RGBA:            return sizeof(unsigned char) * 4;
-          case GL_BGRA_EXT:        return sizeof(unsigned char) * 4;
-          default: UNREACHABLE();
-        }
-        break;
-      case GL_UNSIGNED_SHORT_4_4_4_4:
-      case GL_UNSIGNED_SHORT_5_5_5_1:
-      case GL_UNSIGNED_SHORT_5_6_5:
-      case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
-      case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
-      case GL_UNSIGNED_SHORT:
-        return sizeof(unsigned short);
-      case GL_UNSIGNED_INT:
-      case GL_UNSIGNED_INT_24_8_OES:
-        return sizeof(unsigned int);
-      case GL_FLOAT:
-        switch (format)
-        {
-          case GL_ALPHA:           return sizeof(float);
-          case GL_LUMINANCE:       return sizeof(float);
-          case GL_LUMINANCE_ALPHA: return sizeof(float) * 2;
-          case GL_RGB:             return sizeof(float) * 3;
-          case GL_RGBA:            return sizeof(float) * 4;
-          default: UNREACHABLE();
-        }
-        break;
-      case GL_HALF_FLOAT_OES:
-        switch (format)
-        {
-          case GL_ALPHA:           return sizeof(unsigned short);
-          case GL_LUMINANCE:       return sizeof(unsigned short);
-          case GL_LUMINANCE_ALPHA: return sizeof(unsigned short) * 2;
-          case GL_RGB:             return sizeof(unsigned short) * 3;
-          case GL_RGBA:            return sizeof(unsigned short) * 4;
-          default: UNREACHABLE();
-        }
-        break;
+      case GL_ALPHA8_EXT:                       return sizeof(unsigned char);
+      case GL_LUMINANCE8_EXT:                   return sizeof(unsigned char);
+      case GL_ALPHA32F_EXT:                     return sizeof(float);
+      case GL_LUMINANCE32F_EXT:                 return sizeof(float);
+      case GL_ALPHA16F_EXT:                     return sizeof(unsigned short);
+      case GL_LUMINANCE16F_EXT:                 return sizeof(unsigned short);
+      case GL_LUMINANCE8_ALPHA8_EXT:            return sizeof(unsigned char) * 2;
+      case GL_LUMINANCE_ALPHA32F_EXT:           return sizeof(float) * 2;
+      case GL_LUMINANCE_ALPHA16F_EXT:           return sizeof(unsigned short) * 2;
+      case GL_RGB8_OES:                         return sizeof(unsigned char) * 3;
+      case GL_RGB565:                           return sizeof(unsigned short);
+      case GL_RGB32F_EXT:                       return sizeof(float) * 3;
+      case GL_RGB16F_EXT:                       return sizeof(unsigned short) * 3;
+      case GL_RGBA8_OES:                        return sizeof(unsigned char) * 4;
+      case GL_RGBA4:                            return sizeof(unsigned short);
+      case GL_RGB5_A1:                          return sizeof(unsigned short);
+      case GL_RGBA32F_EXT:                      return sizeof(float) * 4;
+      case GL_RGBA16F_EXT:                      return sizeof(unsigned short) * 4;
+      case GL_BGRA8_EXT:                        return sizeof(unsigned char) * 4;
       default: UNREACHABLE();
     }
 
@@ -350,6 +328,94 @@
     return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target);
 }
 
+GLint ConvertSizedInternalFormat(GLenum format, GLenum type)
+{
+    switch (format)
+    {
+      case GL_ALPHA:
+        switch (type)
+        {
+          case GL_UNSIGNED_BYTE:    return GL_ALPHA8_EXT;
+          case GL_FLOAT:            return GL_ALPHA32F_EXT;
+          case GL_HALF_FLOAT_OES:   return GL_ALPHA16F_EXT;
+          default:                  UNIMPLEMENTED();
+        }
+        break;
+      case GL_LUMINANCE:
+        switch (type)
+        {
+          case GL_UNSIGNED_BYTE:    return GL_LUMINANCE8_EXT;
+          case GL_FLOAT:            return GL_LUMINANCE32F_EXT;
+          case GL_HALF_FLOAT_OES:   return GL_LUMINANCE16F_EXT;
+          default:                  UNIMPLEMENTED();
+        }
+        break;
+      case GL_LUMINANCE_ALPHA:
+        switch (type)
+        {
+          case GL_UNSIGNED_BYTE:    return GL_LUMINANCE8_ALPHA8_EXT;
+          case GL_FLOAT:            return GL_LUMINANCE_ALPHA32F_EXT;
+          case GL_HALF_FLOAT_OES:   return GL_LUMINANCE_ALPHA16F_EXT;
+          default:                  UNIMPLEMENTED();
+        }
+        break;
+      case GL_RGB:
+        switch (type)
+        {
+          case GL_UNSIGNED_BYTE:            return GL_RGB8_OES;
+          case GL_UNSIGNED_SHORT_5_6_5:     return GL_RGB565;
+          case GL_FLOAT:                    return GL_RGB32F_EXT;
+          case GL_HALF_FLOAT_OES:           return GL_RGB16F_EXT;
+          default:                          UNIMPLEMENTED();
+        }
+        break;
+      case GL_RGBA:
+        switch (type)
+        {
+          case GL_UNSIGNED_BYTE:            return GL_RGBA8_OES;
+          case GL_UNSIGNED_SHORT_4_4_4_4:   return GL_RGBA4;
+          case GL_UNSIGNED_SHORT_5_5_5_1:   return GL_RGB5_A1;
+          case GL_FLOAT:                    return GL_RGBA32F_EXT;
+          case GL_HALF_FLOAT_OES:           return GL_RGBA16F_EXT;
+            break;
+          default:                          UNIMPLEMENTED();
+        }
+        break;
+      case GL_BGRA_EXT:
+        switch (type)
+        {
+            // Are there sized internal formats for the packed BGRA types?
+          case GL_UNSIGNED_BYTE:                    return GL_BGRA8_EXT;
+          default:                                  UNIMPLEMENTED();
+        }
+        break;
+      case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+      case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+      case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
+      case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
+        return format;
+      case GL_DEPTH_COMPONENT:
+        switch (type)
+        {
+          case GL_UNSIGNED_SHORT:           return GL_DEPTH_COMPONENT16;
+          case GL_UNSIGNED_INT:             return GL_DEPTH_COMPONENT32_OES;
+          default:                          UNIMPLEMENTED();
+        }
+        break;
+      case GL_DEPTH_STENCIL_OES:
+        switch (type)
+        {
+          case GL_UNSIGNED_INT_24_8_OES:    return GL_DEPTH24_STENCIL8_OES;
+          default:                          UNIMPLEMENTED();
+        }
+        break;
+      default:
+        UNIMPLEMENTED();
+    }
+
+    return GL_NONE;
+}
+
 GLenum ExtractFormat(GLenum internalformat)
 {
     switch (internalformat)
diff --git a/src/libGLESv2/utilities.h b/src/libGLESv2/utilities.h
index 6257e94..2fa2697 100644
--- a/src/libGLESv2/utilities.h
+++ b/src/libGLESv2/utilities.h
@@ -34,14 +34,15 @@
 
 int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize);
 
-int ComputePixelSize(GLenum format, GLenum type);
-GLsizei ComputePitch(GLsizei width, GLenum format, GLenum type, GLint alignment);
+int ComputePixelSize(GLint internalformat);
+GLsizei ComputePitch(GLsizei width, GLint internalformat, GLint alignment);
 GLsizei ComputeCompressedPitch(GLsizei width, GLenum format);
 GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format);
 bool IsCompressed(GLenum format);
 bool IsDepthTexture(GLenum format);
 bool IsCubemapTextureTarget(GLenum target);
 bool IsInternalTextureTarget(GLenum target);
+GLint ConvertSizedInternalFormat(GLenum format, GLenum type);
 GLenum ExtractFormat(GLenum internalformat);
 GLenum ExtractType(GLenum internalformat);