Simplify formatutils.h by exposing the info structures.

Removed all the separate query functions and simply expose the internal
info structures.  This reduces the number of std::map/std::set operations
that were hidden behind the API.

Moved the validation tables for ES3 format combinations and effective
internal formats into validationES3.cpp so that formatutils.h only has
generic GL format queries.

BUG=angle:658

Change-Id: Ieb60d42b8eafcdb4f21dcbec130b39478ce5f7c5
Reviewed-on: https://chromium-review.googlesource.com/206835
Reviewed-by: Nicolas Capens <capn@chromium.org>
Tested-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libGLESv2/formatutils.cpp b/src/libGLESv2/formatutils.cpp
index 8cc2e19..008189a 100644
--- a/src/libGLESv2/formatutils.cpp
+++ b/src/libGLESv2/formatutils.cpp
@@ -22,24 +22,23 @@
 // can decide the true, sized, internal format. The ES2FormatMap determines the internal format for all valid
 // format and type combinations.
 
-struct FormatTypeInfo
+FormatType::FormatType()
+    : internalFormat(GL_NONE),
+      colorWriteFunction(NULL)
 {
-    GLenum mInternalFormat;
-    ColorWriteFunction mColorWriteFunction;
-
-    FormatTypeInfo(GLenum internalFormat, ColorWriteFunction writeFunc)
-        : mInternalFormat(internalFormat), mColorWriteFunction(writeFunc)
-    { }
-};
+}
 
 typedef std::pair<GLenum, GLenum> FormatTypePair;
-typedef std::pair<FormatTypePair, FormatTypeInfo> FormatPair;
-typedef std::map<FormatTypePair, FormatTypeInfo> FormatMap;
+typedef std::pair<FormatTypePair, FormatType> FormatPair;
+typedef std::map<FormatTypePair, FormatType> FormatMap;
 
 // A helper function to insert data into the format map with fewer characters.
 static inline void InsertFormatMapping(FormatMap *map, GLenum format, GLenum type, GLenum internalFormat, ColorWriteFunction writeFunc)
 {
-    map->insert(FormatPair(FormatTypePair(format, type), FormatTypeInfo(internalFormat, writeFunc)));
+    FormatType info;
+    info.internalFormat = internalFormat;
+    info.colorWriteFunction = writeFunc;
+    map->insert(FormatPair(FormatTypePair(format, type), info));
 }
 
 FormatMap BuildFormatMap()
@@ -145,278 +144,59 @@
     return map;
 }
 
-static const FormatMap &GetFormatMap()
+Type::Type()
+    : bytes(0),
+      specialInterpretation(false)
 {
-     static const FormatMap formatMap = BuildFormatMap();
-     return formatMap;
-}
-
-struct FormatInfo
-{
-    GLenum mInternalformat;
-    GLenum mFormat;
-    GLenum mType;
-
-    FormatInfo(GLenum internalformat, GLenum format, GLenum type)
-        : mInternalformat(internalformat), mFormat(format), mType(type) { }
-
-    bool operator<(const FormatInfo& other) const
-    {
-        return memcmp(this, &other, sizeof(FormatInfo)) < 0;
-    }
-};
-
-// ES3 has a specific set of permutations of internal formats, formats and types which are acceptable.
-typedef std::set<FormatInfo> ES3FormatSet;
-
-ES3FormatSet BuildES3FormatSet()
-{
-    ES3FormatSet set;
-
-    // Format combinations from ES 3.0.1 spec, table 3.2
-
-    //                   | Internal format      | Format            | Type                            |
-    //                   |                      |                   |                                 |
-    set.insert(FormatInfo(GL_RGBA8,              GL_RGBA,            GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_RGB5_A1,            GL_RGBA,            GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_RGBA4,              GL_RGBA,            GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_SRGB8_ALPHA8,       GL_RGBA,            GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_RGBA8_SNORM,        GL_RGBA,            GL_BYTE                          ));
-    set.insert(FormatInfo(GL_RGBA4,              GL_RGBA,            GL_UNSIGNED_SHORT_4_4_4_4        ));
-    set.insert(FormatInfo(GL_RGB10_A2,           GL_RGBA,            GL_UNSIGNED_INT_2_10_10_10_REV   ));
-    set.insert(FormatInfo(GL_RGB5_A1,            GL_RGBA,            GL_UNSIGNED_INT_2_10_10_10_REV   ));
-    set.insert(FormatInfo(GL_RGB5_A1,            GL_RGBA,            GL_UNSIGNED_SHORT_5_5_5_1        ));
-    set.insert(FormatInfo(GL_RGBA16F,            GL_RGBA,            GL_HALF_FLOAT                    ));
-    set.insert(FormatInfo(GL_RGBA16F,            GL_RGBA,            GL_HALF_FLOAT_OES                ));
-    set.insert(FormatInfo(GL_RGBA32F,            GL_RGBA,            GL_FLOAT                         ));
-    set.insert(FormatInfo(GL_RGBA16F,            GL_RGBA,            GL_FLOAT                         ));
-    set.insert(FormatInfo(GL_RGBA8UI,            GL_RGBA_INTEGER,    GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_RGBA8I,             GL_RGBA_INTEGER,    GL_BYTE                          ));
-    set.insert(FormatInfo(GL_RGBA16UI,           GL_RGBA_INTEGER,    GL_UNSIGNED_SHORT                ));
-    set.insert(FormatInfo(GL_RGBA16I,            GL_RGBA_INTEGER,    GL_SHORT                         ));
-    set.insert(FormatInfo(GL_RGBA32UI,           GL_RGBA_INTEGER,    GL_UNSIGNED_INT                  ));
-    set.insert(FormatInfo(GL_RGBA32I,            GL_RGBA_INTEGER,    GL_INT                           ));
-    set.insert(FormatInfo(GL_RGB10_A2UI,         GL_RGBA_INTEGER,    GL_UNSIGNED_INT_2_10_10_10_REV   ));
-    set.insert(FormatInfo(GL_RGB8,               GL_RGB,             GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_RGB565,             GL_RGB,             GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_SRGB8,              GL_RGB,             GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_RGB8_SNORM,         GL_RGB,             GL_BYTE                          ));
-    set.insert(FormatInfo(GL_RGB565,             GL_RGB,             GL_UNSIGNED_SHORT_5_6_5          ));
-    set.insert(FormatInfo(GL_R11F_G11F_B10F,     GL_RGB,             GL_UNSIGNED_INT_10F_11F_11F_REV  ));
-    set.insert(FormatInfo(GL_RGB9_E5,            GL_RGB,             GL_UNSIGNED_INT_5_9_9_9_REV      ));
-    set.insert(FormatInfo(GL_RGB16F,             GL_RGB,             GL_HALF_FLOAT                    ));
-    set.insert(FormatInfo(GL_RGB16F,             GL_RGB,             GL_HALF_FLOAT_OES                ));
-    set.insert(FormatInfo(GL_R11F_G11F_B10F,     GL_RGB,             GL_HALF_FLOAT                    ));
-    set.insert(FormatInfo(GL_R11F_G11F_B10F,     GL_RGB,             GL_HALF_FLOAT_OES                ));
-    set.insert(FormatInfo(GL_RGB9_E5,            GL_RGB,             GL_HALF_FLOAT                    ));
-    set.insert(FormatInfo(GL_RGB9_E5,            GL_RGB,             GL_HALF_FLOAT_OES                ));
-    set.insert(FormatInfo(GL_RGB32F,             GL_RGB,             GL_FLOAT                         ));
-    set.insert(FormatInfo(GL_RGB16F,             GL_RGB,             GL_FLOAT                         ));
-    set.insert(FormatInfo(GL_R11F_G11F_B10F,     GL_RGB,             GL_FLOAT                         ));
-    set.insert(FormatInfo(GL_RGB9_E5,            GL_RGB,             GL_FLOAT                         ));
-    set.insert(FormatInfo(GL_RGB8UI,             GL_RGB_INTEGER,     GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_RGB8I,              GL_RGB_INTEGER,     GL_BYTE                          ));
-    set.insert(FormatInfo(GL_RGB16UI,            GL_RGB_INTEGER,     GL_UNSIGNED_SHORT                ));
-    set.insert(FormatInfo(GL_RGB16I,             GL_RGB_INTEGER,     GL_SHORT                         ));
-    set.insert(FormatInfo(GL_RGB32UI,            GL_RGB_INTEGER,     GL_UNSIGNED_INT                  ));
-    set.insert(FormatInfo(GL_RGB32I,             GL_RGB_INTEGER,     GL_INT                           ));
-    set.insert(FormatInfo(GL_RG8,                GL_RG,              GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_RG8_SNORM,          GL_RG,              GL_BYTE                          ));
-    set.insert(FormatInfo(GL_RG16F,              GL_RG,              GL_HALF_FLOAT                    ));
-    set.insert(FormatInfo(GL_RG16F,              GL_RG,              GL_HALF_FLOAT_OES                ));
-    set.insert(FormatInfo(GL_RG32F,              GL_RG,              GL_FLOAT                         ));
-    set.insert(FormatInfo(GL_RG16F,              GL_RG,              GL_FLOAT                         ));
-    set.insert(FormatInfo(GL_RG8UI,              GL_RG_INTEGER,      GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_RG8I,               GL_RG_INTEGER,      GL_BYTE                          ));
-    set.insert(FormatInfo(GL_RG16UI,             GL_RG_INTEGER,      GL_UNSIGNED_SHORT                ));
-    set.insert(FormatInfo(GL_RG16I,              GL_RG_INTEGER,      GL_SHORT                         ));
-    set.insert(FormatInfo(GL_RG32UI,             GL_RG_INTEGER,      GL_UNSIGNED_INT                  ));
-    set.insert(FormatInfo(GL_RG32I,              GL_RG_INTEGER,      GL_INT                           ));
-    set.insert(FormatInfo(GL_R8,                 GL_RED,             GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_R8_SNORM,           GL_RED,             GL_BYTE                          ));
-    set.insert(FormatInfo(GL_R16F,               GL_RED,             GL_HALF_FLOAT                    ));
-    set.insert(FormatInfo(GL_R16F,               GL_RED,             GL_HALF_FLOAT_OES                ));
-    set.insert(FormatInfo(GL_R32F,               GL_RED,             GL_FLOAT                         ));
-    set.insert(FormatInfo(GL_R16F,               GL_RED,             GL_FLOAT                         ));
-    set.insert(FormatInfo(GL_R8UI,               GL_RED_INTEGER,     GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_R8I,                GL_RED_INTEGER,     GL_BYTE                          ));
-    set.insert(FormatInfo(GL_R16UI,              GL_RED_INTEGER,     GL_UNSIGNED_SHORT                ));
-    set.insert(FormatInfo(GL_R16I,               GL_RED_INTEGER,     GL_SHORT                         ));
-    set.insert(FormatInfo(GL_R32UI,              GL_RED_INTEGER,     GL_UNSIGNED_INT                  ));
-    set.insert(FormatInfo(GL_R32I,               GL_RED_INTEGER,     GL_INT                           ));
-
-    // Unsized formats
-    set.insert(FormatInfo(GL_RGBA,               GL_RGBA,            GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_RGBA,               GL_RGBA,            GL_UNSIGNED_SHORT_4_4_4_4        ));
-    set.insert(FormatInfo(GL_RGBA,               GL_RGBA,            GL_UNSIGNED_SHORT_5_5_5_1        ));
-    set.insert(FormatInfo(GL_RGB,                GL_RGB,             GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_RGB,                GL_RGB,             GL_UNSIGNED_SHORT_5_6_5          ));
-    set.insert(FormatInfo(GL_LUMINANCE_ALPHA,    GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_LUMINANCE,          GL_LUMINANCE,       GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_ALPHA,              GL_ALPHA,           GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_SRGB_ALPHA_EXT,     GL_SRGB_ALPHA_EXT,  GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_SRGB_EXT,           GL_SRGB_EXT,        GL_UNSIGNED_BYTE                 ));
-
-    // Depth stencil formats
-    set.insert(FormatInfo(GL_DEPTH_COMPONENT16,  GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT                ));
-    set.insert(FormatInfo(GL_DEPTH_COMPONENT24,  GL_DEPTH_COMPONENT, GL_UNSIGNED_INT                  ));
-    set.insert(FormatInfo(GL_DEPTH_COMPONENT16,  GL_DEPTH_COMPONENT, GL_UNSIGNED_INT                  ));
-    set.insert(FormatInfo(GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT                         ));
-    set.insert(FormatInfo(GL_DEPTH24_STENCIL8,   GL_DEPTH_STENCIL,   GL_UNSIGNED_INT_24_8             ));
-    set.insert(FormatInfo(GL_DEPTH32F_STENCIL8,  GL_DEPTH_STENCIL,   GL_FLOAT_32_UNSIGNED_INT_24_8_REV));
-
-    // From GL_EXT_sRGB
-    set.insert(FormatInfo(GL_SRGB8_ALPHA8_EXT,   GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE                  ));
-    set.insert(FormatInfo(GL_SRGB8,              GL_SRGB_EXT,       GL_UNSIGNED_BYTE                  ));
-
-    // From GL_OES_texture_float
-    set.insert(FormatInfo(GL_LUMINANCE_ALPHA,    GL_LUMINANCE_ALPHA, GL_FLOAT                         ));
-    set.insert(FormatInfo(GL_LUMINANCE,          GL_LUMINANCE,       GL_FLOAT                         ));
-    set.insert(FormatInfo(GL_ALPHA,              GL_ALPHA,           GL_FLOAT                         ));
-
-    // From GL_OES_texture_half_float
-    set.insert(FormatInfo(GL_LUMINANCE_ALPHA,    GL_LUMINANCE_ALPHA, GL_HALF_FLOAT                    ));
-    set.insert(FormatInfo(GL_LUMINANCE_ALPHA,    GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES                ));
-    set.insert(FormatInfo(GL_LUMINANCE,          GL_LUMINANCE,       GL_HALF_FLOAT                    ));
-    set.insert(FormatInfo(GL_LUMINANCE,          GL_LUMINANCE,       GL_HALF_FLOAT_OES                ));
-    set.insert(FormatInfo(GL_ALPHA,              GL_ALPHA,           GL_HALF_FLOAT                    ));
-    set.insert(FormatInfo(GL_ALPHA,              GL_ALPHA,           GL_HALF_FLOAT_OES                ));
-
-    // From GL_EXT_texture_format_BGRA8888
-    set.insert(FormatInfo(GL_BGRA_EXT,           GL_BGRA_EXT,        GL_UNSIGNED_BYTE                 ));
-
-    // From GL_EXT_texture_storage
-    //                   | Internal format          | Format            | Type                            |
-    //                   |                          |                   |                                 |
-    set.insert(FormatInfo(GL_ALPHA8_EXT,             GL_ALPHA,           GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_LUMINANCE8_EXT,         GL_LUMINANCE,       GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_LUMINANCE8_ALPHA8_EXT,  GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_ALPHA32F_EXT,           GL_ALPHA,           GL_FLOAT                         ));
-    set.insert(FormatInfo(GL_LUMINANCE32F_EXT,       GL_LUMINANCE,       GL_FLOAT                         ));
-    set.insert(FormatInfo(GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA, GL_FLOAT                         ));
-    set.insert(FormatInfo(GL_ALPHA16F_EXT,           GL_ALPHA,           GL_HALF_FLOAT                    ));
-    set.insert(FormatInfo(GL_ALPHA16F_EXT,           GL_ALPHA,           GL_HALF_FLOAT_OES                ));
-    set.insert(FormatInfo(GL_LUMINANCE16F_EXT,       GL_LUMINANCE,       GL_HALF_FLOAT                    ));
-    set.insert(FormatInfo(GL_LUMINANCE16F_EXT,       GL_LUMINANCE,       GL_HALF_FLOAT_OES                ));
-    set.insert(FormatInfo(GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT                    ));
-    set.insert(FormatInfo(GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES                ));
-
-    // From GL_EXT_texture_storage and GL_EXT_texture_format_BGRA8888
-    set.insert(FormatInfo(GL_BGRA8_EXT,              GL_BGRA_EXT,        GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_BGRA4_ANGLEX,           GL_BGRA_EXT,        GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT));
-    set.insert(FormatInfo(GL_BGRA4_ANGLEX,           GL_BGRA_EXT,        GL_UNSIGNED_BYTE                 ));
-    set.insert(FormatInfo(GL_BGR5_A1_ANGLEX,         GL_BGRA_EXT,        GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT));
-    set.insert(FormatInfo(GL_BGR5_A1_ANGLEX,         GL_BGRA_EXT,        GL_UNSIGNED_BYTE                 ));
-
-    // From GL_ANGLE_depth_texture
-    set.insert(FormatInfo(GL_DEPTH_COMPONENT32_OES,  GL_DEPTH_COMPONENT, GL_UNSIGNED_INT_24_8_OES         ));
-
-    // Compressed formats
-    // From ES 3.0.1 spec, table 3.16
-    //                   | Internal format                             | Format                                      | Type           |
-    //                   |                                             |                                             |                |
-    set.insert(FormatInfo(GL_COMPRESSED_R11_EAC,                        GL_COMPRESSED_R11_EAC,                        GL_UNSIGNED_BYTE));
-    set.insert(FormatInfo(GL_COMPRESSED_R11_EAC,                        GL_COMPRESSED_R11_EAC,                        GL_UNSIGNED_BYTE));
-    set.insert(FormatInfo(GL_COMPRESSED_SIGNED_R11_EAC,                 GL_COMPRESSED_SIGNED_R11_EAC,                 GL_UNSIGNED_BYTE));
-    set.insert(FormatInfo(GL_COMPRESSED_RG11_EAC,                       GL_COMPRESSED_RG11_EAC,                       GL_UNSIGNED_BYTE));
-    set.insert(FormatInfo(GL_COMPRESSED_SIGNED_RG11_EAC,                GL_COMPRESSED_SIGNED_RG11_EAC,                GL_UNSIGNED_BYTE));
-    set.insert(FormatInfo(GL_COMPRESSED_RGB8_ETC2,                      GL_COMPRESSED_RGB8_ETC2,                      GL_UNSIGNED_BYTE));
-    set.insert(FormatInfo(GL_COMPRESSED_SRGB8_ETC2,                     GL_COMPRESSED_SRGB8_ETC2,                     GL_UNSIGNED_BYTE));
-    set.insert(FormatInfo(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,  GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,  GL_UNSIGNED_BYTE));
-    set.insert(FormatInfo(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE));
-    set.insert(FormatInfo(GL_COMPRESSED_RGBA8_ETC2_EAC,                 GL_COMPRESSED_RGBA8_ETC2_EAC,                 GL_UNSIGNED_BYTE));
-    set.insert(FormatInfo(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,          GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,          GL_UNSIGNED_BYTE));
-
-
-    // From GL_EXT_texture_compression_dxt1
-    set.insert(FormatInfo(GL_COMPRESSED_RGB_S3TC_DXT1_EXT,              GL_COMPRESSED_RGB_S3TC_DXT1_EXT,              GL_UNSIGNED_BYTE));
-    set.insert(FormatInfo(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,             GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,             GL_UNSIGNED_BYTE));
-
-    // From GL_ANGLE_texture_compression_dxt3
-    set.insert(FormatInfo(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE,           GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE,           GL_UNSIGNED_BYTE));
-
-    // From GL_ANGLE_texture_compression_dxt5
-    set.insert(FormatInfo(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE,           GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE,           GL_UNSIGNED_BYTE));
-
-    return set;
-}
-
-static const ES3FormatSet &GetES3FormatSet()
-{
-    static const ES3FormatSet es3FormatSet = BuildES3FormatSet();
-    return es3FormatSet;
 }
 
 // Map of sizes of input types
-struct TypeInfo
+typedef std::pair<GLenum, Type> TypeInfoPair;
+typedef std::map<GLenum, Type> TypeInfoMap;
+
+static inline void InsertTypeInfo(TypeInfoMap *map, GLenum type, GLuint bytes, bool specialInterpretation)
 {
-    GLuint mTypeBytes;
-    bool mSpecialInterpretation;
+    Type info;
+    info.bytes = bytes;
+    info.specialInterpretation = specialInterpretation;
 
-    TypeInfo()
-        : mTypeBytes(0), mSpecialInterpretation(false) { }
+    map->insert(std::make_pair(type, info));
+}
 
-    TypeInfo(GLuint typeBytes, bool specialInterpretation)
-        : mTypeBytes(typeBytes), mSpecialInterpretation(specialInterpretation) { }
-
-    bool operator<(const TypeInfo& other) const
-    {
-        return memcmp(this, &other, sizeof(TypeInfo)) < 0;
-    }
-};
-
-typedef std::pair<GLenum, TypeInfo> TypeInfoPair;
-typedef std::map<GLenum, TypeInfo> TypeInfoMap;
+bool operator<(const Type& a, const Type& b)
+{
+    return memcmp(&a, &b, sizeof(Type)) < 0;
+}
 
 static TypeInfoMap BuildTypeInfoMap()
 {
     TypeInfoMap map;
 
-    map.insert(TypeInfoPair(GL_UNSIGNED_BYTE,                  TypeInfo( 1, false)));
-    map.insert(TypeInfoPair(GL_BYTE,                           TypeInfo( 1, false)));
-    map.insert(TypeInfoPair(GL_UNSIGNED_SHORT,                 TypeInfo( 2, false)));
-    map.insert(TypeInfoPair(GL_SHORT,                          TypeInfo( 2, false)));
-    map.insert(TypeInfoPair(GL_UNSIGNED_INT,                   TypeInfo( 4, false)));
-    map.insert(TypeInfoPair(GL_INT,                            TypeInfo( 4, false)));
-    map.insert(TypeInfoPair(GL_HALF_FLOAT,                     TypeInfo( 2, false)));
-    map.insert(TypeInfoPair(GL_HALF_FLOAT_OES,                 TypeInfo( 2, false)));
-    map.insert(TypeInfoPair(GL_FLOAT,                          TypeInfo( 4, false)));
-    map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_5_6_5,           TypeInfo( 2, true )));
-    map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_4_4_4_4,         TypeInfo( 2, true )));
-    map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_5_5_5_1,         TypeInfo( 2, true )));
-    map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, TypeInfo( 2, true )));
-    map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, TypeInfo( 2, true )));
-    map.insert(TypeInfoPair(GL_UNSIGNED_INT_2_10_10_10_REV,    TypeInfo( 4, true )));
-    map.insert(TypeInfoPair(GL_UNSIGNED_INT_24_8,              TypeInfo( 4, true )));
-    map.insert(TypeInfoPair(GL_UNSIGNED_INT_10F_11F_11F_REV,   TypeInfo( 4, true )));
-    map.insert(TypeInfoPair(GL_UNSIGNED_INT_5_9_9_9_REV,       TypeInfo( 4, true )));
-    map.insert(TypeInfoPair(GL_UNSIGNED_INT_24_8_OES,          TypeInfo( 4, true )));
-    map.insert(TypeInfoPair(GL_FLOAT_32_UNSIGNED_INT_24_8_REV, TypeInfo( 8, true )));
+    InsertTypeInfo(&map, GL_UNSIGNED_BYTE,                  1, false);
+    InsertTypeInfo(&map, GL_BYTE,                           1, false);
+    InsertTypeInfo(&map, GL_UNSIGNED_SHORT,                 2, false);
+    InsertTypeInfo(&map, GL_SHORT,                          2, false);
+    InsertTypeInfo(&map, GL_UNSIGNED_INT,                   4, false);
+    InsertTypeInfo(&map, GL_INT,                            4, false);
+    InsertTypeInfo(&map, GL_HALF_FLOAT,                     2, false);
+    InsertTypeInfo(&map, GL_HALF_FLOAT_OES,                 2, false);
+    InsertTypeInfo(&map, GL_FLOAT,                          4, false);
+    InsertTypeInfo(&map, GL_UNSIGNED_SHORT_5_6_5,           2, true );
+    InsertTypeInfo(&map, GL_UNSIGNED_SHORT_4_4_4_4,         2, true );
+    InsertTypeInfo(&map, GL_UNSIGNED_SHORT_5_5_5_1,         2, true );
+    InsertTypeInfo(&map, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, 2, true );
+    InsertTypeInfo(&map, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, 2, true );
+    InsertTypeInfo(&map, GL_UNSIGNED_INT_2_10_10_10_REV,    4, true );
+    InsertTypeInfo(&map, GL_UNSIGNED_INT_24_8,              4, true );
+    InsertTypeInfo(&map, GL_UNSIGNED_INT_10F_11F_11F_REV,   4, true );
+    InsertTypeInfo(&map, GL_UNSIGNED_INT_5_9_9_9_REV,       4, true );
+    InsertTypeInfo(&map, GL_UNSIGNED_INT_24_8_OES,          4, true );
+    InsertTypeInfo(&map, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8, true );
 
     return map;
 }
 
-static bool GetTypeInfo(GLenum type, TypeInfo *outTypeInfo)
-{
-    static const TypeInfoMap infoMap = BuildTypeInfoMap();
-    TypeInfoMap::const_iterator iter = infoMap.find(type);
-    if (iter != infoMap.end())
-    {
-        if (outTypeInfo)
-        {
-            *outTypeInfo = iter->second;
-        }
-        return true;
-    }
-    else
-    {
-        return false;
-    }
-}
-
 // Information about internal formats
-typedef bool(*SupportCheckFunction)(GLuint, const Extensions &);
-
 static bool AlwaysSupported(GLuint, const Extensions &)
 {
     return true;
@@ -469,273 +249,261 @@
     return extensions.*bool1 || extensions.*bool2;
 }
 
-struct InternalFormatInfo
+InternalFormat::InternalFormat()
+    : redBits(0),
+      greenBits(0),
+      blueBits(0),
+      luminanceBits(0),
+      alphaBits(0),
+      sharedBits(0),
+      depthBits(0),
+      stencilBits(0),
+      pixelBytes(0),
+      componentCount(0),
+      compressedBlockWidth(0),
+      compressedBlockHeight(0),
+      format(GL_NONE),
+      type(GL_NONE),
+      componentType(GL_NONE),
+      colorEncoding(GL_NONE),
+      compressed(false),
+      textureSupport(NeverSupported),
+      renderSupport(NeverSupported),
+      filterSupport(NeverSupported)
 {
-    GLuint mRedBits;
-    GLuint mGreenBits;
-    GLuint mBlueBits;
+}
 
-    GLuint mLuminanceBits;
+static InternalFormat UnsizedFormat(GLenum format, InternalFormat::SupportCheckFunction textureSupport,
+                                    InternalFormat::SupportCheckFunction renderSupport,
+                                    InternalFormat::SupportCheckFunction filterSupport)
+{
+    InternalFormat formatInfo;
+    formatInfo.format = format;
+    formatInfo.textureSupport = textureSupport;
+    formatInfo.renderSupport = renderSupport;
+    formatInfo.filterSupport = filterSupport;
+    return formatInfo;
+}
 
-    GLuint mAlphaBits;
-    GLuint mSharedBits;
+static InternalFormat RGBAFormat(GLuint red, GLuint green, GLuint blue, GLuint alpha, GLuint shared,
+                                 GLenum format, GLenum type, GLenum componentType, bool srgb,
+                                 InternalFormat::SupportCheckFunction textureSupport,
+                                 InternalFormat::SupportCheckFunction renderSupport,
+                                 InternalFormat::SupportCheckFunction filterSupport)
+{
+    InternalFormat formatInfo;
+    formatInfo.redBits = red;
+    formatInfo.greenBits = green;
+    formatInfo.blueBits = blue;
+    formatInfo.alphaBits = alpha;
+    formatInfo.sharedBits = shared;
+    formatInfo.pixelBytes = (red + green + blue + alpha + shared) / 8;
+    formatInfo.componentCount = ((red > 0) ? 1 : 0) + ((green > 0) ? 1 : 0) + ((blue > 0) ? 1 : 0) + ((alpha > 0) ? 1 : 0);
+    formatInfo.format = format;
+    formatInfo.type = type;
+    formatInfo.componentType = componentType;
+    formatInfo.colorEncoding = (srgb ? GL_SRGB : GL_LINEAR);
+    formatInfo.textureSupport = textureSupport;
+    formatInfo.renderSupport = renderSupport;
+    formatInfo.filterSupport = filterSupport;
+    return formatInfo;
+}
 
-    GLuint mDepthBits;
-    GLuint mStencilBits;
+static InternalFormat LUMAFormat(GLuint luminance, GLuint alpha, GLenum format, GLenum type, GLenum componentType,
+                                 InternalFormat::SupportCheckFunction textureSupport,
+                                 InternalFormat::SupportCheckFunction renderSupport,
+                                 InternalFormat::SupportCheckFunction filterSupport)
+{
+    InternalFormat formatInfo;
+    formatInfo.luminanceBits = luminance;
+    formatInfo.alphaBits = alpha;
+    formatInfo.pixelBytes = (luminance + alpha) / 8;
+    formatInfo.componentCount = ((luminance > 0) ? 1 : 0) + ((alpha > 0) ? 1 : 0);
+    formatInfo.format = format;
+    formatInfo.type = type;
+    formatInfo.componentType = componentType;
+    formatInfo.colorEncoding = GL_LINEAR;
+    formatInfo.textureSupport = textureSupport;
+    formatInfo.renderSupport = renderSupport;
+    formatInfo.filterSupport = filterSupport;
+    return formatInfo;
+}
 
-    GLuint mPixelBits;
+static InternalFormat DepthStencilFormat(GLuint depthBits, GLuint stencilBits, GLuint unusedBits, GLenum format,
+                                         GLenum type, GLenum componentType, InternalFormat::SupportCheckFunction textureSupport,
+                                         InternalFormat::SupportCheckFunction renderSupport,
+                                         InternalFormat::SupportCheckFunction filterSupport)
+{
+    InternalFormat formatInfo;
+    formatInfo.depthBits = depthBits;
+    formatInfo.stencilBits = stencilBits;
+    formatInfo.pixelBytes = (depthBits + stencilBits + unusedBits) / 8;
+    formatInfo.componentCount = ((depthBits > 0) ? 1 : 0) + ((stencilBits > 0) ? 1 : 0);
+    formatInfo.format = format;
+    formatInfo.type = type;
+    formatInfo.componentType = componentType;
+    formatInfo.colorEncoding = GL_LINEAR;
+    formatInfo.textureSupport = textureSupport;
+    formatInfo.renderSupport = renderSupport;
+    formatInfo.filterSupport = filterSupport;
+    return formatInfo;
+}
 
-    GLuint mComponentCount;
+static InternalFormat CompressedFormat(GLuint compressedBlockWidth, GLuint compressedBlockHeight, GLuint compressedBlockSize,
+                                       GLuint componentCount, GLenum format, GLenum type, bool srgb,
+                                       InternalFormat::SupportCheckFunction textureSupport,
+                                       InternalFormat::SupportCheckFunction renderSupport,
+                                       InternalFormat::SupportCheckFunction filterSupport)
+{
+    InternalFormat formatInfo;
+    formatInfo.compressedBlockWidth = compressedBlockWidth;
+    formatInfo.compressedBlockHeight = compressedBlockHeight;
+    formatInfo.pixelBytes = compressedBlockSize / 8;
+    formatInfo.componentCount = componentCount;
+    formatInfo.format = format;
+    formatInfo.type = type;
+    formatInfo.componentType = GL_UNSIGNED_NORMALIZED;
+    formatInfo.colorEncoding = (srgb ? GL_SRGB : GL_LINEAR);
+    formatInfo.compressed = true;
+    formatInfo.textureSupport = textureSupport;
+    formatInfo.renderSupport = renderSupport;
+    formatInfo.filterSupport = filterSupport;
+    return formatInfo;
+}
 
-    GLuint mCompressedBlockWidth;
-    GLuint mCompressedBlockHeight;
-
-    GLenum mFormat;
-    GLenum mType;
-
-    GLenum mComponentType;
-    GLenum mColorEncoding;
-
-    bool mIsCompressed;
-
-    SupportCheckFunction mTextureSupportFunction;
-    SupportCheckFunction mRenderSupportFunction;
-    SupportCheckFunction mFilterSupportFunction;
-
-    InternalFormatInfo() : mRedBits(0), mGreenBits(0), mBlueBits(0), mLuminanceBits(0), mAlphaBits(0), mSharedBits(0), mDepthBits(0), mStencilBits(0),
-                           mPixelBits(0), mComponentCount(0), mCompressedBlockWidth(0), mCompressedBlockHeight(0), mFormat(GL_NONE), mType(GL_NONE),
-                           mComponentType(GL_NONE), mColorEncoding(GL_NONE), mIsCompressed(false), mTextureSupportFunction(NeverSupported),
-                           mRenderSupportFunction(NeverSupported), mFilterSupportFunction(NeverSupported)
-    {
-    }
-
-    static InternalFormatInfo UnsizedFormat(GLenum format, SupportCheckFunction textureSupport, SupportCheckFunction renderSupport,
-                                            SupportCheckFunction filterSupport)
-    {
-        InternalFormatInfo formatInfo;
-        formatInfo.mFormat = format;
-        formatInfo.mTextureSupportFunction = textureSupport;
-        formatInfo.mRenderSupportFunction = renderSupport;
-        formatInfo.mFilterSupportFunction = filterSupport;
-        return formatInfo;
-    }
-
-    static InternalFormatInfo RGBAFormat(GLuint red, GLuint green, GLuint blue, GLuint alpha, GLuint shared,
-                                         GLenum format, GLenum type, GLenum componentType, bool srgb,
-                                         SupportCheckFunction textureSupport, SupportCheckFunction renderSupport,
-                                         SupportCheckFunction filterSupport)
-    {
-        InternalFormatInfo formatInfo;
-        formatInfo.mRedBits = red;
-        formatInfo.mGreenBits = green;
-        formatInfo.mBlueBits = blue;
-        formatInfo.mAlphaBits = alpha;
-        formatInfo.mSharedBits = shared;
-        formatInfo.mPixelBits = red + green + blue + alpha + shared;
-        formatInfo.mComponentCount = ((red > 0) ? 1 : 0) + ((green > 0) ? 1 : 0) + ((blue > 0) ? 1 : 0) + ((alpha > 0) ? 1 : 0);
-        formatInfo.mFormat = format;
-        formatInfo.mType = type;
-        formatInfo.mComponentType = componentType;
-        formatInfo.mColorEncoding = (srgb ? GL_SRGB : GL_LINEAR);
-        formatInfo.mTextureSupportFunction = textureSupport;
-        formatInfo.mRenderSupportFunction = renderSupport;
-        formatInfo.mFilterSupportFunction = filterSupport;
-        return formatInfo;
-    }
-
-    static InternalFormatInfo LUMAFormat(GLuint luminance, GLuint alpha, GLenum format, GLenum type, GLenum componentType,
-                                         SupportCheckFunction textureSupport, SupportCheckFunction renderSupport,
-                                         SupportCheckFunction filterSupport)
-    {
-        InternalFormatInfo formatInfo;
-        formatInfo.mLuminanceBits = luminance;
-        formatInfo.mAlphaBits = alpha;
-        formatInfo.mPixelBits = luminance + alpha;
-        formatInfo.mComponentCount = ((luminance > 0) ? 1 : 0) + ((alpha > 0) ? 1 : 0);
-        formatInfo.mFormat = format;
-        formatInfo.mType = type;
-        formatInfo.mComponentType = componentType;
-        formatInfo.mColorEncoding = GL_LINEAR;
-        formatInfo.mTextureSupportFunction = textureSupport;
-        formatInfo.mRenderSupportFunction = renderSupport;
-        formatInfo.mFilterSupportFunction = filterSupport;
-        return formatInfo;
-    }
-
-    static InternalFormatInfo DepthStencilFormat(GLuint depthBits, GLuint stencilBits, GLuint unusedBits, GLenum format,
-                                                 GLenum type, GLenum componentType, SupportCheckFunction textureSupport,
-                                                 SupportCheckFunction renderSupport, SupportCheckFunction filterSupport)
-    {
-        InternalFormatInfo formatInfo;
-        formatInfo.mDepthBits = depthBits;
-        formatInfo.mStencilBits = stencilBits;
-        formatInfo.mPixelBits = depthBits + stencilBits + unusedBits;
-        formatInfo.mComponentCount = ((depthBits > 0) ? 1 : 0) + ((stencilBits > 0) ? 1 : 0);
-        formatInfo.mFormat = format;
-        formatInfo.mType = type;
-        formatInfo.mComponentType = componentType;
-        formatInfo.mColorEncoding = GL_LINEAR;
-        formatInfo.mTextureSupportFunction = textureSupport;
-        formatInfo.mRenderSupportFunction = renderSupport;
-        formatInfo.mFilterSupportFunction = filterSupport;
-        return formatInfo;
-    }
-
-    static InternalFormatInfo CompressedFormat(GLuint compressedBlockWidth, GLuint compressedBlockHeight, GLuint compressedBlockSize,
-                                               GLuint componentCount, GLenum format, GLenum type, bool srgb,
-                                               SupportCheckFunction textureSupport, SupportCheckFunction renderSupport,
-                                               SupportCheckFunction filterSupport)
-    {
-        InternalFormatInfo formatInfo;
-        formatInfo.mCompressedBlockWidth = compressedBlockWidth;
-        formatInfo.mCompressedBlockHeight = compressedBlockHeight;
-        formatInfo.mPixelBits = compressedBlockSize;
-        formatInfo.mComponentCount = componentCount;
-        formatInfo.mFormat = format;
-        formatInfo.mType = type;
-        formatInfo.mComponentType = GL_UNSIGNED_NORMALIZED;
-        formatInfo.mColorEncoding = (srgb ? GL_SRGB : GL_LINEAR);
-        formatInfo.mIsCompressed = true;
-        formatInfo.mTextureSupportFunction = textureSupport;
-        formatInfo.mRenderSupportFunction = renderSupport;
-        formatInfo.mFilterSupportFunction = filterSupport;
-        return formatInfo;
-    }
-};
-
-typedef std::pair<GLenum, InternalFormatInfo> InternalFormatInfoPair;
-typedef std::map<GLenum, InternalFormatInfo> InternalFormatInfoMap;
+typedef std::pair<GLenum, InternalFormat> InternalFormatInfoPair;
+typedef std::map<GLenum, InternalFormat> InternalFormatInfoMap;
 
 static InternalFormatInfoMap BuildInternalFormatInfoMap()
 {
     InternalFormatInfoMap map;
 
     // From ES 3.0.1 spec, table 3.12
-    map.insert(InternalFormatInfoPair(GL_NONE,              InternalFormatInfo()));
+    map.insert(InternalFormatInfoPair(GL_NONE,              InternalFormat()));
 
-    //                               | Internal format     |                              | R | G | B | A |S | Format         | Type                           | Component type        | SRGB | Texture supported                                    | Renderable      | Filterable    |
-    map.insert(InternalFormatInfoPair(GL_R8,                InternalFormatInfo::RGBAFormat( 8,  0,  0,  0, 0, GL_RED,          GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, RequireESVersionOrExtension<3, &Extensions::textureRG>, AlwaysSupported, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_R8_SNORM,          InternalFormatInfo::RGBAFormat( 8,  0,  0,  0, 0, GL_RED,          GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, RequireESVersion<3>,                                    NeverSupported,  AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_RG8,               InternalFormatInfo::RGBAFormat( 8,  8,  0,  0, 0, GL_RG,           GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, RequireESVersionOrExtension<3, &Extensions::textureRG>, AlwaysSupported, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_RG8_SNORM,         InternalFormatInfo::RGBAFormat( 8,  8,  0,  0, 0, GL_RG,           GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, RequireESVersion<3>,                                    NeverSupported,  AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_RGB8,              InternalFormatInfo::RGBAFormat( 8,  8,  8,  0, 0, GL_RGB,          GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, RequireESVersionOrExtension<3, &Extensions::rgb8rgba8>, AlwaysSupported, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_RGB8_SNORM,        InternalFormatInfo::RGBAFormat( 8,  8,  8,  0, 0, GL_RGB,          GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, RequireESVersion<3>,                                    NeverSupported,  AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_RGB565,            InternalFormatInfo::RGBAFormat( 5,  6,  5,  0, 0, GL_RGB,          GL_UNSIGNED_SHORT_5_6_5,         GL_UNSIGNED_NORMALIZED, false, RequireESVersion<2>,                                    AlwaysSupported, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_RGBA4,             InternalFormatInfo::RGBAFormat( 4,  4,  4,  4, 0, GL_RGBA,         GL_UNSIGNED_SHORT_4_4_4_4,       GL_UNSIGNED_NORMALIZED, false, RequireESVersion<2>,                                    AlwaysSupported, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_RGB5_A1,           InternalFormatInfo::RGBAFormat( 5,  5,  5,  1, 0, GL_RGBA,         GL_UNSIGNED_SHORT_5_5_5_1,       GL_UNSIGNED_NORMALIZED, false, RequireESVersion<2>,                                    AlwaysSupported, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_RGBA8,             InternalFormatInfo::RGBAFormat( 8,  8,  8,  8, 0, GL_RGBA,         GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, RequireESVersionOrExtension<3, &Extensions::rgb8rgba8>, AlwaysSupported, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_RGBA8_SNORM,       InternalFormatInfo::RGBAFormat( 8,  8,  8,  8, 0, GL_RGBA,         GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, RequireESVersion<3>,                                    NeverSupported,  AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_RGB10_A2,          InternalFormatInfo::RGBAFormat(10, 10, 10,  2, 0, GL_RGBA,         GL_UNSIGNED_INT_2_10_10_10_REV,  GL_UNSIGNED_NORMALIZED, false, RequireESVersion<3>,                                    AlwaysSupported, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_RGB10_A2UI,        InternalFormatInfo::RGBAFormat(10, 10, 10,  2, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV,  GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    NeverSupported,  NeverSupported)));
-    map.insert(InternalFormatInfoPair(GL_SRGB8,             InternalFormatInfo::RGBAFormat( 8,  8,  8,  0, 0, GL_RGB,          GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, true,  RequireESVersionOrExtension<3, &Extensions::sRGB>,      NeverSupported,  AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_SRGB8_ALPHA8,      InternalFormatInfo::RGBAFormat( 8,  8,  8,  8, 0, GL_RGBA,         GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, true,  RequireESVersionOrExtension<3, &Extensions::sRGB>,      AlwaysSupported, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_R11F_G11F_B10F,    InternalFormatInfo::RGBAFormat(11, 11, 10,  0, 0, GL_RGB,          GL_UNSIGNED_INT_10F_11F_11F_REV, GL_FLOAT,               false, RequireESVersion<3>,                                    RequireExtension<&Extensions::colorBufferFloat>, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_RGB9_E5,           InternalFormatInfo::RGBAFormat( 9,  9,  9,  0, 5, GL_RGB,          GL_UNSIGNED_INT_5_9_9_9_REV,     GL_FLOAT,               false, RequireESVersion<3>,                                    NeverSupported,  AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_R8I,               InternalFormatInfo::RGBAFormat( 8,  0,  0,  0, 0, GL_RED_INTEGER,  GL_BYTE,                         GL_INT,                 false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
-    map.insert(InternalFormatInfoPair(GL_R8UI,              InternalFormatInfo::RGBAFormat( 8,  0,  0,  0, 0, GL_RED_INTEGER,  GL_UNSIGNED_BYTE,                GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
-    map.insert(InternalFormatInfoPair(GL_R16I,              InternalFormatInfo::RGBAFormat(16,  0,  0,  0, 0, GL_RED_INTEGER,  GL_SHORT,                        GL_INT,                 false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
-    map.insert(InternalFormatInfoPair(GL_R16UI,             InternalFormatInfo::RGBAFormat(16,  0,  0,  0, 0, GL_RED_INTEGER,  GL_UNSIGNED_SHORT,               GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
-    map.insert(InternalFormatInfoPair(GL_R32I,              InternalFormatInfo::RGBAFormat(32,  0,  0,  0, 0, GL_RED_INTEGER,  GL_INT,                          GL_INT,                 false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
-    map.insert(InternalFormatInfoPair(GL_R32UI,             InternalFormatInfo::RGBAFormat(32,  0,  0,  0, 0, GL_RED_INTEGER,  GL_UNSIGNED_INT,                 GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
-    map.insert(InternalFormatInfoPair(GL_RG8I,              InternalFormatInfo::RGBAFormat( 8,  8,  0,  0, 0, GL_RG_INTEGER,   GL_BYTE,                         GL_INT,                 false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
-    map.insert(InternalFormatInfoPair(GL_RG8UI,             InternalFormatInfo::RGBAFormat( 8,  8,  0,  0, 0, GL_RG_INTEGER,   GL_UNSIGNED_BYTE,                GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
-    map.insert(InternalFormatInfoPair(GL_RG16I,             InternalFormatInfo::RGBAFormat(16, 16,  0,  0, 0, GL_RG_INTEGER,   GL_SHORT,                        GL_INT,                 false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
-    map.insert(InternalFormatInfoPair(GL_RG16UI,            InternalFormatInfo::RGBAFormat(16, 16,  0,  0, 0, GL_RG_INTEGER,   GL_UNSIGNED_SHORT,               GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
-    map.insert(InternalFormatInfoPair(GL_RG32I,             InternalFormatInfo::RGBAFormat(32, 32,  0,  0, 0, GL_RG_INTEGER,   GL_INT,                          GL_INT,                 false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
-    map.insert(InternalFormatInfoPair(GL_RG32UI,            InternalFormatInfo::RGBAFormat(32, 32,  0,  0, 0, GL_RG_INTEGER,   GL_UNSIGNED_INT,                 GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
-    map.insert(InternalFormatInfoPair(GL_RGB8I,             InternalFormatInfo::RGBAFormat( 8,  8,  8,  0, 0, GL_RGB_INTEGER,  GL_BYTE,                         GL_INT,                 false, RequireESVersion<3>,                                    NeverSupported,   NeverSupported)));
-    map.insert(InternalFormatInfoPair(GL_RGB8UI,            InternalFormatInfo::RGBAFormat( 8,  8,  8,  0, 0, GL_RGB_INTEGER,  GL_UNSIGNED_BYTE,                GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    NeverSupported,   NeverSupported)));
-    map.insert(InternalFormatInfoPair(GL_RGB16I,            InternalFormatInfo::RGBAFormat(16, 16, 16,  0, 0, GL_RGB_INTEGER,  GL_SHORT,                        GL_INT,                 false, RequireESVersion<3>,                                    NeverSupported,   NeverSupported)));
-    map.insert(InternalFormatInfoPair(GL_RGB16UI,           InternalFormatInfo::RGBAFormat(16, 16, 16,  0, 0, GL_RGB_INTEGER,  GL_UNSIGNED_SHORT,               GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    NeverSupported,   NeverSupported)));
-    map.insert(InternalFormatInfoPair(GL_RGB32I,            InternalFormatInfo::RGBAFormat(32, 32, 32,  0, 0, GL_RGB_INTEGER,  GL_INT,                          GL_INT,                 false, RequireESVersion<3>,                                    NeverSupported,   NeverSupported)));
-    map.insert(InternalFormatInfoPair(GL_RGB32UI,           InternalFormatInfo::RGBAFormat(32, 32, 32,  0, 0, GL_RGB_INTEGER,  GL_UNSIGNED_INT,                 GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    NeverSupported,   NeverSupported)));
-    map.insert(InternalFormatInfoPair(GL_RGBA8I,            InternalFormatInfo::RGBAFormat( 8,  8,  8,  8, 0, GL_RGBA_INTEGER, GL_BYTE,                         GL_INT,                 false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
-    map.insert(InternalFormatInfoPair(GL_RGBA8UI,           InternalFormatInfo::RGBAFormat( 8,  8,  8,  8, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE,                GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
-    map.insert(InternalFormatInfoPair(GL_RGBA16I,           InternalFormatInfo::RGBAFormat(16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_SHORT,                        GL_INT,                 false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
-    map.insert(InternalFormatInfoPair(GL_RGBA16UI,          InternalFormatInfo::RGBAFormat(16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT,               GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
-    map.insert(InternalFormatInfoPair(GL_RGBA32I,           InternalFormatInfo::RGBAFormat(32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_INT,                          GL_INT,                 false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
-    map.insert(InternalFormatInfoPair(GL_RGBA32UI,          InternalFormatInfo::RGBAFormat(32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT,                 GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
+    //                               | Internal format     |          | R | G | B | A |S | Format         | Type                           | Component type        | SRGB | Texture supported                                    | Renderable      | Filterable    |
+    map.insert(InternalFormatInfoPair(GL_R8,                RGBAFormat( 8,  0,  0,  0, 0, GL_RED,          GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, RequireESVersionOrExtension<3, &Extensions::textureRG>, AlwaysSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_R8_SNORM,          RGBAFormat( 8,  0,  0,  0, 0, GL_RED,          GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, RequireESVersion<3>,                                    NeverSupported,  AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_RG8,               RGBAFormat( 8,  8,  0,  0, 0, GL_RG,           GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, RequireESVersionOrExtension<3, &Extensions::textureRG>, AlwaysSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_RG8_SNORM,         RGBAFormat( 8,  8,  0,  0, 0, GL_RG,           GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, RequireESVersion<3>,                                    NeverSupported,  AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGB8,              RGBAFormat( 8,  8,  8,  0, 0, GL_RGB,          GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, RequireESVersionOrExtension<3, &Extensions::rgb8rgba8>, AlwaysSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGB8_SNORM,        RGBAFormat( 8,  8,  8,  0, 0, GL_RGB,          GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, RequireESVersion<3>,                                    NeverSupported,  AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGB565,            RGBAFormat( 5,  6,  5,  0, 0, GL_RGB,          GL_UNSIGNED_SHORT_5_6_5,         GL_UNSIGNED_NORMALIZED, false, RequireESVersion<2>,                                    AlwaysSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGBA4,             RGBAFormat( 4,  4,  4,  4, 0, GL_RGBA,         GL_UNSIGNED_SHORT_4_4_4_4,       GL_UNSIGNED_NORMALIZED, false, RequireESVersion<2>,                                    AlwaysSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGB5_A1,           RGBAFormat( 5,  5,  5,  1, 0, GL_RGBA,         GL_UNSIGNED_SHORT_5_5_5_1,       GL_UNSIGNED_NORMALIZED, false, RequireESVersion<2>,                                    AlwaysSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGBA8,             RGBAFormat( 8,  8,  8,  8, 0, GL_RGBA,         GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, RequireESVersionOrExtension<3, &Extensions::rgb8rgba8>, AlwaysSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGBA8_SNORM,       RGBAFormat( 8,  8,  8,  8, 0, GL_RGBA,         GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, RequireESVersion<3>,                                    NeverSupported,  AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGB10_A2,          RGBAFormat(10, 10, 10,  2, 0, GL_RGBA,         GL_UNSIGNED_INT_2_10_10_10_REV,  GL_UNSIGNED_NORMALIZED, false, RequireESVersion<3>,                                    AlwaysSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGB10_A2UI,        RGBAFormat(10, 10, 10,  2, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV,  GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    NeverSupported,  NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_SRGB8,             RGBAFormat( 8,  8,  8,  0, 0, GL_RGB,          GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, true,  RequireESVersionOrExtension<3, &Extensions::sRGB>,      NeverSupported,  AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_SRGB8_ALPHA8,      RGBAFormat( 8,  8,  8,  8, 0, GL_RGBA,         GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, true,  RequireESVersionOrExtension<3, &Extensions::sRGB>,      AlwaysSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_R11F_G11F_B10F,    RGBAFormat(11, 11, 10,  0, 0, GL_RGB,          GL_UNSIGNED_INT_10F_11F_11F_REV, GL_FLOAT,               false, RequireESVersion<3>,                                    RequireExtension<&Extensions::colorBufferFloat>, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGB9_E5,           RGBAFormat( 9,  9,  9,  0, 5, GL_RGB,          GL_UNSIGNED_INT_5_9_9_9_REV,     GL_FLOAT,               false, RequireESVersion<3>,                                    NeverSupported,  AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_R8I,               RGBAFormat( 8,  0,  0,  0, 0, GL_RED_INTEGER,  GL_BYTE,                         GL_INT,                 false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_R8UI,              RGBAFormat( 8,  0,  0,  0, 0, GL_RED_INTEGER,  GL_UNSIGNED_BYTE,                GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_R16I,              RGBAFormat(16,  0,  0,  0, 0, GL_RED_INTEGER,  GL_SHORT,                        GL_INT,                 false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_R16UI,             RGBAFormat(16,  0,  0,  0, 0, GL_RED_INTEGER,  GL_UNSIGNED_SHORT,               GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_R32I,              RGBAFormat(32,  0,  0,  0, 0, GL_RED_INTEGER,  GL_INT,                          GL_INT,                 false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_R32UI,             RGBAFormat(32,  0,  0,  0, 0, GL_RED_INTEGER,  GL_UNSIGNED_INT,                 GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_RG8I,              RGBAFormat( 8,  8,  0,  0, 0, GL_RG_INTEGER,   GL_BYTE,                         GL_INT,                 false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_RG8UI,             RGBAFormat( 8,  8,  0,  0, 0, GL_RG_INTEGER,   GL_UNSIGNED_BYTE,                GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_RG16I,             RGBAFormat(16, 16,  0,  0, 0, GL_RG_INTEGER,   GL_SHORT,                        GL_INT,                 false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_RG16UI,            RGBAFormat(16, 16,  0,  0, 0, GL_RG_INTEGER,   GL_UNSIGNED_SHORT,               GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_RG32I,             RGBAFormat(32, 32,  0,  0, 0, GL_RG_INTEGER,   GL_INT,                          GL_INT,                 false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_RG32UI,            RGBAFormat(32, 32,  0,  0, 0, GL_RG_INTEGER,   GL_UNSIGNED_INT,                 GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGB8I,             RGBAFormat( 8,  8,  8,  0, 0, GL_RGB_INTEGER,  GL_BYTE,                         GL_INT,                 false, RequireESVersion<3>,                                    NeverSupported,   NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGB8UI,            RGBAFormat( 8,  8,  8,  0, 0, GL_RGB_INTEGER,  GL_UNSIGNED_BYTE,                GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    NeverSupported,   NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGB16I,            RGBAFormat(16, 16, 16,  0, 0, GL_RGB_INTEGER,  GL_SHORT,                        GL_INT,                 false, RequireESVersion<3>,                                    NeverSupported,   NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGB16UI,           RGBAFormat(16, 16, 16,  0, 0, GL_RGB_INTEGER,  GL_UNSIGNED_SHORT,               GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    NeverSupported,   NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGB32I,            RGBAFormat(32, 32, 32,  0, 0, GL_RGB_INTEGER,  GL_INT,                          GL_INT,                 false, RequireESVersion<3>,                                    NeverSupported,   NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGB32UI,           RGBAFormat(32, 32, 32,  0, 0, GL_RGB_INTEGER,  GL_UNSIGNED_INT,                 GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    NeverSupported,   NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGBA8I,            RGBAFormat( 8,  8,  8,  8, 0, GL_RGBA_INTEGER, GL_BYTE,                         GL_INT,                 false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGBA8UI,           RGBAFormat( 8,  8,  8,  8, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE,                GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGBA16I,           RGBAFormat(16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_SHORT,                        GL_INT,                 false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGBA16UI,          RGBAFormat(16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT,               GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGBA32I,           RGBAFormat(32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_INT,                          GL_INT,                 false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGBA32UI,          RGBAFormat(32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT,                 GL_UNSIGNED_INT,        false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
 
-    map.insert(InternalFormatInfoPair(GL_BGRA8_EXT,         InternalFormatInfo::RGBAFormat( 8,  8,  8,  8, 0, GL_BGRA_EXT,     GL_UNSIGNED_BYTE,                  GL_UNSIGNED_NORMALIZED, false, RequireExtension<&Extensions::textureFormatBGRA8888>, AlwaysSupported, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_BGRA4_ANGLEX,      InternalFormatInfo::RGBAFormat( 4,  4,  4,  4, 0, GL_BGRA_EXT,     GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_UNSIGNED_NORMALIZED, false, RequireExtension<&Extensions::textureFormatBGRA8888>, AlwaysSupported, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_BGR5_A1_ANGLEX,    InternalFormatInfo::RGBAFormat( 5,  5,  5,  1, 0, GL_BGRA_EXT,     GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_UNSIGNED_NORMALIZED, false, RequireExtension<&Extensions::textureFormatBGRA8888>, AlwaysSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_BGRA8_EXT,         RGBAFormat( 8,  8,  8,  8, 0, GL_BGRA_EXT,     GL_UNSIGNED_BYTE,                  GL_UNSIGNED_NORMALIZED, false, RequireExtension<&Extensions::textureFormatBGRA8888>, AlwaysSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_BGRA4_ANGLEX,      RGBAFormat( 4,  4,  4,  4, 0, GL_BGRA_EXT,     GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_UNSIGNED_NORMALIZED, false, RequireExtension<&Extensions::textureFormatBGRA8888>, AlwaysSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_BGR5_A1_ANGLEX,    RGBAFormat( 5,  5,  5,  1, 0, GL_BGRA_EXT,     GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_UNSIGNED_NORMALIZED, false, RequireExtension<&Extensions::textureFormatBGRA8888>, AlwaysSupported, AlwaysSupported)));
 
     // Floating point renderability and filtering is provided by OES_texture_float and OES_texture_half_float
-    //                               | Internal format        |                                   | D |S | Format             | Type                           | Comp   | SRGB |  Texture supported                                                                     | Renderable     | Filterable                                          |
-    //                               |                        |                                   |   |  |                    |                                | type   |      |                                                                                        |                |                                                     |
-    map.insert(InternalFormatInfoPair(GL_R16F,              InternalFormatInfo::RGBAFormat(16,  0,  0,  0, 0, GL_RED,          GL_HALF_FLOAT,                   GL_FLOAT, false, RequireESVersionOrExtensions<3, &Extensions::textureHalfFloat, &Extensions::textureRG>, AlwaysSupported, RequireExtension<&Extensions::textureHalfFloatLinear>)));
-    map.insert(InternalFormatInfoPair(GL_RG16F,             InternalFormatInfo::RGBAFormat(16, 16,  0,  0, 0, GL_RG,           GL_HALF_FLOAT,                   GL_FLOAT, false, RequireESVersionOrExtensions<3, &Extensions::textureHalfFloat, &Extensions::textureRG>, AlwaysSupported, RequireExtension<&Extensions::textureHalfFloatLinear>)));
-    map.insert(InternalFormatInfoPair(GL_RGB16F,            InternalFormatInfo::RGBAFormat(16, 16, 16,  0, 0, GL_RGB,          GL_HALF_FLOAT,                   GL_FLOAT, false, RequireESVersionOrExtension<3, &Extensions::textureHalfFloat>,                          AlwaysSupported, RequireExtension<&Extensions::textureHalfFloatLinear>)));
-    map.insert(InternalFormatInfoPair(GL_RGBA16F,           InternalFormatInfo::RGBAFormat(16, 16, 16, 16, 0, GL_RGBA,         GL_HALF_FLOAT,                   GL_FLOAT, false, RequireESVersionOrExtension<3, &Extensions::textureHalfFloat>,                          AlwaysSupported, RequireExtension<&Extensions::textureHalfFloatLinear>)));
-    map.insert(InternalFormatInfoPair(GL_R32F,              InternalFormatInfo::RGBAFormat(32,  0,  0,  0, 0, GL_RED,          GL_FLOAT,                        GL_FLOAT, false, RequireESVersionOrExtensions<3, &Extensions::textureFloat, &Extensions::textureRG>,     AlwaysSupported, RequireExtension<&Extensions::textureFloatLinear>    )));
-    map.insert(InternalFormatInfoPair(GL_RG32F,             InternalFormatInfo::RGBAFormat(32, 32,  0,  0, 0, GL_RG,           GL_FLOAT,                        GL_FLOAT, false, RequireESVersionOrExtensions<3, &Extensions::textureFloat, &Extensions::textureRG>,     AlwaysSupported, RequireExtension<&Extensions::textureFloatLinear>    )));
-    map.insert(InternalFormatInfoPair(GL_RGB32F,            InternalFormatInfo::RGBAFormat(32, 32, 32,  0, 0, GL_RGB,          GL_FLOAT,                        GL_FLOAT, false, RequireESVersionOrExtension<3, &Extensions::textureFloat>,                              AlwaysSupported, RequireExtension<&Extensions::textureFloatLinear>    )));
-    map.insert(InternalFormatInfoPair(GL_RGBA32F,           InternalFormatInfo::RGBAFormat(32, 32, 32, 32, 0, GL_RGBA,         GL_FLOAT,                        GL_FLOAT, false, RequireESVersionOrExtension<3, &Extensions::textureFloat>,                              AlwaysSupported, RequireExtension<&Extensions::textureFloatLinear>    )));
+    //                               | Internal format     |          | D |S | Format             | Type                           | Comp   | SRGB |  Texture supported                                                                     | Renderable     | Filterable                                          |
+    //                               |                     |          |   |  |                    |                                | type   |      |                                                                                        |                |                                                     |
+    map.insert(InternalFormatInfoPair(GL_R16F,              RGBAFormat(16,  0,  0,  0, 0, GL_RED,          GL_HALF_FLOAT,                   GL_FLOAT, false, RequireESVersionOrExtensions<3, &Extensions::textureHalfFloat, &Extensions::textureRG>, AlwaysSupported, RequireExtension<&Extensions::textureHalfFloatLinear>)));
+    map.insert(InternalFormatInfoPair(GL_RG16F,             RGBAFormat(16, 16,  0,  0, 0, GL_RG,           GL_HALF_FLOAT,                   GL_FLOAT, false, RequireESVersionOrExtensions<3, &Extensions::textureHalfFloat, &Extensions::textureRG>, AlwaysSupported, RequireExtension<&Extensions::textureHalfFloatLinear>)));
+    map.insert(InternalFormatInfoPair(GL_RGB16F,            RGBAFormat(16, 16, 16,  0, 0, GL_RGB,          GL_HALF_FLOAT,                   GL_FLOAT, false, RequireESVersionOrExtension<3, &Extensions::textureHalfFloat>,                          AlwaysSupported, RequireExtension<&Extensions::textureHalfFloatLinear>)));
+    map.insert(InternalFormatInfoPair(GL_RGBA16F,           RGBAFormat(16, 16, 16, 16, 0, GL_RGBA,         GL_HALF_FLOAT,                   GL_FLOAT, false, RequireESVersionOrExtension<3, &Extensions::textureHalfFloat>,                          AlwaysSupported, RequireExtension<&Extensions::textureHalfFloatLinear>)));
+    map.insert(InternalFormatInfoPair(GL_R32F,              RGBAFormat(32,  0,  0,  0, 0, GL_RED,          GL_FLOAT,                        GL_FLOAT, false, RequireESVersionOrExtensions<3, &Extensions::textureFloat, &Extensions::textureRG>,     AlwaysSupported, RequireExtension<&Extensions::textureFloatLinear>    )));
+    map.insert(InternalFormatInfoPair(GL_RG32F,             RGBAFormat(32, 32,  0,  0, 0, GL_RG,           GL_FLOAT,                        GL_FLOAT, false, RequireESVersionOrExtensions<3, &Extensions::textureFloat, &Extensions::textureRG>,     AlwaysSupported, RequireExtension<&Extensions::textureFloatLinear>    )));
+    map.insert(InternalFormatInfoPair(GL_RGB32F,            RGBAFormat(32, 32, 32,  0, 0, GL_RGB,          GL_FLOAT,                        GL_FLOAT, false, RequireESVersionOrExtension<3, &Extensions::textureFloat>,                              AlwaysSupported, RequireExtension<&Extensions::textureFloatLinear>    )));
+    map.insert(InternalFormatInfoPair(GL_RGBA32F,           RGBAFormat(32, 32, 32, 32, 0, GL_RGBA,         GL_FLOAT,                        GL_FLOAT, false, RequireESVersionOrExtension<3, &Extensions::textureFloat>,                              AlwaysSupported, RequireExtension<&Extensions::textureFloatLinear>    )));
 
     // Depth stencil formats
-    //                               | Internal format         |                                      | D |S | X | Format            | Type                             | Component type        | Supported     |
-    map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT16,     InternalFormatInfo::DepthStencilFormat(16, 0,  0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,                 GL_UNSIGNED_NORMALIZED, RequireESVersion<2>,                                                    AlwaysSupported, RequireESVersionOrExtension<3, &Extensions::depthTextures>)));
-    map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT24,     InternalFormatInfo::DepthStencilFormat(24, 0,  0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,                   GL_UNSIGNED_NORMALIZED, RequireESVersion<3>,                                                    AlwaysSupported, RequireESVersionOrExtension<3, &Extensions::depthTextures>)));
-    map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32F,    InternalFormatInfo::DepthStencilFormat(32, 0,  0, GL_DEPTH_COMPONENT, GL_FLOAT,                          GL_FLOAT,               RequireESVersion<3>,                                                    AlwaysSupported, RequireESVersionOrExtension<3, &Extensions::depthTextures>)));
-    map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32_OES, InternalFormatInfo::DepthStencilFormat(32, 0,  0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,                   GL_UNSIGNED_NORMALIZED, RequireExtension<&Extensions::depthTextures>,                           AlwaysSupported, AlwaysSupported                                           )));
-    map.insert(InternalFormatInfoPair(GL_DEPTH24_STENCIL8,      InternalFormatInfo::DepthStencilFormat(24, 8,  0, GL_DEPTH_STENCIL,   GL_UNSIGNED_INT_24_8,              GL_UNSIGNED_NORMALIZED, RequireESVersionOrExtension<2, &Extensions::depthTextures>,             AlwaysSupported, AlwaysSupported                                           )));
-    map.insert(InternalFormatInfoPair(GL_DEPTH32F_STENCIL8,     InternalFormatInfo::DepthStencilFormat(32, 8, 24, GL_DEPTH_STENCIL,   GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_FLOAT,               RequireESVersion<3>,                                                    AlwaysSupported, AlwaysSupported                                           )));
-    map.insert(InternalFormatInfoPair(GL_STENCIL_INDEX8,        InternalFormatInfo::DepthStencilFormat( 0, 8,  0, GL_DEPTH_STENCIL,   GL_UNSIGNED_BYTE,                  GL_UNSIGNED_INT,        RequireESVersion<2>,                                                    AlwaysSupported, NeverSupported                                            )));
+    //                               | Internal format         |                  | D |S | X | Format            | Type                             | Component type        | Supported     |
+    map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT16,     DepthStencilFormat(16, 0,  0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,                 GL_UNSIGNED_NORMALIZED, RequireESVersion<2>,                                                    AlwaysSupported, RequireESVersionOrExtension<3, &Extensions::depthTextures>)));
+    map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT24,     DepthStencilFormat(24, 0,  0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,                   GL_UNSIGNED_NORMALIZED, RequireESVersion<3>,                                                    AlwaysSupported, RequireESVersionOrExtension<3, &Extensions::depthTextures>)));
+    map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32F,    DepthStencilFormat(32, 0,  0, GL_DEPTH_COMPONENT, GL_FLOAT,                          GL_FLOAT,               RequireESVersion<3>,                                                    AlwaysSupported, RequireESVersionOrExtension<3, &Extensions::depthTextures>)));
+    map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32_OES, DepthStencilFormat(32, 0,  0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,                   GL_UNSIGNED_NORMALIZED, RequireExtension<&Extensions::depthTextures>,                           AlwaysSupported, AlwaysSupported                                           )));
+    map.insert(InternalFormatInfoPair(GL_DEPTH24_STENCIL8,      DepthStencilFormat(24, 8,  0, GL_DEPTH_STENCIL,   GL_UNSIGNED_INT_24_8,              GL_UNSIGNED_NORMALIZED, RequireESVersionOrExtension<2, &Extensions::depthTextures>,             AlwaysSupported, AlwaysSupported                                           )));
+    map.insert(InternalFormatInfoPair(GL_DEPTH32F_STENCIL8,     DepthStencilFormat(32, 8, 24, GL_DEPTH_STENCIL,   GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_FLOAT,               RequireESVersion<3>,                                                    AlwaysSupported, AlwaysSupported                                           )));
+    map.insert(InternalFormatInfoPair(GL_STENCIL_INDEX8,        DepthStencilFormat( 0, 8,  0, GL_DEPTH_STENCIL,   GL_UNSIGNED_BYTE,                  GL_UNSIGNED_INT,        RequireESVersion<2>,                                                    AlwaysSupported, NeverSupported                                            )));
 
     // Luminance alpha formats
-    //                               | Internal format          |                              | L | A | Format            | Type            | Component type        | Supported                                                                    | Renderable    | Filterable    |
-    map.insert(InternalFormatInfoPair(GL_ALPHA8_EXT,             InternalFormatInfo::LUMAFormat( 0,  8, GL_ALPHA,           GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExtension<&Extensions::textureStorage>,                                 NeverSupported, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_LUMINANCE8_EXT,         InternalFormatInfo::LUMAFormat( 8,  0, GL_LUMINANCE,       GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExtension<&Extensions::textureStorage>,                                 NeverSupported, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_ALPHA32F_EXT,           InternalFormatInfo::LUMAFormat( 0, 32, GL_ALPHA,           GL_FLOAT,         GL_FLOAT,               RequireExtensions<&Extensions::textureStorage, &Extensions::textureFloat>,     NeverSupported, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_LUMINANCE32F_EXT,       InternalFormatInfo::LUMAFormat(32,  0, GL_LUMINANCE,       GL_FLOAT,         GL_FLOAT,               RequireExtensions<&Extensions::textureStorage, &Extensions::textureFloat>,     NeverSupported, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_ALPHA16F_EXT,           InternalFormatInfo::LUMAFormat( 0, 16, GL_ALPHA,           GL_HALF_FLOAT,    GL_FLOAT,               RequireExtensions<&Extensions::textureStorage, &Extensions::textureHalfFloat>, NeverSupported, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_LUMINANCE16F_EXT,       InternalFormatInfo::LUMAFormat(16,  0, GL_LUMINANCE,       GL_HALF_FLOAT,    GL_FLOAT,               RequireExtensions<&Extensions::textureStorage, &Extensions::textureHalfFloat>, NeverSupported, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_LUMINANCE8_ALPHA8_EXT,  InternalFormatInfo::LUMAFormat( 8,  8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExtension<&Extensions::textureStorage>,                                 NeverSupported, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA32F_EXT, InternalFormatInfo::LUMAFormat(32, 32, GL_LUMINANCE_ALPHA, GL_FLOAT,         GL_FLOAT,               RequireExtensions<&Extensions::textureStorage, &Extensions::textureFloat>,     NeverSupported, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA16F_EXT, InternalFormatInfo::LUMAFormat(16, 16, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT,    GL_FLOAT,               RequireExtensions<&Extensions::textureStorage, &Extensions::textureHalfFloat>, NeverSupported, AlwaysSupported)));
+    //                               | Internal format          |          | L | A | Format            | Type            | Component type        | Supported                                                                    | Renderable    | Filterable    |
+    map.insert(InternalFormatInfoPair(GL_ALPHA8_EXT,             LUMAFormat( 0,  8, GL_ALPHA,           GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExtension<&Extensions::textureStorage>,                                 NeverSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_LUMINANCE8_EXT,         LUMAFormat( 8,  0, GL_LUMINANCE,       GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExtension<&Extensions::textureStorage>,                                 NeverSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_ALPHA32F_EXT,           LUMAFormat( 0, 32, GL_ALPHA,           GL_FLOAT,         GL_FLOAT,               RequireExtensions<&Extensions::textureStorage, &Extensions::textureFloat>,     NeverSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_LUMINANCE32F_EXT,       LUMAFormat(32,  0, GL_LUMINANCE,       GL_FLOAT,         GL_FLOAT,               RequireExtensions<&Extensions::textureStorage, &Extensions::textureFloat>,     NeverSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_ALPHA16F_EXT,           LUMAFormat( 0, 16, GL_ALPHA,           GL_HALF_FLOAT,    GL_FLOAT,               RequireExtensions<&Extensions::textureStorage, &Extensions::textureHalfFloat>, NeverSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_LUMINANCE16F_EXT,       LUMAFormat(16,  0, GL_LUMINANCE,       GL_HALF_FLOAT,    GL_FLOAT,               RequireExtensions<&Extensions::textureStorage, &Extensions::textureHalfFloat>, NeverSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_LUMINANCE8_ALPHA8_EXT,  LUMAFormat( 8,  8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExtension<&Extensions::textureStorage>,                                 NeverSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA32F_EXT, LUMAFormat(32, 32, GL_LUMINANCE_ALPHA, GL_FLOAT,         GL_FLOAT,               RequireExtensions<&Extensions::textureStorage, &Extensions::textureFloat>,     NeverSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA16F_EXT, LUMAFormat(16, 16, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT,    GL_FLOAT,               RequireExtensions<&Extensions::textureStorage, &Extensions::textureHalfFloat>, NeverSupported, AlwaysSupported)));
 
     // Unsized formats
-    //                               | Internal format   |                                 | Format            | Supported                                                      | Renderable     | Filterable     |
-    map.insert(InternalFormatInfoPair(GL_ALPHA,           InternalFormatInfo::UnsizedFormat(GL_ALPHA,           RequireESVersion<2>,                                             NeverSupported,  AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_LUMINANCE,       InternalFormatInfo::UnsizedFormat(GL_LUMINANCE,       RequireESVersion<2>,                                             NeverSupported,  AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA, InternalFormatInfo::UnsizedFormat(GL_LUMINANCE_ALPHA, RequireESVersion<2>,                                             NeverSupported,  AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_RED,             InternalFormatInfo::UnsizedFormat(GL_RED,             RequireESVersionOrExtension<3, &Extensions::textureRG>,          NeverSupported,  AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_RG,              InternalFormatInfo::UnsizedFormat(GL_RG,              RequireESVersionOrExtension<3, &Extensions::textureRG>,          NeverSupported,  AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_RGB,             InternalFormatInfo::UnsizedFormat(GL_RGB,             RequireESVersion<2>,                                             AlwaysSupported, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_RGBA,            InternalFormatInfo::UnsizedFormat(GL_RGBA,            RequireESVersion<2>,                                             AlwaysSupported, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_RED_INTEGER,     InternalFormatInfo::UnsizedFormat(GL_RED_INTEGER,     RequireESVersion<3>,                                             NeverSupported,  NeverSupported )));
-    map.insert(InternalFormatInfoPair(GL_RG_INTEGER,      InternalFormatInfo::UnsizedFormat(GL_RG_INTEGER,      RequireESVersion<3>,                                             NeverSupported,  NeverSupported )));
-    map.insert(InternalFormatInfoPair(GL_RGB_INTEGER,     InternalFormatInfo::UnsizedFormat(GL_RGB_INTEGER,     RequireESVersion<3>,                                             NeverSupported,  NeverSupported )));
-    map.insert(InternalFormatInfoPair(GL_RGBA_INTEGER,    InternalFormatInfo::UnsizedFormat(GL_RGBA_INTEGER,    RequireESVersion<3>,                                             NeverSupported,  NeverSupported )));
-    map.insert(InternalFormatInfoPair(GL_BGRA_EXT,        InternalFormatInfo::UnsizedFormat(GL_BGRA_EXT,        RequireExtension<&Extensions::textureFormatBGRA8888>,            AlwaysSupported, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT, InternalFormatInfo::UnsizedFormat(GL_DEPTH_COMPONENT, RequireESVersion<2>,                                             AlwaysSupported, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_DEPTH_STENCIL,   InternalFormatInfo::UnsizedFormat(GL_DEPTH_STENCIL,   RequireESVersionOrExtension<3, &Extensions::packedDepthStencil>, AlwaysSupported, AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_SRGB_EXT,        InternalFormatInfo::UnsizedFormat(GL_RGB,             RequireESVersionOrExtension<3, &Extensions::sRGB>,               NeverSupported,  AlwaysSupported)));
-    map.insert(InternalFormatInfoPair(GL_SRGB_ALPHA_EXT,  InternalFormatInfo::UnsizedFormat(GL_RGBA,            RequireESVersionOrExtension<3, &Extensions::sRGB>,               AlwaysSupported, AlwaysSupported)));
+    //                               | Internal format   |             | Format            | Supported                                                      | Renderable     | Filterable     |
+    map.insert(InternalFormatInfoPair(GL_ALPHA,           UnsizedFormat(GL_ALPHA,           RequireESVersion<2>,                                             NeverSupported,  AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_LUMINANCE,       UnsizedFormat(GL_LUMINANCE,       RequireESVersion<2>,                                             NeverSupported,  AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA, UnsizedFormat(GL_LUMINANCE_ALPHA, RequireESVersion<2>,                                             NeverSupported,  AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_RED,             UnsizedFormat(GL_RED,             RequireESVersionOrExtension<3, &Extensions::textureRG>,          NeverSupported,  AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_RG,              UnsizedFormat(GL_RG,              RequireESVersionOrExtension<3, &Extensions::textureRG>,          NeverSupported,  AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGB,             UnsizedFormat(GL_RGB,             RequireESVersion<2>,                                             AlwaysSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_RGBA,            UnsizedFormat(GL_RGBA,            RequireESVersion<2>,                                             AlwaysSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_RED_INTEGER,     UnsizedFormat(GL_RED_INTEGER,     RequireESVersion<3>,                                             NeverSupported,  NeverSupported )));
+    map.insert(InternalFormatInfoPair(GL_RG_INTEGER,      UnsizedFormat(GL_RG_INTEGER,      RequireESVersion<3>,                                             NeverSupported,  NeverSupported )));
+    map.insert(InternalFormatInfoPair(GL_RGB_INTEGER,     UnsizedFormat(GL_RGB_INTEGER,     RequireESVersion<3>,                                             NeverSupported,  NeverSupported )));
+    map.insert(InternalFormatInfoPair(GL_RGBA_INTEGER,    UnsizedFormat(GL_RGBA_INTEGER,    RequireESVersion<3>,                                             NeverSupported,  NeverSupported )));
+    map.insert(InternalFormatInfoPair(GL_BGRA_EXT,        UnsizedFormat(GL_BGRA_EXT,        RequireExtension<&Extensions::textureFormatBGRA8888>,            AlwaysSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT, UnsizedFormat(GL_DEPTH_COMPONENT, RequireESVersion<2>,                                             AlwaysSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_DEPTH_STENCIL,   UnsizedFormat(GL_DEPTH_STENCIL,   RequireESVersionOrExtension<3, &Extensions::packedDepthStencil>, AlwaysSupported, AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_SRGB_EXT,        UnsizedFormat(GL_RGB,             RequireESVersionOrExtension<3, &Extensions::sRGB>,               NeverSupported,  AlwaysSupported)));
+    map.insert(InternalFormatInfoPair(GL_SRGB_ALPHA_EXT,  UnsizedFormat(GL_RGBA,            RequireESVersionOrExtension<3, &Extensions::sRGB>,               AlwaysSupported, AlwaysSupported)));
 
     // Compressed formats, From ES 3.0.1 spec, table 3.16
-    //                               | Internal format                             |                                    |W |H | BS |CC| Format                                      | Type            | SRGB | Supported          | Renderable           | Filterable         |
-    map.insert(InternalFormatInfoPair(GL_COMPRESSED_R11_EAC,                        InternalFormatInfo::CompressedFormat(4, 4,  64, 1, GL_COMPRESSED_R11_EAC,                        GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
-    map.insert(InternalFormatInfoPair(GL_COMPRESSED_SIGNED_R11_EAC,                 InternalFormatInfo::CompressedFormat(4, 4,  64, 1, GL_COMPRESSED_SIGNED_R11_EAC,                 GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
-    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RG11_EAC,                       InternalFormatInfo::CompressedFormat(4, 4, 128, 2, GL_COMPRESSED_RG11_EAC,                       GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
-    map.insert(InternalFormatInfoPair(GL_COMPRESSED_SIGNED_RG11_EAC,                InternalFormatInfo::CompressedFormat(4, 4, 128, 2, GL_COMPRESSED_SIGNED_RG11_EAC,                GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
-    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB8_ETC2,                      InternalFormatInfo::CompressedFormat(4, 4,  64, 3, GL_COMPRESSED_RGB8_ETC2,                      GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
-    map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ETC2,                     InternalFormatInfo::CompressedFormat(4, 4,  64, 3, GL_COMPRESSED_SRGB8_ETC2,                     GL_UNSIGNED_BYTE, true,  UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
-    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,  InternalFormatInfo::CompressedFormat(4, 4,  64, 3, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,  GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
-    map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, InternalFormatInfo::CompressedFormat(4, 4,  64, 3, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE, true,  UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
-    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA8_ETC2_EAC,                 InternalFormatInfo::CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA8_ETC2_EAC,                 GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
-    map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,          InternalFormatInfo::CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,          GL_UNSIGNED_BYTE, true,  UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
+    //                               | Internal format                             |                |W |H | BS |CC| Format                                      | Type            | SRGB | Supported          | Renderable           | Filterable         |
+    map.insert(InternalFormatInfoPair(GL_COMPRESSED_R11_EAC,                        CompressedFormat(4, 4,  64, 1, GL_COMPRESSED_R11_EAC,                        GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
+    map.insert(InternalFormatInfoPair(GL_COMPRESSED_SIGNED_R11_EAC,                 CompressedFormat(4, 4,  64, 1, GL_COMPRESSED_SIGNED_R11_EAC,                 GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
+    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RG11_EAC,                       CompressedFormat(4, 4, 128, 2, GL_COMPRESSED_RG11_EAC,                       GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
+    map.insert(InternalFormatInfoPair(GL_COMPRESSED_SIGNED_RG11_EAC,                CompressedFormat(4, 4, 128, 2, GL_COMPRESSED_SIGNED_RG11_EAC,                GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
+    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB8_ETC2,                      CompressedFormat(4, 4,  64, 3, GL_COMPRESSED_RGB8_ETC2,                      GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
+    map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ETC2,                     CompressedFormat(4, 4,  64, 3, GL_COMPRESSED_SRGB8_ETC2,                     GL_UNSIGNED_BYTE, true,  UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
+    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,  CompressedFormat(4, 4,  64, 3, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,  GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
+    map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, CompressedFormat(4, 4,  64, 3, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE, true,  UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
+    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA8_ETC2_EAC,                 CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA8_ETC2_EAC,                 GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
+    map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,          CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,          GL_UNSIGNED_BYTE, true,  UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
 
     // From GL_EXT_texture_compression_dxt1
-    //                               | Internal format                   |                                    |W |H | BS |CC| Format                            | Type            | SRGB | Supported                                           | Renderable           | Filterable         |
-    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB_S3TC_DXT1_EXT,    InternalFormatInfo::CompressedFormat(4, 4,  64, 3, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,    GL_UNSIGNED_BYTE, false, RequireExtension<&Extensions::textureCompressionDXT1>, NeverSupported,       AlwaysSupported     )));
-    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,   InternalFormatInfo::CompressedFormat(4, 4,  64, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,   GL_UNSIGNED_BYTE, false, RequireExtension<&Extensions::textureCompressionDXT1>, NeverSupported,       AlwaysSupported     )));
+    //                               | Internal format                   |                |W |H | BS |CC| Format                            | Type            | SRGB | Supported                                           | Renderable           | Filterable         |
+    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB_S3TC_DXT1_EXT,    CompressedFormat(4, 4,  64, 3, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,    GL_UNSIGNED_BYTE, false, RequireExtension<&Extensions::textureCompressionDXT1>, NeverSupported,       AlwaysSupported     )));
+    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,   CompressedFormat(4, 4,  64, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,   GL_UNSIGNED_BYTE, false, RequireExtension<&Extensions::textureCompressionDXT1>, NeverSupported,       AlwaysSupported     )));
 
     // From GL_ANGLE_texture_compression_dxt3
-    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, InternalFormatInfo::CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, false, RequireExtension<&Extensions::textureCompressionDXT5>, NeverSupported,       AlwaysSupported     )));
+    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, false, RequireExtension<&Extensions::textureCompressionDXT5>, NeverSupported,       AlwaysSupported     )));
 
     // From GL_ANGLE_texture_compression_dxt5
-    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, InternalFormatInfo::CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, false, RequireExtension<&Extensions::textureCompressionDXT5>, NeverSupported,       AlwaysSupported     )));
+    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, false, RequireExtension<&Extensions::textureCompressionDXT5>, NeverSupported,       AlwaysSupported     )));
 
     return map;
 }
@@ -746,24 +514,6 @@
     return formatMap;
 }
 
-static bool GetInternalFormatInfo(GLenum internalFormat, InternalFormatInfo *outFormatInfo)
-{
-    const InternalFormatInfoMap &map = GetInternalFormatMap();
-    InternalFormatInfoMap::const_iterator iter = map.find(internalFormat);
-    if (iter != map.end())
-    {
-        if (outFormatInfo)
-        {
-            *outFormatInfo = iter->second;
-        }
-        return true;
-    }
-    else
-    {
-        return false;
-    }
-}
-
 static FormatSet BuildAllSizedInternalFormatSet()
 {
     FormatSet result;
@@ -771,7 +521,7 @@
     const InternalFormatInfoMap &formats = GetInternalFormatMap();
     for (InternalFormatInfoMap::const_iterator i = formats.begin(); i != formats.end(); i++)
     {
-        if (i->second.mPixelBits > 0)
+        if (i->second.pixelBytes > 0)
         {
             result.insert(i->first);
         }
@@ -780,756 +530,88 @@
     return result;
 }
 
-typedef std::set<GLenum> TypeSet;
-
-struct EffectiveInternalFormatInfo
+const FormatType &GetFormatTypeInfo(GLenum format, GLenum type)
 {
-    GLenum mEffectiveFormat;
-    GLenum mDestFormat;
-    GLuint mMinRedBits;
-    GLuint mMaxRedBits;
-    GLuint mMinGreenBits;
-    GLuint mMaxGreenBits;
-    GLuint mMinBlueBits;
-    GLuint mMaxBlueBits;
-    GLuint mMinAlphaBits;
-    GLuint mMaxAlphaBits;
-
-    EffectiveInternalFormatInfo(GLenum effectiveFormat, GLenum destFormat, GLuint minRedBits, GLuint maxRedBits,
-                                GLuint minGreenBits, GLuint maxGreenBits, GLuint minBlueBits, GLuint maxBlueBits,
-                                GLuint minAlphaBits, GLuint maxAlphaBits)
-        : mEffectiveFormat(effectiveFormat), mDestFormat(destFormat), mMinRedBits(minRedBits),
-          mMaxRedBits(maxRedBits), mMinGreenBits(minGreenBits), mMaxGreenBits(maxGreenBits),
-          mMinBlueBits(minBlueBits), mMaxBlueBits(maxBlueBits), mMinAlphaBits(minAlphaBits),
-          mMaxAlphaBits(maxAlphaBits) {};
-};
-
-typedef std::vector<EffectiveInternalFormatInfo> EffectiveInternalFormatList;
-
-static EffectiveInternalFormatList BuildSizedEffectiveInternalFormatList()
-{
-    EffectiveInternalFormatList list;
-
-    // OpenGL ES 3.0.3 Specification, Table 3.17, pg 141: Effective internal format coresponding to destination internal format and
-    //                                                    linear source buffer component sizes.
-    //                                                                            | Source channel min/max sizes |
-    //                                         Effective Internal Format |  N/A   |  R   |  G   |  B   |  A      |
-    list.push_back(EffectiveInternalFormatInfo(GL_ALPHA8_EXT,              GL_NONE, 0,  0, 0,  0, 0,  0, 1, 8));
-    list.push_back(EffectiveInternalFormatInfo(GL_R8,                      GL_NONE, 1,  8, 0,  0, 0,  0, 0, 0));
-    list.push_back(EffectiveInternalFormatInfo(GL_RG8,                     GL_NONE, 1,  8, 1,  8, 0,  0, 0, 0));
-    list.push_back(EffectiveInternalFormatInfo(GL_RGB565,                  GL_NONE, 1,  5, 1,  6, 1,  5, 0, 0));
-    list.push_back(EffectiveInternalFormatInfo(GL_RGB8,                    GL_NONE, 6,  8, 7,  8, 6,  8, 0, 0));
-    list.push_back(EffectiveInternalFormatInfo(GL_RGBA4,                   GL_NONE, 1,  4, 1,  4, 1,  4, 1, 4));
-    list.push_back(EffectiveInternalFormatInfo(GL_RGB5_A1,                 GL_NONE, 5,  5, 5,  5, 5,  5, 1, 1));
-    list.push_back(EffectiveInternalFormatInfo(GL_RGBA8,                   GL_NONE, 5,  8, 5,  8, 5,  8, 2, 8));
-    list.push_back(EffectiveInternalFormatInfo(GL_RGB10_A2,                GL_NONE, 9, 10, 9, 10, 9, 10, 2, 2));
-
-    return list;
-}
-
-
-static EffectiveInternalFormatList BuildUnsizedEffectiveInternalFormatList()
-{
-    EffectiveInternalFormatList list;
-
-    // OpenGL ES 3.0.3 Specification, Table 3.17, pg 141: Effective internal format coresponding to destination internal format and
-    //                                                    linear source buffer component sizes.
-    //                                                                                        |          Source channel min/max sizes            |
-    //                                         Effective Internal Format |    Dest Format     |     R     |      G     |      B     |      A     |
-    list.push_back(EffectiveInternalFormatInfo(GL_ALPHA8_EXT,              GL_ALPHA,           0, UINT_MAX, 0, UINT_MAX, 0, UINT_MAX, 1,        8));
-    list.push_back(EffectiveInternalFormatInfo(GL_LUMINANCE8_EXT,          GL_LUMINANCE,       1,        8, 0, UINT_MAX, 0, UINT_MAX, 0, UINT_MAX));
-    list.push_back(EffectiveInternalFormatInfo(GL_LUMINANCE8_ALPHA8_EXT,   GL_LUMINANCE_ALPHA, 1,        8, 0, UINT_MAX, 0, UINT_MAX, 1,        8));
-    list.push_back(EffectiveInternalFormatInfo(GL_RGB565,                  GL_RGB,             1,        5, 1,        6, 1,        5, 0, UINT_MAX));
-    list.push_back(EffectiveInternalFormatInfo(GL_RGB8,                    GL_RGB,             6,        8, 7,        8, 6,        8, 0, UINT_MAX));
-    list.push_back(EffectiveInternalFormatInfo(GL_RGBA4,                   GL_RGBA,            1,        4, 1,        4, 1,        4, 1,        4));
-    list.push_back(EffectiveInternalFormatInfo(GL_RGB5_A1,                 GL_RGBA,            5,        5, 5,        5, 5,        5, 1,        1));
-    list.push_back(EffectiveInternalFormatInfo(GL_RGBA8,                   GL_RGBA,            5,        8, 5,        8, 5,        8, 5,        8));
-
-    return list;
-}
-
-static bool GetEffectiveInternalFormat(const InternalFormatInfo &srcFormat, const InternalFormatInfo &destFormat,
-                                       GLenum *outEffectiveFormat)
-{
-    const EffectiveInternalFormatList *list = NULL;
-    GLenum targetFormat = GL_NONE;
-
-    if (gl::IsSizedInternalFormat(destFormat.mFormat))
+    static const FormatMap formatMap = BuildFormatMap();
+    FormatMap::const_iterator iter = formatMap.find(FormatTypePair(format, type));
+    if (iter != formatMap.end())
     {
-        static const EffectiveInternalFormatList sizedList = BuildSizedEffectiveInternalFormatList();
-        list = &sizedList;
+        return iter->second;
     }
     else
     {
-        static const EffectiveInternalFormatList unsizedList = BuildUnsizedEffectiveInternalFormatList();
-        list = &unsizedList;
-        targetFormat = destFormat.mFormat;
+        static const FormatType defaultInfo;
+        return defaultInfo;
     }
-
-    for (size_t curFormat = 0; curFormat < list->size(); ++curFormat)
-    {
-        const EffectiveInternalFormatInfo& formatInfo = list->at(curFormat);
-        if ((formatInfo.mDestFormat == targetFormat) &&
-            (formatInfo.mMinRedBits   <= srcFormat.mRedBits   && formatInfo.mMaxRedBits   >= srcFormat.mRedBits)   &&
-            (formatInfo.mMinGreenBits <= srcFormat.mGreenBits && formatInfo.mMaxGreenBits >= srcFormat.mGreenBits) &&
-            (formatInfo.mMinBlueBits  <= srcFormat.mBlueBits  && formatInfo.mMaxBlueBits  >= srcFormat.mBlueBits)  &&
-            (formatInfo.mMinAlphaBits <= srcFormat.mAlphaBits && formatInfo.mMaxAlphaBits >= srcFormat.mAlphaBits))
-        {
-            *outEffectiveFormat = formatInfo.mEffectiveFormat;
-            return true;
-        }
-    }
-
-    return false;
 }
 
-struct CopyConversion
+const Type &GetTypeInfo(GLenum type)
 {
-    GLenum mTextureFormat;
-    GLenum mFramebufferFormat;
-
-    CopyConversion(GLenum textureFormat, GLenum framebufferFormat)
-        : mTextureFormat(textureFormat), mFramebufferFormat(framebufferFormat) { }
-
-    bool operator<(const CopyConversion& other) const
+    static const TypeInfoMap infoMap = BuildTypeInfoMap();
+    TypeInfoMap::const_iterator iter = infoMap.find(type);
+    if (iter != infoMap.end())
     {
-        return memcmp(this, &other, sizeof(CopyConversion)) < 0;
-    }
-};
-
-typedef std::set<CopyConversion> CopyConversionSet;
-
-static CopyConversionSet BuildValidES3CopyTexImageCombinations()
-{
-    CopyConversionSet set;
-
-    // From ES 3.0.1 spec, table 3.15
-    set.insert(CopyConversion(GL_ALPHA,           GL_RGBA));
-    set.insert(CopyConversion(GL_LUMINANCE,       GL_RED));
-    set.insert(CopyConversion(GL_LUMINANCE,       GL_RG));
-    set.insert(CopyConversion(GL_LUMINANCE,       GL_RGB));
-    set.insert(CopyConversion(GL_LUMINANCE,       GL_RGBA));
-    set.insert(CopyConversion(GL_LUMINANCE_ALPHA, GL_RGBA));
-    set.insert(CopyConversion(GL_RED,             GL_RED));
-    set.insert(CopyConversion(GL_RED,             GL_RG));
-    set.insert(CopyConversion(GL_RED,             GL_RGB));
-    set.insert(CopyConversion(GL_RED,             GL_RGBA));
-    set.insert(CopyConversion(GL_RG,              GL_RG));
-    set.insert(CopyConversion(GL_RG,              GL_RGB));
-    set.insert(CopyConversion(GL_RG,              GL_RGBA));
-    set.insert(CopyConversion(GL_RGB,             GL_RGB));
-    set.insert(CopyConversion(GL_RGB,             GL_RGBA));
-    set.insert(CopyConversion(GL_RGBA,            GL_RGBA));
-
-    // Necessary for ANGLE back-buffers
-    set.insert(CopyConversion(GL_ALPHA,           GL_BGRA_EXT));
-    set.insert(CopyConversion(GL_LUMINANCE,       GL_BGRA_EXT));
-    set.insert(CopyConversion(GL_LUMINANCE_ALPHA, GL_BGRA_EXT));
-    set.insert(CopyConversion(GL_RED,             GL_BGRA_EXT));
-    set.insert(CopyConversion(GL_RG,              GL_BGRA_EXT));
-    set.insert(CopyConversion(GL_RGB,             GL_BGRA_EXT));
-    set.insert(CopyConversion(GL_RGBA,            GL_BGRA_EXT));
-
-    set.insert(CopyConversion(GL_RED_INTEGER,     GL_RED_INTEGER));
-    set.insert(CopyConversion(GL_RED_INTEGER,     GL_RG_INTEGER));
-    set.insert(CopyConversion(GL_RED_INTEGER,     GL_RGB_INTEGER));
-    set.insert(CopyConversion(GL_RED_INTEGER,     GL_RGBA_INTEGER));
-    set.insert(CopyConversion(GL_RG_INTEGER,      GL_RG_INTEGER));
-    set.insert(CopyConversion(GL_RG_INTEGER,      GL_RGB_INTEGER));
-    set.insert(CopyConversion(GL_RG_INTEGER,      GL_RGBA_INTEGER));
-    set.insert(CopyConversion(GL_RGB_INTEGER,     GL_RGB_INTEGER));
-    set.insert(CopyConversion(GL_RGB_INTEGER,     GL_RGBA_INTEGER));
-    set.insert(CopyConversion(GL_RGBA_INTEGER,    GL_RGBA_INTEGER));
-
-    return set;
-}
-
-bool IsValidInternalFormat(GLenum internalFormat, const Extensions &extensions, GLuint clientVersion)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
-    {
-        ASSERT(internalFormatInfo.mTextureSupportFunction != NULL);
-        return internalFormatInfo.mTextureSupportFunction(clientVersion, extensions);
+        return iter->second;
     }
     else
     {
-        return false;
+        static const Type defaultInfo;
+        return defaultInfo;
     }
 }
 
-bool IsValidFormat(GLenum format, const Extensions &extensions, GLuint clientVersion)
+const InternalFormat &GetInternalFormatInfo(GLenum internalFormat)
 {
-    const InternalFormatInfoMap &internalFormats = GetInternalFormatMap();
-    for (InternalFormatInfoMap::const_iterator i = internalFormats.begin(); i != internalFormats.end(); i++)
+    const InternalFormatInfoMap &formatMap = GetInternalFormatMap();
+    InternalFormatInfoMap::const_iterator iter = formatMap.find(internalFormat);
+    if (iter != formatMap.end())
     {
-        if (i->second.mFormat == format && i->second.mTextureSupportFunction(clientVersion, extensions))
-        {
-            return true;
-        }
-    }
-
-    return false;
-}
-
-bool IsValidType(GLenum type, const Extensions &extensions, GLuint clientVersion)
-{
-    const InternalFormatInfoMap &internalFormats = GetInternalFormatMap();
-    for (InternalFormatInfoMap::const_iterator i = internalFormats.begin(); i != internalFormats.end(); i++)
-    {
-        if (i->second.mType == type && i->second.mTextureSupportFunction(clientVersion, extensions))
-        {
-            return true;
-        }
-    }
-
-    return false;
-}
-
-bool IsValidFormatCombination(GLenum internalFormat, GLenum format, GLenum type, const Extensions &extensions, GLuint clientVersion)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
-    {
-        if (!internalFormatInfo.mTextureSupportFunction(clientVersion, extensions))
-        {
-            return false;
-        }
+        return iter->second;
     }
     else
     {
-        UNREACHABLE();
-        return false;
-    }
-
-    if (clientVersion == 2)
-    {
-        static const FormatMap &formats = GetFormatMap();
-        FormatMap::const_iterator iter = formats.find(FormatTypePair(format, type));
-        return (iter != formats.end()) && ((internalFormat == (GLint)type) || (internalFormat == iter->second.mInternalFormat));
-    }
-    else if (clientVersion == 3)
-    {
-        static const ES3FormatSet &formats = GetES3FormatSet();
-        return formats.find(FormatInfo(internalFormat, format, type)) != formats.end();
-    }
-    else
-    {
-        UNREACHABLE();
-        return false;
+        static const InternalFormat defaultInternalFormat;
+        return defaultInternalFormat;
     }
 }
 
-bool IsValidCopyTexImageCombination(GLenum textureInternalFormat, GLenum frameBufferInternalFormat, GLuint readBufferHandle, GLuint clientVersion)
-{
-    InternalFormatInfo textureInternalFormatInfo;
-    InternalFormatInfo framebufferInternalFormatInfo;
-    if (GetInternalFormatInfo(textureInternalFormat, &textureInternalFormatInfo) &&
-        GetInternalFormatInfo(frameBufferInternalFormat, &framebufferInternalFormatInfo))
-    {
-        if (clientVersion == 2)
-        {
-            UNIMPLEMENTED();
-            return false;
-        }
-        else if (clientVersion == 3)
-        {
-            static const CopyConversionSet conversionSet = BuildValidES3CopyTexImageCombinations();
-            const CopyConversion conversion = CopyConversion(textureInternalFormatInfo.mFormat,
-                                                             framebufferInternalFormatInfo.mFormat);
-            if (conversionSet.find(conversion) != conversionSet.end())
-            {
-                // Section 3.8.5 of the GLES 3.0.3 spec states that source and destination formats
-                // must both be signed, unsigned, or fixed point and both source and destinations
-                // must be either both SRGB or both not SRGB. EXT_color_buffer_float adds allowed
-                // conversion between fixed and floating point.
-
-                if ((textureInternalFormatInfo.mColorEncoding == GL_SRGB) != (framebufferInternalFormatInfo.mColorEncoding == GL_SRGB))
-                {
-                    return false;
-                }
-
-                if (((textureInternalFormatInfo.mComponentType == GL_INT) != (framebufferInternalFormatInfo.mComponentType == GL_INT)) ||
-                    ((textureInternalFormatInfo.mComponentType == GL_UNSIGNED_INT) != (framebufferInternalFormatInfo.mComponentType == GL_UNSIGNED_INT)))
-                {
-                    return false;
-                }
-
-                if (gl::IsFloatOrFixedComponentType(textureInternalFormatInfo.mComponentType) &&
-                    !gl::IsFloatOrFixedComponentType(framebufferInternalFormatInfo.mComponentType))
-                {
-                    return false;
-                }
-
-                // GLES specification 3.0.3, sec 3.8.5, pg 139-140:
-                // The effective internal format of the source buffer is determined with the following rules applied in order:
-                //    * If the source buffer is a texture or renderbuffer that was created with a sized internal format then the
-                //      effective internal format is the source buffer's sized internal format.
-                //    * If the source buffer is a texture that was created with an unsized base internal format, then the
-                //      effective internal format is the source image array's effective internal format, as specified by table
-                //      3.12, which is determined from the <format> and <type> that were used when the source image array was
-                //      specified by TexImage*.
-                //    * Otherwise the effective internal format is determined by the row in table 3.17 or 3.18 where
-                //      Destination Internal Format matches internalformat and where the [source channel sizes] are consistent
-                //      with the values of the source buffer's [channel sizes]. Table 3.17 is used if the
-                //      FRAMEBUFFER_ATTACHMENT_ENCODING is LINEAR and table 3.18 is used if the FRAMEBUFFER_ATTACHMENT_ENCODING
-                //      is SRGB.
-                InternalFormatInfo sourceEffectiveFormat;
-                if (readBufferHandle != 0)
-                {
-                    // Not the default framebuffer, therefore the read buffer must be a user-created texture or renderbuffer
-                    if (gl::IsSizedInternalFormat(framebufferInternalFormatInfo.mFormat))
-                    {
-                        sourceEffectiveFormat = framebufferInternalFormatInfo;
-                    }
-                    else
-                    {
-                        // Renderbuffers cannot be created with an unsized internal format, so this must be an unsized-format
-                        // texture. We can use the same table we use when creating textures to get its effective sized format.
-                        GLenum effectiveFormat = gl::GetSizedInternalFormat(framebufferInternalFormatInfo.mFormat,
-                                                                            framebufferInternalFormatInfo.mType);
-                        gl::GetInternalFormatInfo(effectiveFormat, &sourceEffectiveFormat);
-                    }
-                }
-                else
-                {
-                    // The effective internal format must be derived from the source framebuffer's channel sizes.
-                    // This is done in GetEffectiveInternalFormat for linear buffers (table 3.17)
-                    if (framebufferInternalFormatInfo.mColorEncoding == GL_LINEAR)
-                    {
-                        GLenum effectiveFormat;
-                        if (GetEffectiveInternalFormat(framebufferInternalFormatInfo, textureInternalFormatInfo, &effectiveFormat))
-                        {
-                            gl::GetInternalFormatInfo(effectiveFormat, &sourceEffectiveFormat);
-                        }
-                        else
-                        {
-                            return false;
-                        }
-                    }
-                    else if (framebufferInternalFormatInfo.mColorEncoding == GL_SRGB)
-                    {
-                        // SRGB buffers can only be copied to sized format destinations according to table 3.18
-                        if (gl::IsSizedInternalFormat(textureInternalFormat) &&
-                            (framebufferInternalFormatInfo.mRedBits   >= 1 && framebufferInternalFormatInfo.mRedBits   <= 8) &&
-                            (framebufferInternalFormatInfo.mGreenBits >= 1 && framebufferInternalFormatInfo.mGreenBits <= 8) &&
-                            (framebufferInternalFormatInfo.mBlueBits  >= 1 && framebufferInternalFormatInfo.mBlueBits  <= 8) &&
-                            (framebufferInternalFormatInfo.mAlphaBits >= 1 && framebufferInternalFormatInfo.mAlphaBits <= 8))
-                        {
-                            gl::GetInternalFormatInfo(GL_SRGB8_ALPHA8, &sourceEffectiveFormat);
-                        }
-                        else
-                        {
-                            return false;
-                        }
-                    }
-                    else
-                    {
-                        UNREACHABLE();
-                    }
-                }
-
-                if (gl::IsSizedInternalFormat(textureInternalFormatInfo.mFormat))
-                {
-                    // Section 3.8.5 of the GLES 3.0.3 spec, pg 139, requires that, if the destination format is sized,
-                    // component sizes of the source and destination formats must exactly match
-                    if (textureInternalFormatInfo.mRedBits != sourceEffectiveFormat.mRedBits ||
-                        textureInternalFormatInfo.mGreenBits != sourceEffectiveFormat.mGreenBits ||
-                        textureInternalFormatInfo.mBlueBits != sourceEffectiveFormat.mBlueBits ||
-                        textureInternalFormatInfo.mAlphaBits != sourceEffectiveFormat.mAlphaBits)
-                    {
-                        return false;
-                    }
-                }
-
-
-                return true; // A conversion function exists, and no rule in the specification has precluded conversion
-                             // between these formats.
-            }
-
-            return false;
-        }
-        else
-        {
-            UNREACHABLE();
-            return false;
-        }
-    }
-    else
-    {
-        UNREACHABLE();
-        return false;
-    }
-}
-
-bool IsRenderingSupported(GLenum internalFormat, const Extensions &extensions, GLuint clientVersion)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
-    {
-        ASSERT(internalFormatInfo.mTextureSupportFunction != NULL);
-        ASSERT(internalFormatInfo.mRenderSupportFunction != NULL);
-        return internalFormatInfo.mTextureSupportFunction(clientVersion, extensions) &&
-               internalFormatInfo.mRenderSupportFunction(clientVersion, extensions);
-    }
-    else
-    {
-        return false;
-    }
-}
-
-bool IsFilteringSupported(GLenum internalFormat, const Extensions &extensions, GLuint clientVersion)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
-    {
-        ASSERT(internalFormatInfo.mTextureSupportFunction != NULL);
-        ASSERT(internalFormatInfo.mFilterSupportFunction != NULL);
-        return internalFormatInfo.mTextureSupportFunction(clientVersion, extensions) &&
-               internalFormatInfo.mFilterSupportFunction(clientVersion, extensions);
-    }
-    else
-    {
-        return false;
-    }
-}
-
-bool IsSizedInternalFormat(GLenum internalFormat)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
-    {
-        return internalFormatInfo.mPixelBits > 0;
-    }
-    else
-    {
-        UNREACHABLE();
-        return false;
-    }
-}
-
-GLenum GetSizedInternalFormat(GLenum format, GLenum type)
-{
-    const FormatMap &formats = GetFormatMap();
-    FormatMap::const_iterator iter = formats.find(FormatTypePair(format, type));
-    return (iter != formats.end()) ? iter->second.mInternalFormat : GL_NONE;
-}
-
-GLuint GetPixelBytes(GLenum internalFormat)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
-    {
-        return internalFormatInfo.mPixelBits / 8;
-    }
-    else
-    {
-        UNREACHABLE();
-        return 0;
-    }
-}
-
-GLuint GetAlphaBits(GLenum internalFormat)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
-    {
-        return internalFormatInfo.mAlphaBits;
-    }
-    else
-    {
-        UNREACHABLE();
-        return 0;
-    }
-}
-
-GLuint GetRedBits(GLenum internalFormat)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
-    {
-        return internalFormatInfo.mRedBits;
-    }
-    else
-    {
-        UNREACHABLE();
-        return 0;
-    }
-}
-
-GLuint GetGreenBits(GLenum internalFormat)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
-    {
-        return internalFormatInfo.mGreenBits;
-    }
-    else
-    {
-        UNREACHABLE();
-        return 0;
-    }
-}
-
-GLuint GetBlueBits(GLenum internalFormat)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
-    {
-        return internalFormatInfo.mBlueBits;
-    }
-    else
-    {
-        UNREACHABLE();
-        return 0;
-    }
-}
-
-GLuint GetLuminanceBits(GLenum internalFormat)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
-    {
-        return internalFormatInfo.mLuminanceBits;
-    }
-    else
-    {
-        UNREACHABLE();
-        return 0;
-    }
-}
-
-GLuint GetDepthBits(GLenum internalFormat)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
-    {
-        return internalFormatInfo.mDepthBits;
-    }
-    else
-    {
-        UNREACHABLE();
-        return 0;
-    }
-}
-
-GLuint GetStencilBits(GLenum internalFormat)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
-    {
-        return internalFormatInfo.mStencilBits;
-    }
-    else
-    {
-        UNREACHABLE();
-        return 0;
-    }
-}
-
-GLuint GetTypeBytes(GLenum type)
-{
-    TypeInfo typeInfo;
-    if (GetTypeInfo(type, &typeInfo))
-    {
-        return typeInfo.mTypeBytes;
-    }
-    else
-    {
-        UNREACHABLE();
-        return 0;
-    }
-}
-
-bool IsSpecialInterpretationType(GLenum type)
-{
-    TypeInfo typeInfo;
-    if (GetTypeInfo(type, &typeInfo))
-    {
-        return typeInfo.mSpecialInterpretation;
-    }
-    else
-    {
-        UNREACHABLE();
-        return false;
-    }
-}
-
-bool IsFloatOrFixedComponentType(GLenum type)
-{
-    if (type == GL_UNSIGNED_NORMALIZED ||
-        type == GL_SIGNED_NORMALIZED ||
-        type == GL_FLOAT)
-    {
-        return true;
-    }
-    else
-    {
-        return false;
-    }
-}
-
-GLenum GetFormat(GLenum internalFormat)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
-    {
-        return internalFormatInfo.mFormat;
-    }
-    else
-    {
-        UNREACHABLE();
-        return GL_NONE;
-    }
-}
-
-GLenum GetType(GLenum internalFormat)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
-    {
-        return internalFormatInfo.mType;
-    }
-    else
-    {
-        UNREACHABLE();
-        return GL_NONE;
-    }
-}
-
-GLenum GetComponentType(GLenum internalFormat)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
-    {
-        return internalFormatInfo.mComponentType;
-    }
-    else
-    {
-        UNREACHABLE();
-        return GL_NONE;
-    }
-}
-
-GLuint GetComponentCount(GLenum internalFormat)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
-    {
-        return internalFormatInfo.mComponentCount;
-    }
-    else
-    {
-        UNREACHABLE();
-        return false;
-    }
-}
-
-GLenum GetColorEncoding(GLenum internalFormat)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
-    {
-        return internalFormatInfo.mColorEncoding;
-    }
-    else
-    {
-        UNREACHABLE();
-        return false;
-    }
-}
-
-GLuint GetRowPitch(GLenum internalFormat, GLenum type, GLsizei width, GLint alignment)
+GLuint InternalFormat::computeRowPitch(GLenum type, GLsizei width, GLint alignment) const
 {
     ASSERT(alignment > 0 && isPow2(alignment));
-    return rx::roundUp(GetBlockSize(internalFormat, type, width, 1), static_cast<GLuint>(alignment));
+    return rx::roundUp(computeBlockSize(type, width, 1), static_cast<GLuint>(alignment));
 }
 
-GLuint GetDepthPitch(GLenum internalFormat, GLenum type, GLsizei width, GLsizei height, GLint alignment)
+GLuint InternalFormat::computeDepthPitch(GLenum type, GLsizei width, GLsizei height, GLint alignment) const
 {
-    return GetRowPitch(internalFormat, type, width, alignment) * height;
+    return computeRowPitch(type, width, alignment) * height;
 }
 
-GLuint GetBlockSize(GLenum internalFormat, GLenum type, GLsizei width, GLsizei height)
+GLuint InternalFormat::computeBlockSize(GLenum type, GLsizei width, GLsizei height) const
 {
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
+    if (compressed)
     {
-        if (internalFormatInfo.mIsCompressed)
+        GLsizei numBlocksWide = (width + compressedBlockWidth - 1) / compressedBlockWidth;
+        GLsizei numBlocksHight = (height + compressedBlockHeight - 1) / compressedBlockHeight;
+        return (pixelBytes * numBlocksWide * numBlocksHight);
+    }
+    else
+    {
+        const Type &typeInfo = GetTypeInfo(type);
+        if (typeInfo.specialInterpretation)
         {
-            GLsizei numBlocksWide = (width + internalFormatInfo.mCompressedBlockWidth - 1) / internalFormatInfo.mCompressedBlockWidth;
-            GLsizei numBlocksHight = (height + internalFormatInfo.mCompressedBlockHeight - 1) / internalFormatInfo.mCompressedBlockHeight;
-
-            return (internalFormatInfo.mPixelBits * numBlocksWide * numBlocksHight) / 8;
+            return typeInfo.bytes * width * height;
         }
         else
         {
-            TypeInfo typeInfo;
-            if (GetTypeInfo(type, &typeInfo))
-            {
-                if (typeInfo.mSpecialInterpretation)
-                {
-                    return typeInfo.mTypeBytes * width * height;
-                }
-                else
-                {
-                    return internalFormatInfo.mComponentCount * typeInfo.mTypeBytes * width * height;
-                }
-            }
-            else
-            {
-                UNREACHABLE();
-                return 0;
-            }
+            return componentCount * typeInfo.bytes * width * height;
         }
     }
-    else
-    {
-        UNREACHABLE();
-        return 0;
-    }
 }
 
-bool IsFormatCompressed(GLenum internalFormat)
+GLenum GetSizedInternalFormat(GLenum internalFormat, GLenum type)
 {
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
-    {
-        return internalFormatInfo.mIsCompressed;
-    }
-    else
-    {
-        UNREACHABLE();
-        return false;
-    }
-}
-
-GLuint GetCompressedBlockWidth(GLenum internalFormat)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
-    {
-        return internalFormatInfo.mCompressedBlockWidth;
-    }
-    else
-    {
-        UNREACHABLE();
-        return 0;
-    }
-}
-
-GLuint GetCompressedBlockHeight(GLenum internalFormat)
-{
-    InternalFormatInfo internalFormatInfo;
-    if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
-    {
-        return internalFormatInfo.mCompressedBlockHeight;
-    }
-    else
-    {
-        UNREACHABLE();
-        return 0;
-    }
+    const InternalFormat& formatInfo = GetInternalFormatInfo(internalFormat);
+    return (formatInfo.pixelBytes > 0) ? internalFormat : GetFormatTypeInfo(internalFormat, type).internalFormat;
 }
 
 const FormatSet &GetAllSizedInternalFormats()
@@ -1538,11 +620,4 @@
     return formatSet;
 }
 
-ColorWriteFunction GetColorWriteFunction(GLenum format, GLenum type)
-{
-    static const FormatMap &formats = GetFormatMap();
-    FormatMap::const_iterator iter = formats.find(FormatTypePair(format, type));
-    return (iter != formats.end()) ? iter->second.mColorWriteFunction : NULL;
-}
-
 }