1#include "precompiled.h"
2//
3// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
4// Use of this source code is governed by a BSD-style license that can be
5// found in the LICENSE file.
6//
7
8// formatutils.cpp: Queries for GL image formats.
9
10#include "common/mathutil.h"
11#include "libGLESv2/formatutils.h"
12#include "libGLESv2/Context.h"
13#include "libGLESv2/Framebuffer.h"
14#include "libGLESv2/renderer/Renderer.h"
15#include "libGLESv2/renderer/imageformats.h"
16#include "libGLESv2/renderer/copyimage.h"
17
18namespace gl
19{
20
21// ES2 requires that format is equal to internal format at all glTex*Image2D entry points and the implementation
22// can decide the true, sized, internal format. The ES2FormatMap determines the internal format for all valid
23// format and type combinations.
24
25struct FormatTypeInfo
26{
27    GLenum mInternalFormat;
28    ColorWriteFunction mColorWriteFunction;
29
30    FormatTypeInfo(GLenum internalFormat, ColorWriteFunction writeFunc)
31        : mInternalFormat(internalFormat), mColorWriteFunction(writeFunc)
32    { }
33};
34
35typedef std::pair<GLenum, GLenum> FormatTypePair;
36typedef std::pair<FormatTypePair, FormatTypeInfo> FormatPair;
37typedef std::map<FormatTypePair, FormatTypeInfo> FormatMap;
38
39// A helper function to insert data into the format map with fewer characters.
40static inline void InsertFormatMapping(FormatMap *map, GLenum format, GLenum type, GLenum internalFormat, ColorWriteFunction writeFunc)
41{
42    map->insert(FormatPair(FormatTypePair(format, type), FormatTypeInfo(internalFormat, writeFunc)));
43}
44
45FormatMap BuildES2FormatMap()
46{
47    FormatMap map;
48
49    using namespace rx;
50
51    //                       | Format                            | Type                             | Internal format                   | Color write function             |
52    InsertFormatMapping(&map, GL_ALPHA,                           GL_UNSIGNED_BYTE,                  GL_ALPHA8_EXT,                      WriteColor<A8, GLfloat>           );
53    InsertFormatMapping(&map, GL_ALPHA,                           GL_FLOAT,                          GL_ALPHA32F_EXT,                    WriteColor<A32F, GLfloat>         );
54    InsertFormatMapping(&map, GL_ALPHA,                           GL_HALF_FLOAT_OES,                 GL_ALPHA16F_EXT,                    WriteColor<A16F, GLfloat>         );
55
56    InsertFormatMapping(&map, GL_LUMINANCE,                       GL_UNSIGNED_BYTE,                  GL_LUMINANCE8_EXT,                  WriteColor<L8, GLfloat>           );
57    InsertFormatMapping(&map, GL_LUMINANCE,                       GL_FLOAT,                          GL_LUMINANCE32F_EXT,                WriteColor<L32F, GLfloat>         );
58    InsertFormatMapping(&map, GL_LUMINANCE,                       GL_HALF_FLOAT_OES,                 GL_LUMINANCE16F_EXT,                WriteColor<L16F, GLfloat>         );
59
60    InsertFormatMapping(&map, GL_LUMINANCE_ALPHA,                 GL_UNSIGNED_BYTE,                  GL_LUMINANCE8_ALPHA8_EXT,           WriteColor<L8A8, GLfloat>         );
61    InsertFormatMapping(&map, GL_LUMINANCE_ALPHA,                 GL_FLOAT,                          GL_LUMINANCE_ALPHA32F_EXT,          WriteColor<L32A32F, GLfloat>      );
62    InsertFormatMapping(&map, GL_LUMINANCE_ALPHA,                 GL_HALF_FLOAT_OES,                 GL_LUMINANCE_ALPHA16F_EXT,          WriteColor<L16A16F, GLfloat>      );
63
64    InsertFormatMapping(&map, GL_RED,                             GL_UNSIGNED_BYTE,                  GL_R8_EXT,                          WriteColor<R8, GLfloat>           );
65    InsertFormatMapping(&map, GL_RED,                             GL_FLOAT,                          GL_R32F_EXT,                        WriteColor<R32F, GLfloat>         );
66    InsertFormatMapping(&map, GL_RED,                             GL_HALF_FLOAT_OES,                 GL_R16F_EXT,                        WriteColor<R16F, GLfloat>         );
67
68    InsertFormatMapping(&map, GL_RG,                              GL_UNSIGNED_BYTE,                  GL_RG8_EXT,                         WriteColor<R8G8, GLfloat>         );
69    InsertFormatMapping(&map, GL_RG,                              GL_FLOAT,                          GL_RG32F_EXT,                       WriteColor<R32G32F, GLfloat>      );
70    InsertFormatMapping(&map, GL_RG,                              GL_HALF_FLOAT_OES,                 GL_RG16F_EXT,                       WriteColor<R16G16F, GLfloat>      );
71
72    InsertFormatMapping(&map, GL_RGB,                             GL_UNSIGNED_BYTE,                  GL_RGB8_OES,                        WriteColor<R8G8B8, GLfloat>       );
73    InsertFormatMapping(&map, GL_RGB,                             GL_UNSIGNED_SHORT_5_6_5,           GL_RGB565,                          WriteColor<R5G6B5, GLfloat>       );
74    InsertFormatMapping(&map, GL_RGB,                             GL_FLOAT,                          GL_RGB32F_EXT,                      WriteColor<R32G32B32F, GLfloat>   );
75    InsertFormatMapping(&map, GL_RGB,                             GL_HALF_FLOAT_OES,                 GL_RGB16F_EXT,                      WriteColor<R16G16B16F, GLfloat>   );
76
77    InsertFormatMapping(&map, GL_RGBA,                            GL_UNSIGNED_BYTE,                  GL_RGBA8_OES,                       WriteColor<R8G8B8A8, GLfloat>     );
78    InsertFormatMapping(&map, GL_RGBA,                            GL_UNSIGNED_SHORT_4_4_4_4,         GL_RGBA4,                           WriteColor<R4G4B4A4, GLfloat>     );
79    InsertFormatMapping(&map, GL_RGBA,                            GL_UNSIGNED_SHORT_5_5_5_1,         GL_RGB5_A1,                         WriteColor<R5G5B5A1, GLfloat>     );
80    InsertFormatMapping(&map, GL_RGBA,                            GL_FLOAT,                          GL_RGBA32F_EXT,                     WriteColor<R32G32B32A32F, GLfloat>);
81    InsertFormatMapping(&map, GL_RGBA,                            GL_HALF_FLOAT_OES,                 GL_RGBA16F_EXT,                     WriteColor<R16G16B16A16F, GLfloat>);
82
83    InsertFormatMapping(&map, GL_BGRA_EXT,                        GL_UNSIGNED_BYTE,                  GL_BGRA8_EXT,                       WriteColor<B8G8R8A8, GLfloat>     );
84    InsertFormatMapping(&map, GL_BGRA_EXT,                        GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_BGRA4_ANGLEX,                    WriteColor<B4G4R4A4, GLfloat>     );
85    InsertFormatMapping(&map, GL_BGRA_EXT,                        GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_BGR5_A1_ANGLEX,                  WriteColor<B5G5R5A1, GLfloat>     );
86
87    InsertFormatMapping(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,    GL_UNSIGNED_BYTE,                  GL_COMPRESSED_RGB_S3TC_DXT1_EXT,    NULL                              );
88    InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,   GL_UNSIGNED_BYTE,                  GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,   NULL                              );
89    InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE,                  GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, NULL                              );
90    InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE,                  GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, NULL                              );
91
92    InsertFormatMapping(&map, GL_DEPTH_COMPONENT,                 GL_UNSIGNED_SHORT,                 GL_DEPTH_COMPONENT16,               NULL                              );
93    InsertFormatMapping(&map, GL_DEPTH_COMPONENT,                 GL_UNSIGNED_INT,                   GL_DEPTH_COMPONENT32_OES,           NULL                              );
94
95    InsertFormatMapping(&map, GL_DEPTH_STENCIL_OES,               GL_UNSIGNED_INT_24_8_OES,          GL_DEPTH24_STENCIL8_OES,            NULL                              );
96
97    return map;
98}
99
100FormatMap BuildES3FormatMap()
101{
102    FormatMap map;
103
104    using namespace rx;
105
106    //                       | Format               | Type                             | Internal format          | Color write function             |
107    InsertFormatMapping(&map, GL_RGBA,               GL_UNSIGNED_BYTE,                  GL_RGBA8,                  WriteColor<R8G8B8A8, GLfloat>     );
108    InsertFormatMapping(&map, GL_RGBA,               GL_BYTE,                           GL_RGBA8_SNORM,            WriteColor<R8G8B8A8S, GLfloat>    );
109    InsertFormatMapping(&map, GL_RGBA,               GL_UNSIGNED_SHORT_4_4_4_4,         GL_RGBA4,                  WriteColor<R4G4B4A4, GLfloat>     );
110    InsertFormatMapping(&map, GL_RGBA,               GL_UNSIGNED_SHORT_5_5_5_1,         GL_RGB5_A1,                WriteColor<R5G5B5A1, GLfloat>     );
111    InsertFormatMapping(&map, GL_RGBA,               GL_UNSIGNED_INT_2_10_10_10_REV,    GL_RGB10_A2,               WriteColor<R10G10B10A2, GLfloat>  );
112    InsertFormatMapping(&map, GL_RGBA,               GL_FLOAT,                          GL_RGBA32F,                WriteColor<R32G32B32A32F, GLfloat>);
113    InsertFormatMapping(&map, GL_RGBA,               GL_HALF_FLOAT,                     GL_RGBA16F,                WriteColor<R16G16B16A16F, GLfloat>);
114
115    InsertFormatMapping(&map, GL_RGBA_INTEGER,       GL_UNSIGNED_BYTE,                  GL_RGBA8UI,                WriteColor<R8G8B8A8, GLuint>      );
116    InsertFormatMapping(&map, GL_RGBA_INTEGER,       GL_BYTE,                           GL_RGBA8I,                 WriteColor<R8G8B8A8S, GLint>      );
117    InsertFormatMapping(&map, GL_RGBA_INTEGER,       GL_UNSIGNED_SHORT,                 GL_RGBA16UI,               WriteColor<R16G16B16A16, GLuint>  );
118    InsertFormatMapping(&map, GL_RGBA_INTEGER,       GL_SHORT,                          GL_RGBA16I,                WriteColor<R16G16B16A16S, GLint>  );
119    InsertFormatMapping(&map, GL_RGBA_INTEGER,       GL_UNSIGNED_INT,                   GL_RGBA32UI,               WriteColor<R32G32B32A32, GLuint>  );
120    InsertFormatMapping(&map, GL_RGBA_INTEGER,       GL_INT,                            GL_RGBA32I,                WriteColor<R32G32B32A32S, GLint>  );
121    InsertFormatMapping(&map, GL_RGBA_INTEGER,       GL_UNSIGNED_INT_2_10_10_10_REV,    GL_RGB10_A2UI,             WriteColor<R10G10B10A2, GLuint>   );
122
123    InsertFormatMapping(&map, GL_RGB,                GL_UNSIGNED_BYTE,                  GL_RGB8,                   WriteColor<R8G8B8, GLfloat>       );
124    InsertFormatMapping(&map, GL_RGB,                GL_BYTE,                           GL_RGB8_SNORM,             WriteColor<R8G8B8S, GLfloat>      );
125    InsertFormatMapping(&map, GL_RGB,                GL_UNSIGNED_SHORT_5_6_5,           GL_RGB565,                 WriteColor<R5G6B5, GLfloat>       );
126    InsertFormatMapping(&map, GL_RGB,                GL_UNSIGNED_INT_10F_11F_11F_REV,   GL_R11F_G11F_B10F,         WriteColor<R11G11B10F, GLfloat>   );
127    InsertFormatMapping(&map, GL_RGB,                GL_UNSIGNED_INT_5_9_9_9_REV,       GL_RGB9_E5,                WriteColor<R9G9B9E5, GLfloat>     );
128    InsertFormatMapping(&map, GL_RGB,                GL_FLOAT,                          GL_RGB32F,                 WriteColor<R32G32B32F, GLfloat>   );
129    InsertFormatMapping(&map, GL_RGB,                GL_HALF_FLOAT,                     GL_RGB16F,                 WriteColor<R16G16B16F, GLfloat>   );
130
131    InsertFormatMapping(&map, GL_RGB_INTEGER,        GL_UNSIGNED_BYTE,                  GL_RGB8UI,                 WriteColor<R8G8B8, GLuint>        );
132    InsertFormatMapping(&map, GL_RGB_INTEGER,        GL_BYTE,                           GL_RGB8I,                  WriteColor<R8G8B8S, GLint>        );
133    InsertFormatMapping(&map, GL_RGB_INTEGER,        GL_UNSIGNED_SHORT,                 GL_RGB16UI,                WriteColor<R16G16B16, GLuint>     );
134    InsertFormatMapping(&map, GL_RGB_INTEGER,        GL_SHORT,                          GL_RGB16I,                 WriteColor<R16G16B16S, GLint>     );
135    InsertFormatMapping(&map, GL_RGB_INTEGER,        GL_UNSIGNED_INT,                   GL_RGB32UI,                WriteColor<R32G32B32, GLuint>     );
136    InsertFormatMapping(&map, GL_RGB_INTEGER,        GL_INT,                            GL_RGB32I,                 WriteColor<R32G32B32S, GLint>     );
137
138    InsertFormatMapping(&map, GL_RG,                 GL_UNSIGNED_BYTE,                  GL_RG8,                    WriteColor<R8G8, GLfloat>         );
139    InsertFormatMapping(&map, GL_RG,                 GL_BYTE,                           GL_RG8_SNORM,              WriteColor<R8G8S, GLfloat>        );
140    InsertFormatMapping(&map, GL_RG,                 GL_FLOAT,                          GL_RG32F,                  WriteColor<R32G32F, GLfloat>      );
141    InsertFormatMapping(&map, GL_RG,                 GL_HALF_FLOAT,                     GL_RG16F,                  WriteColor<R16G16F, GLfloat>      );
142
143    InsertFormatMapping(&map, GL_RG_INTEGER,         GL_UNSIGNED_BYTE,                  GL_RG8UI,                  WriteColor<R8G8, GLuint>          );
144    InsertFormatMapping(&map, GL_RG_INTEGER,         GL_BYTE,                           GL_RG8I,                   WriteColor<R8G8S, GLint>          );
145    InsertFormatMapping(&map, GL_RG_INTEGER,         GL_UNSIGNED_SHORT,                 GL_RG16UI,                 WriteColor<R16G16, GLuint>        );
146    InsertFormatMapping(&map, GL_RG_INTEGER,         GL_SHORT,                          GL_RG16I,                  WriteColor<R16G16S, GLint>        );
147    InsertFormatMapping(&map, GL_RG_INTEGER,         GL_UNSIGNED_INT,                   GL_RG32UI,                 WriteColor<R32G32, GLuint>        );
148    InsertFormatMapping(&map, GL_RG_INTEGER,         GL_INT,                            GL_RG32I,                  WriteColor<R32G32S, GLint>        );
149
150    InsertFormatMapping(&map, GL_RED,                GL_UNSIGNED_BYTE,                  GL_R8,                     WriteColor<R8, GLfloat>           );
151    InsertFormatMapping(&map, GL_RED,                GL_BYTE,                           GL_R8_SNORM,               WriteColor<R8S, GLfloat>          );
152    InsertFormatMapping(&map, GL_RED,                GL_FLOAT,                          GL_R32F,                   WriteColor<R32F, GLfloat>         );
153    InsertFormatMapping(&map, GL_RED,                GL_HALF_FLOAT,                     GL_R16F,                   WriteColor<R16F, GLfloat>         );
154
155    InsertFormatMapping(&map, GL_RED_INTEGER,        GL_UNSIGNED_BYTE,                  GL_R8UI,                   WriteColor<R8, GLuint>            );
156    InsertFormatMapping(&map, GL_RED_INTEGER,        GL_BYTE,                           GL_R8I,                    WriteColor<R8S, GLint>            );
157    InsertFormatMapping(&map, GL_RED_INTEGER,        GL_UNSIGNED_SHORT,                 GL_R16UI,                  WriteColor<R16, GLuint>           );
158    InsertFormatMapping(&map, GL_RED_INTEGER,        GL_SHORT,                          GL_R16I,                   WriteColor<R16S, GLint>           );
159    InsertFormatMapping(&map, GL_RED_INTEGER,        GL_UNSIGNED_INT,                   GL_R32UI,                  WriteColor<R32, GLuint>           );
160    InsertFormatMapping(&map, GL_RED_INTEGER,        GL_INT,                            GL_R32I,                   WriteColor<R32S, GLint>           );
161
162    InsertFormatMapping(&map, GL_LUMINANCE_ALPHA,    GL_UNSIGNED_BYTE,                  GL_LUMINANCE8_ALPHA8_EXT,  WriteColor<L8A8, GLfloat>         );
163    InsertFormatMapping(&map, GL_LUMINANCE,          GL_UNSIGNED_BYTE,                  GL_LUMINANCE8_EXT,         WriteColor<L8, GLfloat>           );
164    InsertFormatMapping(&map, GL_ALPHA,              GL_UNSIGNED_BYTE,                  GL_ALPHA8_EXT,             WriteColor<A8, GLfloat>           );
165    InsertFormatMapping(&map, GL_LUMINANCE_ALPHA,    GL_FLOAT,                          GL_LUMINANCE_ALPHA32F_EXT, WriteColor<L32A32F, GLfloat>      );
166    InsertFormatMapping(&map, GL_LUMINANCE,          GL_FLOAT,                          GL_LUMINANCE32F_EXT,       WriteColor<L32F, GLfloat>         );
167    InsertFormatMapping(&map, GL_ALPHA,              GL_FLOAT,                          GL_ALPHA32F_EXT,           WriteColor<A32F, GLfloat>         );
168    InsertFormatMapping(&map, GL_LUMINANCE_ALPHA,    GL_HALF_FLOAT,                     GL_LUMINANCE_ALPHA16F_EXT, WriteColor<L16A16F, GLfloat>      );
169    InsertFormatMapping(&map, GL_LUMINANCE,          GL_HALF_FLOAT,                     GL_LUMINANCE16F_EXT,       WriteColor<L16F, GLfloat>         );
170    InsertFormatMapping(&map, GL_ALPHA,              GL_HALF_FLOAT,                     GL_ALPHA16F_EXT,           WriteColor<A16F, GLfloat>         );
171
172    InsertFormatMapping(&map, GL_BGRA_EXT,           GL_UNSIGNED_BYTE,                  GL_BGRA8_EXT,              WriteColor<B8G8R8A8, GLfloat>     );
173    InsertFormatMapping(&map, GL_BGRA_EXT,           GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_BGRA4_ANGLEX,           WriteColor<B4G4R4A4, GLfloat>     );
174    InsertFormatMapping(&map, GL_BGRA_EXT,           GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_BGR5_A1_ANGLEX,         WriteColor<B5G5R5A1, GLfloat>     );
175
176    InsertFormatMapping(&map, GL_DEPTH_COMPONENT,    GL_UNSIGNED_SHORT,                 GL_DEPTH_COMPONENT16,      NULL                              );
177    InsertFormatMapping(&map, GL_DEPTH_COMPONENT,    GL_UNSIGNED_INT,                   GL_DEPTH_COMPONENT24,      NULL                              );
178    InsertFormatMapping(&map, GL_DEPTH_COMPONENT,    GL_FLOAT,                          GL_DEPTH_COMPONENT32F,     NULL                              );
179
180    InsertFormatMapping(&map, GL_DEPTH_STENCIL,      GL_UNSIGNED_INT_24_8,              GL_DEPTH24_STENCIL8,       NULL                              );
181    InsertFormatMapping(&map, GL_DEPTH_STENCIL,      GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_DEPTH32F_STENCIL8,      NULL                              );
182
183    return map;
184}
185
186static const FormatMap &GetFormatMap(GLuint clientVersion)
187{
188    if (clientVersion == 2)
189    {
190        static const FormatMap formats = BuildES2FormatMap();
191        return formats;
192    }
193    else if (clientVersion == 3)
194    {
195        static const FormatMap formats = BuildES3FormatMap();
196        return formats;
197    }
198    else
199    {
200        UNREACHABLE();
201        static FormatMap emptyMap;
202        return emptyMap;
203    }
204}
205
206struct FormatInfo
207{
208    GLenum mInternalformat;
209    GLenum mFormat;
210    GLenum mType;
211
212    FormatInfo(GLenum internalformat, GLenum format, GLenum type)
213        : mInternalformat(internalformat), mFormat(format), mType(type) { }
214
215    bool operator<(const FormatInfo& other) const
216    {
217        return memcmp(this, &other, sizeof(FormatInfo)) < 0;
218    }
219};
220
221// ES3 has a specific set of permutations of internal formats, formats and types which are acceptable.
222typedef std::set<FormatInfo> ES3FormatSet;
223
224ES3FormatSet BuildES3FormatSet()
225{
226    ES3FormatSet set;
227
228    // Format combinations from ES 3.0.1 spec, table 3.2
229
230    //                   | Internal format      | Format            | Type                            |
231    //                   |                      |                   |                                 |
232    set.insert(FormatInfo(GL_RGBA8,              GL_RGBA,            GL_UNSIGNED_BYTE                 ));
233    set.insert(FormatInfo(GL_RGB5_A1,            GL_RGBA,            GL_UNSIGNED_BYTE                 ));
234    set.insert(FormatInfo(GL_RGBA4,              GL_RGBA,            GL_UNSIGNED_BYTE                 ));
235    set.insert(FormatInfo(GL_SRGB8_ALPHA8,       GL_RGBA,            GL_UNSIGNED_BYTE                 ));
236    set.insert(FormatInfo(GL_RGBA8_SNORM,        GL_RGBA,            GL_BYTE                          ));
237    set.insert(FormatInfo(GL_RGBA4,              GL_RGBA,            GL_UNSIGNED_SHORT_4_4_4_4        ));
238    set.insert(FormatInfo(GL_RGB10_A2,           GL_RGBA,            GL_UNSIGNED_INT_2_10_10_10_REV   ));
239    set.insert(FormatInfo(GL_RGB5_A1,            GL_RGBA,            GL_UNSIGNED_INT_2_10_10_10_REV   ));
240    set.insert(FormatInfo(GL_RGB5_A1,            GL_RGBA,            GL_UNSIGNED_SHORT_5_5_5_1        ));
241    set.insert(FormatInfo(GL_RGBA16F,            GL_RGBA,            GL_HALF_FLOAT                    ));
242    set.insert(FormatInfo(GL_RGBA32F,            GL_RGBA,            GL_FLOAT                         ));
243    set.insert(FormatInfo(GL_RGBA16F,            GL_RGBA,            GL_FLOAT                         ));
244    set.insert(FormatInfo(GL_RGBA8UI,            GL_RGBA_INTEGER,    GL_UNSIGNED_BYTE                 ));
245    set.insert(FormatInfo(GL_RGBA8I,             GL_RGBA_INTEGER,    GL_BYTE                          ));
246    set.insert(FormatInfo(GL_RGBA16UI,           GL_RGBA_INTEGER,    GL_UNSIGNED_SHORT                ));
247    set.insert(FormatInfo(GL_RGBA16I,            GL_RGBA_INTEGER,    GL_SHORT                         ));
248    set.insert(FormatInfo(GL_RGBA32UI,           GL_RGBA_INTEGER,    GL_UNSIGNED_INT                  ));
249    set.insert(FormatInfo(GL_RGBA32I,            GL_RGBA_INTEGER,    GL_INT                           ));
250    set.insert(FormatInfo(GL_RGB10_A2UI,         GL_RGBA_INTEGER,    GL_UNSIGNED_INT_2_10_10_10_REV   ));
251    set.insert(FormatInfo(GL_RGB8,               GL_RGB,             GL_UNSIGNED_BYTE                 ));
252    set.insert(FormatInfo(GL_RGB565,             GL_RGB,             GL_UNSIGNED_BYTE                 ));
253    set.insert(FormatInfo(GL_SRGB8,              GL_RGB,             GL_UNSIGNED_BYTE                 ));
254    set.insert(FormatInfo(GL_RGB8_SNORM,         GL_RGB,             GL_BYTE                          ));
255    set.insert(FormatInfo(GL_RGB565,             GL_RGB,             GL_UNSIGNED_SHORT_5_6_5          ));
256    set.insert(FormatInfo(GL_R11F_G11F_B10F,     GL_RGB,             GL_UNSIGNED_INT_10F_11F_11F_REV  ));
257    set.insert(FormatInfo(GL_RGB9_E5,            GL_RGB,             GL_UNSIGNED_INT_5_9_9_9_REV      ));
258    set.insert(FormatInfo(GL_RGB16F,             GL_RGB,             GL_HALF_FLOAT                    ));
259    set.insert(FormatInfo(GL_R11F_G11F_B10F,     GL_RGB,             GL_HALF_FLOAT                    ));
260    set.insert(FormatInfo(GL_RGB9_E5,            GL_RGB,             GL_HALF_FLOAT                    ));
261    set.insert(FormatInfo(GL_RGB32F,             GL_RGB,             GL_FLOAT                         ));
262    set.insert(FormatInfo(GL_RGB16F,             GL_RGB,             GL_FLOAT                         ));
263    set.insert(FormatInfo(GL_R11F_G11F_B10F,     GL_RGB,             GL_FLOAT                         ));
264    set.insert(FormatInfo(GL_RGB9_E5,            GL_RGB,             GL_FLOAT                         ));
265    set.insert(FormatInfo(GL_RGB8UI,             GL_RGB_INTEGER,     GL_UNSIGNED_BYTE                 ));
266    set.insert(FormatInfo(GL_RGB8I,              GL_RGB_INTEGER,     GL_BYTE                          ));
267    set.insert(FormatInfo(GL_RGB16UI,            GL_RGB_INTEGER,     GL_UNSIGNED_SHORT                ));
268    set.insert(FormatInfo(GL_RGB16I,             GL_RGB_INTEGER,     GL_SHORT                         ));
269    set.insert(FormatInfo(GL_RGB32UI,            GL_RGB_INTEGER,     GL_UNSIGNED_INT                  ));
270    set.insert(FormatInfo(GL_RGB32I,             GL_RGB_INTEGER,     GL_INT                           ));
271    set.insert(FormatInfo(GL_RG8,                GL_RG,              GL_UNSIGNED_BYTE                 ));
272    set.insert(FormatInfo(GL_RG8_SNORM,          GL_RG,              GL_BYTE                          ));
273    set.insert(FormatInfo(GL_RG16F,              GL_RG,              GL_HALF_FLOAT                    ));
274    set.insert(FormatInfo(GL_RG32F,              GL_RG,              GL_FLOAT                         ));
275    set.insert(FormatInfo(GL_RG16F,              GL_RG,              GL_FLOAT                         ));
276    set.insert(FormatInfo(GL_RG8UI,              GL_RG_INTEGER,      GL_UNSIGNED_BYTE                 ));
277    set.insert(FormatInfo(GL_RG8I,               GL_RG_INTEGER,      GL_BYTE                          ));
278    set.insert(FormatInfo(GL_RG16UI,             GL_RG_INTEGER,      GL_UNSIGNED_SHORT                ));
279    set.insert(FormatInfo(GL_RG16I,              GL_RG_INTEGER,      GL_SHORT                         ));
280    set.insert(FormatInfo(GL_RG32UI,             GL_RG_INTEGER,      GL_UNSIGNED_INT                  ));
281    set.insert(FormatInfo(GL_RG32I,              GL_RG_INTEGER,      GL_INT                           ));
282    set.insert(FormatInfo(GL_R8,                 GL_RED,             GL_UNSIGNED_BYTE                 ));
283    set.insert(FormatInfo(GL_R8_SNORM,           GL_RED,             GL_BYTE                          ));
284    set.insert(FormatInfo(GL_R16F,               GL_RED,             GL_HALF_FLOAT                    ));
285    set.insert(FormatInfo(GL_R32F,               GL_RED,             GL_FLOAT                         ));
286    set.insert(FormatInfo(GL_R16F,               GL_RED,             GL_FLOAT                         ));
287    set.insert(FormatInfo(GL_R8UI,               GL_RED_INTEGER,     GL_UNSIGNED_BYTE                 ));
288    set.insert(FormatInfo(GL_R8I,                GL_RED_INTEGER,     GL_BYTE                          ));
289    set.insert(FormatInfo(GL_R16UI,              GL_RED_INTEGER,     GL_UNSIGNED_SHORT                ));
290    set.insert(FormatInfo(GL_R16I,               GL_RED_INTEGER,     GL_SHORT                         ));
291    set.insert(FormatInfo(GL_R32UI,              GL_RED_INTEGER,     GL_UNSIGNED_INT                  ));
292    set.insert(FormatInfo(GL_R32I,               GL_RED_INTEGER,     GL_INT                           ));
293
294    // Unsized formats
295    set.insert(FormatInfo(GL_RGBA,               GL_RGBA,            GL_UNSIGNED_BYTE                 ));
296    set.insert(FormatInfo(GL_RGBA,               GL_RGBA,            GL_UNSIGNED_SHORT_4_4_4_4        ));
297    set.insert(FormatInfo(GL_RGBA,               GL_RGBA,            GL_UNSIGNED_SHORT_5_5_5_1        ));
298    set.insert(FormatInfo(GL_RGB,                GL_RGB,             GL_UNSIGNED_BYTE                 ));
299    set.insert(FormatInfo(GL_RGB,                GL_RGB,             GL_UNSIGNED_SHORT_5_6_5          ));
300    set.insert(FormatInfo(GL_LUMINANCE_ALPHA,    GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE                 ));
301    set.insert(FormatInfo(GL_LUMINANCE,          GL_LUMINANCE,       GL_UNSIGNED_BYTE                 ));
302    set.insert(FormatInfo(GL_ALPHA,              GL_ALPHA,           GL_UNSIGNED_BYTE                 ));
303
304    // Depth stencil formats
305    set.insert(FormatInfo(GL_DEPTH_COMPONENT16,  GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT                ));
306    set.insert(FormatInfo(GL_DEPTH_COMPONENT24,  GL_DEPTH_COMPONENT, GL_UNSIGNED_INT                  ));
307    set.insert(FormatInfo(GL_DEPTH_COMPONENT16,  GL_DEPTH_COMPONENT, GL_UNSIGNED_INT                  ));
308    set.insert(FormatInfo(GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT                         ));
309    set.insert(FormatInfo(GL_DEPTH24_STENCIL8,   GL_DEPTH_STENCIL,   GL_UNSIGNED_INT_24_8             ));
310    set.insert(FormatInfo(GL_DEPTH32F_STENCIL8,  GL_DEPTH_STENCIL,   GL_FLOAT_32_UNSIGNED_INT_24_8_REV));
311
312    // From GL_OES_texture_float
313    set.insert(FormatInfo(GL_LUMINANCE_ALPHA,    GL_LUMINANCE_ALPHA, GL_FLOAT                         ));
314    set.insert(FormatInfo(GL_LUMINANCE,          GL_LUMINANCE,       GL_FLOAT                         ));
315    set.insert(FormatInfo(GL_ALPHA,              GL_ALPHA,           GL_FLOAT                         ));
316
317    // From GL_OES_texture_half_float
318    set.insert(FormatInfo(GL_LUMINANCE_ALPHA,    GL_LUMINANCE_ALPHA, GL_HALF_FLOAT                    ));
319    set.insert(FormatInfo(GL_LUMINANCE,          GL_LUMINANCE,       GL_HALF_FLOAT                    ));
320    set.insert(FormatInfo(GL_ALPHA,              GL_ALPHA,           GL_HALF_FLOAT                    ));
321
322    // From GL_EXT_texture_format_BGRA8888
323    set.insert(FormatInfo(GL_BGRA_EXT,           GL_BGRA_EXT,        GL_UNSIGNED_BYTE                 ));
324
325    // From GL_EXT_texture_storage
326    //                   | Internal format          | Format            | Type                            |
327    //                   |                          |                   |                                 |
328    set.insert(FormatInfo(GL_ALPHA8_EXT,             GL_ALPHA,           GL_UNSIGNED_BYTE                 ));
329    set.insert(FormatInfo(GL_LUMINANCE8_EXT,         GL_LUMINANCE,       GL_UNSIGNED_BYTE                 ));
330    set.insert(FormatInfo(GL_LUMINANCE8_ALPHA8_EXT,  GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE                 ));
331    set.insert(FormatInfo(GL_ALPHA32F_EXT,           GL_ALPHA,           GL_FLOAT                         ));
332    set.insert(FormatInfo(GL_LUMINANCE32F_EXT,       GL_LUMINANCE,       GL_FLOAT                         ));
333    set.insert(FormatInfo(GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA, GL_FLOAT                         ));
334    set.insert(FormatInfo(GL_ALPHA16F_EXT,           GL_ALPHA,           GL_HALF_FLOAT                    ));
335    set.insert(FormatInfo(GL_LUMINANCE16F_EXT,       GL_LUMINANCE,       GL_HALF_FLOAT                    ));
336    set.insert(FormatInfo(GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT                    ));
337
338    // From GL_EXT_texture_storage and GL_EXT_texture_format_BGRA8888
339    set.insert(FormatInfo(GL_BGRA8_EXT,              GL_BGRA_EXT,        GL_UNSIGNED_BYTE                 ));
340    set.insert(FormatInfo(GL_BGRA4_ANGLEX,           GL_BGRA_EXT,        GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT));
341    set.insert(FormatInfo(GL_BGRA4_ANGLEX,           GL_BGRA_EXT,        GL_UNSIGNED_BYTE                 ));
342    set.insert(FormatInfo(GL_BGR5_A1_ANGLEX,         GL_BGRA_EXT,        GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT));
343    set.insert(FormatInfo(GL_BGR5_A1_ANGLEX,         GL_BGRA_EXT,        GL_UNSIGNED_BYTE                 ));
344
345    // From GL_ANGLE_depth_texture
346    set.insert(FormatInfo(GL_DEPTH_COMPONENT32_OES,  GL_DEPTH_COMPONENT, GL_UNSIGNED_INT_24_8_OES         ));
347
348    // Compressed formats
349    // From ES 3.0.1 spec, table 3.16
350    //                   | Internal format                             | Format                                      | Type           |
351    //                   |                                             |                                             |                |
352    set.insert(FormatInfo(GL_COMPRESSED_R11_EAC,                        GL_COMPRESSED_R11_EAC,                        GL_UNSIGNED_BYTE));
353    set.insert(FormatInfo(GL_COMPRESSED_R11_EAC,                        GL_COMPRESSED_R11_EAC,                        GL_UNSIGNED_BYTE));
354    set.insert(FormatInfo(GL_COMPRESSED_SIGNED_R11_EAC,                 GL_COMPRESSED_SIGNED_R11_EAC,                 GL_UNSIGNED_BYTE));
355    set.insert(FormatInfo(GL_COMPRESSED_RG11_EAC,                       GL_COMPRESSED_RG11_EAC,                       GL_UNSIGNED_BYTE));
356    set.insert(FormatInfo(GL_COMPRESSED_SIGNED_RG11_EAC,                GL_COMPRESSED_SIGNED_RG11_EAC,                GL_UNSIGNED_BYTE));
357    set.insert(FormatInfo(GL_COMPRESSED_RGB8_ETC2,                      GL_COMPRESSED_RGB8_ETC2,                      GL_UNSIGNED_BYTE));
358    set.insert(FormatInfo(GL_COMPRESSED_SRGB8_ETC2,                     GL_COMPRESSED_SRGB8_ETC2,                     GL_UNSIGNED_BYTE));
359    set.insert(FormatInfo(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,  GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,  GL_UNSIGNED_BYTE));
360    set.insert(FormatInfo(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE));
361    set.insert(FormatInfo(GL_COMPRESSED_RGBA8_ETC2_EAC,                 GL_COMPRESSED_RGBA8_ETC2_EAC,                 GL_UNSIGNED_BYTE));
362    set.insert(FormatInfo(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,          GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,          GL_UNSIGNED_BYTE));
363
364
365    // From GL_EXT_texture_compression_dxt1
366    set.insert(FormatInfo(GL_COMPRESSED_RGB_S3TC_DXT1_EXT,              GL_COMPRESSED_RGB_S3TC_DXT1_EXT,              GL_UNSIGNED_BYTE));
367    set.insert(FormatInfo(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,             GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,             GL_UNSIGNED_BYTE));
368
369    // From GL_ANGLE_texture_compression_dxt3
370    set.insert(FormatInfo(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE,           GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE,           GL_UNSIGNED_BYTE));
371
372    // From GL_ANGLE_texture_compression_dxt5
373    set.insert(FormatInfo(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE,           GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE,           GL_UNSIGNED_BYTE));
374
375    return set;
376}
377
378static const ES3FormatSet &GetES3FormatSet()
379{
380    static const ES3FormatSet es3FormatSet = BuildES3FormatSet();
381    return es3FormatSet;
382}
383
384// Map of sizes of input types
385struct TypeInfo
386{
387    GLuint mTypeBytes;
388    bool mSpecialInterpretation;
389
390    TypeInfo()
391        : mTypeBytes(0), mSpecialInterpretation(false) { }
392
393    TypeInfo(GLuint typeBytes, bool specialInterpretation)
394        : mTypeBytes(typeBytes), mSpecialInterpretation(specialInterpretation) { }
395
396    bool operator<(const TypeInfo& other) const
397    {
398        return memcmp(this, &other, sizeof(TypeInfo)) < 0;
399    }
400};
401
402typedef std::pair<GLenum, TypeInfo> TypeInfoPair;
403typedef std::map<GLenum, TypeInfo> TypeInfoMap;
404
405static TypeInfoMap BuildTypeInfoMap()
406{
407    TypeInfoMap map;
408
409    map.insert(TypeInfoPair(GL_UNSIGNED_BYTE,                  TypeInfo( 1, false)));
410    map.insert(TypeInfoPair(GL_BYTE,                           TypeInfo( 1, false)));
411    map.insert(TypeInfoPair(GL_UNSIGNED_SHORT,                 TypeInfo( 2, false)));
412    map.insert(TypeInfoPair(GL_SHORT,                          TypeInfo( 2, false)));
413    map.insert(TypeInfoPair(GL_UNSIGNED_INT,                   TypeInfo( 4, false)));
414    map.insert(TypeInfoPair(GL_INT,                            TypeInfo( 4, false)));
415    map.insert(TypeInfoPair(GL_HALF_FLOAT,                     TypeInfo( 2, false)));
416    map.insert(TypeInfoPair(GL_HALF_FLOAT_OES,                 TypeInfo( 2, false)));
417    map.insert(TypeInfoPair(GL_FLOAT,                          TypeInfo( 4, false)));
418    map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_5_6_5,           TypeInfo( 2, true )));
419    map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_4_4_4_4,         TypeInfo( 2, true )));
420    map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_5_5_5_1,         TypeInfo( 2, true )));
421    map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, TypeInfo( 2, true )));
422    map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, TypeInfo( 2, true )));
423    map.insert(TypeInfoPair(GL_UNSIGNED_INT_2_10_10_10_REV,    TypeInfo( 4, true )));
424    map.insert(TypeInfoPair(GL_UNSIGNED_INT_24_8,              TypeInfo( 4, true )));
425    map.insert(TypeInfoPair(GL_UNSIGNED_INT_10F_11F_11F_REV,   TypeInfo( 4, true )));
426    map.insert(TypeInfoPair(GL_UNSIGNED_INT_5_9_9_9_REV,       TypeInfo( 4, true )));
427    map.insert(TypeInfoPair(GL_UNSIGNED_INT_24_8_OES,          TypeInfo( 4, true )));
428    map.insert(TypeInfoPair(GL_FLOAT_32_UNSIGNED_INT_24_8_REV, TypeInfo( 8, true )));
429
430    return map;
431}
432
433static bool GetTypeInfo(GLenum type, TypeInfo *outTypeInfo)
434{
435    static const TypeInfoMap infoMap = BuildTypeInfoMap();
436    TypeInfoMap::const_iterator iter = infoMap.find(type);
437    if (iter != infoMap.end())
438    {
439        if (outTypeInfo)
440        {
441            *outTypeInfo = iter->second;
442        }
443        return true;
444    }
445    else
446    {
447        return false;
448    }
449}
450
451// Information about internal formats
452typedef bool ((Context::*ContextSupportCheckMemberFunction)(void) const);
453typedef bool (*ContextSupportCheckFunction)(const Context *context);
454
455typedef bool ((rx::Renderer::*RendererSupportCheckMemberFunction)(void) const);
456typedef bool (*ContextRendererSupportCheckFunction)(const Context *context, const rx::Renderer *renderer);
457
458template <ContextSupportCheckMemberFunction func>
459bool CheckSupport(const Context *context)
460{
461    return (context->*func)();
462}
463
464template <ContextSupportCheckMemberFunction contextFunc, RendererSupportCheckMemberFunction rendererFunc>
465bool CheckSupport(const Context *context, const rx::Renderer *renderer)
466{
467    if (context)
468    {
469        return (context->*contextFunc)();
470    }
471    else if (renderer)
472    {
473        return (renderer->*rendererFunc)();
474    }
475    else
476    {
477        UNREACHABLE();
478        return false;
479    }
480}
481
482template <typename objectType>
483bool AlwaysSupported(const objectType*)
484{
485    return true;
486}
487
488template <typename objectTypeA, typename objectTypeB>
489bool AlwaysSupported(const objectTypeA*, const objectTypeB*)
490{
491    return true;
492}
493
494template <typename objectType>
495bool NeverSupported(const objectType*)
496{
497    return false;
498}
499
500template <typename objectTypeA, typename objectTypeB>
501bool NeverSupported(const objectTypeA *, const objectTypeB *)
502{
503    return false;
504}
505
506template <typename objectType>
507bool UnimplementedSupport(const objectType*)
508{
509    UNIMPLEMENTED();
510    return false;
511}
512
513template <typename objectTypeA, typename objectTypeB>
514bool UnimplementedSupport(const objectTypeA*, const objectTypeB*)
515{
516    UNIMPLEMENTED();
517    return false;
518}
519
520struct InternalFormatInfo
521{
522    GLuint mRedBits;
523    GLuint mGreenBits;
524    GLuint mBlueBits;
525
526    GLuint mLuminanceBits;
527
528    GLuint mAlphaBits;
529    GLuint mSharedBits;
530
531    GLuint mDepthBits;
532    GLuint mStencilBits;
533
534    GLuint mPixelBits;
535
536    GLuint mComponentCount;
537
538    GLuint mCompressedBlockWidth;
539    GLuint mCompressedBlockHeight;
540
541    GLenum mFormat;
542    GLenum mType;
543
544    GLenum mComponentType;
545    GLenum mColorEncoding;
546
547    bool mIsCompressed;
548
549    ContextRendererSupportCheckFunction mIsColorRenderable;
550    ContextRendererSupportCheckFunction mIsDepthRenderable;
551    ContextRendererSupportCheckFunction mIsStencilRenderable;
552    ContextRendererSupportCheckFunction mIsTextureFilterable;
553
554    ContextSupportCheckFunction mSupportFunction;
555
556    InternalFormatInfo() : mRedBits(0), mGreenBits(0), mBlueBits(0), mLuminanceBits(0), mAlphaBits(0), mSharedBits(0), mDepthBits(0), mStencilBits(0),
557                           mPixelBits(0), mComponentCount(0), mCompressedBlockWidth(0), mCompressedBlockHeight(0), mFormat(GL_NONE), mType(GL_NONE),
558                           mComponentType(GL_NONE), mColorEncoding(GL_NONE), mIsCompressed(false), mIsColorRenderable(NeverSupported),
559                           mIsDepthRenderable(NeverSupported), mIsStencilRenderable(NeverSupported), mIsTextureFilterable(NeverSupported),
560                           mSupportFunction(NeverSupported)
561    {
562    }
563
564    static InternalFormatInfo UnsizedFormat(GLenum format, ContextSupportCheckFunction supportFunction)
565    {
566        InternalFormatInfo formatInfo;
567        formatInfo.mFormat = format;
568        formatInfo.mSupportFunction = supportFunction;
569
570        if (format == GL_RGB || format == GL_RGBA)
571            formatInfo.mIsColorRenderable = AlwaysSupported;
572
573        return formatInfo;
574    }
575
576    static InternalFormatInfo RGBAFormat(GLuint red, GLuint green, GLuint blue, GLuint alpha, GLuint shared,
577                                         GLenum format, GLenum type, GLenum componentType, bool srgb,
578                                         ContextRendererSupportCheckFunction colorRenderable,
579                                         ContextRendererSupportCheckFunction textureFilterable,
580                                         ContextSupportCheckFunction supportFunction)
581    {
582        InternalFormatInfo formatInfo;
583        formatInfo.mRedBits = red;
584        formatInfo.mGreenBits = green;
585        formatInfo.mBlueBits = blue;
586        formatInfo.mAlphaBits = alpha;
587        formatInfo.mSharedBits = shared;
588        formatInfo.mPixelBits = red + green + blue + alpha + shared;
589        formatInfo.mComponentCount = ((red > 0) ? 1 : 0) + ((green > 0) ? 1 : 0) + ((blue > 0) ? 1 : 0) + ((alpha > 0) ? 1 : 0);
590        formatInfo.mFormat = format;
591        formatInfo.mType = type;
592        formatInfo.mComponentType = componentType;
593        formatInfo.mColorEncoding = (srgb ? GL_SRGB : GL_LINEAR);
594        formatInfo.mIsColorRenderable = colorRenderable;
595        formatInfo.mIsTextureFilterable = textureFilterable;
596        formatInfo.mSupportFunction = supportFunction;
597        return formatInfo;
598    }
599
600    static InternalFormatInfo LUMAFormat(GLuint luminance, GLuint alpha, GLenum format, GLenum type, GLenum componentType,
601                                         ContextSupportCheckFunction supportFunction)
602    {
603        InternalFormatInfo formatInfo;
604        formatInfo.mLuminanceBits = luminance;
605        formatInfo.mAlphaBits = alpha;
606        formatInfo.mPixelBits = luminance + alpha;
607        formatInfo.mComponentCount = ((luminance > 0) ? 1 : 0) + ((alpha > 0) ? 1 : 0);
608        formatInfo.mFormat = format;
609        formatInfo.mType = type;
610        formatInfo.mComponentType = componentType;
611        formatInfo.mColorEncoding = GL_LINEAR;
612        formatInfo.mIsTextureFilterable = AlwaysSupported;
613        formatInfo.mSupportFunction = supportFunction;
614        return formatInfo;
615    }
616
617    static InternalFormatInfo DepthStencilFormat(GLuint depthBits, GLuint stencilBits, GLuint unusedBits, GLenum format,
618                                                 GLenum type, GLenum componentType,
619                                                 ContextRendererSupportCheckFunction depthRenderable,
620                                                 ContextRendererSupportCheckFunction stencilRenderable,
621                                                 ContextSupportCheckFunction supportFunction)
622    {
623        InternalFormatInfo formatInfo;
624        formatInfo.mDepthBits = depthBits;
625        formatInfo.mStencilBits = stencilBits;
626        formatInfo.mPixelBits = depthBits + stencilBits + unusedBits;
627        formatInfo.mComponentCount = ((depthBits > 0) ? 1 : 0) + ((stencilBits > 0) ? 1 : 0);
628        formatInfo.mFormat = format;
629        formatInfo.mType = type;
630        formatInfo.mComponentType = componentType;
631        formatInfo.mColorEncoding = GL_LINEAR;
632        formatInfo.mIsDepthRenderable = depthRenderable;
633        formatInfo.mIsStencilRenderable = stencilRenderable;
634        formatInfo.mIsTextureFilterable = AlwaysSupported;
635        formatInfo.mSupportFunction = supportFunction;
636        return formatInfo;
637    }
638
639    static InternalFormatInfo CompressedFormat(GLuint compressedBlockWidth, GLuint compressedBlockHeight, GLuint compressedBlockSize,
640                                               GLuint componentCount, GLenum format, GLenum type, bool srgb,
641                                               ContextSupportCheckFunction supportFunction)
642    {
643        InternalFormatInfo formatInfo;
644        formatInfo.mCompressedBlockWidth = compressedBlockWidth;
645        formatInfo.mCompressedBlockHeight = compressedBlockHeight;
646        formatInfo.mPixelBits = compressedBlockSize;
647        formatInfo.mComponentCount = componentCount;
648        formatInfo.mFormat = format;
649        formatInfo.mType = type;
650        formatInfo.mComponentType = GL_UNSIGNED_NORMALIZED;
651        formatInfo.mColorEncoding = (srgb ? GL_SRGB : GL_LINEAR);
652        formatInfo.mIsCompressed = true;
653        formatInfo.mIsTextureFilterable = AlwaysSupported;
654        formatInfo.mSupportFunction = supportFunction;
655        return formatInfo;
656    }
657};
658
659typedef std::pair<GLenum, InternalFormatInfo> InternalFormatInfoPair;
660typedef std::map<GLenum, InternalFormatInfo> InternalFormatInfoMap;
661
662static InternalFormatInfoMap BuildES3InternalFormatInfoMap()
663{
664    InternalFormatInfoMap map;
665
666    // From ES 3.0.1 spec, table 3.12
667    map.insert(InternalFormatInfoPair(GL_NONE,              InternalFormatInfo()));
668
669    //                               | Internal format     |                              | R | G | B | A |S | Format         | Type                           | Component type        | SRGB | Color          | Texture        | Supported          |
670    //                               |                     |                              |   |   |   |   |  |                |                                |                       |      | renderable     | filterable     |                    |
671    map.insert(InternalFormatInfoPair(GL_R8,                InternalFormatInfo::RGBAFormat( 8,  0,  0,  0, 0, GL_RED,          GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
672    map.insert(InternalFormatInfoPair(GL_R8_SNORM,          InternalFormatInfo::RGBAFormat( 8,  0,  0,  0, 0, GL_RED,          GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, NeverSupported,  AlwaysSupported, AlwaysSupported     )));
673    map.insert(InternalFormatInfoPair(GL_RG8,               InternalFormatInfo::RGBAFormat( 8,  8,  0,  0, 0, GL_RG,           GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
674    map.insert(InternalFormatInfoPair(GL_RG8_SNORM,         InternalFormatInfo::RGBAFormat( 8,  8,  0,  0, 0, GL_RG,           GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, NeverSupported,  AlwaysSupported, AlwaysSupported     )));
675    map.insert(InternalFormatInfoPair(GL_RGB8,              InternalFormatInfo::RGBAFormat( 8,  8,  8,  0, 0, GL_RGB,          GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
676    map.insert(InternalFormatInfoPair(GL_RGB8_SNORM,        InternalFormatInfo::RGBAFormat( 8,  8,  8,  0, 0, GL_RGB,          GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, NeverSupported,  AlwaysSupported, AlwaysSupported     )));
677    map.insert(InternalFormatInfoPair(GL_RGB565,            InternalFormatInfo::RGBAFormat( 5,  6,  5,  0, 0, GL_RGB,          GL_UNSIGNED_SHORT_5_6_5,         GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
678    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, AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
679    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, AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
680    map.insert(InternalFormatInfoPair(GL_RGBA8,             InternalFormatInfo::RGBAFormat( 8,  8,  8,  8, 0, GL_RGBA,         GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
681    map.insert(InternalFormatInfoPair(GL_RGBA8_SNORM,       InternalFormatInfo::RGBAFormat( 8,  8,  8,  8, 0, GL_RGBA,         GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, NeverSupported,  AlwaysSupported, AlwaysSupported     )));
682    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, AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
683    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, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
684    map.insert(InternalFormatInfoPair(GL_SRGB8,             InternalFormatInfo::RGBAFormat( 8,  8,  8,  0, 0, GL_RGB,          GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, true,  NeverSupported,  AlwaysSupported, AlwaysSupported     )));
685    map.insert(InternalFormatInfoPair(GL_SRGB8_ALPHA8,      InternalFormatInfo::RGBAFormat( 8,  8,  8,  8, 0, GL_RGBA,         GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, true,  AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
686    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, AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
687    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, NeverSupported,  AlwaysSupported, AlwaysSupported     )));
688    map.insert(InternalFormatInfoPair(GL_R8I,               InternalFormatInfo::RGBAFormat( 8,  0,  0,  0, 0, GL_RED_INTEGER,  GL_BYTE,                         GL_INT,                 false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
689    map.insert(InternalFormatInfoPair(GL_R8UI,              InternalFormatInfo::RGBAFormat( 8,  0,  0,  0, 0, GL_RED_INTEGER,  GL_UNSIGNED_BYTE,                GL_UNSIGNED_INT,        false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
690    map.insert(InternalFormatInfoPair(GL_R16I,              InternalFormatInfo::RGBAFormat(16,  0,  0,  0, 0, GL_RED_INTEGER,  GL_SHORT,                        GL_INT,                 false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
691    map.insert(InternalFormatInfoPair(GL_R16UI,             InternalFormatInfo::RGBAFormat(16,  0,  0,  0, 0, GL_RED_INTEGER,  GL_UNSIGNED_SHORT,               GL_UNSIGNED_INT,        false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
692    map.insert(InternalFormatInfoPair(GL_R32I,              InternalFormatInfo::RGBAFormat(32,  0,  0,  0, 0, GL_RED_INTEGER,  GL_INT,                          GL_INT,                 false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
693    map.insert(InternalFormatInfoPair(GL_R32UI,             InternalFormatInfo::RGBAFormat(32,  0,  0,  0, 0, GL_RED_INTEGER,  GL_UNSIGNED_INT,                 GL_UNSIGNED_INT,        false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
694    map.insert(InternalFormatInfoPair(GL_RG8I,              InternalFormatInfo::RGBAFormat( 8,  8,  0,  0, 0, GL_RG_INTEGER,   GL_BYTE,                         GL_INT,                 false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
695    map.insert(InternalFormatInfoPair(GL_RG8UI,             InternalFormatInfo::RGBAFormat( 8,  8,  0,  0, 0, GL_RG_INTEGER,   GL_UNSIGNED_BYTE,                GL_UNSIGNED_INT,        false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
696    map.insert(InternalFormatInfoPair(GL_RG16I,             InternalFormatInfo::RGBAFormat(16, 16,  0,  0, 0, GL_RG_INTEGER,   GL_SHORT,                        GL_INT,                 false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
697    map.insert(InternalFormatInfoPair(GL_RG16UI,            InternalFormatInfo::RGBAFormat(16, 16,  0,  0, 0, GL_RG_INTEGER,   GL_UNSIGNED_SHORT,               GL_UNSIGNED_INT,        false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
698    map.insert(InternalFormatInfoPair(GL_RG32I,             InternalFormatInfo::RGBAFormat(32, 32,  0,  0, 0, GL_RG_INTEGER,   GL_INT,                          GL_INT,                 false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
699    map.insert(InternalFormatInfoPair(GL_RG32UI,            InternalFormatInfo::RGBAFormat(32, 32,  0,  0, 0, GL_RG_INTEGER,   GL_UNSIGNED_INT,                 GL_UNSIGNED_INT,        false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
700    map.insert(InternalFormatInfoPair(GL_RGB8I,             InternalFormatInfo::RGBAFormat( 8,  8,  8,  0, 0, GL_RGB_INTEGER,  GL_BYTE,                         GL_INT,                 false, NeverSupported,  NeverSupported,  AlwaysSupported     )));
701    map.insert(InternalFormatInfoPair(GL_RGB8UI,            InternalFormatInfo::RGBAFormat( 8,  8,  8,  0, 0, GL_RGB_INTEGER,  GL_UNSIGNED_BYTE,                GL_UNSIGNED_INT,        false, NeverSupported,  NeverSupported,  AlwaysSupported     )));
702    map.insert(InternalFormatInfoPair(GL_RGB16I,            InternalFormatInfo::RGBAFormat(16, 16, 16,  0, 0, GL_RGB_INTEGER,  GL_SHORT,                        GL_INT,                 false, NeverSupported,  NeverSupported,  AlwaysSupported     )));
703    map.insert(InternalFormatInfoPair(GL_RGB16UI,           InternalFormatInfo::RGBAFormat(16, 16, 16,  0, 0, GL_RGB_INTEGER,  GL_UNSIGNED_SHORT,               GL_UNSIGNED_INT,        false, NeverSupported,  NeverSupported,  AlwaysSupported     )));
704    map.insert(InternalFormatInfoPair(GL_RGB32I,            InternalFormatInfo::RGBAFormat(32, 32, 32,  0, 0, GL_RGB_INTEGER,  GL_INT,                          GL_INT,                 false, NeverSupported,  NeverSupported,  AlwaysSupported     )));
705    map.insert(InternalFormatInfoPair(GL_RGB32UI,           InternalFormatInfo::RGBAFormat(32, 32, 32,  0, 0, GL_RGB_INTEGER,  GL_UNSIGNED_INT,                 GL_UNSIGNED_INT,        false, NeverSupported,  NeverSupported,  AlwaysSupported     )));
706    map.insert(InternalFormatInfoPair(GL_RGBA8I,            InternalFormatInfo::RGBAFormat( 8,  8,  8,  8, 0, GL_RGBA_INTEGER, GL_BYTE,                         GL_INT,                 false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
707    map.insert(InternalFormatInfoPair(GL_RGBA8UI,           InternalFormatInfo::RGBAFormat( 8,  8,  8,  8, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE,                GL_UNSIGNED_INT,        false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
708    map.insert(InternalFormatInfoPair(GL_RGBA16I,           InternalFormatInfo::RGBAFormat(16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_SHORT,                        GL_INT,                 false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
709    map.insert(InternalFormatInfoPair(GL_RGBA16UI,          InternalFormatInfo::RGBAFormat(16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT,               GL_UNSIGNED_INT,        false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
710    map.insert(InternalFormatInfoPair(GL_RGBA32I,           InternalFormatInfo::RGBAFormat(32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_INT,                          GL_INT,                 false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
711    map.insert(InternalFormatInfoPair(GL_RGBA32UI,          InternalFormatInfo::RGBAFormat(32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT,                 GL_UNSIGNED_INT,        false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
712
713    map.insert(InternalFormatInfoPair(GL_BGRA8_EXT,         InternalFormatInfo::RGBAFormat( 8,  8,  8,  8, 0, GL_BGRA_EXT,     GL_UNSIGNED_BYTE,                  GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
714    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, AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
715    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, AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
716
717    // Floating point renderability and filtering is provided by OES_texture_float and OES_texture_half_float
718    //                               | Internal format        |                                   | D |S | Format             | Type                           | Comp   | SRGB | Color renderable                                                                                           | Texture filterable                                                                                    | Supported          |
719    //                               |                        |                                   |   |  |                    |                                | type   |      |                                                                                                            |                                                                                                       |                    |
720    map.insert(InternalFormatInfoPair(GL_R16F,              InternalFormatInfo::RGBAFormat(16,  0,  0,  0, 0, GL_RED,          GL_HALF_FLOAT,                   GL_FLOAT, false, CheckSupport<&Context::supportsFloat16RenderableTextures, &rx::Renderer::getFloat16TextureRenderingSupport>, CheckSupport<&Context::supportsFloat16LinearFilter, &rx::Renderer::getFloat16TextureFilteringSupport>, AlwaysSupported     )));
721    map.insert(InternalFormatInfoPair(GL_RG16F,             InternalFormatInfo::RGBAFormat(16, 16,  0,  0, 0, GL_RG,           GL_HALF_FLOAT,                   GL_FLOAT, false, CheckSupport<&Context::supportsFloat16RenderableTextures, &rx::Renderer::getFloat16TextureRenderingSupport>, CheckSupport<&Context::supportsFloat16LinearFilter, &rx::Renderer::getFloat16TextureFilteringSupport>, AlwaysSupported     )));
722    map.insert(InternalFormatInfoPair(GL_RGB16F,            InternalFormatInfo::RGBAFormat(16, 16, 16,  0, 0, GL_RGB,          GL_HALF_FLOAT,                   GL_FLOAT, false, CheckSupport<&Context::supportsFloat16RenderableTextures, &rx::Renderer::getFloat16TextureRenderingSupport>, CheckSupport<&Context::supportsFloat16LinearFilter, &rx::Renderer::getFloat16TextureFilteringSupport>, AlwaysSupported     )));
723    map.insert(InternalFormatInfoPair(GL_RGBA16F,           InternalFormatInfo::RGBAFormat(16, 16, 16, 16, 0, GL_RGBA,         GL_HALF_FLOAT,                   GL_FLOAT, false, CheckSupport<&Context::supportsFloat16RenderableTextures, &rx::Renderer::getFloat16TextureRenderingSupport>, CheckSupport<&Context::supportsFloat16LinearFilter, &rx::Renderer::getFloat16TextureFilteringSupport>, AlwaysSupported     )));
724    map.insert(InternalFormatInfoPair(GL_R32F,              InternalFormatInfo::RGBAFormat(32,  0,  0,  0, 0, GL_RED,          GL_FLOAT,                        GL_FLOAT, false, CheckSupport<&Context::supportsFloat32RenderableTextures, &rx::Renderer::getFloat32TextureRenderingSupport>, CheckSupport<&Context::supportsFloat32LinearFilter, &rx::Renderer::getFloat32TextureFilteringSupport>, AlwaysSupported     )));
725    map.insert(InternalFormatInfoPair(GL_RG32F,             InternalFormatInfo::RGBAFormat(32, 32,  0,  0, 0, GL_RG,           GL_FLOAT,                        GL_FLOAT, false, CheckSupport<&Context::supportsFloat32RenderableTextures, &rx::Renderer::getFloat32TextureRenderingSupport>, CheckSupport<&Context::supportsFloat32LinearFilter, &rx::Renderer::getFloat32TextureFilteringSupport>, AlwaysSupported     )));
726    map.insert(InternalFormatInfoPair(GL_RGB32F,            InternalFormatInfo::RGBAFormat(32, 32, 32,  0, 0, GL_RGB,          GL_FLOAT,                        GL_FLOAT, false, CheckSupport<&Context::supportsFloat32RenderableTextures, &rx::Renderer::getFloat32TextureRenderingSupport>, CheckSupport<&Context::supportsFloat32LinearFilter, &rx::Renderer::getFloat32TextureFilteringSupport>, AlwaysSupported     )));
727    map.insert(InternalFormatInfoPair(GL_RGBA32F,           InternalFormatInfo::RGBAFormat(32, 32, 32, 32, 0, GL_RGBA,         GL_FLOAT,                        GL_FLOAT, false, CheckSupport<&Context::supportsFloat32RenderableTextures, &rx::Renderer::getFloat32TextureRenderingSupport>, CheckSupport<&Context::supportsFloat32LinearFilter, &rx::Renderer::getFloat32TextureFilteringSupport>, AlwaysSupported     )));
728
729    // Depth stencil formats
730    //                               | Internal format         |                                      | D |S | X | Format            | Type                             | Component type        | Depth          | Stencil        | Supported     |
731    //                               |                         |                                      |   |  |   |                   |                                  |                       | renderable     | renderable     |               |
732    map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT16,     InternalFormatInfo::DepthStencilFormat(16, 0,  0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,                 GL_UNSIGNED_NORMALIZED, AlwaysSupported, NeverSupported,  AlwaysSupported)));
733    map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT24,     InternalFormatInfo::DepthStencilFormat(24, 0,  0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,                   GL_UNSIGNED_NORMALIZED, AlwaysSupported, NeverSupported,  AlwaysSupported)));
734    map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32F,    InternalFormatInfo::DepthStencilFormat(32, 0,  0, GL_DEPTH_COMPONENT, GL_FLOAT,                          GL_FLOAT,               AlwaysSupported, NeverSupported,  AlwaysSupported)));
735    map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32_OES, InternalFormatInfo::DepthStencilFormat(32, 0,  0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,                   GL_UNSIGNED_NORMALIZED, AlwaysSupported, NeverSupported,  AlwaysSupported)));
736    map.insert(InternalFormatInfoPair(GL_DEPTH24_STENCIL8,      InternalFormatInfo::DepthStencilFormat(24, 8,  0, GL_DEPTH_STENCIL,   GL_UNSIGNED_INT_24_8,              GL_UNSIGNED_NORMALIZED, AlwaysSupported, AlwaysSupported, AlwaysSupported)));
737    map.insert(InternalFormatInfoPair(GL_DEPTH32F_STENCIL8,     InternalFormatInfo::DepthStencilFormat(32, 8, 24, GL_DEPTH_STENCIL,   GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_FLOAT,               AlwaysSupported, AlwaysSupported, AlwaysSupported)));
738    map.insert(InternalFormatInfoPair(GL_STENCIL_INDEX8,        InternalFormatInfo::DepthStencilFormat( 0, 8,  0, GL_DEPTH_STENCIL,   GL_UNSIGNED_BYTE,                  GL_UNSIGNED_INT,        NeverSupported,  AlwaysSupported, AlwaysSupported)));
739
740    // Luminance alpha formats
741    //                               | Internal format          |                              | L | A | Format            | Type            | Component type        | Supported     |
742    map.insert(InternalFormatInfoPair(GL_ALPHA8_EXT,             InternalFormatInfo::LUMAFormat( 0,  8, GL_ALPHA,           GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, AlwaysSupported)));
743    map.insert(InternalFormatInfoPair(GL_LUMINANCE8_EXT,         InternalFormatInfo::LUMAFormat( 8,  0, GL_LUMINANCE,       GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, AlwaysSupported)));
744    map.insert(InternalFormatInfoPair(GL_ALPHA32F_EXT,           InternalFormatInfo::LUMAFormat( 0, 32, GL_ALPHA,           GL_FLOAT,         GL_FLOAT,               AlwaysSupported)));
745    map.insert(InternalFormatInfoPair(GL_LUMINANCE32F_EXT,       InternalFormatInfo::LUMAFormat(32,  0, GL_LUMINANCE,       GL_FLOAT,         GL_FLOAT,               AlwaysSupported)));
746    map.insert(InternalFormatInfoPair(GL_ALPHA16F_EXT,           InternalFormatInfo::LUMAFormat( 0, 16, GL_ALPHA,           GL_HALF_FLOAT,    GL_FLOAT,               AlwaysSupported)));
747    map.insert(InternalFormatInfoPair(GL_LUMINANCE16F_EXT,       InternalFormatInfo::LUMAFormat(16,  0, GL_LUMINANCE,       GL_HALF_FLOAT,    GL_FLOAT,               AlwaysSupported)));
748    map.insert(InternalFormatInfoPair(GL_LUMINANCE8_ALPHA8_EXT,  InternalFormatInfo::LUMAFormat( 8,  8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, AlwaysSupported)));
749    map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA32F_EXT, InternalFormatInfo::LUMAFormat(32, 32, GL_LUMINANCE_ALPHA, GL_FLOAT,         GL_FLOAT,               AlwaysSupported)));
750    map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA16F_EXT, InternalFormatInfo::LUMAFormat(16, 16, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT,    GL_FLOAT,               AlwaysSupported)));
751
752    // Unsized formats
753    //                               | Internal format   |                                 | Format            | Supported     |
754    map.insert(InternalFormatInfoPair(GL_ALPHA,           InternalFormatInfo::UnsizedFormat(GL_ALPHA,           AlwaysSupported)));
755    map.insert(InternalFormatInfoPair(GL_LUMINANCE,       InternalFormatInfo::UnsizedFormat(GL_LUMINANCE,       AlwaysSupported)));
756    map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA, InternalFormatInfo::UnsizedFormat(GL_LUMINANCE_ALPHA, AlwaysSupported)));
757    map.insert(InternalFormatInfoPair(GL_RED,             InternalFormatInfo::UnsizedFormat(GL_RED,             AlwaysSupported)));
758    map.insert(InternalFormatInfoPair(GL_RG,              InternalFormatInfo::UnsizedFormat(GL_RG,              AlwaysSupported)));
759    map.insert(InternalFormatInfoPair(GL_RGB,             InternalFormatInfo::UnsizedFormat(GL_RGB,             AlwaysSupported)));
760    map.insert(InternalFormatInfoPair(GL_RGBA,            InternalFormatInfo::UnsizedFormat(GL_RGBA,            AlwaysSupported)));
761    map.insert(InternalFormatInfoPair(GL_RED_INTEGER,     InternalFormatInfo::UnsizedFormat(GL_RED_INTEGER,     AlwaysSupported)));
762    map.insert(InternalFormatInfoPair(GL_RG_INTEGER,      InternalFormatInfo::UnsizedFormat(GL_RG_INTEGER,      AlwaysSupported)));
763    map.insert(InternalFormatInfoPair(GL_RGB_INTEGER,     InternalFormatInfo::UnsizedFormat(GL_RGB_INTEGER,     AlwaysSupported)));
764    map.insert(InternalFormatInfoPair(GL_RGBA_INTEGER,    InternalFormatInfo::UnsizedFormat(GL_RGBA_INTEGER,    AlwaysSupported)));
765    map.insert(InternalFormatInfoPair(GL_BGRA_EXT,        InternalFormatInfo::UnsizedFormat(GL_BGRA_EXT,        AlwaysSupported)));
766
767    // Compressed formats, From ES 3.0.1 spec, table 3.16
768    //                               | Internal format                             |                                    |W |H | BS |CC| Format                                      | Type            | SRGB | Supported          |
769    map.insert(InternalFormatInfoPair(GL_COMPRESSED_R11_EAC,                        InternalFormatInfo::CompressedFormat(4, 4,  64, 1, GL_COMPRESSED_R11_EAC,                        GL_UNSIGNED_BYTE, false, UnimplementedSupport)));
770    map.insert(InternalFormatInfoPair(GL_COMPRESSED_SIGNED_R11_EAC,                 InternalFormatInfo::CompressedFormat(4, 4,  64, 1, GL_COMPRESSED_SIGNED_R11_EAC,                 GL_UNSIGNED_BYTE, false, UnimplementedSupport)));
771    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RG11_EAC,                       InternalFormatInfo::CompressedFormat(4, 4, 128, 2, GL_COMPRESSED_RG11_EAC,                       GL_UNSIGNED_BYTE, false, UnimplementedSupport)));
772    map.insert(InternalFormatInfoPair(GL_COMPRESSED_SIGNED_RG11_EAC,                InternalFormatInfo::CompressedFormat(4, 4, 128, 2, GL_COMPRESSED_SIGNED_RG11_EAC,                GL_UNSIGNED_BYTE, false, UnimplementedSupport)));
773    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB8_ETC2,                      InternalFormatInfo::CompressedFormat(4, 4,  64, 3, GL_COMPRESSED_RGB8_ETC2,                      GL_UNSIGNED_BYTE, false, UnimplementedSupport)));
774    map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ETC2,                     InternalFormatInfo::CompressedFormat(4, 4,  64, 3, GL_COMPRESSED_SRGB8_ETC2,                     GL_UNSIGNED_BYTE, true,  UnimplementedSupport)));
775    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)));
776    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)));
777    map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA8_ETC2_EAC,                 InternalFormatInfo::CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA8_ETC2_EAC,                 GL_UNSIGNED_BYTE, false, UnimplementedSupport)));
778    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)));
779
780    // From GL_EXT_texture_compression_dxt1
781    //                               | Internal format                   |                                    |W |H | BS |CC| Format                            | Type            | SRGB | Supported     |
782    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, AlwaysSupported)));
783    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, AlwaysSupported)));
784
785    // From GL_ANGLE_texture_compression_dxt3
786    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, AlwaysSupported)));
787
788    // From GL_ANGLE_texture_compression_dxt5
789    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, AlwaysSupported)));
790
791    return map;
792}
793
794static InternalFormatInfoMap BuildES2InternalFormatInfoMap()
795{
796    InternalFormatInfoMap map;
797
798    // From ES 2.0.25 table 4.5
799    map.insert(InternalFormatInfoPair(GL_NONE,                 InternalFormatInfo()));
800
801    //                               | Internal format        |                              | R | G | B | A |S | Format          | Type                     | Component type        | SRGB | Color         | Texture        | Supported      |
802    //                               |                        |                              |   |   |   |   |  |                 |                          |                       |      | renderable    | filterable     |                |
803    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, AlwaysSupported, AlwaysSupported, AlwaysSupported)));
804    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, AlwaysSupported, AlwaysSupported, AlwaysSupported)));
805    map.insert(InternalFormatInfoPair(GL_RGB565,               InternalFormatInfo::RGBAFormat( 5,  6,  5,  0, 0, GL_RGB,           GL_UNSIGNED_SHORT_5_6_5,   GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported)));
806
807    // Extension formats
808    map.insert(InternalFormatInfoPair(GL_R8_EXT,               InternalFormatInfo::RGBAFormat( 8,  0,  0,  0, 0, GL_RED_EXT,       GL_UNSIGNED_BYTE,          GL_UNSIGNED_NORMALIZED, false, CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>, CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>, CheckSupport<&Context::supportsRGTextures>)));
809    map.insert(InternalFormatInfoPair(GL_RG8_EXT,              InternalFormatInfo::RGBAFormat( 8,  8,  0,  0, 0, GL_RG_EXT,        GL_UNSIGNED_BYTE,          GL_UNSIGNED_NORMALIZED, false, CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>, CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>, CheckSupport<&Context::supportsRGTextures>)));
810    map.insert(InternalFormatInfoPair(GL_RGB8_OES,             InternalFormatInfo::RGBAFormat( 8,  8,  8,  0, 0, GL_RGB,           GL_UNSIGNED_BYTE,          GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported)));
811    map.insert(InternalFormatInfoPair(GL_RGBA8_OES,            InternalFormatInfo::RGBAFormat( 8,  8,  8,  8, 0, GL_RGBA,          GL_UNSIGNED_BYTE,          GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported)));
812    map.insert(InternalFormatInfoPair(GL_BGRA8_EXT,            InternalFormatInfo::RGBAFormat( 8,  8,  8,  8, 0, GL_BGRA_EXT,      GL_UNSIGNED_BYTE,          GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported)));
813    map.insert(InternalFormatInfoPair(GL_BGRA4_ANGLEX,         InternalFormatInfo::RGBAFormat( 4,  4,  4,  4, 0, GL_BGRA_EXT,      GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_NORMALIZED, false, NeverSupported,  AlwaysSupported, AlwaysSupported)));
814    map.insert(InternalFormatInfoPair(GL_BGR5_A1_ANGLEX,       InternalFormatInfo::RGBAFormat( 5,  5,  5,  1, 0, GL_BGRA_EXT,      GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_NORMALIZED, false, NeverSupported,  AlwaysSupported, AlwaysSupported)));
815
816    // Floating point formats have to query the renderer for support
817    //                               | Internal format        |                              | R | G | B | A |S | Format          | Type                     | Comp    | SRGB | Color renderable                                                                                           | Texture filterable                                                                                   | Supported                                     |
818    //                               |                        |                              |   |   |   |   |  |                 |                          | type    |      |                                                                                                            |                                                                                                      |                                               |
819    map.insert(InternalFormatInfoPair(GL_R16F_EXT,             InternalFormatInfo::RGBAFormat(16,  0,  0,  0, 0, GL_RED,           GL_HALF_FLOAT_OES,         GL_FLOAT, false, CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>,                              CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>,                        CheckSupport<&Context::supportsRGTextures>     )));
820    map.insert(InternalFormatInfoPair(GL_R32F_EXT,             InternalFormatInfo::RGBAFormat(32,  0,  0,  0, 0, GL_RED,           GL_FLOAT,                  GL_FLOAT, false, CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>,                              CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>,                        CheckSupport<&Context::supportsRGTextures>     )));
821    map.insert(InternalFormatInfoPair(GL_RG16F_EXT,            InternalFormatInfo::RGBAFormat(16, 16,  0,  0, 0, GL_RG,            GL_HALF_FLOAT_OES,         GL_FLOAT, false, CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>,                              CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>,                        CheckSupport<&Context::supportsRGTextures>     )));
822    map.insert(InternalFormatInfoPair(GL_RG32F_EXT,            InternalFormatInfo::RGBAFormat(32, 32,  0,  0, 0, GL_RG,            GL_FLOAT,                  GL_FLOAT, false, CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>,                              CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>,                        CheckSupport<&Context::supportsRGTextures>     )));
823    map.insert(InternalFormatInfoPair(GL_RGB16F_EXT,           InternalFormatInfo::RGBAFormat(16, 16, 16,  0, 0, GL_RGB,           GL_HALF_FLOAT_OES,         GL_FLOAT, false, CheckSupport<&Context::supportsFloat16RenderableTextures, &rx::Renderer::getFloat16TextureRenderingSupport>, CheckSupport<&Context::supportsFloat16LinearFilter, &rx::Renderer::getFloat16TextureFilteringSupport>, CheckSupport<&Context::supportsFloat16Textures>)));
824    map.insert(InternalFormatInfoPair(GL_RGB32F_EXT,           InternalFormatInfo::RGBAFormat(32, 32, 32,  0, 0, GL_RGB,           GL_FLOAT,                  GL_FLOAT, false, CheckSupport<&Context::supportsFloat32RenderableTextures, &rx::Renderer::getFloat32TextureRenderingSupport>, CheckSupport<&Context::supportsFloat32LinearFilter, &rx::Renderer::getFloat32TextureFilteringSupport>, CheckSupport<&Context::supportsFloat32Textures>)));
825    map.insert(InternalFormatInfoPair(GL_RGBA16F_EXT,          InternalFormatInfo::RGBAFormat(16, 16, 16, 16, 0, GL_RGBA,          GL_HALF_FLOAT_OES,         GL_FLOAT, false, CheckSupport<&Context::supportsFloat16RenderableTextures, &rx::Renderer::getFloat16TextureRenderingSupport>, CheckSupport<&Context::supportsFloat16LinearFilter, &rx::Renderer::getFloat16TextureFilteringSupport>, CheckSupport<&Context::supportsFloat16Textures>)));
826    map.insert(InternalFormatInfoPair(GL_RGBA32F_EXT,          InternalFormatInfo::RGBAFormat(32, 32, 32, 32, 0, GL_RGBA,          GL_FLOAT,                  GL_FLOAT, false, CheckSupport<&Context::supportsFloat32RenderableTextures, &rx::Renderer::getFloat32TextureRenderingSupport>, CheckSupport<&Context::supportsFloat32LinearFilter, &rx::Renderer::getFloat32TextureFilteringSupport>, CheckSupport<&Context::supportsFloat32Textures>)));
827
828    // Depth and stencil formats
829    //                               | Internal format        |                                      | D |S |X | Format              | Type                     | Internal format     | Depth          | Stencil         | Supported                                  |
830    //                               |                        |                                      |   |  |  |                     |                          | type                | renderable     | renderable      |                                            |
831    map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32_OES,InternalFormatInfo::DepthStencilFormat(32, 0, 0, GL_DEPTH_COMPONENT,   GL_UNSIGNED_INT,           GL_UNSIGNED_NORMALIZED, AlwaysSupported, NeverSupported,  CheckSupport<&Context::supportsDepthTextures>)));
832    map.insert(InternalFormatInfoPair(GL_DEPTH24_STENCIL8_OES, InternalFormatInfo::DepthStencilFormat(24, 8, 0, GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES,  GL_UNSIGNED_NORMALIZED, AlwaysSupported, AlwaysSupported, CheckSupport<&Context::supportsDepthTextures>)));
833    map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT16,    InternalFormatInfo::DepthStencilFormat(16, 0, 0, GL_DEPTH_COMPONENT,   GL_UNSIGNED_SHORT,         GL_UNSIGNED_NORMALIZED, AlwaysSupported, NeverSupported,  AlwaysSupported)));
834    map.insert(InternalFormatInfoPair(GL_STENCIL_INDEX8,       InternalFormatInfo::DepthStencilFormat( 0, 8, 0, GL_DEPTH_STENCIL_OES, GL_UNSIGNED_BYTE,          GL_UNSIGNED_NORMALIZED, NeverSupported,  AlwaysSupported, AlwaysSupported)));
835
836    // Unsized formats
837    //                               | Internal format        |                                 | Format              | Supported     |
838    map.insert(InternalFormatInfoPair(GL_ALPHA,                InternalFormatInfo::UnsizedFormat(GL_ALPHA,             AlwaysSupported)));
839    map.insert(InternalFormatInfoPair(GL_LUMINANCE,            InternalFormatInfo::UnsizedFormat(GL_LUMINANCE,         AlwaysSupported)));
840    map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA,      InternalFormatInfo::UnsizedFormat(GL_LUMINANCE_ALPHA,   AlwaysSupported)));
841    map.insert(InternalFormatInfoPair(GL_RED_EXT,              InternalFormatInfo::UnsizedFormat(GL_RED_EXT,           CheckSupport<&Context::supportsRGTextures>)));
842    map.insert(InternalFormatInfoPair(GL_RG_EXT,               InternalFormatInfo::UnsizedFormat(GL_RG_EXT,            CheckSupport<&Context::supportsRGTextures>)));
843    map.insert(InternalFormatInfoPair(GL_RGB,                  InternalFormatInfo::UnsizedFormat(GL_RGB,               AlwaysSupported)));
844    map.insert(InternalFormatInfoPair(GL_RGBA,                 InternalFormatInfo::UnsizedFormat(GL_RGBA,              AlwaysSupported)));
845    map.insert(InternalFormatInfoPair(GL_BGRA_EXT,             InternalFormatInfo::UnsizedFormat(GL_BGRA_EXT,          AlwaysSupported)));
846    map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT,      InternalFormatInfo::UnsizedFormat(GL_DEPTH_COMPONENT,   AlwaysSupported)));
847    map.insert(InternalFormatInfoPair(GL_DEPTH_STENCIL_OES,    InternalFormatInfo::UnsizedFormat(GL_DEPTH_STENCIL_OES, AlwaysSupported)));
848
849    // Luminance alpha formats from GL_EXT_texture_storage
850    //                               | Internal format          |                              | L | A | Format                   | Type                     | Component type        | Supported     |
851    map.insert(InternalFormatInfoPair(GL_ALPHA8_EXT,             InternalFormatInfo::LUMAFormat( 0,  8, GL_ALPHA,                  GL_UNSIGNED_BYTE,          GL_UNSIGNED_NORMALIZED, AlwaysSupported)));
852    map.insert(InternalFormatInfoPair(GL_LUMINANCE8_EXT,         InternalFormatInfo::LUMAFormat( 8,  0, GL_LUMINANCE,              GL_UNSIGNED_BYTE,          GL_UNSIGNED_NORMALIZED, AlwaysSupported)));
853    map.insert(InternalFormatInfoPair(GL_ALPHA32F_EXT,           InternalFormatInfo::LUMAFormat( 0, 32, GL_ALPHA,                  GL_FLOAT,                  GL_FLOAT,               AlwaysSupported)));
854    map.insert(InternalFormatInfoPair(GL_LUMINANCE32F_EXT,       InternalFormatInfo::LUMAFormat(32,  0, GL_LUMINANCE,              GL_FLOAT,                  GL_FLOAT,               AlwaysSupported)));
855    map.insert(InternalFormatInfoPair(GL_ALPHA16F_EXT,           InternalFormatInfo::LUMAFormat( 0, 16, GL_ALPHA,                  GL_HALF_FLOAT_OES,         GL_FLOAT,               AlwaysSupported)));
856    map.insert(InternalFormatInfoPair(GL_LUMINANCE16F_EXT,       InternalFormatInfo::LUMAFormat(16,  0, GL_LUMINANCE,              GL_HALF_FLOAT_OES,         GL_FLOAT,               AlwaysSupported)));
857    map.insert(InternalFormatInfoPair(GL_LUMINANCE8_ALPHA8_EXT,  InternalFormatInfo::LUMAFormat( 8,  8, GL_LUMINANCE_ALPHA,        GL_UNSIGNED_BYTE,          GL_UNSIGNED_NORMALIZED, AlwaysSupported)));
858    map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA32F_EXT, InternalFormatInfo::LUMAFormat(32, 32, GL_LUMINANCE_ALPHA,        GL_FLOAT,                  GL_FLOAT,               AlwaysSupported)));
859    map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA16F_EXT, InternalFormatInfo::LUMAFormat(16, 16, GL_LUMINANCE_ALPHA,        GL_HALF_FLOAT_OES,         GL_FLOAT,               AlwaysSupported)));
860
861    // From GL_EXT_texture_compression_dxt1
862    //                               | Internal format                   |                                    |W |H | BS |CC|Format                             | Type            | SRGB | Supported                                  |
863    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, CheckSupport<&Context::supportsDXT1Textures>)));
864    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, CheckSupport<&Context::supportsDXT1Textures>)));
865
866    // From GL_ANGLE_texture_compression_dxt3
867    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, CheckSupport<&Context::supportsDXT3Textures>)));
868
869    // From GL_ANGLE_texture_compression_dxt5
870    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, CheckSupport<&Context::supportsDXT5Textures>)));
871
872    return map;
873}
874
875static bool GetInternalFormatInfo(GLenum internalFormat, GLuint clientVersion, InternalFormatInfo *outFormatInfo)
876{
877    const InternalFormatInfoMap* map = NULL;
878
879    if (clientVersion == 2)
880    {
881        static const InternalFormatInfoMap formatMap = BuildES2InternalFormatInfoMap();
882        map = &formatMap;
883    }
884    else if (clientVersion == 3)
885    {
886        static const InternalFormatInfoMap formatMap = BuildES3InternalFormatInfoMap();
887        map = &formatMap;
888    }
889    else
890    {
891        UNREACHABLE();
892    }
893
894    InternalFormatInfoMap::const_iterator iter = map->find(internalFormat);
895    if (iter != map->end())
896    {
897        if (outFormatInfo)
898        {
899            *outFormatInfo = iter->second;
900        }
901        return true;
902    }
903    else
904    {
905        return false;
906    }
907}
908
909typedef std::set<GLenum> FormatSet;
910
911static FormatSet BuildES2ValidFormatSet()
912{
913    static const FormatMap &formatMap = GetFormatMap(2);
914
915    FormatSet set;
916
917    for (FormatMap::const_iterator i = formatMap.begin(); i != formatMap.end(); i++)
918    {
919        const FormatTypePair& formatPair = i->first;
920        set.insert(formatPair.first);
921    }
922
923    return set;
924}
925
926static FormatSet BuildES3ValidFormatSet()
927{
928    static const ES3FormatSet &formatSet = GetES3FormatSet();
929
930    FormatSet set;
931
932    for (ES3FormatSet::const_iterator i = formatSet.begin(); i != formatSet.end(); i++)
933    {
934        const FormatInfo& formatInfo = *i;
935        set.insert(formatInfo.mFormat);
936    }
937
938    return set;
939}
940
941typedef std::set<GLenum> TypeSet;
942
943static TypeSet BuildES2ValidTypeSet()
944{
945    static const FormatMap &formatMap = GetFormatMap(2);
946
947    TypeSet set;
948
949    for (FormatMap::const_iterator i = formatMap.begin(); i != formatMap.end(); i++)
950    {
951        const FormatTypePair& formatPair = i->first;
952        set.insert(formatPair.second);
953    }
954
955    return set;
956}
957
958static TypeSet BuildES3ValidTypeSet()
959{
960    static const ES3FormatSet &formatSet = GetES3FormatSet();
961
962    TypeSet set;
963
964    for (ES3FormatSet::const_iterator i = formatSet.begin(); i != formatSet.end(); i++)
965    {
966        const FormatInfo& formatInfo = *i;
967        set.insert(formatInfo.mType);
968    }
969
970    return set;
971}
972
973struct EffectiveInternalFormatInfo
974{
975    GLenum mEffectiveFormat;
976    GLenum mDestFormat;
977    GLuint mMinRedBits;
978    GLuint mMaxRedBits;
979    GLuint mMinGreenBits;
980    GLuint mMaxGreenBits;
981    GLuint mMinBlueBits;
982    GLuint mMaxBlueBits;
983    GLuint mMinAlphaBits;
984    GLuint mMaxAlphaBits;
985
986    EffectiveInternalFormatInfo(GLenum effectiveFormat, GLenum destFormat, GLuint minRedBits, GLuint maxRedBits,
987                                GLuint minGreenBits, GLuint maxGreenBits, GLuint minBlueBits, GLuint maxBlueBits,
988                                GLuint minAlphaBits, GLuint maxAlphaBits)
989        : mEffectiveFormat(effectiveFormat), mDestFormat(destFormat), mMinRedBits(minRedBits),
990          mMaxRedBits(maxRedBits), mMinGreenBits(minGreenBits), mMaxGreenBits(maxGreenBits),
991          mMinBlueBits(minBlueBits), mMaxBlueBits(maxBlueBits), mMinAlphaBits(minAlphaBits),
992          mMaxAlphaBits(maxAlphaBits) {};
993};
994
995typedef std::vector<EffectiveInternalFormatInfo> EffectiveInternalFormatList;
996
997static EffectiveInternalFormatList BuildSizedEffectiveInternalFormatList()
998{
999    EffectiveInternalFormatList list;
1000
1001    // OpenGL ES 3.0.3 Specification, Table 3.17, pg 141: Effective internal format coresponding to destination internal format and
1002    //                                                    linear source buffer component sizes.
1003    //                                                                            | Source channel min/max sizes |
1004    //                                         Effective Internal Format |  N/A   |  R   |  G   |  B   |  A      |
1005    list.push_back(EffectiveInternalFormatInfo(GL_ALPHA8_EXT,              GL_NONE, 0,  0, 0,  0, 0,  0, 1, 8));
1006    list.push_back(EffectiveInternalFormatInfo(GL_R8,                      GL_NONE, 1,  8, 0,  0, 0,  0, 0, 0));
1007    list.push_back(EffectiveInternalFormatInfo(GL_RG8,                     GL_NONE, 1,  8, 1,  8, 0,  0, 0, 0));
1008    list.push_back(EffectiveInternalFormatInfo(GL_RGB565,                  GL_NONE, 1,  5, 1,  6, 1,  5, 0, 0));
1009    list.push_back(EffectiveInternalFormatInfo(GL_RGB8,                    GL_NONE, 6,  8, 7,  8, 6,  8, 0, 0));
1010    list.push_back(EffectiveInternalFormatInfo(GL_RGBA4,                   GL_NONE, 1,  4, 1,  4, 1,  4, 1, 4));
1011    list.push_back(EffectiveInternalFormatInfo(GL_RGB5_A1,                 GL_NONE, 5,  5, 5,  5, 5,  5, 1, 1));
1012    list.push_back(EffectiveInternalFormatInfo(GL_RGBA8,                   GL_NONE, 5,  8, 5,  8, 5,  8, 2, 8));
1013    list.push_back(EffectiveInternalFormatInfo(GL_RGB10_A2,                GL_NONE, 9, 10, 9, 10, 9, 10, 2, 2));
1014
1015    return list;
1016}
1017
1018
1019static EffectiveInternalFormatList BuildUnsizedEffectiveInternalFormatList()
1020{
1021    EffectiveInternalFormatList list;
1022
1023    // OpenGL ES 3.0.3 Specification, Table 3.17, pg 141: Effective internal format coresponding to destination internal format and
1024    //                                                    linear source buffer component sizes.
1025    //                                                                                        |          Source channel min/max sizes            |
1026    //                                         Effective Internal Format |    Dest Format     |     R     |      G     |      B     |      A     |
1027    list.push_back(EffectiveInternalFormatInfo(GL_ALPHA8_EXT,              GL_ALPHA,           0, UINT_MAX, 0, UINT_MAX, 0, UINT_MAX, 1,        8));
1028    list.push_back(EffectiveInternalFormatInfo(GL_LUMINANCE8_EXT,          GL_LUMINANCE,       1,        8, 0, UINT_MAX, 0, UINT_MAX, 0, UINT_MAX));
1029    list.push_back(EffectiveInternalFormatInfo(GL_LUMINANCE8_ALPHA8_EXT,   GL_LUMINANCE_ALPHA, 1,        8, 0, UINT_MAX, 0, UINT_MAX, 1,        8));
1030    list.push_back(EffectiveInternalFormatInfo(GL_RGB565,                  GL_RGB,             1,        5, 1,        6, 1,        5, 0, UINT_MAX));
1031    list.push_back(EffectiveInternalFormatInfo(GL_RGB8,                    GL_RGB,             6,        8, 7,        8, 6,        8, 0, UINT_MAX));
1032    list.push_back(EffectiveInternalFormatInfo(GL_RGBA4,                   GL_RGBA,            1,        4, 1,        4, 1,        4, 1,        4));
1033    list.push_back(EffectiveInternalFormatInfo(GL_RGB5_A1,                 GL_RGBA,            5,        5, 5,        5, 5,        5, 1,        1));
1034    list.push_back(EffectiveInternalFormatInfo(GL_RGBA8,                   GL_RGBA,            5,        8, 5,        8, 5,        8, 5,        8));
1035
1036    return list;
1037}
1038
1039static bool GetEffectiveInternalFormat(const InternalFormatInfo &srcFormat, const InternalFormatInfo &destFormat,
1040                                       GLuint clientVersion, GLenum *outEffectiveFormat)
1041{
1042    const EffectiveInternalFormatList *list = NULL;
1043    GLenum targetFormat = GL_NONE;
1044
1045    if (gl::IsSizedInternalFormat(destFormat.mFormat, clientVersion))
1046    {
1047        static const EffectiveInternalFormatList sizedList = BuildSizedEffectiveInternalFormatList();
1048        list = &sizedList;
1049    }
1050    else
1051    {
1052        static const EffectiveInternalFormatList unsizedList = BuildUnsizedEffectiveInternalFormatList();
1053        list = &unsizedList;
1054        targetFormat = destFormat.mFormat;
1055    }
1056
1057    for (size_t curFormat = 0; curFormat < list->size(); ++curFormat)
1058    {
1059        const EffectiveInternalFormatInfo& formatInfo = list->at(curFormat);
1060        if ((formatInfo.mDestFormat == targetFormat) &&
1061            (formatInfo.mMinRedBits   <= srcFormat.mRedBits   && formatInfo.mMaxRedBits   >= srcFormat.mRedBits)   &&
1062            (formatInfo.mMinGreenBits <= srcFormat.mGreenBits && formatInfo.mMaxGreenBits >= srcFormat.mGreenBits) &&
1063            (formatInfo.mMinBlueBits  <= srcFormat.mBlueBits  && formatInfo.mMaxBlueBits  >= srcFormat.mBlueBits)  &&
1064            (formatInfo.mMinAlphaBits <= srcFormat.mAlphaBits && formatInfo.mMaxAlphaBits >= srcFormat.mAlphaBits))
1065        {
1066            *outEffectiveFormat = formatInfo.mEffectiveFormat;
1067            return true;
1068        }
1069    }
1070
1071    return false;
1072}
1073
1074struct CopyConversion
1075{
1076    GLenum mTextureFormat;
1077    GLenum mFramebufferFormat;
1078
1079    CopyConversion(GLenum textureFormat, GLenum framebufferFormat)
1080        : mTextureFormat(textureFormat), mFramebufferFormat(framebufferFormat) { }
1081
1082    bool operator<(const CopyConversion& other) const
1083    {
1084        return memcmp(this, &other, sizeof(CopyConversion)) < 0;
1085    }
1086};
1087
1088typedef std::set<CopyConversion> CopyConversionSet;
1089
1090static CopyConversionSet BuildValidES3CopyTexImageCombinations()
1091{
1092    CopyConversionSet set;
1093
1094    // From ES 3.0.1 spec, table 3.15
1095    set.insert(CopyConversion(GL_ALPHA,           GL_RGBA));
1096    set.insert(CopyConversion(GL_LUMINANCE,       GL_RED));
1097    set.insert(CopyConversion(GL_LUMINANCE,       GL_RG));
1098    set.insert(CopyConversion(GL_LUMINANCE,       GL_RGB));
1099    set.insert(CopyConversion(GL_LUMINANCE,       GL_RGBA));
1100    set.insert(CopyConversion(GL_LUMINANCE_ALPHA, GL_RGBA));
1101    set.insert(CopyConversion(GL_RED,             GL_RED));
1102    set.insert(CopyConversion(GL_RED,             GL_RG));
1103    set.insert(CopyConversion(GL_RED,             GL_RGB));
1104    set.insert(CopyConversion(GL_RED,             GL_RGBA));
1105    set.insert(CopyConversion(GL_RG,              GL_RG));
1106    set.insert(CopyConversion(GL_RG,              GL_RGB));
1107    set.insert(CopyConversion(GL_RG,              GL_RGBA));
1108    set.insert(CopyConversion(GL_RGB,             GL_RGB));
1109    set.insert(CopyConversion(GL_RGB,             GL_RGBA));
1110    set.insert(CopyConversion(GL_RGBA,            GL_RGBA));
1111
1112    // Necessary for ANGLE back-buffers
1113    set.insert(CopyConversion(GL_ALPHA,           GL_BGRA_EXT));
1114    set.insert(CopyConversion(GL_LUMINANCE,       GL_BGRA_EXT));
1115    set.insert(CopyConversion(GL_LUMINANCE_ALPHA, GL_BGRA_EXT));
1116    set.insert(CopyConversion(GL_RED,             GL_BGRA_EXT));
1117    set.insert(CopyConversion(GL_RG,              GL_BGRA_EXT));
1118    set.insert(CopyConversion(GL_RGB,             GL_BGRA_EXT));
1119    set.insert(CopyConversion(GL_RGBA,            GL_BGRA_EXT));
1120
1121    set.insert(CopyConversion(GL_RED_INTEGER,     GL_RED_INTEGER));
1122    set.insert(CopyConversion(GL_RED_INTEGER,     GL_RG_INTEGER));
1123    set.insert(CopyConversion(GL_RED_INTEGER,     GL_RGB_INTEGER));
1124    set.insert(CopyConversion(GL_RED_INTEGER,     GL_RGBA_INTEGER));
1125    set.insert(CopyConversion(GL_RG_INTEGER,      GL_RG_INTEGER));
1126    set.insert(CopyConversion(GL_RG_INTEGER,      GL_RGB_INTEGER));
1127    set.insert(CopyConversion(GL_RG_INTEGER,      GL_RGBA_INTEGER));
1128    set.insert(CopyConversion(GL_RGB_INTEGER,     GL_RGB_INTEGER));
1129    set.insert(CopyConversion(GL_RGB_INTEGER,     GL_RGBA_INTEGER));
1130    set.insert(CopyConversion(GL_RGBA_INTEGER,    GL_RGBA_INTEGER));
1131
1132    return set;
1133}
1134
1135bool IsValidInternalFormat(GLenum internalFormat, const Context *context)
1136{
1137    if (!context)
1138    {
1139        return false;
1140    }
1141
1142    InternalFormatInfo internalFormatInfo;
1143    if (GetInternalFormatInfo(internalFormat, context->getClientVersion(), &internalFormatInfo))
1144    {
1145        ASSERT(internalFormatInfo.mSupportFunction != NULL);
1146        return internalFormatInfo.mSupportFunction(context);
1147    }
1148    else
1149    {
1150        return false;
1151    }
1152}
1153
1154bool IsValidFormat(GLenum format, GLuint clientVersion)
1155{
1156    if (clientVersion == 2)
1157    {
1158        static const FormatSet formatSet = BuildES2ValidFormatSet();
1159        return formatSet.find(format) != formatSet.end();
1160    }
1161    else if (clientVersion == 3)
1162    {
1163        static const FormatSet formatSet = BuildES3ValidFormatSet();
1164        return formatSet.find(format) != formatSet.end();
1165    }
1166    else
1167    {
1168        UNREACHABLE();
1169        return false;
1170    }
1171}
1172
1173bool IsValidType(GLenum type, GLuint clientVersion)
1174{
1175    if (clientVersion == 2)
1176    {
1177        static const TypeSet typeSet = BuildES2ValidTypeSet();
1178        return typeSet.find(type) != typeSet.end();
1179    }
1180    else if (clientVersion == 3)
1181    {
1182        static const TypeSet typeSet = BuildES3ValidTypeSet();
1183        return typeSet.find(type) != typeSet.end();
1184    }
1185    else
1186    {
1187        UNREACHABLE();
1188        return false;
1189    }
1190}
1191
1192bool IsValidFormatCombination(GLenum internalFormat, GLenum format, GLenum type, GLuint clientVersion)
1193{
1194    if (clientVersion == 2)
1195    {
1196        static const FormatMap &formats = GetFormatMap(clientVersion);
1197        FormatMap::const_iterator iter = formats.find(FormatTypePair(format, type));
1198
1199        return (iter != formats.end()) && ((internalFormat == (GLint)type) || (internalFormat == iter->second.mInternalFormat));
1200    }
1201    else if (clientVersion == 3)
1202    {
1203        static const ES3FormatSet &formats = GetES3FormatSet();
1204        return formats.find(FormatInfo(internalFormat, format, type)) != formats.end();
1205    }
1206    else
1207    {
1208        UNREACHABLE();
1209        return false;
1210    }
1211}
1212
1213bool IsValidCopyTexImageCombination(GLenum textureInternalFormat, GLenum frameBufferInternalFormat, GLuint readBufferHandle, GLuint clientVersion)
1214{
1215    InternalFormatInfo textureInternalFormatInfo;
1216    InternalFormatInfo framebufferInternalFormatInfo;
1217    if (GetInternalFormatInfo(textureInternalFormat, clientVersion, &textureInternalFormatInfo) &&
1218        GetInternalFormatInfo(frameBufferInternalFormat, clientVersion, &framebufferInternalFormatInfo))
1219    {
1220        if (clientVersion == 2)
1221        {
1222            UNIMPLEMENTED();
1223            return false;
1224        }
1225        else if (clientVersion == 3)
1226        {
1227            static const CopyConversionSet conversionSet = BuildValidES3CopyTexImageCombinations();
1228            const CopyConversion conversion = CopyConversion(textureInternalFormatInfo.mFormat,
1229                                                             framebufferInternalFormatInfo.mFormat);
1230            if (conversionSet.find(conversion) != conversionSet.end())
1231            {
1232                // Section 3.8.5 of the GLES 3.0.3 spec states that source and destination formats
1233                // must both be signed, unsigned, or fixed point and both source and destinations
1234                // must be either both SRGB or both not SRGB. EXT_color_buffer_float adds allowed
1235                // conversion between fixed and floating point.
1236
1237                if ((textureInternalFormatInfo.mColorEncoding == GL_SRGB) != (framebufferInternalFormatInfo.mColorEncoding == GL_SRGB))
1238                {
1239                    return false;
1240                }
1241
1242                if (((textureInternalFormatInfo.mComponentType == GL_INT) != (framebufferInternalFormatInfo.mComponentType == GL_INT)) ||
1243                    ((textureInternalFormatInfo.mComponentType == GL_UNSIGNED_INT) != (framebufferInternalFormatInfo.mComponentType == GL_UNSIGNED_INT)))
1244                {
1245                    return false;
1246                }
1247
1248                if (gl::IsFloatOrFixedComponentType(textureInternalFormatInfo.mComponentType) &&
1249                    !gl::IsFloatOrFixedComponentType(framebufferInternalFormatInfo.mComponentType))
1250                {
1251                    return false;
1252                }
1253
1254                // GLES specification 3.0.3, sec 3.8.5, pg 139-140:
1255                // The effective internal format of the source buffer is determined with the following rules applied in order:
1256                //    * If the source buffer is a texture or renderbuffer that was created with a sized internal format then the
1257                //      effective internal format is the source buffer's sized internal format.
1258                //    * If the source buffer is a texture that was created with an unsized base internal format, then the
1259                //      effective internal format is the source image array's effective internal format, as specified by table
1260                //      3.12, which is determined from the <format> and <type> that were used when the source image array was
1261                //      specified by TexImage*.
1262                //    * Otherwise the effective internal format is determined by the row in table 3.17 or 3.18 where
1263                //      Destination Internal Format matches internalformat and where the [source channel sizes] are consistent
1264                //      with the values of the source buffer's [channel sizes]. Table 3.17 is used if the
1265                //      FRAMEBUFFER_ATTACHMENT_ENCODING is LINEAR and table 3.18 is used if the FRAMEBUFFER_ATTACHMENT_ENCODING
1266                //      is SRGB.
1267                InternalFormatInfo sourceEffectiveFormat;
1268                if (readBufferHandle != 0)
1269                {
1270                    // Not the default framebuffer, therefore the read buffer must be a user-created texture or renderbuffer
1271                    if (gl::IsSizedInternalFormat(framebufferInternalFormatInfo.mFormat, clientVersion))
1272                    {
1273                        sourceEffectiveFormat = framebufferInternalFormatInfo;
1274                    }
1275                    else
1276                    {
1277                        // Renderbuffers cannot be created with an unsized internal format, so this must be an unsized-format
1278                        // texture. We can use the same table we use when creating textures to get its effective sized format.
1279                        GLenum effectiveFormat = gl::GetSizedInternalFormat(framebufferInternalFormatInfo.mFormat,
1280                                                                            framebufferInternalFormatInfo.mType, clientVersion);
1281                        gl::GetInternalFormatInfo(effectiveFormat, clientVersion, &sourceEffectiveFormat);
1282                    }
1283                }
1284                else
1285                {
1286                    // The effective internal format must be derived from the source framebuffer's channel sizes.
1287                    // This is done in GetEffectiveInternalFormat for linear buffers (table 3.17)
1288                    if (framebufferInternalFormatInfo.mColorEncoding == GL_LINEAR)
1289                    {
1290                        GLenum effectiveFormat;
1291                        if (GetEffectiveInternalFormat(framebufferInternalFormatInfo, textureInternalFormatInfo, clientVersion, &effectiveFormat))
1292                        {
1293                            gl::GetInternalFormatInfo(effectiveFormat, clientVersion, &sourceEffectiveFormat);
1294                        }
1295                        else
1296                        {
1297                            return false;
1298                        }
1299                    }
1300                    else if (framebufferInternalFormatInfo.mColorEncoding == GL_SRGB)
1301                    {
1302                        // SRGB buffers can only be copied to sized format destinations according to table 3.18
1303                        if (gl::IsSizedInternalFormat(textureInternalFormat, clientVersion) &&
1304                            (framebufferInternalFormatInfo.mRedBits   >= 1 && framebufferInternalFormatInfo.mRedBits   <= 8) &&
1305                            (framebufferInternalFormatInfo.mGreenBits >= 1 && framebufferInternalFormatInfo.mGreenBits <= 8) &&
1306                            (framebufferInternalFormatInfo.mBlueBits  >= 1 && framebufferInternalFormatInfo.mBlueBits  <= 8) &&
1307                            (framebufferInternalFormatInfo.mAlphaBits >= 1 && framebufferInternalFormatInfo.mAlphaBits <= 8))
1308                        {
1309                            gl::GetInternalFormatInfo(GL_SRGB8_ALPHA8, clientVersion, &sourceEffectiveFormat);
1310                        }
1311                        else
1312                        {
1313                            return false;
1314                        }
1315                    }
1316                    else
1317                    {
1318                        UNREACHABLE();
1319                    }
1320                }
1321
1322                if (gl::IsSizedInternalFormat(textureInternalFormatInfo.mFormat, clientVersion))
1323                {
1324                    // Section 3.8.5 of the GLES 3.0.3 spec, pg 139, requires that, if the destination format is sized,
1325                    // component sizes of the source and destination formats must exactly match
1326                    if (textureInternalFormatInfo.mRedBits != sourceEffectiveFormat.mRedBits ||
1327                        textureInternalFormatInfo.mGreenBits != sourceEffectiveFormat.mGreenBits ||
1328                        textureInternalFormatInfo.mBlueBits != sourceEffectiveFormat.mBlueBits ||
1329                        textureInternalFormatInfo.mAlphaBits != sourceEffectiveFormat.mAlphaBits)
1330                    {
1331                        return false;
1332                    }
1333                }
1334
1335
1336                return true; // A conversion function exists, and no rule in the specification has precluded conversion
1337                             // between these formats.
1338            }
1339
1340            return false;
1341        }
1342        else
1343        {
1344            UNREACHABLE();
1345            return false;
1346        }
1347    }
1348    else
1349    {
1350        UNREACHABLE();
1351        return false;
1352    }
1353}
1354
1355bool IsSizedInternalFormat(GLenum internalFormat, GLuint clientVersion)
1356{
1357    InternalFormatInfo internalFormatInfo;
1358    if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
1359    {
1360        return internalFormatInfo.mPixelBits > 0;
1361    }
1362    else
1363    {
1364        UNREACHABLE();
1365        return false;
1366    }
1367}
1368
1369GLenum GetSizedInternalFormat(GLenum format, GLenum type, GLuint clientVersion)
1370{
1371    const FormatMap &formats = GetFormatMap(clientVersion);
1372    FormatMap::const_iterator iter = formats.find(FormatTypePair(format, type));
1373    return (iter != formats.end()) ? iter->second.mInternalFormat : GL_NONE;
1374}
1375
1376GLuint GetPixelBytes(GLenum internalFormat, GLuint clientVersion)
1377{
1378    InternalFormatInfo internalFormatInfo;
1379    if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
1380    {
1381        return internalFormatInfo.mPixelBits / 8;
1382    }
1383    else
1384    {
1385        UNREACHABLE();
1386        return 0;
1387    }
1388}
1389
1390GLuint GetAlphaBits(GLenum internalFormat, GLuint clientVersion)
1391{
1392    InternalFormatInfo internalFormatInfo;
1393    if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
1394    {
1395        return internalFormatInfo.mAlphaBits;
1396    }
1397    else
1398    {
1399        UNREACHABLE();
1400        return 0;
1401    }
1402}
1403
1404GLuint GetRedBits(GLenum internalFormat, GLuint clientVersion)
1405{
1406    InternalFormatInfo internalFormatInfo;
1407    if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
1408    {
1409        return internalFormatInfo.mRedBits;
1410    }
1411    else
1412    {
1413        UNREACHABLE();
1414        return 0;
1415    }
1416}
1417
1418GLuint GetGreenBits(GLenum internalFormat, GLuint clientVersion)
1419{
1420    InternalFormatInfo internalFormatInfo;
1421    if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
1422    {
1423        return internalFormatInfo.mGreenBits;
1424    }
1425    else
1426    {
1427        UNREACHABLE();
1428        return 0;
1429    }
1430}
1431
1432GLuint GetBlueBits(GLenum internalFormat, GLuint clientVersion)
1433{
1434    InternalFormatInfo internalFormatInfo;
1435    if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
1436    {
1437        return internalFormatInfo.mBlueBits;
1438    }
1439    else
1440    {
1441        UNREACHABLE();
1442        return 0;
1443    }
1444}
1445
1446GLuint GetLuminanceBits(GLenum internalFormat, GLuint clientVersion)
1447{
1448    InternalFormatInfo internalFormatInfo;
1449    if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
1450    {
1451        return internalFormatInfo.mLuminanceBits;
1452    }
1453    else
1454    {
1455        UNREACHABLE();
1456        return 0;
1457    }
1458}
1459
1460GLuint GetDepthBits(GLenum internalFormat, GLuint clientVersion)
1461{
1462    InternalFormatInfo internalFormatInfo;
1463    if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
1464    {
1465        return internalFormatInfo.mDepthBits;
1466    }
1467    else
1468    {
1469        UNREACHABLE();
1470        return 0;
1471    }
1472}
1473
1474GLuint GetStencilBits(GLenum internalFormat, GLuint clientVersion)
1475{
1476    InternalFormatInfo internalFormatInfo;
1477    if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
1478    {
1479        return internalFormatInfo.mStencilBits;
1480    }
1481    else
1482    {
1483        UNREACHABLE();
1484        return 0;
1485    }
1486}
1487
1488GLuint GetTypeBytes(GLenum type)
1489{
1490    TypeInfo typeInfo;
1491    if (GetTypeInfo(type, &typeInfo))
1492    {
1493        return typeInfo.mTypeBytes;
1494    }
1495    else
1496    {
1497        UNREACHABLE();
1498        return 0;
1499    }
1500}
1501
1502bool IsSpecialInterpretationType(GLenum type)
1503{
1504    TypeInfo typeInfo;
1505    if (GetTypeInfo(type, &typeInfo))
1506    {
1507        return typeInfo.mSpecialInterpretation;
1508    }
1509    else
1510    {
1511        UNREACHABLE();
1512        return false;
1513    }
1514}
1515
1516bool IsFloatOrFixedComponentType(GLenum type)
1517{
1518    if (type == GL_UNSIGNED_NORMALIZED ||
1519        type == GL_SIGNED_NORMALIZED ||
1520        type == GL_FLOAT)
1521    {
1522        return true;
1523    }
1524    else
1525    {
1526        return false;
1527    }
1528}
1529
1530GLenum GetFormat(GLenum internalFormat, GLuint clientVersion)
1531{
1532    InternalFormatInfo internalFormatInfo;
1533    if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
1534    {
1535        return internalFormatInfo.mFormat;
1536    }
1537    else
1538    {
1539        UNREACHABLE();
1540        return GL_NONE;
1541    }
1542}
1543
1544GLenum GetType(GLenum internalFormat, GLuint clientVersion)
1545{
1546    InternalFormatInfo internalFormatInfo;
1547    if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
1548    {
1549        return internalFormatInfo.mType;
1550    }
1551    else
1552    {
1553        UNREACHABLE();
1554        return GL_NONE;
1555    }
1556}
1557
1558GLenum GetComponentType(GLenum internalFormat, GLuint clientVersion)
1559{
1560    InternalFormatInfo internalFormatInfo;
1561    if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
1562    {
1563        return internalFormatInfo.mComponentType;
1564    }
1565    else
1566    {
1567        UNREACHABLE();
1568        return GL_NONE;
1569    }
1570}
1571
1572GLuint GetComponentCount(GLenum internalFormat, GLuint clientVersion)
1573{
1574    InternalFormatInfo internalFormatInfo;
1575    if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
1576    {
1577        return internalFormatInfo.mComponentCount;
1578    }
1579    else
1580    {
1581        UNREACHABLE();
1582        return false;
1583    }
1584}
1585
1586GLenum GetColorEncoding(GLenum internalFormat, GLuint clientVersion)
1587{
1588    InternalFormatInfo internalFormatInfo;
1589    if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
1590    {
1591        return internalFormatInfo.mColorEncoding;
1592    }
1593    else
1594    {
1595        UNREACHABLE();
1596        return false;
1597    }
1598}
1599
1600bool IsColorRenderingSupported(GLenum internalFormat, const rx::Renderer *renderer)
1601{
1602    InternalFormatInfo internalFormatInfo;
1603    if (renderer && GetInternalFormatInfo(internalFormat, renderer->getCurrentClientVersion(), &internalFormatInfo))
1604    {
1605        return internalFormatInfo.mIsColorRenderable(NULL, renderer);
1606    }
1607    else
1608    {
1609        UNREACHABLE();
1610        return false;
1611    }
1612}
1613
1614bool IsColorRenderingSupported(GLenum internalFormat, const Context *context)
1615{
1616    InternalFormatInfo internalFormatInfo;
1617    if (context && GetInternalFormatInfo(internalFormat, context->getClientVersion(), &internalFormatInfo))
1618    {
1619        return internalFormatInfo.mIsColorRenderable(context, NULL);
1620    }
1621    else
1622    {
1623        UNREACHABLE();
1624        return false;
1625    }
1626}
1627
1628bool IsTextureFilteringSupported(GLenum internalFormat, const rx::Renderer *renderer)
1629{
1630    InternalFormatInfo internalFormatInfo;
1631    if (renderer && GetInternalFormatInfo(internalFormat, renderer->getCurrentClientVersion(), &internalFormatInfo))
1632    {
1633        return internalFormatInfo.mIsTextureFilterable(NULL, renderer);
1634    }
1635    else
1636    {
1637        UNREACHABLE();
1638        return false;
1639    }
1640}
1641
1642bool IsTextureFilteringSupported(GLenum internalFormat, const Context *context)
1643{
1644    InternalFormatInfo internalFormatInfo;
1645    if (context && GetInternalFormatInfo(internalFormat, context->getClientVersion(), &internalFormatInfo))
1646    {
1647        return internalFormatInfo.mIsTextureFilterable(context, NULL);
1648    }
1649    else
1650    {
1651        UNREACHABLE();
1652        return false;
1653    }
1654}
1655
1656bool IsDepthRenderingSupported(GLenum internalFormat, const rx::Renderer *renderer)
1657{
1658    InternalFormatInfo internalFormatInfo;
1659    if (renderer && GetInternalFormatInfo(internalFormat, renderer->getCurrentClientVersion(), &internalFormatInfo))
1660    {
1661        return internalFormatInfo.mIsDepthRenderable(NULL, renderer);
1662    }
1663    else
1664    {
1665        UNREACHABLE();
1666        return false;
1667    }
1668}
1669
1670bool IsDepthRenderingSupported(GLenum internalFormat, const Context *context)
1671{
1672    InternalFormatInfo internalFormatInfo;
1673    if (context && GetInternalFormatInfo(internalFormat, context->getClientVersion(), &internalFormatInfo))
1674    {
1675        return internalFormatInfo.mIsDepthRenderable(context, NULL);
1676    }
1677    else
1678    {
1679        UNREACHABLE();
1680        return false;
1681    }
1682}
1683
1684bool IsStencilRenderingSupported(GLenum internalFormat, const rx::Renderer *renderer)
1685{
1686    InternalFormatInfo internalFormatInfo;
1687    if (renderer && GetInternalFormatInfo(internalFormat, renderer->getCurrentClientVersion(), &internalFormatInfo))
1688    {
1689        return internalFormatInfo.mIsStencilRenderable(NULL, renderer);
1690    }
1691    else
1692    {
1693        UNREACHABLE();
1694        return false;
1695    }
1696}
1697
1698bool IsStencilRenderingSupported(GLenum internalFormat, const Context *context)
1699{
1700    InternalFormatInfo internalFormatInfo;
1701    if (context && GetInternalFormatInfo(internalFormat, context->getClientVersion(), &internalFormatInfo))
1702    {
1703        return internalFormatInfo.mIsStencilRenderable(context, NULL);
1704    }
1705    else
1706    {
1707        UNREACHABLE();
1708        return false;
1709    }
1710}
1711
1712GLuint GetRowPitch(GLenum internalFormat, GLenum type, GLuint clientVersion, GLsizei width, GLint alignment)
1713{
1714    ASSERT(alignment > 0 && isPow2(alignment));
1715    return rx::roundUp(GetBlockSize(internalFormat, type, clientVersion, width, 1), static_cast<GLuint>(alignment));
1716}
1717
1718GLuint GetDepthPitch(GLenum internalFormat, GLenum type, GLuint clientVersion, GLsizei width, GLsizei height, GLint alignment)
1719{
1720    return GetRowPitch(internalFormat, type, clientVersion, width, alignment) * height;
1721}
1722
1723GLuint GetBlockSize(GLenum internalFormat, GLenum type, GLuint clientVersion, GLsizei width, GLsizei height)
1724{
1725    InternalFormatInfo internalFormatInfo;
1726    if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
1727    {
1728        if (internalFormatInfo.mIsCompressed)
1729        {
1730            GLsizei numBlocksWide = (width + internalFormatInfo.mCompressedBlockWidth - 1) / internalFormatInfo.mCompressedBlockWidth;
1731            GLsizei numBlocksHight = (height + internalFormatInfo.mCompressedBlockHeight - 1) / internalFormatInfo.mCompressedBlockHeight;
1732
1733            return (internalFormatInfo.mPixelBits * numBlocksWide * numBlocksHight) / 8;
1734        }
1735        else
1736        {
1737            TypeInfo typeInfo;
1738            if (GetTypeInfo(type, &typeInfo))
1739            {
1740                if (typeInfo.mSpecialInterpretation)
1741                {
1742                    return typeInfo.mTypeBytes * width * height;
1743                }
1744                else
1745                {
1746                    return internalFormatInfo.mComponentCount * typeInfo.mTypeBytes * width * height;
1747                }
1748            }
1749            else
1750            {
1751                UNREACHABLE();
1752                return 0;
1753            }
1754        }
1755    }
1756    else
1757    {
1758        UNREACHABLE();
1759        return 0;
1760    }
1761}
1762
1763bool IsFormatCompressed(GLenum internalFormat, GLuint clientVersion)
1764{
1765    InternalFormatInfo internalFormatInfo;
1766    if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
1767    {
1768        return internalFormatInfo.mIsCompressed;
1769    }
1770    else
1771    {
1772        UNREACHABLE();
1773        return false;
1774    }
1775}
1776
1777GLuint GetCompressedBlockWidth(GLenum internalFormat, GLuint clientVersion)
1778{
1779    InternalFormatInfo internalFormatInfo;
1780    if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
1781    {
1782        return internalFormatInfo.mCompressedBlockWidth;
1783    }
1784    else
1785    {
1786        UNREACHABLE();
1787        return 0;
1788    }
1789}
1790
1791GLuint GetCompressedBlockHeight(GLenum internalFormat, GLuint clientVersion)
1792{
1793    InternalFormatInfo internalFormatInfo;
1794    if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
1795    {
1796        return internalFormatInfo.mCompressedBlockHeight;
1797    }
1798    else
1799    {
1800        UNREACHABLE();
1801        return 0;
1802    }
1803}
1804
1805ColorWriteFunction GetColorWriteFunction(GLenum format, GLenum type, GLuint clientVersion)
1806{
1807    static const FormatMap &formats = GetFormatMap(clientVersion);
1808    FormatMap::const_iterator iter = formats.find(FormatTypePair(format, type));
1809    return (iter != formats.end()) ? iter->second.mColorWriteFunction : NULL;
1810}
1811
1812}
1813