Home | History | Annotate | Download | only in libGLESv2
      1 //
      2 // Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 
      7 // formatutils.cpp: Queries for GL image formats.
      8 
      9 #include "common/mathutil.h"
     10 #include "libGLESv2/formatutils.h"
     11 #include "libGLESv2/Context.h"
     12 #include "libGLESv2/Framebuffer.h"
     13 #include "libGLESv2/renderer/Renderer.h"
     14 #include "libGLESv2/renderer/imageformats.h"
     15 #include "libGLESv2/renderer/copyimage.h"
     16 
     17 namespace gl
     18 {
     19 
     20 // ES2 requires that format is equal to internal format at all glTex*Image2D entry points and the implementation
     21 // can decide the true, sized, internal format. The ES2FormatMap determines the internal format for all valid
     22 // format and type combinations.
     23 
     24 FormatType::FormatType()
     25     : internalFormat(GL_NONE),
     26       colorWriteFunction(NULL)
     27 {
     28 }
     29 
     30 typedef std::pair<GLenum, GLenum> FormatTypePair;
     31 typedef std::pair<FormatTypePair, FormatType> FormatPair;
     32 typedef std::map<FormatTypePair, FormatType> FormatMap;
     33 
     34 // A helper function to insert data into the format map with fewer characters.
     35 static inline void InsertFormatMapping(FormatMap *map, GLenum format, GLenum type, GLenum internalFormat, ColorWriteFunction writeFunc)
     36 {
     37     FormatType info;
     38     info.internalFormat = internalFormat;
     39     info.colorWriteFunction = writeFunc;
     40     map->insert(FormatPair(FormatTypePair(format, type), info));
     41 }
     42 
     43 FormatMap BuildFormatMap()
     44 {
     45     FormatMap map;
     46 
     47     using namespace rx;
     48 
     49     //                       | Format               | Type                             | Internal format          | Color write function             |
     50     InsertFormatMapping(&map, GL_RGBA,               GL_UNSIGNED_BYTE,                  GL_RGBA8,                  WriteColor<R8G8B8A8, GLfloat>     );
     51     InsertFormatMapping(&map, GL_RGBA,               GL_BYTE,                           GL_RGBA8_SNORM,            WriteColor<R8G8B8A8S, GLfloat>    );
     52     InsertFormatMapping(&map, GL_RGBA,               GL_UNSIGNED_SHORT_4_4_4_4,         GL_RGBA4,                  WriteColor<R4G4B4A4, GLfloat>     );
     53     InsertFormatMapping(&map, GL_RGBA,               GL_UNSIGNED_SHORT_5_5_5_1,         GL_RGB5_A1,                WriteColor<R5G5B5A1, GLfloat>     );
     54     InsertFormatMapping(&map, GL_RGBA,               GL_UNSIGNED_INT_2_10_10_10_REV,    GL_RGB10_A2,               WriteColor<R10G10B10A2, GLfloat>  );
     55     InsertFormatMapping(&map, GL_RGBA,               GL_FLOAT,                          GL_RGBA32F,                WriteColor<R32G32B32A32F, GLfloat>);
     56     InsertFormatMapping(&map, GL_RGBA,               GL_HALF_FLOAT,                     GL_RGBA16F,                WriteColor<R16G16B16A16F, GLfloat>);
     57     InsertFormatMapping(&map, GL_RGBA,               GL_HALF_FLOAT_OES,                 GL_RGBA16F,                WriteColor<R16G16B16A16F, GLfloat>);
     58 
     59     InsertFormatMapping(&map, GL_RGBA_INTEGER,       GL_UNSIGNED_BYTE,                  GL_RGBA8UI,                WriteColor<R8G8B8A8, GLuint>      );
     60     InsertFormatMapping(&map, GL_RGBA_INTEGER,       GL_BYTE,                           GL_RGBA8I,                 WriteColor<R8G8B8A8S, GLint>      );
     61     InsertFormatMapping(&map, GL_RGBA_INTEGER,       GL_UNSIGNED_SHORT,                 GL_RGBA16UI,               WriteColor<R16G16B16A16, GLuint>  );
     62     InsertFormatMapping(&map, GL_RGBA_INTEGER,       GL_SHORT,                          GL_RGBA16I,                WriteColor<R16G16B16A16S, GLint>  );
     63     InsertFormatMapping(&map, GL_RGBA_INTEGER,       GL_UNSIGNED_INT,                   GL_RGBA32UI,               WriteColor<R32G32B32A32, GLuint>  );
     64     InsertFormatMapping(&map, GL_RGBA_INTEGER,       GL_INT,                            GL_RGBA32I,                WriteColor<R32G32B32A32S, GLint>  );
     65     InsertFormatMapping(&map, GL_RGBA_INTEGER,       GL_UNSIGNED_INT_2_10_10_10_REV,    GL_RGB10_A2UI,             WriteColor<R10G10B10A2, GLuint>   );
     66 
     67     InsertFormatMapping(&map, GL_RGB,                GL_UNSIGNED_BYTE,                  GL_RGB8,                   WriteColor<R8G8B8, GLfloat>       );
     68     InsertFormatMapping(&map, GL_RGB,                GL_BYTE,                           GL_RGB8_SNORM,             WriteColor<R8G8B8S, GLfloat>      );
     69     InsertFormatMapping(&map, GL_RGB,                GL_UNSIGNED_SHORT_5_6_5,           GL_RGB565,                 WriteColor<R5G6B5, GLfloat>       );
     70     InsertFormatMapping(&map, GL_RGB,                GL_UNSIGNED_INT_10F_11F_11F_REV,   GL_R11F_G11F_B10F,         WriteColor<R11G11B10F, GLfloat>   );
     71     InsertFormatMapping(&map, GL_RGB,                GL_UNSIGNED_INT_5_9_9_9_REV,       GL_RGB9_E5,                WriteColor<R9G9B9E5, GLfloat>     );
     72     InsertFormatMapping(&map, GL_RGB,                GL_FLOAT,                          GL_RGB32F,                 WriteColor<R32G32B32F, GLfloat>   );
     73     InsertFormatMapping(&map, GL_RGB,                GL_HALF_FLOAT,                     GL_RGB16F,                 WriteColor<R16G16B16F, GLfloat>   );
     74     InsertFormatMapping(&map, GL_RGB,                GL_HALF_FLOAT_OES,                 GL_RGB16F,                 WriteColor<R16G16B16F, GLfloat>   );
     75 
     76     InsertFormatMapping(&map, GL_RGB_INTEGER,        GL_UNSIGNED_BYTE,                  GL_RGB8UI,                 WriteColor<R8G8B8, GLuint>        );
     77     InsertFormatMapping(&map, GL_RGB_INTEGER,        GL_BYTE,                           GL_RGB8I,                  WriteColor<R8G8B8S, GLint>        );
     78     InsertFormatMapping(&map, GL_RGB_INTEGER,        GL_UNSIGNED_SHORT,                 GL_RGB16UI,                WriteColor<R16G16B16, GLuint>     );
     79     InsertFormatMapping(&map, GL_RGB_INTEGER,        GL_SHORT,                          GL_RGB16I,                 WriteColor<R16G16B16S, GLint>     );
     80     InsertFormatMapping(&map, GL_RGB_INTEGER,        GL_UNSIGNED_INT,                   GL_RGB32UI,                WriteColor<R32G32B32, GLuint>     );
     81     InsertFormatMapping(&map, GL_RGB_INTEGER,        GL_INT,                            GL_RGB32I,                 WriteColor<R32G32B32S, GLint>     );
     82 
     83     InsertFormatMapping(&map, GL_RG,                 GL_UNSIGNED_BYTE,                  GL_RG8,                    WriteColor<R8G8, GLfloat>         );
     84     InsertFormatMapping(&map, GL_RG,                 GL_BYTE,                           GL_RG8_SNORM,              WriteColor<R8G8S, GLfloat>        );
     85     InsertFormatMapping(&map, GL_RG,                 GL_FLOAT,                          GL_RG32F,                  WriteColor<R32G32F, GLfloat>      );
     86     InsertFormatMapping(&map, GL_RG,                 GL_HALF_FLOAT,                     GL_RG16F,                  WriteColor<R16G16F, GLfloat>      );
     87     InsertFormatMapping(&map, GL_RG,                 GL_HALF_FLOAT_OES,                 GL_RG16F,                  WriteColor<R16G16F, GLfloat>      );
     88 
     89     InsertFormatMapping(&map, GL_RG_INTEGER,         GL_UNSIGNED_BYTE,                  GL_RG8UI,                  WriteColor<R8G8, GLuint>          );
     90     InsertFormatMapping(&map, GL_RG_INTEGER,         GL_BYTE,                           GL_RG8I,                   WriteColor<R8G8S, GLint>          );
     91     InsertFormatMapping(&map, GL_RG_INTEGER,         GL_UNSIGNED_SHORT,                 GL_RG16UI,                 WriteColor<R16G16, GLuint>        );
     92     InsertFormatMapping(&map, GL_RG_INTEGER,         GL_SHORT,                          GL_RG16I,                  WriteColor<R16G16S, GLint>        );
     93     InsertFormatMapping(&map, GL_RG_INTEGER,         GL_UNSIGNED_INT,                   GL_RG32UI,                 WriteColor<R32G32, GLuint>        );
     94     InsertFormatMapping(&map, GL_RG_INTEGER,         GL_INT,                            GL_RG32I,                  WriteColor<R32G32S, GLint>        );
     95 
     96     InsertFormatMapping(&map, GL_RED,                GL_UNSIGNED_BYTE,                  GL_R8,                     WriteColor<R8, GLfloat>           );
     97     InsertFormatMapping(&map, GL_RED,                GL_BYTE,                           GL_R8_SNORM,               WriteColor<R8S, GLfloat>          );
     98     InsertFormatMapping(&map, GL_RED,                GL_FLOAT,                          GL_R32F,                   WriteColor<R32F, GLfloat>         );
     99     InsertFormatMapping(&map, GL_RED,                GL_HALF_FLOAT,                     GL_R16F,                   WriteColor<R16F, GLfloat>         );
    100     InsertFormatMapping(&map, GL_RED,                GL_HALF_FLOAT_OES,                 GL_R16F,                   WriteColor<R16F, GLfloat>         );
    101 
    102     InsertFormatMapping(&map, GL_RED_INTEGER,        GL_UNSIGNED_BYTE,                  GL_R8UI,                   WriteColor<R8, GLuint>            );
    103     InsertFormatMapping(&map, GL_RED_INTEGER,        GL_BYTE,                           GL_R8I,                    WriteColor<R8S, GLint>            );
    104     InsertFormatMapping(&map, GL_RED_INTEGER,        GL_UNSIGNED_SHORT,                 GL_R16UI,                  WriteColor<R16, GLuint>           );
    105     InsertFormatMapping(&map, GL_RED_INTEGER,        GL_SHORT,                          GL_R16I,                   WriteColor<R16S, GLint>           );
    106     InsertFormatMapping(&map, GL_RED_INTEGER,        GL_UNSIGNED_INT,                   GL_R32UI,                  WriteColor<R32, GLuint>           );
    107     InsertFormatMapping(&map, GL_RED_INTEGER,        GL_INT,                            GL_R32I,                   WriteColor<R32S, GLint>           );
    108 
    109     InsertFormatMapping(&map, GL_LUMINANCE_ALPHA,    GL_UNSIGNED_BYTE,                  GL_LUMINANCE8_ALPHA8_EXT,  WriteColor<L8A8, GLfloat>         );
    110     InsertFormatMapping(&map, GL_LUMINANCE,          GL_UNSIGNED_BYTE,                  GL_LUMINANCE8_EXT,         WriteColor<L8, GLfloat>           );
    111     InsertFormatMapping(&map, GL_ALPHA,              GL_UNSIGNED_BYTE,                  GL_ALPHA8_EXT,             WriteColor<A8, GLfloat>           );
    112     InsertFormatMapping(&map, GL_LUMINANCE_ALPHA,    GL_FLOAT,                          GL_LUMINANCE_ALPHA32F_EXT, WriteColor<L32A32F, GLfloat>      );
    113     InsertFormatMapping(&map, GL_LUMINANCE,          GL_FLOAT,                          GL_LUMINANCE32F_EXT,       WriteColor<L32F, GLfloat>         );
    114     InsertFormatMapping(&map, GL_ALPHA,              GL_FLOAT,                          GL_ALPHA32F_EXT,           WriteColor<A32F, GLfloat>         );
    115     InsertFormatMapping(&map, GL_LUMINANCE_ALPHA,    GL_HALF_FLOAT,                     GL_LUMINANCE_ALPHA16F_EXT, WriteColor<L16A16F, GLfloat>      );
    116     InsertFormatMapping(&map, GL_LUMINANCE_ALPHA,    GL_HALF_FLOAT_OES,                 GL_LUMINANCE_ALPHA16F_EXT, WriteColor<L16A16F, GLfloat>      );
    117     InsertFormatMapping(&map, GL_LUMINANCE,          GL_HALF_FLOAT,                     GL_LUMINANCE16F_EXT,       WriteColor<L16F, GLfloat>         );
    118     InsertFormatMapping(&map, GL_LUMINANCE,          GL_HALF_FLOAT_OES,                 GL_LUMINANCE16F_EXT,       WriteColor<L16F, GLfloat>         );
    119     InsertFormatMapping(&map, GL_ALPHA,              GL_HALF_FLOAT,                     GL_ALPHA16F_EXT,           WriteColor<A16F, GLfloat>         );
    120     InsertFormatMapping(&map, GL_ALPHA,              GL_HALF_FLOAT_OES,                 GL_ALPHA16F_EXT,           WriteColor<A16F, GLfloat>         );
    121 
    122     InsertFormatMapping(&map, GL_BGRA_EXT,           GL_UNSIGNED_BYTE,                  GL_BGRA8_EXT,              WriteColor<B8G8R8A8, GLfloat>     );
    123     InsertFormatMapping(&map, GL_BGRA_EXT,           GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_BGRA4_ANGLEX,           WriteColor<B4G4R4A4, GLfloat>     );
    124     InsertFormatMapping(&map, GL_BGRA_EXT,           GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_BGR5_A1_ANGLEX,         WriteColor<B5G5R5A1, GLfloat>     );
    125 
    126     InsertFormatMapping(&map, GL_SRGB_EXT,           GL_UNSIGNED_BYTE,                  GL_SRGB8,                  WriteColor<R8G8B8, GLfloat>       );
    127     InsertFormatMapping(&map, GL_SRGB_ALPHA_EXT,     GL_UNSIGNED_BYTE,                  GL_SRGB8_ALPHA8,           WriteColor<R8G8B8A8, GLfloat>     );
    128 
    129     InsertFormatMapping(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,    GL_UNSIGNED_BYTE,     GL_COMPRESSED_RGB_S3TC_DXT1_EXT,    NULL                     );
    130     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,   GL_UNSIGNED_BYTE,     GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,   NULL                     );
    131     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE,     GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, NULL                     );
    132     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE,     GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, NULL                     );
    133 
    134     InsertFormatMapping(&map, GL_DEPTH_COMPONENT,    GL_UNSIGNED_SHORT,                 GL_DEPTH_COMPONENT16,      NULL                              );
    135     InsertFormatMapping(&map, GL_DEPTH_COMPONENT,    GL_UNSIGNED_INT,                   GL_DEPTH_COMPONENT32_OES,  NULL                              );
    136     InsertFormatMapping(&map, GL_DEPTH_COMPONENT,    GL_FLOAT,                          GL_DEPTH_COMPONENT32F,     NULL                              );
    137 
    138     InsertFormatMapping(&map, GL_STENCIL,            GL_UNSIGNED_BYTE,                  GL_STENCIL_INDEX8,         NULL                              );
    139 
    140     InsertFormatMapping(&map, GL_DEPTH_STENCIL,      GL_UNSIGNED_INT_24_8,              GL_DEPTH24_STENCIL8,       NULL                              );
    141     InsertFormatMapping(&map, GL_DEPTH_STENCIL,      GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_DEPTH32F_STENCIL8,      NULL                              );
    142 
    143     return map;
    144 }
    145 
    146 Type::Type()
    147     : bytes(0),
    148       specialInterpretation(false)
    149 {
    150 }
    151 
    152 // Map of sizes of input types
    153 typedef std::pair<GLenum, Type> TypeInfoPair;
    154 typedef std::map<GLenum, Type> TypeInfoMap;
    155 
    156 static inline void InsertTypeInfo(TypeInfoMap *map, GLenum type, GLuint bytes, bool specialInterpretation)
    157 {
    158     Type info;
    159     info.bytes = bytes;
    160     info.specialInterpretation = specialInterpretation;
    161 
    162     map->insert(std::make_pair(type, info));
    163 }
    164 
    165 bool operator<(const Type& a, const Type& b)
    166 {
    167     return memcmp(&a, &b, sizeof(Type)) < 0;
    168 }
    169 
    170 static TypeInfoMap BuildTypeInfoMap()
    171 {
    172     TypeInfoMap map;
    173 
    174     InsertTypeInfo(&map, GL_UNSIGNED_BYTE,                  1, false);
    175     InsertTypeInfo(&map, GL_BYTE,                           1, false);
    176     InsertTypeInfo(&map, GL_UNSIGNED_SHORT,                 2, false);
    177     InsertTypeInfo(&map, GL_SHORT,                          2, false);
    178     InsertTypeInfo(&map, GL_UNSIGNED_INT,                   4, false);
    179     InsertTypeInfo(&map, GL_INT,                            4, false);
    180     InsertTypeInfo(&map, GL_HALF_FLOAT,                     2, false);
    181     InsertTypeInfo(&map, GL_HALF_FLOAT_OES,                 2, false);
    182     InsertTypeInfo(&map, GL_FLOAT,                          4, false);
    183     InsertTypeInfo(&map, GL_UNSIGNED_SHORT_5_6_5,           2, true );
    184     InsertTypeInfo(&map, GL_UNSIGNED_SHORT_4_4_4_4,         2, true );
    185     InsertTypeInfo(&map, GL_UNSIGNED_SHORT_5_5_5_1,         2, true );
    186     InsertTypeInfo(&map, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, 2, true );
    187     InsertTypeInfo(&map, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, 2, true );
    188     InsertTypeInfo(&map, GL_UNSIGNED_INT_2_10_10_10_REV,    4, true );
    189     InsertTypeInfo(&map, GL_UNSIGNED_INT_24_8,              4, true );
    190     InsertTypeInfo(&map, GL_UNSIGNED_INT_10F_11F_11F_REV,   4, true );
    191     InsertTypeInfo(&map, GL_UNSIGNED_INT_5_9_9_9_REV,       4, true );
    192     InsertTypeInfo(&map, GL_UNSIGNED_INT_24_8_OES,          4, true );
    193     InsertTypeInfo(&map, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8, true );
    194 
    195     return map;
    196 }
    197 
    198 // Information about internal formats
    199 static bool AlwaysSupported(GLuint, const Extensions &)
    200 {
    201     return true;
    202 }
    203 
    204 static bool UnimplementedSupport(GLuint, const Extensions &)
    205 {
    206     return false;
    207 }
    208 
    209 static bool NeverSupported(GLuint, const Extensions &)
    210 {
    211     return false;
    212 }
    213 
    214 template <GLuint minCoreGLVersion>
    215 static bool RequireESVersion(GLuint clientVersion, const Extensions &)
    216 {
    217     return clientVersion >= minCoreGLVersion;
    218 }
    219 
    220 // Pointer to a boolean memeber of the Extensions struct
    221 typedef bool(Extensions::*ExtensionBool);
    222 
    223 // Check support for a single extension
    224 template <ExtensionBool bool1>
    225 static bool RequireExtension(GLuint, const Extensions & extensions)
    226 {
    227     return extensions.*bool1;
    228 }
    229 
    230 // Check for a minimum client version or a single extension
    231 template <GLuint minCoreGLVersion, ExtensionBool bool1>
    232 static bool RequireESVersionOrExtension(GLuint clientVersion, const Extensions &extensions)
    233 {
    234     return clientVersion >= minCoreGLVersion || extensions.*bool1;
    235 }
    236 
    237 // Check for a minimum client version or two extensions
    238 template <GLuint minCoreGLVersion, ExtensionBool bool1, ExtensionBool bool2>
    239 static bool RequireESVersionOrExtensions(GLuint clientVersion, const Extensions &extensions)
    240 {
    241     return clientVersion >= minCoreGLVersion || (extensions.*bool1 || extensions.*bool2);
    242 }
    243 
    244 // Check support for two extensions
    245 template <ExtensionBool bool1, ExtensionBool bool2>
    246 static bool RequireExtensions(GLuint, const Extensions &extensions)
    247 {
    248     return extensions.*bool1 || extensions.*bool2;
    249 }
    250 
    251 InternalFormat::InternalFormat()
    252     : redBits(0),
    253       greenBits(0),
    254       blueBits(0),
    255       luminanceBits(0),
    256       alphaBits(0),
    257       sharedBits(0),
    258       depthBits(0),
    259       stencilBits(0),
    260       pixelBytes(0),
    261       componentCount(0),
    262       compressedBlockWidth(0),
    263       compressedBlockHeight(0),
    264       format(GL_NONE),
    265       type(GL_NONE),
    266       componentType(GL_NONE),
    267       colorEncoding(GL_NONE),
    268       compressed(false),
    269       textureSupport(NeverSupported),
    270       renderSupport(NeverSupported),
    271       filterSupport(NeverSupported)
    272 {
    273 }
    274 
    275 static InternalFormat UnsizedFormat(GLenum format, InternalFormat::SupportCheckFunction textureSupport,
    276                                     InternalFormat::SupportCheckFunction renderSupport,
    277                                     InternalFormat::SupportCheckFunction filterSupport)
    278 {
    279     InternalFormat formatInfo;
    280     formatInfo.format = format;
    281     formatInfo.textureSupport = textureSupport;
    282     formatInfo.renderSupport = renderSupport;
    283     formatInfo.filterSupport = filterSupport;
    284     return formatInfo;
    285 }
    286 
    287 static InternalFormat RGBAFormat(GLuint red, GLuint green, GLuint blue, GLuint alpha, GLuint shared,
    288                                  GLenum format, GLenum type, GLenum componentType, bool srgb,
    289                                  InternalFormat::SupportCheckFunction textureSupport,
    290                                  InternalFormat::SupportCheckFunction renderSupport,
    291                                  InternalFormat::SupportCheckFunction filterSupport)
    292 {
    293     InternalFormat formatInfo;
    294     formatInfo.redBits = red;
    295     formatInfo.greenBits = green;
    296     formatInfo.blueBits = blue;
    297     formatInfo.alphaBits = alpha;
    298     formatInfo.sharedBits = shared;
    299     formatInfo.pixelBytes = (red + green + blue + alpha + shared) / 8;
    300     formatInfo.componentCount = ((red > 0) ? 1 : 0) + ((green > 0) ? 1 : 0) + ((blue > 0) ? 1 : 0) + ((alpha > 0) ? 1 : 0);
    301     formatInfo.format = format;
    302     formatInfo.type = type;
    303     formatInfo.componentType = componentType;
    304     formatInfo.colorEncoding = (srgb ? GL_SRGB : GL_LINEAR);
    305     formatInfo.textureSupport = textureSupport;
    306     formatInfo.renderSupport = renderSupport;
    307     formatInfo.filterSupport = filterSupport;
    308     return formatInfo;
    309 }
    310 
    311 static InternalFormat LUMAFormat(GLuint luminance, GLuint alpha, GLenum format, GLenum type, GLenum componentType,
    312                                  InternalFormat::SupportCheckFunction textureSupport,
    313                                  InternalFormat::SupportCheckFunction renderSupport,
    314                                  InternalFormat::SupportCheckFunction filterSupport)
    315 {
    316     InternalFormat formatInfo;
    317     formatInfo.luminanceBits = luminance;
    318     formatInfo.alphaBits = alpha;
    319     formatInfo.pixelBytes = (luminance + alpha) / 8;
    320     formatInfo.componentCount = ((luminance > 0) ? 1 : 0) + ((alpha > 0) ? 1 : 0);
    321     formatInfo.format = format;
    322     formatInfo.type = type;
    323     formatInfo.componentType = componentType;
    324     formatInfo.colorEncoding = GL_LINEAR;
    325     formatInfo.textureSupport = textureSupport;
    326     formatInfo.renderSupport = renderSupport;
    327     formatInfo.filterSupport = filterSupport;
    328     return formatInfo;
    329 }
    330 
    331 static InternalFormat DepthStencilFormat(GLuint depthBits, GLuint stencilBits, GLuint unusedBits, GLenum format,
    332                                          GLenum type, GLenum componentType, InternalFormat::SupportCheckFunction textureSupport,
    333                                          InternalFormat::SupportCheckFunction renderSupport,
    334                                          InternalFormat::SupportCheckFunction filterSupport)
    335 {
    336     InternalFormat formatInfo;
    337     formatInfo.depthBits = depthBits;
    338     formatInfo.stencilBits = stencilBits;
    339     formatInfo.pixelBytes = (depthBits + stencilBits + unusedBits) / 8;
    340     formatInfo.componentCount = ((depthBits > 0) ? 1 : 0) + ((stencilBits > 0) ? 1 : 0);
    341     formatInfo.format = format;
    342     formatInfo.type = type;
    343     formatInfo.componentType = componentType;
    344     formatInfo.colorEncoding = GL_LINEAR;
    345     formatInfo.textureSupport = textureSupport;
    346     formatInfo.renderSupport = renderSupport;
    347     formatInfo.filterSupport = filterSupport;
    348     return formatInfo;
    349 }
    350 
    351 static InternalFormat CompressedFormat(GLuint compressedBlockWidth, GLuint compressedBlockHeight, GLuint compressedBlockSize,
    352                                        GLuint componentCount, GLenum format, GLenum type, bool srgb,
    353                                        InternalFormat::SupportCheckFunction textureSupport,
    354                                        InternalFormat::SupportCheckFunction renderSupport,
    355                                        InternalFormat::SupportCheckFunction filterSupport)
    356 {
    357     InternalFormat formatInfo;
    358     formatInfo.compressedBlockWidth = compressedBlockWidth;
    359     formatInfo.compressedBlockHeight = compressedBlockHeight;
    360     formatInfo.pixelBytes = compressedBlockSize / 8;
    361     formatInfo.componentCount = componentCount;
    362     formatInfo.format = format;
    363     formatInfo.type = type;
    364     formatInfo.componentType = GL_UNSIGNED_NORMALIZED;
    365     formatInfo.colorEncoding = (srgb ? GL_SRGB : GL_LINEAR);
    366     formatInfo.compressed = true;
    367     formatInfo.textureSupport = textureSupport;
    368     formatInfo.renderSupport = renderSupport;
    369     formatInfo.filterSupport = filterSupport;
    370     return formatInfo;
    371 }
    372 
    373 typedef std::pair<GLenum, InternalFormat> InternalFormatInfoPair;
    374 typedef std::map<GLenum, InternalFormat> InternalFormatInfoMap;
    375 
    376 static InternalFormatInfoMap BuildInternalFormatInfoMap()
    377 {
    378     InternalFormatInfoMap map;
    379 
    380     // From ES 3.0.1 spec, table 3.12
    381     map.insert(InternalFormatInfoPair(GL_NONE,              InternalFormat()));
    382 
    383     //                               | Internal format     |          | R | G | B | A |S | Format         | Type                           | Component type        | SRGB | Texture supported                                    | Renderable      | Filterable    |
    384     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)));
    385     map.insert(InternalFormatInfoPair(GL_R8_SNORM,          RGBAFormat( 8,  0,  0,  0, 0, GL_RED,          GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, RequireESVersion<3>,                                    NeverSupported,  AlwaysSupported)));
    386     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)));
    387     map.insert(InternalFormatInfoPair(GL_RG8_SNORM,         RGBAFormat( 8,  8,  0,  0, 0, GL_RG,           GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, RequireESVersion<3>,                                    NeverSupported,  AlwaysSupported)));
    388     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)));
    389     map.insert(InternalFormatInfoPair(GL_RGB8_SNORM,        RGBAFormat( 8,  8,  8,  0, 0, GL_RGB,          GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, RequireESVersion<3>,                                    NeverSupported,  AlwaysSupported)));
    390     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)));
    391     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)));
    392     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)));
    393     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)));
    394     map.insert(InternalFormatInfoPair(GL_RGBA8_SNORM,       RGBAFormat( 8,  8,  8,  8, 0, GL_RGBA,         GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, RequireESVersion<3>,                                    NeverSupported,  AlwaysSupported)));
    395     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)));
    396     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)));
    397     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)));
    398     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)));
    399     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)));
    400     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)));
    401     map.insert(InternalFormatInfoPair(GL_R8I,               RGBAFormat( 8,  0,  0,  0, 0, GL_RED_INTEGER,  GL_BYTE,                         GL_INT,                 false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
    402     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)));
    403     map.insert(InternalFormatInfoPair(GL_R16I,              RGBAFormat(16,  0,  0,  0, 0, GL_RED_INTEGER,  GL_SHORT,                        GL_INT,                 false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
    404     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)));
    405     map.insert(InternalFormatInfoPair(GL_R32I,              RGBAFormat(32,  0,  0,  0, 0, GL_RED_INTEGER,  GL_INT,                          GL_INT,                 false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
    406     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)));
    407     map.insert(InternalFormatInfoPair(GL_RG8I,              RGBAFormat( 8,  8,  0,  0, 0, GL_RG_INTEGER,   GL_BYTE,                         GL_INT,                 false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
    408     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)));
    409     map.insert(InternalFormatInfoPair(GL_RG16I,             RGBAFormat(16, 16,  0,  0, 0, GL_RG_INTEGER,   GL_SHORT,                        GL_INT,                 false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
    410     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)));
    411     map.insert(InternalFormatInfoPair(GL_RG32I,             RGBAFormat(32, 32,  0,  0, 0, GL_RG_INTEGER,   GL_INT,                          GL_INT,                 false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
    412     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)));
    413     map.insert(InternalFormatInfoPair(GL_RGB8I,             RGBAFormat( 8,  8,  8,  0, 0, GL_RGB_INTEGER,  GL_BYTE,                         GL_INT,                 false, RequireESVersion<3>,                                    NeverSupported,   NeverSupported)));
    414     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)));
    415     map.insert(InternalFormatInfoPair(GL_RGB16I,            RGBAFormat(16, 16, 16,  0, 0, GL_RGB_INTEGER,  GL_SHORT,                        GL_INT,                 false, RequireESVersion<3>,                                    NeverSupported,   NeverSupported)));
    416     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)));
    417     map.insert(InternalFormatInfoPair(GL_RGB32I,            RGBAFormat(32, 32, 32,  0, 0, GL_RGB_INTEGER,  GL_INT,                          GL_INT,                 false, RequireESVersion<3>,                                    NeverSupported,   NeverSupported)));
    418     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)));
    419     map.insert(InternalFormatInfoPair(GL_RGBA8I,            RGBAFormat( 8,  8,  8,  8, 0, GL_RGBA_INTEGER, GL_BYTE,                         GL_INT,                 false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
    420     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)));
    421     map.insert(InternalFormatInfoPair(GL_RGBA16I,           RGBAFormat(16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_SHORT,                        GL_INT,                 false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
    422     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)));
    423     map.insert(InternalFormatInfoPair(GL_RGBA32I,           RGBAFormat(32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_INT,                          GL_INT,                 false, RequireESVersion<3>,                                    AlwaysSupported,  NeverSupported)));
    424     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)));
    425 
    426     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)));
    427     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)));
    428     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)));
    429 
    430     // Floating point renderability and filtering is provided by OES_texture_float and OES_texture_half_float
    431     //                               | Internal format     |          | D |S | Format             | Type                           | Comp   | SRGB |  Texture supported                                                                     | Renderable     | Filterable                                          |
    432     //                               |                     |          |   |  |                    |                                | type   |      |                                                                                        |                |                                                     |
    433     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>)));
    434     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>)));
    435     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>)));
    436     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>)));
    437     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>    )));
    438     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>    )));
    439     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>    )));
    440     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>    )));
    441 
    442     // Depth stencil formats
    443     //                               | Internal format         |                  | D |S | X | Format            | Type                             | Component type        | Supported     |
    444     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>)));
    445     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>)));
    446     map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32F,    DepthStencilFormat(32, 0,  0, GL_DEPTH_COMPONENT, GL_FLOAT,                          GL_FLOAT,               RequireESVersion<3>,                                                    AlwaysSupported, RequireESVersionOrExtension<3, &Extensions::depthTextures>)));
    447     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                                           )));
    448     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                                           )));
    449     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                                           )));
    450     map.insert(InternalFormatInfoPair(GL_STENCIL_INDEX8,        DepthStencilFormat( 0, 8,  0, GL_DEPTH_STENCIL,   GL_UNSIGNED_BYTE,                  GL_UNSIGNED_INT,        RequireESVersion<2>,                                                    AlwaysSupported, NeverSupported                                            )));
    451 
    452     // Luminance alpha formats
    453     //                               | Internal format          |          | L | A | Format            | Type            | Component type        | Supported                                                                    | Renderable    | Filterable    |
    454     map.insert(InternalFormatInfoPair(GL_ALPHA8_EXT,             LUMAFormat( 0,  8, GL_ALPHA,           GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExtension<&Extensions::textureStorage>,                                 NeverSupported, AlwaysSupported)));
    455     map.insert(InternalFormatInfoPair(GL_LUMINANCE8_EXT,         LUMAFormat( 8,  0, GL_LUMINANCE,       GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExtension<&Extensions::textureStorage>,                                 NeverSupported, AlwaysSupported)));
    456     map.insert(InternalFormatInfoPair(GL_ALPHA32F_EXT,           LUMAFormat( 0, 32, GL_ALPHA,           GL_FLOAT,         GL_FLOAT,               RequireExtensions<&Extensions::textureStorage, &Extensions::textureFloat>,     NeverSupported, AlwaysSupported)));
    457     map.insert(InternalFormatInfoPair(GL_LUMINANCE32F_EXT,       LUMAFormat(32,  0, GL_LUMINANCE,       GL_FLOAT,         GL_FLOAT,               RequireExtensions<&Extensions::textureStorage, &Extensions::textureFloat>,     NeverSupported, AlwaysSupported)));
    458     map.insert(InternalFormatInfoPair(GL_ALPHA16F_EXT,           LUMAFormat( 0, 16, GL_ALPHA,           GL_HALF_FLOAT,    GL_FLOAT,               RequireExtensions<&Extensions::textureStorage, &Extensions::textureHalfFloat>, NeverSupported, AlwaysSupported)));
    459     map.insert(InternalFormatInfoPair(GL_LUMINANCE16F_EXT,       LUMAFormat(16,  0, GL_LUMINANCE,       GL_HALF_FLOAT,    GL_FLOAT,               RequireExtensions<&Extensions::textureStorage, &Extensions::textureHalfFloat>, NeverSupported, AlwaysSupported)));
    460     map.insert(InternalFormatInfoPair(GL_LUMINANCE8_ALPHA8_EXT,  LUMAFormat( 8,  8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExtension<&Extensions::textureStorage>,                                 NeverSupported, AlwaysSupported)));
    461     map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA32F_EXT, LUMAFormat(32, 32, GL_LUMINANCE_ALPHA, GL_FLOAT,         GL_FLOAT,               RequireExtensions<&Extensions::textureStorage, &Extensions::textureFloat>,     NeverSupported, AlwaysSupported)));
    462     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)));
    463 
    464     // Unsized formats
    465     //                               | Internal format   |             | Format            | Supported                                                      | Renderable     | Filterable     |
    466     map.insert(InternalFormatInfoPair(GL_ALPHA,           UnsizedFormat(GL_ALPHA,           RequireESVersion<2>,                                             NeverSupported,  AlwaysSupported)));
    467     map.insert(InternalFormatInfoPair(GL_LUMINANCE,       UnsizedFormat(GL_LUMINANCE,       RequireESVersion<2>,                                             NeverSupported,  AlwaysSupported)));
    468     map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA, UnsizedFormat(GL_LUMINANCE_ALPHA, RequireESVersion<2>,                                             NeverSupported,  AlwaysSupported)));
    469     map.insert(InternalFormatInfoPair(GL_RED,             UnsizedFormat(GL_RED,             RequireESVersionOrExtension<3, &Extensions::textureRG>,          NeverSupported,  AlwaysSupported)));
    470     map.insert(InternalFormatInfoPair(GL_RG,              UnsizedFormat(GL_RG,              RequireESVersionOrExtension<3, &Extensions::textureRG>,          NeverSupported,  AlwaysSupported)));
    471     map.insert(InternalFormatInfoPair(GL_RGB,             UnsizedFormat(GL_RGB,             RequireESVersion<2>,                                             AlwaysSupported, AlwaysSupported)));
    472     map.insert(InternalFormatInfoPair(GL_RGBA,            UnsizedFormat(GL_RGBA,            RequireESVersion<2>,                                             AlwaysSupported, AlwaysSupported)));
    473     map.insert(InternalFormatInfoPair(GL_RED_INTEGER,     UnsizedFormat(GL_RED_INTEGER,     RequireESVersion<3>,                                             NeverSupported,  NeverSupported )));
    474     map.insert(InternalFormatInfoPair(GL_RG_INTEGER,      UnsizedFormat(GL_RG_INTEGER,      RequireESVersion<3>,                                             NeverSupported,  NeverSupported )));
    475     map.insert(InternalFormatInfoPair(GL_RGB_INTEGER,     UnsizedFormat(GL_RGB_INTEGER,     RequireESVersion<3>,                                             NeverSupported,  NeverSupported )));
    476     map.insert(InternalFormatInfoPair(GL_RGBA_INTEGER,    UnsizedFormat(GL_RGBA_INTEGER,    RequireESVersion<3>,                                             NeverSupported,  NeverSupported )));
    477     map.insert(InternalFormatInfoPair(GL_BGRA_EXT,        UnsizedFormat(GL_BGRA_EXT,        RequireExtension<&Extensions::textureFormatBGRA8888>,            AlwaysSupported, AlwaysSupported)));
    478     map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT, UnsizedFormat(GL_DEPTH_COMPONENT, RequireESVersion<2>,                                             AlwaysSupported, AlwaysSupported)));
    479     map.insert(InternalFormatInfoPair(GL_DEPTH_STENCIL,   UnsizedFormat(GL_DEPTH_STENCIL,   RequireESVersionOrExtension<3, &Extensions::packedDepthStencil>, AlwaysSupported, AlwaysSupported)));
    480     map.insert(InternalFormatInfoPair(GL_SRGB_EXT,        UnsizedFormat(GL_RGB,             RequireESVersionOrExtension<3, &Extensions::sRGB>,               NeverSupported,  AlwaysSupported)));
    481     map.insert(InternalFormatInfoPair(GL_SRGB_ALPHA_EXT,  UnsizedFormat(GL_RGBA,            RequireESVersionOrExtension<3, &Extensions::sRGB>,               AlwaysSupported, AlwaysSupported)));
    482 
    483     // Compressed formats, From ES 3.0.1 spec, table 3.16
    484     //                               | Internal format                             |                |W |H | BS |CC| Format                                      | Type            | SRGB | Supported          | Renderable           | Filterable         |
    485     map.insert(InternalFormatInfoPair(GL_COMPRESSED_R11_EAC,                        CompressedFormat(4, 4,  64, 1, GL_COMPRESSED_R11_EAC,                        GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
    486     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)));
    487     map.insert(InternalFormatInfoPair(GL_COMPRESSED_RG11_EAC,                       CompressedFormat(4, 4, 128, 2, GL_COMPRESSED_RG11_EAC,                       GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
    488     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)));
    489     map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB8_ETC2,                      CompressedFormat(4, 4,  64, 3, GL_COMPRESSED_RGB8_ETC2,                      GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
    490     map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ETC2,                     CompressedFormat(4, 4,  64, 3, GL_COMPRESSED_SRGB8_ETC2,                     GL_UNSIGNED_BYTE, true,  UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
    491     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)));
    492     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)));
    493     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)));
    494     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)));
    495 
    496     // From GL_EXT_texture_compression_dxt1
    497     //                               | Internal format                   |                |W |H | BS |CC| Format                            | Type            | SRGB | Supported                                           | Renderable           | Filterable         |
    498     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     )));
    499     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     )));
    500 
    501     // From GL_ANGLE_texture_compression_dxt3
    502     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     )));
    503 
    504     // From GL_ANGLE_texture_compression_dxt5
    505     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     )));
    506 
    507     return map;
    508 }
    509 
    510 static const InternalFormatInfoMap &GetInternalFormatMap()
    511 {
    512     static const InternalFormatInfoMap formatMap = BuildInternalFormatInfoMap();
    513     return formatMap;
    514 }
    515 
    516 static FormatSet BuildAllSizedInternalFormatSet()
    517 {
    518     FormatSet result;
    519 
    520     const InternalFormatInfoMap &formats = GetInternalFormatMap();
    521     for (InternalFormatInfoMap::const_iterator i = formats.begin(); i != formats.end(); i++)
    522     {
    523         if (i->second.pixelBytes > 0)
    524         {
    525             result.insert(i->first);
    526         }
    527     }
    528 
    529     return result;
    530 }
    531 
    532 const FormatType &GetFormatTypeInfo(GLenum format, GLenum type)
    533 {
    534     static const FormatMap formatMap = BuildFormatMap();
    535     FormatMap::const_iterator iter = formatMap.find(FormatTypePair(format, type));
    536     if (iter != formatMap.end())
    537     {
    538         return iter->second;
    539     }
    540     else
    541     {
    542         static const FormatType defaultInfo;
    543         return defaultInfo;
    544     }
    545 }
    546 
    547 const Type &GetTypeInfo(GLenum type)
    548 {
    549     static const TypeInfoMap infoMap = BuildTypeInfoMap();
    550     TypeInfoMap::const_iterator iter = infoMap.find(type);
    551     if (iter != infoMap.end())
    552     {
    553         return iter->second;
    554     }
    555     else
    556     {
    557         static const Type defaultInfo;
    558         return defaultInfo;
    559     }
    560 }
    561 
    562 const InternalFormat &GetInternalFormatInfo(GLenum internalFormat)
    563 {
    564     const InternalFormatInfoMap &formatMap = GetInternalFormatMap();
    565     InternalFormatInfoMap::const_iterator iter = formatMap.find(internalFormat);
    566     if (iter != formatMap.end())
    567     {
    568         return iter->second;
    569     }
    570     else
    571     {
    572         static const InternalFormat defaultInternalFormat;
    573         return defaultInternalFormat;
    574     }
    575 }
    576 
    577 GLuint InternalFormat::computeRowPitch(GLenum type, GLsizei width, GLint alignment) const
    578 {
    579     ASSERT(alignment > 0 && isPow2(alignment));
    580     return rx::roundUp(computeBlockSize(type, width, 1), static_cast<GLuint>(alignment));
    581 }
    582 
    583 GLuint InternalFormat::computeDepthPitch(GLenum type, GLsizei width, GLsizei height, GLint alignment) const
    584 {
    585     return computeRowPitch(type, width, alignment) * height;
    586 }
    587 
    588 GLuint InternalFormat::computeBlockSize(GLenum type, GLsizei width, GLsizei height) const
    589 {
    590     if (compressed)
    591     {
    592         GLsizei numBlocksWide = (width + compressedBlockWidth - 1) / compressedBlockWidth;
    593         GLsizei numBlocksHight = (height + compressedBlockHeight - 1) / compressedBlockHeight;
    594         return (pixelBytes * numBlocksWide * numBlocksHight);
    595     }
    596     else
    597     {
    598         const Type &typeInfo = GetTypeInfo(type);
    599         if (typeInfo.specialInterpretation)
    600         {
    601             return typeInfo.bytes * width * height;
    602         }
    603         else
    604         {
    605             return componentCount * typeInfo.bytes * width * height;
    606         }
    607     }
    608 }
    609 
    610 GLenum GetSizedInternalFormat(GLenum internalFormat, GLenum type)
    611 {
    612     const InternalFormat& formatInfo = GetInternalFormatInfo(internalFormat);
    613     return (formatInfo.pixelBytes > 0) ? internalFormat : GetFormatTypeInfo(internalFormat, type).internalFormat;
    614 }
    615 
    616 const FormatSet &GetAllSizedInternalFormats()
    617 {
    618     static FormatSet formatSet = BuildAllSizedInternalFormatSet();
    619     return formatSet;
    620 }
    621 
    622 }
    623