Update the format table to check support for filtering and rendering.

Since filerability and renderability may depend on separate extensions,
use functions to determine their support.  Context now uses these
functions to fill it's own TextureFormatCaps.

BUG=angle:658

Change-Id: Ib4dc877ba7c24f84a3823fd5aa2e01a3b3621705
Reviewed-on: https://chromium-review.googlesource.com/206831
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Brandon Jones <bajones@chromium.org>
Tested-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libGLESv2/Caps.cpp b/src/libGLESv2/Caps.cpp
index e7a31da..c1c4dc9 100644
--- a/src/libGLESv2/Caps.cpp
+++ b/src/libGLESv2/Caps.cpp
@@ -45,6 +45,21 @@
     return (iter != mCapsMap.end()) ? iter->second : defaultUnsupportedTexture;
 }
 
+TextureCapsMap::const_iterator TextureCapsMap::begin() const
+{
+    return mCapsMap.begin();
+}
+
+TextureCapsMap::const_iterator TextureCapsMap::end() const
+{
+    return mCapsMap.end();
+}
+
+size_t TextureCapsMap::size() const
+{
+    return mCapsMap.size();
+}
+
 Extensions::Extensions()
     : elementIndexUint(false),
       packedDepthStencil(false),
@@ -87,59 +102,57 @@
 {
 }
 
-static void InsertExtensionString(const std::string &extension, GLuint minClientVersion, GLuint maxClientVersion, bool supported,
-                                  GLuint curClientVersion, std::vector<std::string> *extensionVector)
+static void InsertExtensionString(const std::string &extension, bool supported, std::vector<std::string> *extensionVector)
 {
-    if (supported && minClientVersion >= curClientVersion && (maxClientVersion == 0 || curClientVersion <= maxClientVersion))
+    if (supported)
     {
         extensionVector->push_back(extension);
     }
 }
 
-std::vector<std::string> Extensions::getStrings(GLuint clientVersion) const
+std::vector<std::string> Extensions::getStrings() const
 {
     std::vector<std::string> extensionStrings;
 
-    //                   | Extension name                     | Min | Max  | Supported flag          | Current      | Output vector   |
-    //                   |                                    | ver | ver  |                         | version      |                 |
-    InsertExtensionString("GL_OES_element_index_uint",         2,    0,     elementIndexUint,         clientVersion, &extensionStrings);
-    InsertExtensionString("GL_OES_packed_depth_stencil",       2,    0,     packedDepthStencil,       clientVersion, &extensionStrings);
-    InsertExtensionString("GL_OES_get_program_binary",         2,    0,     getProgramBinary,         clientVersion, &extensionStrings);
-    InsertExtensionString("GL_OES_rgb8_rgba8",                 2,    0,     rgb8rgba8,                clientVersion, &extensionStrings);
-    InsertExtensionString("GL_EXT_texture_format_BGRA8888",    2,    0,     textureFormatBGRA8888,    clientVersion, &extensionStrings);
-    InsertExtensionString("GL_EXT_read_format_bgra",           2,    0,     readFormatBGRA,           clientVersion, &extensionStrings);
-    InsertExtensionString("GL_NV_pixel_buffer_object",         2,    0,     pixelBufferObject,        clientVersion, &extensionStrings);
-    InsertExtensionString("GL_OES_mapbuffer",                  2,    0,     mapBuffer,                clientVersion, &extensionStrings);
-    InsertExtensionString("GL_EXT_map_buffer_range",           2,    0,     mapBufferRange,           clientVersion, &extensionStrings);
-    InsertExtensionString("GL_OES_texture_half_float",         2,    0,     textureHalfFloat,         clientVersion, &extensionStrings);
-    InsertExtensionString("GL_OES_texture_half_float_linear",  2,    0,     textureHalfFloatLinear,   clientVersion, &extensionStrings);
-    InsertExtensionString("GL_OES_texture_float",              2,    0,     textureFloat,             clientVersion, &extensionStrings);
-    InsertExtensionString("GL_OES_texture_float_linear",       2,    0,     textureFloatLinear,       clientVersion, &extensionStrings);
-    InsertExtensionString("GL_EXT_texture_rg",                 2,    0,     textureRG,                clientVersion, &extensionStrings);
-    InsertExtensionString("GL_EXT_texture_compression_dxt1",   2,    0,     textureCompressionDXT1,   clientVersion, &extensionStrings);
-    InsertExtensionString("GL_ANGLE_texture_compression_dxt3", 2,    0,     textureCompressionDXT3,   clientVersion, &extensionStrings);
-    InsertExtensionString("GL_ANGLE_texture_compression_dxt5", 2,    0,     textureCompressionDXT5,   clientVersion, &extensionStrings);
-    InsertExtensionString("GL_EXT_sRGB",                       2,    0,     sRGB,                     clientVersion, &extensionStrings); // FIXME: Don't advertise in ES3
-    InsertExtensionString("GL_ANGLE_depth_texture",            2,    0,     depthTextures,            clientVersion, &extensionStrings);
-    InsertExtensionString("GL_EXT_texture_storage",            2,    0,     textureStorage,           clientVersion, &extensionStrings);
-    InsertExtensionString("GL_OES_texture_npot",               2,    0,     textureNPOT,              clientVersion, &extensionStrings);
-    InsertExtensionString("GL_EXT_draw_buffers",               2,    0,     drawBuffers,              clientVersion, &extensionStrings);
-    InsertExtensionString("GL_EXT_texture_filter_anisotropic", 2,    0,     textureFilterAnisotropic, clientVersion, &extensionStrings);
-    InsertExtensionString("GL_EXT_occlusion_query_boolean",    2,    0,     occlusionQueryBoolean,    clientVersion, &extensionStrings);
-    InsertExtensionString("GL_NV_fence",                       2,    0,     fence,                    clientVersion, &extensionStrings);
-    InsertExtensionString("GL_ANGLE_timer_query",              2,    0,     timerQuery,               clientVersion, &extensionStrings);
-    InsertExtensionString("GL_EXT_robustness",                 2,    0,     robustness,               clientVersion, &extensionStrings);
-    InsertExtensionString("GL_EXT_blend_minmax",               2,    0,     blendMinMax,              clientVersion, &extensionStrings);
-    InsertExtensionString("GL_ANGLE_framebuffer_blit",         2,    0,     framebufferBlit,          clientVersion, &extensionStrings);
-    InsertExtensionString("GL_ANGLE_framebuffer_multisample",  2,    0,     framebufferMultisample,   clientVersion, &extensionStrings);
-    InsertExtensionString("GL_ANGLE_instanced_arrays",         2,    0,     instancedArrays,          clientVersion, &extensionStrings);
-    InsertExtensionString("GL_ANGLE_pack_reverse_row_order",   2,    0,     packReverseRowOrder,      clientVersion, &extensionStrings);
-    InsertExtensionString("GL_OES_standard_derivatives",       2,    0,     standardDerivatives,      clientVersion, &extensionStrings);
-    InsertExtensionString("GL_EXT_shader_texture_lod",         2,    0,     shaderTextureLOD,         clientVersion, &extensionStrings);
-    InsertExtensionString("GL_EXT_frag_depth",                 2,    0,     fragDepth,                clientVersion, &extensionStrings);
-    InsertExtensionString("GL_ANGLE_texture_usage",            2,    0,     textureUsage,             clientVersion, &extensionStrings);
-    InsertExtensionString("GL_ANGLE_translated_shader_source", 2,    0,     translatedShaderSource,   clientVersion, &extensionStrings);
-    InsertExtensionString("GL_EXT_color_buffer_float",         3,    0,     colorBufferFloat,         clientVersion, &extensionStrings);
+    //                   | Extension name                     | Supported flag          | Output vector   |
+    InsertExtensionString("GL_OES_element_index_uint",         elementIndexUint,         &extensionStrings);
+    InsertExtensionString("GL_OES_packed_depth_stencil",       packedDepthStencil,       &extensionStrings);
+    InsertExtensionString("GL_OES_get_program_binary",         getProgramBinary,         &extensionStrings);
+    InsertExtensionString("GL_OES_rgb8_rgba8",                 rgb8rgba8,                &extensionStrings);
+    InsertExtensionString("GL_EXT_texture_format_BGRA8888",    textureFormatBGRA8888,    &extensionStrings);
+    InsertExtensionString("GL_EXT_read_format_bgra",           readFormatBGRA,           &extensionStrings);
+    InsertExtensionString("GL_NV_pixel_buffer_object",         pixelBufferObject,        &extensionStrings);
+    InsertExtensionString("GL_OES_mapbuffer",                  mapBuffer,                &extensionStrings);
+    InsertExtensionString("GL_EXT_map_buffer_range",           mapBufferRange,           &extensionStrings);
+    InsertExtensionString("GL_OES_texture_half_float",         textureHalfFloat,         &extensionStrings);
+    InsertExtensionString("GL_OES_texture_half_float_linear",  textureHalfFloatLinear,   &extensionStrings);
+    InsertExtensionString("GL_OES_texture_float",              textureFloat,             &extensionStrings);
+    InsertExtensionString("GL_OES_texture_float_linear",       textureFloatLinear,       &extensionStrings);
+    InsertExtensionString("GL_EXT_texture_rg",                 textureRG,                &extensionStrings);
+    InsertExtensionString("GL_EXT_texture_compression_dxt1",   textureCompressionDXT1,   &extensionStrings);
+    InsertExtensionString("GL_ANGLE_texture_compression_dxt3", textureCompressionDXT3,   &extensionStrings);
+    InsertExtensionString("GL_ANGLE_texture_compression_dxt5", textureCompressionDXT5,   &extensionStrings);
+    InsertExtensionString("GL_EXT_sRGB",                       sRGB,                     &extensionStrings);
+    InsertExtensionString("GL_ANGLE_depth_texture",            depthTextures,            &extensionStrings);
+    InsertExtensionString("GL_EXT_texture_storage",            textureStorage,           &extensionStrings);
+    InsertExtensionString("GL_OES_texture_npot",               textureNPOT,              &extensionStrings);
+    InsertExtensionString("GL_EXT_draw_buffers",               drawBuffers,              &extensionStrings);
+    InsertExtensionString("GL_EXT_texture_filter_anisotropic", textureFilterAnisotropic, &extensionStrings);
+    InsertExtensionString("GL_EXT_occlusion_query_boolean",    occlusionQueryBoolean,    &extensionStrings);
+    InsertExtensionString("GL_NV_fence",                       fence,                    &extensionStrings);
+    InsertExtensionString("GL_ANGLE_timer_query",              timerQuery,               &extensionStrings);
+    InsertExtensionString("GL_EXT_robustness",                 robustness,               &extensionStrings);
+    InsertExtensionString("GL_EXT_blend_minmax",               blendMinMax,              &extensionStrings);
+    InsertExtensionString("GL_ANGLE_framebuffer_blit",         framebufferBlit,          &extensionStrings);
+    InsertExtensionString("GL_ANGLE_framebuffer_multisample",  framebufferMultisample,   &extensionStrings);
+    InsertExtensionString("GL_ANGLE_instanced_arrays",         instancedArrays,          &extensionStrings);
+    InsertExtensionString("GL_ANGLE_pack_reverse_row_order",   packReverseRowOrder,      &extensionStrings);
+    InsertExtensionString("GL_OES_standard_derivatives",       standardDerivatives,      &extensionStrings);
+    InsertExtensionString("GL_EXT_shader_texture_lod",         shaderTextureLOD,         &extensionStrings);
+    InsertExtensionString("GL_EXT_frag_depth",                 fragDepth,                &extensionStrings);
+    InsertExtensionString("GL_ANGLE_texture_usage",            textureUsage,             &extensionStrings);
+    InsertExtensionString("GL_ANGLE_translated_shader_source", translatedShaderSource,   &extensionStrings);
+    InsertExtensionString("GL_EXT_color_buffer_float",         colorBufferFloat,         &extensionStrings);
 
     return extensionStrings;
 }
diff --git a/src/libGLESv2/Caps.h b/src/libGLESv2/Caps.h
index 79a9109..a08618e 100644
--- a/src/libGLESv2/Caps.h
+++ b/src/libGLESv2/Caps.h
@@ -36,11 +36,18 @@
 class TextureCapsMap
 {
   public:
+    typedef std::unordered_map<GLenum, TextureCaps>::const_iterator const_iterator;
+
     void insert(GLenum internalFormat, const TextureCaps &caps);
     void remove(GLenum internalFormat);
 
     const TextureCaps &get(GLenum internalFormat) const;
 
+    const_iterator begin() const;
+    const_iterator end() const;
+
+    size_t size() const;
+
   private:
     typedef std::unordered_map<GLenum, TextureCaps> InternalFormatToCapsMap;
     InternalFormatToCapsMap mCapsMap;
@@ -51,7 +58,7 @@
     Extensions();
 
     // Generate a vector of supported extension strings
-    std::vector<std::string> getStrings(GLuint clientVersion) const;
+    std::vector<std::string> getStrings() const;
 
     // Set all texture related extension support based on the supported textures.
     // Determines support for:
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index 10bd6f8..74244dc 100644
--- a/src/libGLESv2/Context.cpp
+++ b/src/libGLESv2/Context.cpp
@@ -44,9 +44,7 @@
 {
     ASSERT(robustAccess == false);   // Unimplemented
 
-    mCaps = mRenderer->getRendererCaps();
-    mTextureCaps = mRenderer->getRendererTextureCaps();
-    mExtensions = mRenderer->getRendererExtensions();
+    initCaps(clientVersion);
 
     mClientVersion = clientVersion;
 
@@ -2329,7 +2327,7 @@
 
 void Context::initExtensionStrings()
 {
-    mExtensionStrings = mExtensions.getStrings(mClientVersion);
+    mExtensionStrings = mExtensions.getStrings();
 
     std::ostringstream combinedStringStream;
     std::copy(mExtensionStrings.begin(), mExtensionStrings.end(), std::ostream_iterator<std::string>(combinedStringStream, " "));
@@ -2508,6 +2506,40 @@
     return false;
 }
 
+void Context::initCaps(GLuint clientVersion)
+{
+    mCaps = mRenderer->getRendererCaps();
+
+    mExtensions = mRenderer->getRendererExtensions();
+
+    if (clientVersion < 3)
+    {
+        // Disable ES3+ extensions
+        mExtensions.colorBufferFloat = false;
+    }
+
+    if (clientVersion > 2)
+    {
+        // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
+        //mExtensions.sRGB = false;
+    }
+
+    const TextureCapsMap &rendererFormats = mRenderer->getRendererTextureCaps();
+    for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
+    {
+        GLenum format = i->first;
+        TextureCaps formatCaps = i->second;
+
+        if (formatCaps.texturable && IsValidInternalFormat(format, mExtensions, clientVersion))
+        {
+            // Update the format caps based on the client version and extensions
+            formatCaps.renderable = IsRenderingSupported(format, mExtensions, clientVersion);
+            formatCaps.filterable = IsFilteringSupported(format, mExtensions, clientVersion);
+            mTextureCaps.insert(format, formatCaps);
+        }
+    }
+}
+
 }
 
 extern "C"
diff --git a/src/libGLESv2/Context.h b/src/libGLESv2/Context.h
index a257b29..4b7e59e 100644
--- a/src/libGLESv2/Context.h
+++ b/src/libGLESv2/Context.h
@@ -278,6 +278,8 @@
 
     size_t getBoundFramebufferTextureSerials(FramebufferTextureSerialArray *outSerialArray);
 
+    void initCaps(GLuint clientVersion);
+
     // Caps to use for validation
     Caps mCaps;
     TextureCapsMap mTextureCaps;
diff --git a/src/libGLESv2/formatutils.cpp b/src/libGLESv2/formatutils.cpp
index 82fced5..8cc2e19 100644
--- a/src/libGLESv2/formatutils.cpp
+++ b/src/libGLESv2/formatutils.cpp
@@ -417,13 +417,17 @@
 // Information about internal formats
 typedef bool(*SupportCheckFunction)(GLuint, const Extensions &);
 
-static bool UnimplementedSupport(GLuint clientVersion, const Extensions &)
+static bool AlwaysSupported(GLuint, const Extensions &)
 {
-    UNIMPLEMENTED();
+    return true;
+}
+
+static bool UnimplementedSupport(GLuint, const Extensions &)
+{
     return false;
 }
 
-static bool NeverSupported(GLuint clientVersion, const Extensions &)
+static bool NeverSupported(GLuint, const Extensions &)
 {
     return false;
 }
@@ -494,25 +498,32 @@
 
     bool mIsCompressed;
 
-    SupportCheckFunction mSupportFunction;
+    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), mSupportFunction(NeverSupported)
+                           mComponentType(GL_NONE), mColorEncoding(GL_NONE), mIsCompressed(false), mTextureSupportFunction(NeverSupported),
+                           mRenderSupportFunction(NeverSupported), mFilterSupportFunction(NeverSupported)
     {
     }
 
-    static InternalFormatInfo UnsizedFormat(GLenum format, SupportCheckFunction supportFunction)
+    static InternalFormatInfo UnsizedFormat(GLenum format, SupportCheckFunction textureSupport, SupportCheckFunction renderSupport,
+                                            SupportCheckFunction filterSupport)
     {
         InternalFormatInfo formatInfo;
         formatInfo.mFormat = format;
-        formatInfo.mSupportFunction = supportFunction;
+        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 supportFunction)
+                                         SupportCheckFunction textureSupport, SupportCheckFunction renderSupport,
+                                         SupportCheckFunction filterSupport)
     {
         InternalFormatInfo formatInfo;
         formatInfo.mRedBits = red;
@@ -526,12 +537,15 @@
         formatInfo.mType = type;
         formatInfo.mComponentType = componentType;
         formatInfo.mColorEncoding = (srgb ? GL_SRGB : GL_LINEAR);
-        formatInfo.mSupportFunction = supportFunction;
+        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 supportFunction)
+                                         SupportCheckFunction textureSupport, SupportCheckFunction renderSupport,
+                                         SupportCheckFunction filterSupport)
     {
         InternalFormatInfo formatInfo;
         formatInfo.mLuminanceBits = luminance;
@@ -542,12 +556,15 @@
         formatInfo.mType = type;
         formatInfo.mComponentType = componentType;
         formatInfo.mColorEncoding = GL_LINEAR;
-        formatInfo.mSupportFunction = supportFunction;
+        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 supportFunction)
+                                                 GLenum type, GLenum componentType, SupportCheckFunction textureSupport,
+                                                 SupportCheckFunction renderSupport, SupportCheckFunction filterSupport)
     {
         InternalFormatInfo formatInfo;
         formatInfo.mDepthBits = depthBits;
@@ -558,13 +575,16 @@
         formatInfo.mType = type;
         formatInfo.mComponentType = componentType;
         formatInfo.mColorEncoding = GL_LINEAR;
-        formatInfo.mSupportFunction = supportFunction;
+        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 supportFunction)
+                                               SupportCheckFunction textureSupport, SupportCheckFunction renderSupport,
+                                               SupportCheckFunction filterSupport)
     {
         InternalFormatInfo formatInfo;
         formatInfo.mCompressedBlockWidth = compressedBlockWidth;
@@ -576,7 +596,9 @@
         formatInfo.mComponentType = GL_UNSIGNED_NORMALIZED;
         formatInfo.mColorEncoding = (srgb ? GL_SRGB : GL_LINEAR);
         formatInfo.mIsCompressed = true;
-        formatInfo.mSupportFunction = supportFunction;
+        formatInfo.mTextureSupportFunction = textureSupport;
+        formatInfo.mRenderSupportFunction = renderSupport;
+        formatInfo.mFilterSupportFunction = filterSupport;
         return formatInfo;
     }
 };
@@ -591,129 +613,129 @@
     // From ES 3.0.1 spec, table 3.12
     map.insert(InternalFormatInfoPair(GL_NONE,              InternalFormatInfo()));
 
-    //                               | Internal format     |                              | R | G | B | A |S | Format         | Type                           | Component type        | SRGB | Supported                             |
-    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>)));
-    map.insert(InternalFormatInfoPair(GL_R8_SNORM,          InternalFormatInfo::RGBAFormat( 8,  0,  0,  0, 0, GL_RED,          GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, RequireESVersion<3>                    )));
-    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>)));
-    map.insert(InternalFormatInfoPair(GL_RG8_SNORM,         InternalFormatInfo::RGBAFormat( 8,  8,  0,  0, 0, GL_RG,           GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, RequireESVersion<3>                    )));
-    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>)));
-    map.insert(InternalFormatInfoPair(GL_RGB8_SNORM,        InternalFormatInfo::RGBAFormat( 8,  8,  8,  0, 0, GL_RGB,          GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, RequireESVersion<3>                    )));
-    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>                    )));
-    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>                    )));
-    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>                    )));
-    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>)));
-    map.insert(InternalFormatInfoPair(GL_RGBA8_SNORM,       InternalFormatInfo::RGBAFormat( 8,  8,  8,  8, 0, GL_RGBA,         GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, RequireESVersion<3>                    )));
-    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>                    )));
-    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>                    )));
-    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>)));
-    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>)));
-    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>                    )));
-    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>                    )));
-    map.insert(InternalFormatInfoPair(GL_R8I,               InternalFormatInfo::RGBAFormat( 8,  0,  0,  0, 0, GL_RED_INTEGER,  GL_BYTE,                         GL_INT,                 false, RequireESVersion<3>                    )));
-    map.insert(InternalFormatInfoPair(GL_R8UI,              InternalFormatInfo::RGBAFormat( 8,  0,  0,  0, 0, GL_RED_INTEGER,  GL_UNSIGNED_BYTE,                GL_UNSIGNED_INT,        false, RequireESVersion<3>                    )));
-    map.insert(InternalFormatInfoPair(GL_R16I,              InternalFormatInfo::RGBAFormat(16,  0,  0,  0, 0, GL_RED_INTEGER,  GL_SHORT,                        GL_INT,                 false, RequireESVersion<3>                    )));
-    map.insert(InternalFormatInfoPair(GL_R16UI,             InternalFormatInfo::RGBAFormat(16,  0,  0,  0, 0, GL_RED_INTEGER,  GL_UNSIGNED_SHORT,               GL_UNSIGNED_INT,        false, RequireESVersion<3>                    )));
-    map.insert(InternalFormatInfoPair(GL_R32I,              InternalFormatInfo::RGBAFormat(32,  0,  0,  0, 0, GL_RED_INTEGER,  GL_INT,                          GL_INT,                 false, RequireESVersion<3>                    )));
-    map.insert(InternalFormatInfoPair(GL_R32UI,             InternalFormatInfo::RGBAFormat(32,  0,  0,  0, 0, GL_RED_INTEGER,  GL_UNSIGNED_INT,                 GL_UNSIGNED_INT,        false, RequireESVersion<3>                    )));
-    map.insert(InternalFormatInfoPair(GL_RG8I,              InternalFormatInfo::RGBAFormat( 8,  8,  0,  0, 0, GL_RG_INTEGER,   GL_BYTE,                         GL_INT,                 false, RequireESVersion<3>                    )));
-    map.insert(InternalFormatInfoPair(GL_RG8UI,             InternalFormatInfo::RGBAFormat( 8,  8,  0,  0, 0, GL_RG_INTEGER,   GL_UNSIGNED_BYTE,                GL_UNSIGNED_INT,        false, RequireESVersion<3>                    )));
-    map.insert(InternalFormatInfoPair(GL_RG16I,             InternalFormatInfo::RGBAFormat(16, 16,  0,  0, 0, GL_RG_INTEGER,   GL_SHORT,                        GL_INT,                 false, RequireESVersion<3>                    )));
-    map.insert(InternalFormatInfoPair(GL_RG16UI,            InternalFormatInfo::RGBAFormat(16, 16,  0,  0, 0, GL_RG_INTEGER,   GL_UNSIGNED_SHORT,               GL_UNSIGNED_INT,        false, RequireESVersion<3>                    )));
-    map.insert(InternalFormatInfoPair(GL_RG32I,             InternalFormatInfo::RGBAFormat(32, 32,  0,  0, 0, GL_RG_INTEGER,   GL_INT,                          GL_INT,                 false, RequireESVersion<3>                    )));
-    map.insert(InternalFormatInfoPair(GL_RG32UI,            InternalFormatInfo::RGBAFormat(32, 32,  0,  0, 0, GL_RG_INTEGER,   GL_UNSIGNED_INT,                 GL_UNSIGNED_INT,        false, RequireESVersion<3>                    )));
-    map.insert(InternalFormatInfoPair(GL_RGB8I,             InternalFormatInfo::RGBAFormat( 8,  8,  8,  0, 0, GL_RGB_INTEGER,  GL_BYTE,                         GL_INT,                 false, RequireESVersion<3>                    )));
-    map.insert(InternalFormatInfoPair(GL_RGB8UI,            InternalFormatInfo::RGBAFormat( 8,  8,  8,  0, 0, GL_RGB_INTEGER,  GL_UNSIGNED_BYTE,                GL_UNSIGNED_INT,        false, RequireESVersion<3>                    )));
-    map.insert(InternalFormatInfoPair(GL_RGB16I,            InternalFormatInfo::RGBAFormat(16, 16, 16,  0, 0, GL_RGB_INTEGER,  GL_SHORT,                        GL_INT,                 false, RequireESVersion<3>                    )));
-    map.insert(InternalFormatInfoPair(GL_RGB16UI,           InternalFormatInfo::RGBAFormat(16, 16, 16,  0, 0, GL_RGB_INTEGER,  GL_UNSIGNED_SHORT,               GL_UNSIGNED_INT,        false, RequireESVersion<3>                    )));
-    map.insert(InternalFormatInfoPair(GL_RGB32I,            InternalFormatInfo::RGBAFormat(32, 32, 32,  0, 0, GL_RGB_INTEGER,  GL_INT,                          GL_INT,                 false, RequireESVersion<3>                    )));
-    map.insert(InternalFormatInfoPair(GL_RGB32UI,           InternalFormatInfo::RGBAFormat(32, 32, 32,  0, 0, GL_RGB_INTEGER,  GL_UNSIGNED_INT,                 GL_UNSIGNED_INT,        false, RequireESVersion<3>                    )));
-    map.insert(InternalFormatInfoPair(GL_RGBA8I,            InternalFormatInfo::RGBAFormat( 8,  8,  8,  8, 0, GL_RGBA_INTEGER, GL_BYTE,                         GL_INT,                 false, RequireESVersion<3>                    )));
-    map.insert(InternalFormatInfoPair(GL_RGBA8UI,           InternalFormatInfo::RGBAFormat( 8,  8,  8,  8, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE,                GL_UNSIGNED_INT,        false, RequireESVersion<3>                    )));
-    map.insert(InternalFormatInfoPair(GL_RGBA16I,           InternalFormatInfo::RGBAFormat(16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_SHORT,                        GL_INT,                 false, RequireESVersion<3>                    )));
-    map.insert(InternalFormatInfoPair(GL_RGBA16UI,          InternalFormatInfo::RGBAFormat(16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT,               GL_UNSIGNED_INT,        false, RequireESVersion<3>                    )));
-    map.insert(InternalFormatInfoPair(GL_RGBA32I,           InternalFormatInfo::RGBAFormat(32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_INT,                          GL_INT,                 false, RequireESVersion<3>                    )));
-    map.insert(InternalFormatInfoPair(GL_RGBA32UI,          InternalFormatInfo::RGBAFormat(32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT,                 GL_UNSIGNED_INT,        false, RequireESVersion<3>                    )));
+    //                               | 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)));
 
-    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>)));
-    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>)));
-    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>)));
+    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)));
 
     // Floating point renderability and filtering is provided by OES_texture_float and OES_texture_half_float
-    //                               | Internal format        |                                   | D |S | Format             | Type                           | Comp   | SRGB | Supported                                                                             |
-    //                               |                        |                                   |   |  |                    |                                | 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>)));
-    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>)));
-    map.insert(InternalFormatInfoPair(GL_RGB16F,            InternalFormatInfo::RGBAFormat(16, 16, 16,  0, 0, GL_RGB,          GL_HALF_FLOAT,                   GL_FLOAT, false, RequireESVersionOrExtension<3, &Extensions::textureHalfFloat>                         )));
-    map.insert(InternalFormatInfoPair(GL_RGBA16F,           InternalFormatInfo::RGBAFormat(16, 16, 16, 16, 0, GL_RGBA,         GL_HALF_FLOAT,                   GL_FLOAT, false, RequireESVersionOrExtension<3, &Extensions::textureHalfFloat>                         )));
-    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>    )));
-    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>    )));
-    map.insert(InternalFormatInfoPair(GL_RGB32F,            InternalFormatInfo::RGBAFormat(32, 32, 32,  0, 0, GL_RGB,          GL_FLOAT,                        GL_FLOAT, false, RequireESVersionOrExtension<3, &Extensions::textureFloat>                             )));
-    map.insert(InternalFormatInfoPair(GL_RGBA32F,           InternalFormatInfo::RGBAFormat(32, 32, 32, 32, 0, GL_RGBA,         GL_FLOAT,                        GL_FLOAT, false, RequireESVersionOrExtension<3, &Extensions::textureFloat>                             )));
+    //                               | 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>    )));
 
     // 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>                        )));
-    map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT24,     InternalFormatInfo::DepthStencilFormat(24, 0,  0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,                   GL_UNSIGNED_NORMALIZED, RequireESVersion<3>                        )));
-    map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32F,    InternalFormatInfo::DepthStencilFormat(32, 0,  0, GL_DEPTH_COMPONENT, GL_FLOAT,                          GL_FLOAT,               RequireESVersion<3>                        )));
-    map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32_OES, InternalFormatInfo::DepthStencilFormat(32, 0,  0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,                   GL_UNSIGNED_NORMALIZED, RequireExtension<&Extensions::depthTextures>)));
-    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>)));
-    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>                        )));
-    map.insert(InternalFormatInfoPair(GL_STENCIL_INDEX8,        InternalFormatInfo::DepthStencilFormat( 0, 8,  0, GL_DEPTH_STENCIL,   GL_UNSIGNED_BYTE,                  GL_UNSIGNED_INT,        RequireESVersion<2>                        )));
+    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                                            )));
 
     // Luminance alpha formats
-    //                               | Internal format          |                              | L | A | Format            | Type            | Component type        | Supported                                                                   |
-    map.insert(InternalFormatInfoPair(GL_ALPHA8_EXT,             InternalFormatInfo::LUMAFormat( 0,  8, GL_ALPHA,           GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExtension<&Extensions::textureStorage>                                )));
-    map.insert(InternalFormatInfoPair(GL_LUMINANCE8_EXT,         InternalFormatInfo::LUMAFormat( 8,  0, GL_LUMINANCE,       GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExtension<&Extensions::textureStorage>                                )));
-    map.insert(InternalFormatInfoPair(GL_ALPHA32F_EXT,           InternalFormatInfo::LUMAFormat( 0, 32, GL_ALPHA,           GL_FLOAT,         GL_FLOAT,               RequireExtensions<&Extensions::textureStorage, &Extensions::textureFloat>    )));
-    map.insert(InternalFormatInfoPair(GL_LUMINANCE32F_EXT,       InternalFormatInfo::LUMAFormat(32,  0, GL_LUMINANCE,       GL_FLOAT,         GL_FLOAT,               RequireExtensions<&Extensions::textureStorage, &Extensions::textureFloat>    )));
-    map.insert(InternalFormatInfoPair(GL_ALPHA16F_EXT,           InternalFormatInfo::LUMAFormat( 0, 16, GL_ALPHA,           GL_HALF_FLOAT,    GL_FLOAT,               RequireExtensions<&Extensions::textureStorage, &Extensions::textureHalfFloat>)));
-    map.insert(InternalFormatInfoPair(GL_LUMINANCE16F_EXT,       InternalFormatInfo::LUMAFormat(16,  0, GL_LUMINANCE,       GL_HALF_FLOAT,    GL_FLOAT,               RequireExtensions<&Extensions::textureStorage, &Extensions::textureHalfFloat>)));
-    map.insert(InternalFormatInfoPair(GL_LUMINANCE8_ALPHA8_EXT,  InternalFormatInfo::LUMAFormat( 8,  8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExtension<&Extensions::textureStorage>                                )));
-    map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA32F_EXT, InternalFormatInfo::LUMAFormat(32, 32, GL_LUMINANCE_ALPHA, GL_FLOAT,         GL_FLOAT,               RequireExtensions<&Extensions::textureStorage, &Extensions::textureFloat>    )));
-    map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA16F_EXT, InternalFormatInfo::LUMAFormat(16, 16, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT,    GL_FLOAT,               RequireExtensions<&Extensions::textureStorage, &Extensions::textureHalfFloat>)));
+    //                               | 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)));
 
     // Unsized formats
-    //                               | Internal format   |                                 | Format            | Supported                                                     |
-    map.insert(InternalFormatInfoPair(GL_ALPHA,           InternalFormatInfo::UnsizedFormat(GL_ALPHA,           RequireESVersion<2>                                            )));
-    map.insert(InternalFormatInfoPair(GL_LUMINANCE,       InternalFormatInfo::UnsizedFormat(GL_LUMINANCE,       RequireESVersion<2>                                            )));
-    map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA, InternalFormatInfo::UnsizedFormat(GL_LUMINANCE_ALPHA, RequireESVersion<2>                                            )));
-    map.insert(InternalFormatInfoPair(GL_RED,             InternalFormatInfo::UnsizedFormat(GL_RED,             RequireESVersionOrExtension<3, &Extensions::textureRG>         )));
-    map.insert(InternalFormatInfoPair(GL_RG,              InternalFormatInfo::UnsizedFormat(GL_RG,              RequireESVersionOrExtension<3, &Extensions::textureRG>         )));
-    map.insert(InternalFormatInfoPair(GL_RGB,             InternalFormatInfo::UnsizedFormat(GL_RGB,             RequireESVersion<2>                                            )));
-    map.insert(InternalFormatInfoPair(GL_RGBA,            InternalFormatInfo::UnsizedFormat(GL_RGBA,            RequireESVersion<2>                                            )));
-    map.insert(InternalFormatInfoPair(GL_RED_INTEGER,     InternalFormatInfo::UnsizedFormat(GL_RED_INTEGER,     RequireESVersion<3>                                            )));
-    map.insert(InternalFormatInfoPair(GL_RG_INTEGER,      InternalFormatInfo::UnsizedFormat(GL_RG_INTEGER,      RequireESVersion<3>                                            )));
-    map.insert(InternalFormatInfoPair(GL_RGB_INTEGER,     InternalFormatInfo::UnsizedFormat(GL_RGB_INTEGER,     RequireESVersion<3>                                            )));
-    map.insert(InternalFormatInfoPair(GL_RGBA_INTEGER,    InternalFormatInfo::UnsizedFormat(GL_RGBA_INTEGER,    RequireESVersion<3>                                            )));
-    map.insert(InternalFormatInfoPair(GL_BGRA_EXT,        InternalFormatInfo::UnsizedFormat(GL_BGRA_EXT,        RequireExtension<&Extensions::textureFormatBGRA8888>           )));
-    map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT, InternalFormatInfo::UnsizedFormat(GL_DEPTH_COMPONENT, RequireESVersion<2>                                            )));
-    map.insert(InternalFormatInfoPair(GL_DEPTH_STENCIL,   InternalFormatInfo::UnsizedFormat(GL_DEPTH_STENCIL,   RequireESVersionOrExtension<3, &Extensions::packedDepthStencil>)));
-    map.insert(InternalFormatInfoPair(GL_SRGB_EXT,        InternalFormatInfo::UnsizedFormat(GL_RGB,             RequireESVersionOrExtension<3, &Extensions::sRGB>              )));
-    map.insert(InternalFormatInfoPair(GL_SRGB_ALPHA_EXT,  InternalFormatInfo::UnsizedFormat(GL_RGBA,            RequireESVersionOrExtension<3, &Extensions::sRGB>              )));
+    //                               | 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)));
 
     // Compressed formats, From ES 3.0.1 spec, table 3.16
-    //                               | Internal format                             |                                    |W |H | BS |CC| Format                                      | Type            | SRGB | Supported          |
-    map.insert(InternalFormatInfoPair(GL_COMPRESSED_R11_EAC,                        InternalFormatInfo::CompressedFormat(4, 4,  64, 1, GL_COMPRESSED_R11_EAC,                        GL_UNSIGNED_BYTE, false, 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)));
-    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RG11_EAC,                       InternalFormatInfo::CompressedFormat(4, 4, 128, 2, GL_COMPRESSED_RG11_EAC,                       GL_UNSIGNED_BYTE, false, 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)));
-    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB8_ETC2,                      InternalFormatInfo::CompressedFormat(4, 4,  64, 3, GL_COMPRESSED_RGB8_ETC2,                      GL_UNSIGNED_BYTE, false, UnimplementedSupport)));
-    map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ETC2,                     InternalFormatInfo::CompressedFormat(4, 4,  64, 3, GL_COMPRESSED_SRGB8_ETC2,                     GL_UNSIGNED_BYTE, true,  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)));
-    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)));
-    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA8_ETC2_EAC,                 InternalFormatInfo::CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA8_ETC2_EAC,                 GL_UNSIGNED_BYTE, false, 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)));
+    //                               | 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)));
 
     // From GL_EXT_texture_compression_dxt1
-    //                               | Internal format                   |                                    |W |H | BS |CC| Format                            | Type            | SRGB | Supported                                           |
-    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>)));
-    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>)));
+    //                               | 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     )));
 
     // 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>)));
+    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     )));
 
     // 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>)));
+    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     )));
 
     return map;
 }
@@ -927,8 +949,8 @@
     InternalFormatInfo internalFormatInfo;
     if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
     {
-        ASSERT(internalFormatInfo.mSupportFunction != NULL);
-        return internalFormatInfo.mSupportFunction(clientVersion, extensions);
+        ASSERT(internalFormatInfo.mTextureSupportFunction != NULL);
+        return internalFormatInfo.mTextureSupportFunction(clientVersion, extensions);
     }
     else
     {
@@ -941,7 +963,7 @@
     const InternalFormatInfoMap &internalFormats = GetInternalFormatMap();
     for (InternalFormatInfoMap::const_iterator i = internalFormats.begin(); i != internalFormats.end(); i++)
     {
-        if (i->second.mFormat == format && i->second.mSupportFunction(clientVersion, extensions))
+        if (i->second.mFormat == format && i->second.mTextureSupportFunction(clientVersion, extensions))
         {
             return true;
         }
@@ -955,7 +977,7 @@
     const InternalFormatInfoMap &internalFormats = GetInternalFormatMap();
     for (InternalFormatInfoMap::const_iterator i = internalFormats.begin(); i != internalFormats.end(); i++)
     {
-        if (i->second.mType == type && i->second.mSupportFunction(clientVersion, extensions))
+        if (i->second.mType == type && i->second.mTextureSupportFunction(clientVersion, extensions))
         {
             return true;
         }
@@ -969,7 +991,7 @@
     InternalFormatInfo internalFormatInfo;
     if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
     {
-        if (!internalFormatInfo.mSupportFunction(clientVersion, extensions))
+        if (!internalFormatInfo.mTextureSupportFunction(clientVersion, extensions))
         {
             return false;
         }
@@ -1140,6 +1162,38 @@
     }
 }
 
+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;
diff --git a/src/libGLESv2/formatutils.h b/src/libGLESv2/formatutils.h
index 3e5d67c..fb4d2a3 100644
--- a/src/libGLESv2/formatutils.h
+++ b/src/libGLESv2/formatutils.h
@@ -45,6 +45,9 @@
 bool IsValidFormatCombination(GLenum internalFormat, GLenum format, GLenum type, const Extensions &extensions, GLuint clientVersion);
 bool IsValidCopyTexImageCombination(GLenum textureInternalFormat, GLenum frameBufferInternalFormat, GLuint readBufferHandle, GLuint clientVersion);
 
+bool IsRenderingSupported(GLenum internalFormat, const Extensions &extensions, GLuint clientVersion);
+bool IsFilteringSupported(GLenum internalFormat, const Extensions &extensions, GLuint clientVersion);
+
 bool IsSizedInternalFormat(GLenum internalFormat);
 GLenum GetSizedInternalFormat(GLenum format, GLenum type);