• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 // formatutilsgl.cpp: Queries for GL image formats and their translations to native
8 // GL formats.
9 
10 #include "libANGLE/renderer/gl/formatutilsgl.h"
11 
12 #include <limits>
13 
14 #include "anglebase/no_destructor.h"
15 #include "common/string_utils.h"
16 #include "libANGLE/formatutils.h"
17 #include "platform/FeaturesGL.h"
18 
19 namespace rx
20 {
21 
22 namespace nativegl
23 {
24 
SupportRequirement()25 SupportRequirement::SupportRequirement()
26     : version(std::numeric_limits<GLuint>::max(), std::numeric_limits<GLuint>::max()),
27       versionExtensions(),
28       requiredExtensions()
29 {}
30 
31 SupportRequirement::SupportRequirement(const SupportRequirement &other) = default;
32 
~SupportRequirement()33 SupportRequirement::~SupportRequirement() {}
34 
InternalFormat()35 InternalFormat::InternalFormat() : texture(), filter(), textureAttachment(), renderbuffer() {}
36 
37 InternalFormat::InternalFormat(const InternalFormat &other) = default;
38 
~InternalFormat()39 InternalFormat::~InternalFormat() {}
40 
41 // supported = version || vertexExt
VersionOrExts(GLuint major,GLuint minor,const std::string & versionExt)42 static inline SupportRequirement VersionOrExts(GLuint major,
43                                                GLuint minor,
44                                                const std::string &versionExt)
45 {
46     SupportRequirement requirement;
47     requirement.version.major = major;
48     requirement.version.minor = minor;
49     angle::SplitStringAlongWhitespace(versionExt, &requirement.versionExtensions);
50     return requirement;
51 }
52 
53 // supported = version
VersionOnly(GLuint major,GLuint minor)54 static inline SupportRequirement VersionOnly(GLuint major, GLuint minor)
55 {
56     SupportRequirement requirement;
57     requirement.version.major = major;
58     requirement.version.minor = minor;
59     return requirement;
60 }
61 
62 // supported = any one of sets in exts
ExtsOnly(const std::vector<std::string> & exts)63 static inline SupportRequirement ExtsOnly(const std::vector<std::string> &exts)
64 {
65     SupportRequirement requirement;
66     requirement.version.major = 0;
67     requirement.version.minor = 0;
68     requirement.requiredExtensions.resize(exts.size());
69     for (size_t i = 0; i < exts.size(); i++)
70     {
71         angle::SplitStringAlongWhitespace(exts[i], &requirement.requiredExtensions[i]);
72     }
73     return requirement;
74 }
75 
76 // supported = ext
ExtsOnly(const std::string & ext)77 static inline SupportRequirement ExtsOnly(const std::string &ext)
78 {
79     return ExtsOnly(std::vector<std::string>({ext}));
80 }
81 
82 // supported = ext1 || ext2
ExtsOnly(const std::string & ext1,const std::string & ext2)83 static inline SupportRequirement ExtsOnly(const std::string &ext1, const std::string &ext2)
84 {
85     return ExtsOnly(std::vector<std::string>({ext1, ext2}));
86 }
87 
88 // supported = true
AlwaysSupported()89 static inline SupportRequirement AlwaysSupported()
90 {
91     SupportRequirement requirement;
92     requirement.version.major = 0;
93     requirement.version.minor = 0;
94     return requirement;
95 }
96 
97 // supported = false
NeverSupported()98 static inline SupportRequirement NeverSupported()
99 {
100     SupportRequirement requirement;
101     requirement.version.major = std::numeric_limits<GLuint>::max();
102     requirement.version.minor = std::numeric_limits<GLuint>::max();
103     return requirement;
104 }
105 
106 struct InternalFormatInfo
107 {
108     InternalFormat glesInfo;
109     InternalFormat glInfo;
110 };
111 
112 typedef std::pair<GLenum, InternalFormatInfo> InternalFormatInfoPair;
113 typedef std::map<GLenum, InternalFormatInfo> InternalFormatInfoMap;
114 
115 // A helper function to insert data into the format map with fewer characters.
InsertFormatMapping(InternalFormatInfoMap * map,GLenum internalFormat,const SupportRequirement & desktopTexture,const SupportRequirement & desktopFilter,const SupportRequirement & desktopRender,const SupportRequirement & esTexture,const SupportRequirement & esFilter,const SupportRequirement & esTextureAttachment,const SupportRequirement & esRenderbufferAttachment)116 static inline void InsertFormatMapping(InternalFormatInfoMap *map,
117                                        GLenum internalFormat,
118                                        const SupportRequirement &desktopTexture,
119                                        const SupportRequirement &desktopFilter,
120                                        const SupportRequirement &desktopRender,
121                                        const SupportRequirement &esTexture,
122                                        const SupportRequirement &esFilter,
123                                        const SupportRequirement &esTextureAttachment,
124                                        const SupportRequirement &esRenderbufferAttachment)
125 {
126     InternalFormatInfo formatInfo;
127     formatInfo.glInfo.texture = desktopTexture;
128     formatInfo.glInfo.filter  = desktopFilter;
129     // No difference spotted yet in Desktop GL texture attachment and renderbuffer capabilities
130     formatInfo.glInfo.textureAttachment   = desktopRender;
131     formatInfo.glInfo.renderbuffer        = desktopRender;
132     formatInfo.glesInfo.texture           = esTexture;
133     formatInfo.glesInfo.filter            = esFilter;
134     formatInfo.glesInfo.textureAttachment = esTextureAttachment;
135     formatInfo.glesInfo.renderbuffer      = esRenderbufferAttachment;
136     map->insert(std::make_pair(internalFormat, formatInfo));
137 }
138 
139 // Note 1: This map is used to determine extensions support, which is based on checking support for
140 // sized formats (this is ANGLE implementation limitation - D3D backend supports only sized formats)
141 // In order to determine support for extensions which introduce unsized formats, this map would say
142 // that a corresponding sized format is supported, instead. Thus, if this map says that a sized
143 // format is supported, this means that either the actual sized format or a corresponding unsized
144 // format is supported by the native driver.
145 // For example, GL_EXT_texture_rg provides support for RED_EXT format with UNSIGNED_BYTE type.
146 // Therefore, DetermineRGTextureSupport checks for GL_R8 support. Therefore this map says that
147 // GL_R8 (and not RED_EXT) is supported if GL_EXT_texture_rg is available. GL_R8 itself
148 // is supported in ES3, thus the combined condition is VersionOrExts(3, 0, "GL_EXT_texture_rg").
149 //
150 // Note 2: Texture Attachment support is checked also by SupportsNativeRendering().
151 // Unsized formats appear in this map for this reason. The assumption is
152 // that SupportsNativeRendering() will not check sized formats in the ES2 frontend
153 // and the information in unsized formats is correct, and not merged like for sized formats.
154 // In the ES3 frontend, it could happen that SupportsNativeRendering() would be wrong,
155 // but this will be mitigated by fall back to CPU-readback in TextureGL::copySubTextureHelper().
156 //
157 // Note 3: Because creating renderbuffers with unsized formats is impossible,
158 // the value of renderbuffer support is actually correct for the sized formats.
159 //
160 // Note 4: To determine whether a format is filterable, one must check both "Filter" and "Texture"
161 // support, like it is done in GenerateTextureFormatCaps().
162 // On the other hand, "Texture Attachment" support formula is self-contained.
163 //
164 // TODO(ynovikov): http://anglebug.com/2846 Verify support fields of BGRA, depth, stencil and
165 // compressed formats, and all formats for Desktop GL.
BuildInternalFormatInfoMap()166 static InternalFormatInfoMap BuildInternalFormatInfoMap()
167 {
168     InternalFormatInfoMap map;
169 
170     // clang-format off
171     //                       | Format              | OpenGL texture support                          | Filter           | OpenGL render support                        | OpenGL ES texture support                 | Filter           | OpenGL ES texture attachment support    | OpenGL ES renderbuffer support           |
172     InsertFormatMapping(&map, GL_R8,                VersionOrExts(3, 0, "GL_ARB_texture_rg"),         AlwaysSupported(), VersionOrExts(3, 0, "GL_ARB_texture_rg"),      VersionOrExts(3, 0, "GL_EXT_texture_rg"),   AlwaysSupported(), VersionOrExts(3, 0, "GL_EXT_texture_rg"), VersionOrExts(3, 0, "GL_EXT_texture_rg")  );
173     InsertFormatMapping(&map, GL_R8_SNORM,          VersionOnly(3, 1),                                AlwaysSupported(), NeverSupported(),                              VersionOnly(3, 0),                          AlwaysSupported(), NeverSupported(),                         NeverSupported()                          );
174     InsertFormatMapping(&map, GL_RG8,               VersionOrExts(3, 0, "GL_ARB_texture_rg"),         AlwaysSupported(), VersionOrExts(3, 0, "GL_ARB_texture_rg"),      VersionOrExts(3, 0, "GL_EXT_texture_rg"),   AlwaysSupported(), VersionOrExts(3, 0, "GL_EXT_texture_rg"), VersionOrExts(3, 0, "GL_EXT_texture_rg")  );
175     InsertFormatMapping(&map, GL_RG8_SNORM,         VersionOnly(3, 1),                                AlwaysSupported(), NeverSupported(),                              VersionOnly(3, 0),                          AlwaysSupported(), NeverSupported(),                         NeverSupported()                          );
176     InsertFormatMapping(&map, GL_RGB8,              AlwaysSupported(),                                AlwaysSupported(), AlwaysSupported(),                             AlwaysSupported(),                          AlwaysSupported(), VersionOnly(2, 0),                        VersionOrExts(3, 0, "GL_OES_rgb8_rgba8")  );
177     InsertFormatMapping(&map, GL_RGB8_SNORM,        VersionOnly(3, 1),                                AlwaysSupported(), NeverSupported(),                              VersionOnly(3, 0),                          AlwaysSupported(), NeverSupported(),                         NeverSupported()                          );
178     InsertFormatMapping(&map, GL_RGB565,            AlwaysSupported(),                                AlwaysSupported(), AlwaysSupported(),                             AlwaysSupported(),                          AlwaysSupported(), AlwaysSupported(),                        AlwaysSupported()                         );
179     InsertFormatMapping(&map, GL_RGBA4,             AlwaysSupported(),                                AlwaysSupported(), AlwaysSupported(),                             AlwaysSupported(),                          AlwaysSupported(), AlwaysSupported(),                        AlwaysSupported()                         );
180     InsertFormatMapping(&map, GL_RGB5_A1,           AlwaysSupported(),                                AlwaysSupported(), AlwaysSupported(),                             AlwaysSupported(),                          AlwaysSupported(), AlwaysSupported(),                        AlwaysSupported()                         );
181     InsertFormatMapping(&map, GL_RGBA8,             AlwaysSupported(),                                AlwaysSupported(), AlwaysSupported(),                             AlwaysSupported(),                          AlwaysSupported(), VersionOnly(2, 0),                        VersionOrExts(3, 0, "GL_OES_rgb8_rgba8")  );
182     InsertFormatMapping(&map, GL_RGBA8_SNORM,       VersionOnly(3, 1),                                AlwaysSupported(), NeverSupported(),                              VersionOnly(3, 0),                          AlwaysSupported(), NeverSupported(),                         NeverSupported()                          );
183     InsertFormatMapping(&map, GL_RGB10_A2,          AlwaysSupported(),                                AlwaysSupported(), AlwaysSupported(),                             VersionOnly(3, 0),                          AlwaysSupported(), VersionOnly(3, 0),                        VersionOnly(3, 0)                         );
184     InsertFormatMapping(&map, GL_RGB10_A2UI,        VersionOrExts(3, 3, "GL_ARB_texture_rgb10_a2ui"), NeverSupported(),  AlwaysSupported(),                             VersionOnly(3, 0),                          NeverSupported(),  AlwaysSupported(),                        AlwaysSupported()                         );
185     InsertFormatMapping(&map, GL_SRGB8,             VersionOrExts(2, 1, "GL_EXT_texture_sRGB"),       AlwaysSupported(), VersionOrExts(2, 1, "GL_EXT_texture_sRGB"),    VersionOrExts(3, 0, "GL_EXT_sRGB"),         AlwaysSupported(), NeverSupported(),                         NeverSupported()                          );
186     InsertFormatMapping(&map, GL_SRGB8_ALPHA8,      VersionOrExts(2, 1, "GL_EXT_texture_sRGB"),       AlwaysSupported(), VersionOrExts(2, 1, "GL_EXT_texture_sRGB"),    VersionOrExts(3, 0, "GL_EXT_sRGB"),         AlwaysSupported(), VersionOrExts(3, 0, "GL_EXT_sRGB"),       VersionOrExts(3, 0, "GL_EXT_sRGB")        );
187     InsertFormatMapping(&map, GL_R8I,               VersionOrExts(3, 0, "GL_ARB_texture_rg"),         NeverSupported(),  VersionOrExts(3, 0, "GL_ARB_texture_rg"),      VersionOnly(3, 0),                          NeverSupported(),  VersionOnly(3, 0),                        VersionOnly(3, 0)                         );
188     InsertFormatMapping(&map, GL_R8UI,              VersionOrExts(3, 0, "GL_ARB_texture_rg"),         NeverSupported(),  VersionOrExts(3, 0, "GL_ARB_texture_rg"),      VersionOnly(3, 0),                          NeverSupported(),  VersionOnly(3, 0),                        VersionOnly(3, 0)                         );
189     InsertFormatMapping(&map, GL_R16I,              VersionOrExts(3, 0, "GL_ARB_texture_rg"),         NeverSupported(),  VersionOrExts(3, 0, "GL_ARB_texture_rg"),      VersionOnly(3, 0),                          NeverSupported(),  VersionOnly(3, 0),                        VersionOnly(3, 0)                         );
190     InsertFormatMapping(&map, GL_R16UI,             VersionOrExts(3, 0, "GL_ARB_texture_rg"),         NeverSupported(),  VersionOrExts(3, 0, "GL_ARB_texture_rg"),      VersionOnly(3, 0),                          NeverSupported(),  VersionOnly(3, 0),                        VersionOnly(3, 0)                         );
191     InsertFormatMapping(&map, GL_R32I,              VersionOrExts(3, 0, "GL_ARB_texture_rg"),         NeverSupported(),  VersionOrExts(3, 0, "GL_ARB_texture_rg"),      VersionOnly(3, 0),                          NeverSupported(),  VersionOnly(3, 0),                        VersionOnly(3, 0)                         );
192     InsertFormatMapping(&map, GL_R32UI,             VersionOrExts(3, 0, "GL_ARB_texture_rg"),         NeverSupported(),  VersionOrExts(3, 0, "GL_ARB_texture_rg"),      VersionOnly(3, 0),                          NeverSupported(),  VersionOnly(3, 0),                        VersionOnly(3, 0)                         );
193     InsertFormatMapping(&map, GL_RG8I,              VersionOrExts(3, 0, "GL_ARB_texture_rg"),         NeverSupported(),  VersionOrExts(3, 0, "GL_ARB_texture_rg"),      VersionOnly(3, 0),                          NeverSupported(),  VersionOnly(3, 0),                        VersionOnly(3, 0)                         );
194     InsertFormatMapping(&map, GL_RG8UI,             VersionOrExts(3, 0, "GL_ARB_texture_rg"),         NeverSupported(),  VersionOrExts(3, 0, "GL_ARB_texture_rg"),      VersionOnly(3, 0),                          NeverSupported(),  VersionOnly(3, 0),                        VersionOnly(3, 0)                         );
195     InsertFormatMapping(&map, GL_RG16I,             VersionOrExts(3, 0, "GL_ARB_texture_rg"),         NeverSupported(),  VersionOrExts(3, 0, "GL_ARB_texture_rg"),      VersionOnly(3, 0),                          NeverSupported(),  VersionOnly(3, 0),                        VersionOnly(3, 0)                         );
196     InsertFormatMapping(&map, GL_RG16UI,            VersionOrExts(3, 0, "GL_ARB_texture_rg"),         NeverSupported(),  VersionOrExts(3, 0, "GL_ARB_texture_rg"),      VersionOnly(3, 0),                          NeverSupported(),  VersionOnly(3, 0),                        VersionOnly(3, 0)                         );
197     InsertFormatMapping(&map, GL_RG32I,             VersionOrExts(3, 0, "GL_ARB_texture_rg"),         NeverSupported(),  VersionOrExts(3, 0, "GL_ARB_texture_rg"),      VersionOnly(3, 0),                          NeverSupported(),  VersionOnly(3, 0),                        VersionOnly(3, 0)                         );
198     InsertFormatMapping(&map, GL_RG32UI,            VersionOrExts(3, 0, "GL_ARB_texture_rg"),         NeverSupported(),  VersionOrExts(3, 0, "GL_ARB_texture_rg"),      VersionOnly(3, 0),                          NeverSupported(),  VersionOnly(3, 0),                        VersionOnly(3, 0)                         );
199     InsertFormatMapping(&map, GL_RGB8I,             VersionOrExts(3, 0, "GL_EXT_texture_integer"),    NeverSupported(),  NeverSupported(),                              VersionOnly(3, 0),                          NeverSupported(),  NeverSupported(),                         NeverSupported()                          );
200     InsertFormatMapping(&map, GL_RGB8UI,            VersionOrExts(3, 0, "GL_EXT_texture_integer"),    NeverSupported(),  NeverSupported(),                              VersionOnly(3, 0),                          NeverSupported(),  NeverSupported(),                         NeverSupported()                          );
201     InsertFormatMapping(&map, GL_RGB16I,            VersionOrExts(3, 0, "GL_EXT_texture_integer"),    NeverSupported(),  NeverSupported(),                              VersionOnly(3, 0),                          NeverSupported(),  NeverSupported(),                         NeverSupported()                          );
202     InsertFormatMapping(&map, GL_RGB16UI,           VersionOrExts(3, 0, "GL_EXT_texture_integer"),    NeverSupported(),  NeverSupported(),                              VersionOnly(3, 0),                          NeverSupported(),  NeverSupported(),                         NeverSupported()                          );
203     InsertFormatMapping(&map, GL_RGB32I,            VersionOrExts(3, 0, "GL_EXT_texture_integer"),    NeverSupported(),  NeverSupported(),                              VersionOnly(3, 0),                          NeverSupported(),  NeverSupported(),                         NeverSupported()                          );
204     InsertFormatMapping(&map, GL_RGB32UI,           VersionOrExts(3, 0, "GL_EXT_texture_integer"),    NeverSupported(),  NeverSupported(),                              VersionOnly(3, 0),                          NeverSupported(),  NeverSupported(),                         NeverSupported()                          );
205     InsertFormatMapping(&map, GL_RGBA8I,            VersionOrExts(3, 0, "GL_EXT_texture_integer"),    NeverSupported(),  VersionOrExts(3, 0, "GL_EXT_texture_integer"), VersionOnly(3, 0),                          NeverSupported(),  VersionOnly(3, 0),                        VersionOnly(3, 0)                         );
206     InsertFormatMapping(&map, GL_RGBA8UI,           VersionOrExts(3, 0, "GL_EXT_texture_integer"),    NeverSupported(),  VersionOrExts(3, 0, "GL_EXT_texture_integer"), VersionOnly(3, 0),                          NeverSupported(),  VersionOnly(3, 0),                        VersionOnly(3, 0)                         );
207     InsertFormatMapping(&map, GL_RGBA16I,           VersionOrExts(3, 0, "GL_EXT_texture_integer"),    NeverSupported(),  VersionOrExts(3, 0, "GL_EXT_texture_integer"), VersionOnly(3, 0),                          NeverSupported(),  VersionOnly(3, 0),                        VersionOnly(3, 0)                         );
208     InsertFormatMapping(&map, GL_RGBA16UI,          VersionOrExts(3, 0, "GL_EXT_texture_integer"),    NeverSupported(),  VersionOrExts(3, 0, "GL_EXT_texture_integer"), VersionOnly(3, 0),                          NeverSupported(),  VersionOnly(3, 0),                        VersionOnly(3, 0)                         );
209     InsertFormatMapping(&map, GL_RGBA32I,           VersionOrExts(3, 0, "GL_EXT_texture_integer"),    NeverSupported(),  VersionOrExts(3, 0, "GL_EXT_texture_integer"), VersionOnly(3, 0),                          NeverSupported(),  VersionOnly(3, 0),                        VersionOnly(3, 0)                         );
210     InsertFormatMapping(&map, GL_RGBA32UI,          VersionOrExts(3, 0, "GL_EXT_texture_integer"),    NeverSupported(),  VersionOrExts(3, 0, "GL_EXT_texture_integer"), VersionOnly(3, 0),                          NeverSupported(),  VersionOnly(3, 0),                        VersionOnly(3, 0)                         );
211 
212     InsertFormatMapping(&map, GL_R16,               VersionOrExts(3, 0, "GL_ARB_texture_rg"),         AlwaysSupported(), VersionOrExts(3, 0, "GL_ARB_texture_rg"),      ExtsOnly("GL_EXT_texture_norm16"),          AlwaysSupported(), ExtsOnly("GL_EXT_texture_norm16"),        ExtsOnly("GL_EXT_texture_norm16")         );
213     InsertFormatMapping(&map, GL_RG16,              VersionOrExts(3, 0, "GL_ARB_texture_rg"),         AlwaysSupported(), VersionOrExts(3, 0, "GL_ARB_texture_rg"),      ExtsOnly("GL_EXT_texture_norm16"),          AlwaysSupported(), ExtsOnly("GL_EXT_texture_norm16"),        ExtsOnly("GL_EXT_texture_norm16")         );
214     InsertFormatMapping(&map, GL_RGB16,             AlwaysSupported(),                                AlwaysSupported(), NeverSupported(),                              ExtsOnly("GL_EXT_texture_norm16"),          AlwaysSupported(), NeverSupported(),                         NeverSupported()                          );
215     InsertFormatMapping(&map, GL_RGBA16,            AlwaysSupported(),                                AlwaysSupported(), AlwaysSupported(),                             ExtsOnly("GL_EXT_texture_norm16"),          AlwaysSupported(), ExtsOnly("GL_EXT_texture_norm16"),        ExtsOnly("GL_EXT_texture_norm16")         );
216 
217     InsertFormatMapping(&map, GL_R16_SNORM,         VersionOnly(3, 1),                                AlwaysSupported(), NeverSupported(),                              ExtsOnly("GL_EXT_texture_norm16"),          AlwaysSupported(), NeverSupported(),                         NeverSupported()                          );
218     InsertFormatMapping(&map, GL_RG16_SNORM,        VersionOnly(3, 1),                                AlwaysSupported(), NeverSupported(),                              ExtsOnly("GL_EXT_texture_norm16"),          AlwaysSupported(), NeverSupported(),                         NeverSupported()                          );
219     InsertFormatMapping(&map, GL_RGB16_SNORM,       VersionOnly(3, 1),                                AlwaysSupported(), NeverSupported(),                              ExtsOnly("GL_EXT_texture_norm16"),          AlwaysSupported(), NeverSupported(),                         NeverSupported()                          );
220     InsertFormatMapping(&map, GL_RGBA16_SNORM,      VersionOnly(3, 1),                                AlwaysSupported(), NeverSupported(),                              ExtsOnly("GL_EXT_texture_norm16"),          AlwaysSupported(), NeverSupported(),                         NeverSupported()                          );
221 
222     // Unsized formats
223     InsertFormatMapping(&map, GL_ALPHA,             NeverSupported(),                                 NeverSupported(),  NeverSupported(),                              AlwaysSupported(),                          AlwaysSupported(), NeverSupported(),                         NeverSupported()                          );
224     InsertFormatMapping(&map, GL_LUMINANCE,         NeverSupported(),                                 NeverSupported(),  NeverSupported(),                              AlwaysSupported(),                          AlwaysSupported(), NeverSupported(),                         NeverSupported()                          );
225     InsertFormatMapping(&map, GL_LUMINANCE_ALPHA,   NeverSupported(),                                 NeverSupported(),  NeverSupported(),                              AlwaysSupported(),                          AlwaysSupported(), NeverSupported(),                         NeverSupported()                          );
226     InsertFormatMapping(&map, GL_RED,               VersionOrExts(3, 0, "GL_ARB_texture_rg"),         AlwaysSupported(), VersionOrExts(3, 0, "GL_ARB_texture_rg"),      ExtsOnly("GL_EXT_texture_rg"),              AlwaysSupported(), ExtsOnly("GL_EXT_texture_rg"),            NeverSupported()                          );
227     InsertFormatMapping(&map, GL_RG,                VersionOrExts(3, 0, "GL_ARB_texture_rg"),         AlwaysSupported(), VersionOrExts(3, 0, "GL_ARB_texture_rg"),      ExtsOnly("GL_EXT_texture_rg"),              AlwaysSupported(), ExtsOnly("GL_EXT_texture_rg"),            NeverSupported()                          );
228     InsertFormatMapping(&map, GL_RGB,               AlwaysSupported(),                                AlwaysSupported(), AlwaysSupported(),                             AlwaysSupported(),                          AlwaysSupported(), VersionOnly(2, 0),                        NeverSupported()                          );
229     InsertFormatMapping(&map, GL_RGBA,              AlwaysSupported(),                                AlwaysSupported(), AlwaysSupported(),                             AlwaysSupported(),                          AlwaysSupported(), VersionOnly(2, 0),                        NeverSupported()                          );
230     InsertFormatMapping(&map, GL_RED_INTEGER,       VersionOrExts(3, 0, "GL_ARB_texture_rg"),         NeverSupported(),  VersionOrExts(3, 0, "GL_ARB_texture_rg"),      VersionOnly(3, 0),                          NeverSupported(),  VersionOnly(3, 0),                        NeverSupported()                          );
231     InsertFormatMapping(&map, GL_RG_INTEGER,        VersionOrExts(3, 0, "GL_ARB_texture_rg"),         NeverSupported(),  VersionOrExts(3, 0, "GL_ARB_texture_rg"),      VersionOnly(3, 0),                          NeverSupported(),  VersionOnly(3, 0),                        NeverSupported()                          );
232     InsertFormatMapping(&map, GL_RGB_INTEGER,       VersionOrExts(3, 0, "GL_EXT_texture_integer"),    NeverSupported(),  NeverSupported(),                              VersionOnly(3, 0),                          NeverSupported(),  NeverSupported(),                         NeverSupported()                          );
233     InsertFormatMapping(&map, GL_RGBA_INTEGER,      VersionOrExts(3, 0, "GL_EXT_texture_integer"),    NeverSupported(),  VersionOrExts(3, 0, "GL_EXT_texture_integer"), VersionOnly(3, 0),                          NeverSupported(),  VersionOnly(3, 0),                        NeverSupported()                          );
234     InsertFormatMapping(&map, GL_SRGB,              VersionOrExts(2, 1, "GL_EXT_texture_sRGB"),       AlwaysSupported(), VersionOrExts(2, 1, "GL_EXT_texture_sRGB"),    ExtsOnly("GL_EXT_sRGB"),                    AlwaysSupported(), NeverSupported(),                         NeverSupported()                          );
235     InsertFormatMapping(&map, GL_SRGB_ALPHA,        VersionOrExts(2, 1, "GL_EXT_texture_sRGB"),       AlwaysSupported(), VersionOrExts(2, 1, "GL_EXT_texture_sRGB"),    ExtsOnly("GL_EXT_sRGB"),                    AlwaysSupported(), ExtsOnly("GL_EXT_sRGB"),                  NeverSupported()                          );
236 
237     // From GL_EXT_texture_format_BGRA8888
238     InsertFormatMapping(&map, GL_BGRA8_EXT,         VersionOrExts(1, 2, "GL_EXT_bgra"),               AlwaysSupported(), VersionOrExts(1, 2, "GL_EXT_bgra"),            ExtsOnly("GL_EXT_texture_format_BGRA8888"), AlwaysSupported(), NeverSupported(),                         NeverSupported()                          );
239     InsertFormatMapping(&map, GL_BGRA_EXT,          VersionOrExts(1, 2, "GL_EXT_bgra"),               AlwaysSupported(), VersionOrExts(1, 2, "GL_EXT_bgra"),            ExtsOnly("GL_EXT_texture_format_BGRA8888"), AlwaysSupported(), NeverSupported(),                         NeverSupported()                          );
240 
241     // Floating point formats
242     // Note 1: GL_EXT_texture_shared_exponent and GL_ARB_color_buffer_float suggest that RGB9_E5
243     // would be renderable, but once support for renderable float textures got rolled into core GL
244     // spec it wasn't intended to be renderable. In practice it's not reliably renderable even
245     // with the extensions, there's a known bug in at least NVIDIA driver version 370.
246     //
247     // Note 2: It's a bit unclear whether texture attachments with GL_RGB16F should be supported
248     // in ES3 with GL_EXT_color_buffer_half_float. Probably not, since in ES3 type is HALF_FLOAT,
249     // but GL_EXT_color_buffer_half_float is applicable only to type HALF_FLOAT_OES.
250     //
251     // Note 3: GL_EXT_color_buffer_float implies that ES3.0 is supported, this simplifies the check.
252     //
253     //                       | Format              | OpenGL texture support                                       | Filter           | OpenGL render support                                                                  | OpenGL ES texture support                                         | Filter                                                 | OpenGL ES texture attachment support                                                                                                      | OpenGL ES renderbuffer support                                                                                    |
254     InsertFormatMapping(&map, GL_R11F_G11F_B10F,    VersionOrExts(3, 0, "GL_EXT_packed_float"),                    AlwaysSupported(), VersionOrExts(3, 0, "GL_EXT_packed_float GL_ARB_color_buffer_float"),                    VersionOnly(3, 0),                                                  AlwaysSupported(),                                       ExtsOnly("GL_EXT_color_buffer_float"),                                                                                                      ExtsOnly("GL_EXT_color_buffer_float")                                                                              );
255     InsertFormatMapping(&map, GL_RGB9_E5,           VersionOrExts(3, 0, "GL_EXT_texture_shared_exponent"),         AlwaysSupported(), NeverSupported(),                                                                        VersionOnly(3, 0),                                                  AlwaysSupported(),                                       NeverSupported(),                                                                                                                           NeverSupported()                                                                                                   );
256     InsertFormatMapping(&map, GL_R16F,              VersionOrExts(3, 0, "GL_ARB_texture_rg ARB_texture_float"),    AlwaysSupported(), VersionOrExts(3, 0, "GL_ARB_texture_rg GL_ARB_texture_float GL_ARB_color_buffer_float"), VersionOrExts(3, 0, "GL_OES_texture_half_float GL_EXT_texture_rg"), VersionOrExts(3, 0, "GL_OES_texture_half_float_linear"), ExtsOnly("GL_EXT_texture_storage GL_OES_texture_half_float GL_EXT_texture_rg GL_EXT_color_buffer_half_float", "GL_EXT_color_buffer_float"), ExtsOnly("GL_EXT_texture_rg GL_OES_texture_half_float GL_EXT_color_buffer_half_float", "GL_EXT_color_buffer_float"));
257     InsertFormatMapping(&map, GL_RG16F,             VersionOrExts(3, 0, "GL_ARB_texture_rg ARB_texture_float"),    AlwaysSupported(), VersionOrExts(3, 0, "GL_ARB_texture_rg GL_ARB_texture_float GL_ARB_color_buffer_float"), VersionOrExts(3, 0, "GL_OES_texture_half_float GL_EXT_texture_rg"), VersionOrExts(3, 0, "GL_OES_texture_half_float_linear"), ExtsOnly("GL_EXT_texture_storage GL_OES_texture_half_float GL_EXT_texture_rg GL_EXT_color_buffer_half_float", "GL_EXT_color_buffer_float"), ExtsOnly("GL_EXT_texture_rg GL_OES_texture_half_float GL_EXT_color_buffer_half_float", "GL_EXT_color_buffer_float"));
258     InsertFormatMapping(&map, GL_RGB16F,            VersionOrExts(3, 0, "GL_ARB_texture_float"),                   AlwaysSupported(), VersionOrExts(3, 0, "GL_ARB_texture_float GL_ARB_color_buffer_float"),                   VersionOrExts(3, 0, "GL_OES_texture_half_float"),                   VersionOrExts(3, 0, "GL_OES_texture_half_float_linear"), ExtsOnly("GL_EXT_texture_storage GL_OES_texture_half_float GL_EXT_color_buffer_half_float"),                                                ExtsOnly("GL_OES_texture_half_float GL_EXT_color_buffer_half_float")                                               );
259     InsertFormatMapping(&map, GL_RGBA16F,           VersionOrExts(3, 0, "GL_ARB_texture_float"),                   AlwaysSupported(), VersionOrExts(3, 0, "GL_ARB_texture_float GL_ARB_color_buffer_float"),                   VersionOrExts(3, 0, "GL_OES_texture_half_float"),                   VersionOrExts(3, 0, "GL_OES_texture_half_float_linear"), ExtsOnly("GL_OES_texture_half_float GL_EXT_color_buffer_half_float", "GL_EXT_color_buffer_float"),                                          ExtsOnly("GL_OES_texture_half_float GL_EXT_color_buffer_half_float", "GL_EXT_color_buffer_float")                  );
260     InsertFormatMapping(&map, GL_R32F,              VersionOrExts(3, 0, "GL_ARB_texture_rg GL_ARB_texture_float"), AlwaysSupported(), VersionOrExts(3, 0, "GL_ARB_texture_rg GL_ARB_texture_float GL_ARB_color_buffer_float"), VersionOrExts(3, 0, "GL_OES_texture_float GL_EXT_texture_rg"),      ExtsOnly("GL_OES_texture_float_linear"),                 ExtsOnly("GL_EXT_color_buffer_float"),                                                                                                      ExtsOnly("GL_EXT_color_buffer_float")                                                                              );
261     InsertFormatMapping(&map, GL_RG32F,             VersionOrExts(3, 0, "GL_ARB_texture_rg GL_ARB_texture_float"), AlwaysSupported(), VersionOrExts(3, 0, "GL_ARB_texture_rg GL_ARB_texture_float GL_ARB_color_buffer_float"), VersionOrExts(3, 0, "GL_OES_texture_float GL_EXT_texture_rg"),      ExtsOnly("GL_OES_texture_float_linear"),                 ExtsOnly("GL_EXT_color_buffer_float"),                                                                                                      ExtsOnly("GL_EXT_color_buffer_float")                                                                              );
262     InsertFormatMapping(&map, GL_RGB32F,            VersionOrExts(3, 0, "GL_ARB_texture_float"),                   AlwaysSupported(), VersionOrExts(3, 0, "GL_ARB_texture_float GL_ARB_color_buffer_float"),                   VersionOrExts(3, 0, "GL_OES_texture_float"),                        ExtsOnly("GL_OES_texture_float_linear"),                 NeverSupported(),                                                                                                                           NeverSupported()                                                                                                   );
263     InsertFormatMapping(&map, GL_RGBA32F,           VersionOrExts(3, 0, "GL_ARB_texture_float"),                   AlwaysSupported(), VersionOrExts(3, 0, "GL_ARB_texture_float GL_ARB_color_buffer_float"),                   VersionOrExts(3, 0, "GL_OES_texture_float"),                        ExtsOnly("GL_OES_texture_float_linear"),                 ExtsOnly("GL_EXT_color_buffer_float"),                                                                                                      ExtsOnly("GL_EXT_color_buffer_float")                                                                              );
264 
265     // Depth stencil formats
266     //                       | Format                  | OpenGL texture support                            | Filter                                     | OpenGL render support                             | OpenGL ES texture support                  | Filter                                     | OpenGL ES texture attachment support                                   | OpenGL ES renderbuffer support                                        |
267     InsertFormatMapping(&map, GL_DEPTH_COMPONENT16,     VersionOnly(1, 5),                                  VersionOrExts(1, 5, "GL_ARB_depth_texture"), VersionOnly(1, 5),                                  VersionOnly(2, 0),                           VersionOrExts(3, 0, "GL_OES_depth_texture"), VersionOnly(2, 0),                                                       VersionOnly(2, 0)                                                      );
268     InsertFormatMapping(&map, GL_DEPTH_COMPONENT24,     VersionOnly(1, 5),                                  VersionOrExts(1, 5, "GL_ARB_depth_texture"), VersionOnly(1, 5),                                  VersionOnly(2, 0),                           VersionOrExts(3, 0, "GL_OES_depth_texture"), VersionOnly(2, 0),                                                       VersionOnly(2, 0)                                                      );
269     InsertFormatMapping(&map, GL_DEPTH_COMPONENT32_OES, VersionOnly(1, 5),                                  VersionOrExts(1, 5, "GL_ARB_depth_texture"), VersionOnly(1, 5),                                  ExtsOnly("GL_OES_depth_texture"),            AlwaysSupported(),                           ExtsOnly("GL_OES_depth_texture"),                                        ExtsOnly("GL_OES_depth32")                                             );
270     InsertFormatMapping(&map, GL_DEPTH_COMPONENT32F,    VersionOrExts(3, 0, "GL_ARB_depth_buffer_float"),   AlwaysSupported(),                           VersionOrExts(3, 0, "GL_ARB_depth_buffer_float"),   VersionOnly(3, 0),                           VersionOrExts(3, 0, "GL_OES_depth_texture"), VersionOnly(3, 0),                                                       VersionOnly(3, 0)                                                      );
271     InsertFormatMapping(&map, GL_STENCIL_INDEX8,        VersionOrExts(3, 0, "GL_EXT_packed_depth_stencil"), NeverSupported(),                            VersionOrExts(3, 0, "GL_EXT_packed_depth_stencil"), VersionOnly(2, 0),                           NeverSupported(),                            VersionOnly(2, 0),                                                       VersionOnly(2, 0)                                                      );
272     InsertFormatMapping(&map, GL_DEPTH24_STENCIL8,      VersionOrExts(3, 0, "GL_ARB_framebuffer_object"),   VersionOrExts(3, 0, "GL_ARB_depth_texture"), VersionOrExts(3, 0, "GL_ARB_framebuffer_object"),   VersionOrExts(3, 0, "GL_OES_depth_texture"), AlwaysSupported(),                           VersionOrExts(3, 0, "GL_OES_depth_texture GL_OES_packed_depth_stencil"), VersionOrExts(3, 0, "GL_OES_depth_texture GL_OES_packed_depth_stencil"));
273     InsertFormatMapping(&map, GL_DEPTH32F_STENCIL8,     VersionOrExts(3, 0, "GL_ARB_depth_buffer_float"),   AlwaysSupported(),                           VersionOrExts(3, 0, "GL_ARB_depth_buffer_float"),   VersionOnly(3, 0),                           AlwaysSupported(),                           VersionOnly(3, 0),                                                       VersionOnly(3, 0)                                                      );
274     InsertFormatMapping(&map, GL_DEPTH_COMPONENT,       VersionOnly(1, 5),                                  VersionOrExts(1, 5, "GL_ARB_depth_texture"), VersionOnly(1, 5),                                  VersionOnly(2, 0),                           VersionOrExts(3, 0, "GL_OES_depth_texture"), VersionOnly(2, 0),                                                       VersionOnly(2, 0)                                                      );
275     InsertFormatMapping(&map, GL_DEPTH_STENCIL,         VersionOnly(1, 5),                                  VersionOrExts(1, 5, "GL_ARB_depth_texture"), VersionOnly(1, 5),                                  VersionOnly(2, 0),                           VersionOrExts(3, 0, "GL_OES_depth_texture"), VersionOnly(2, 0),                                                       VersionOnly(2, 0)                                                      );
276 
277     // Luminance alpha formats
278     //                       | Format                  | OpenGL texture support                      | Filter           | Render          | OpenGL ES texture support            | Filter                                      | OpenGL ES texture attachment support | OpenGL ES renderbuffer support |
279     InsertFormatMapping(&map, GL_ALPHA8_EXT,             AlwaysSupported(),                           AlwaysSupported(), NeverSupported(), AlwaysSupported(),                     AlwaysSupported(),                            NeverSupported(),                      NeverSupported()                );
280     InsertFormatMapping(&map, GL_LUMINANCE8_EXT,         AlwaysSupported(),                           AlwaysSupported(), NeverSupported(), AlwaysSupported(),                     AlwaysSupported(),                            NeverSupported(),                      NeverSupported()                );
281     InsertFormatMapping(&map, GL_LUMINANCE8_ALPHA8_EXT,  AlwaysSupported(),                           AlwaysSupported(), NeverSupported(), AlwaysSupported(),                     AlwaysSupported(),                            NeverSupported(),                      NeverSupported()                );
282     InsertFormatMapping(&map, GL_ALPHA16F_EXT,           VersionOrExts(3, 0, "GL_ARB_texture_float"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_half_float"), ExtsOnly("GL_OES_texture_half_float_linear"), NeverSupported(),                      NeverSupported()                );
283     InsertFormatMapping(&map, GL_LUMINANCE16F_EXT,       VersionOrExts(3, 0, "GL_ARB_texture_float"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_half_float"), ExtsOnly("GL_OES_texture_half_float_linear"), NeverSupported(),                      NeverSupported()                );
284     InsertFormatMapping(&map, GL_LUMINANCE_ALPHA16F_EXT, VersionOrExts(3, 0, "GL_ARB_texture_float"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_half_float"), ExtsOnly("GL_OES_texture_half_float_linear"), NeverSupported(),                      NeverSupported()                );
285     InsertFormatMapping(&map, GL_ALPHA32F_EXT,           VersionOrExts(3, 0, "GL_ARB_texture_float"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_float"),      ExtsOnly("GL_OES_texture_float_linear"),      NeverSupported(),                      NeverSupported()                );
286     InsertFormatMapping(&map, GL_LUMINANCE32F_EXT,       VersionOrExts(3, 0, "GL_ARB_texture_float"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_float"),      ExtsOnly("GL_OES_texture_float_linear"),      NeverSupported(),                      NeverSupported()                );
287     InsertFormatMapping(&map, GL_LUMINANCE_ALPHA32F_EXT, VersionOrExts(3, 0, "GL_ARB_texture_float"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_float"),      ExtsOnly("GL_OES_texture_float_linear"),      NeverSupported(),                      NeverSupported()                );
288 
289     // EXT_texture_compression_rgtc formats
290     //                       | Format                                  | OpenGL texture support                                | Filter           | Render          | OpenGL ES texture support                  | Filter           | OpenGL ES texture attachment support | OpenGL ES renderbuffer support |
291     InsertFormatMapping(&map, GL_COMPRESSED_RED_RGTC1_EXT,              VersionOrExts(3, 0, "GL_ARB_texture_compression_rgtc"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_EXT_texture_compression_rgtc"), AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
292     InsertFormatMapping(&map, GL_COMPRESSED_SIGNED_RED_RGTC1_EXT,       VersionOrExts(3, 0, "GL_ARB_texture_compression_rgtc"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_EXT_texture_compression_rgtc"), AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
293     InsertFormatMapping(&map, GL_COMPRESSED_RED_GREEN_RGTC2_EXT,        VersionOrExts(3, 0, "GL_ARB_texture_compression_rgtc"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_EXT_texture_compression_rgtc"), AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
294     InsertFormatMapping(&map, GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT, VersionOrExts(3, 0, "GL_ARB_texture_compression_rgtc"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_EXT_texture_compression_rgtc"), AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
295 
296     // EXT_texture_compression_bptc formats
297     //                       | Format                                   | OpenGL texture support                                | Filter           | Render          | OpenGL ES texture support                  | Filter           | OpenGL ES texture attachment support | OpenGL ES renderbuffer support |
298     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT,         VersionOrExts(4, 2, "GL_ARB_texture_compression_bptc"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_EXT_texture_compression_bptc"), AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
299     InsertFormatMapping(&map, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT,   VersionOrExts(4, 2, "GL_ARB_texture_compression_bptc"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_EXT_texture_compression_bptc"), AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
300     InsertFormatMapping(&map, GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT,   VersionOrExts(4, 2, "GL_ARB_texture_compression_bptc"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_EXT_texture_compression_bptc"), AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
301     InsertFormatMapping(&map, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT, VersionOrExts(4, 2, "GL_ARB_texture_compression_bptc"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_EXT_texture_compression_bptc"), AlwaysSupported(), NeverSupported(),                      NeverSupported()                 );
302 
303     // Compressed formats, From ES 3.0.1 spec, table 3.16
304     //                       | Format                                      | OpenGL texture support                         | Filter           | Render          | OpenGL ES texture support                                                   | Filter           | OpenGL ES texture attachment support | OpenGL ES renderbuffer support |
305     InsertFormatMapping(&map, GL_COMPRESSED_R11_EAC,                        VersionOrExts(4, 3, "GL_ARB_ES3_compatibility"), AlwaysSupported(), NeverSupported(), VersionOrExts(3, 0, "OES_compressed_EAC_R11_unsigned_texture"),               AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
306     InsertFormatMapping(&map, GL_COMPRESSED_SIGNED_R11_EAC,                 VersionOrExts(4, 3, "GL_ARB_ES3_compatibility"), AlwaysSupported(), NeverSupported(), VersionOrExts(3, 0, "OES_compressed_EAC_R11_signed_texture"),                 AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
307     InsertFormatMapping(&map, GL_COMPRESSED_RG11_EAC,                       VersionOrExts(4, 3, "GL_ARB_ES3_compatibility"), AlwaysSupported(), NeverSupported(), VersionOrExts(3, 0, "OES_compressed_EAC_RG11_unsigned_texture"),              AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
308     InsertFormatMapping(&map, GL_COMPRESSED_SIGNED_RG11_EAC,                VersionOrExts(4, 3, "GL_ARB_ES3_compatibility"), AlwaysSupported(), NeverSupported(), VersionOrExts(3, 0, "OES_compressed_EAC_RG11_signed_texture"),                AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
309     InsertFormatMapping(&map, GL_COMPRESSED_RGB8_ETC2,                      VersionOrExts(4, 3, "GL_ARB_ES3_compatibility"), AlwaysSupported(), NeverSupported(), VersionOrExts(3, 0, "OES_compressed_ETC2_RGB8_texture"),                      AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
310     InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ETC2,                     VersionOrExts(4, 3, "GL_ARB_ES3_compatibility"), AlwaysSupported(), NeverSupported(), VersionOrExts(3, 0, "OES_compressed_ETC2_sRGB8_texture"),                     AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
311     InsertFormatMapping(&map, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,  VersionOrExts(4, 3, "GL_ARB_ES3_compatibility"), AlwaysSupported(), NeverSupported(), VersionOrExts(3, 0, "OES_compressed_ETC2_punchthroughA_RGBA8_texture"),       AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
312     InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, VersionOrExts(4, 3, "GL_ARB_ES3_compatibility"), AlwaysSupported(), NeverSupported(), VersionOrExts(3, 0, "OES_compressed_ETC2_punchthroughA_sRGB8_alpha_texture"), AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
313     InsertFormatMapping(&map, GL_COMPRESSED_RGBA8_ETC2_EAC,                 VersionOrExts(4, 3, "GL_ARB_ES3_compatibility"), AlwaysSupported(), NeverSupported(), VersionOrExts(3, 0, "OES_compressed_ETC2_RGBA8_texture"),                     AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
314     InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,          VersionOrExts(4, 3, "GL_ARB_ES3_compatibility"), AlwaysSupported(), NeverSupported(), VersionOrExts(3, 0, "OES_compressed_ETC2_sRGB8_alpha8_texture"),              AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
315 
316     // From GL_EXT_texture_compression_dxt1
317     //                       | Format                            | OpenGL texture support                         | Filter           | Render          | OpenGL ES texture support                                                       | Filter           | OpenGL ES texture attachment support | OpenGL ES renderbuffer support |
318     InsertFormatMapping(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,    ExtsOnly("GL_EXT_texture_compression_s3tc"),     AlwaysSupported(), NeverSupported(), ExtsOnly("GL_EXT_texture_compression_dxt1", "GL_EXT_texture_compression_s3tc"),   AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
319     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,   ExtsOnly("GL_EXT_texture_compression_s3tc"),     AlwaysSupported(), NeverSupported(), ExtsOnly("GL_EXT_texture_compression_dxt1", "GL_EXT_texture_compression_s3tc"),   AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
320 
321     // From GL_ANGLE_texture_compression_dxt3
322     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, ExtsOnly("GL_EXT_texture_compression_s3tc"),     AlwaysSupported(), NeverSupported(), ExtsOnly("GL_ANGLE_texture_compression_dxt3", "GL_EXT_texture_compression_s3tc"), AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
323 
324     // From GL_ANGLE_texture_compression_dxt5
325     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, ExtsOnly("GL_EXT_texture_compression_s3tc"),     AlwaysSupported(), NeverSupported(), ExtsOnly("GL_ANGLE_texture_compression_dxt5", "GL_EXT_texture_compression_s3tc"), AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
326 
327     // From GL_EXT_texture_compression_s3tc_srgb
328     //                       | Format                                | OpenGL texture support                                         | Filter           | Render          | OpenGL ES texture support                                                                             | Filter           | OpenGL ES texture attachment support | OpenGL ES renderbuffer support |
329     InsertFormatMapping(&map, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT,       ExtsOnly("GL_EXT_texture_compression_s3tc GL_EXT_texture_sRGB"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_EXT_texture_compression_s3tc_srgb", "GL_EXT_texture_compression_s3tc GL_NV_sRGB_formats"), AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
330     InsertFormatMapping(&map, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, ExtsOnly("GL_EXT_texture_compression_s3tc GL_EXT_texture_sRGB"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_EXT_texture_compression_s3tc_srgb", "GL_EXT_texture_compression_s3tc GL_NV_sRGB_formats"), AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
331     InsertFormatMapping(&map, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, ExtsOnly("GL_EXT_texture_compression_s3tc GL_EXT_texture_sRGB"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_EXT_texture_compression_s3tc_srgb", "GL_EXT_texture_compression_s3tc GL_NV_sRGB_formats"), AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
332     InsertFormatMapping(&map, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, ExtsOnly("GL_EXT_texture_compression_s3tc GL_EXT_texture_sRGB"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_EXT_texture_compression_s3tc_srgb", "GL_EXT_texture_compression_s3tc GL_NV_sRGB_formats"), AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
333 
334     // From GL_OES_compressed_ETC1_RGB8_texture
335     InsertFormatMapping(&map, GL_ETC1_RGB8_OES,                   VersionOrExts(4, 3, "GL_ARB_ES3_compatibility"), AlwaysSupported(), NeverSupported(), VersionOrExts(3, 0, "GL_OES_compressed_ETC1_RGB8_texture"),       AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
336 
337     // From GL_OES_texture_compression_astc
338     //                       | Format                                   | OpenGL texture                                 | Filter           | Render          | OpenGL ES texture support                      | Filter           | ES attachment   | ES renderbuffer |
339     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_ASTC_4x4_KHR,           ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), NeverSupported());
340     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_ASTC_5x4_KHR,           ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), NeverSupported());
341     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_ASTC_5x5_KHR,           ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), NeverSupported());
342     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_ASTC_6x5_KHR,           ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), NeverSupported());
343     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_ASTC_6x6_KHR,           ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), NeverSupported());
344     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_ASTC_8x5_KHR,           ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), NeverSupported());
345     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_ASTC_8x6_KHR,           ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), NeverSupported());
346     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_ASTC_8x8_KHR,           ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), NeverSupported());
347     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_ASTC_10x5_KHR,          ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), NeverSupported());
348     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_ASTC_10x6_KHR,          ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), NeverSupported());
349     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_ASTC_10x8_KHR,          ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), NeverSupported());
350     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_ASTC_10x10_KHR,         ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), NeverSupported());
351     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_ASTC_12x10_KHR,         ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), NeverSupported());
352     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_ASTC_12x12_KHR,         ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), NeverSupported());
353     InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR,   ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), NeverSupported());
354     InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR,   ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), NeverSupported());
355     InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR,   ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), NeverSupported());
356     InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR,   ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), NeverSupported());
357     InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR,   ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), NeverSupported());
358     InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR,   ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), NeverSupported());
359     InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR,   ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), NeverSupported());
360     InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR,   ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), NeverSupported());
361     InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR,  ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), NeverSupported());
362     InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR,  ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), NeverSupported());
363     InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR,  ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), NeverSupported());
364     InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), NeverSupported());
365     InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), NeverSupported());
366     InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_KHR_texture_compression_astc_ldr"), AlwaysSupported(), NeverSupported(), NeverSupported());
367     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_ASTC_3x3x3_OES,         NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
368     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_ASTC_4x3x3_OES,         NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
369     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_ASTC_4x4x3_OES,         NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
370     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_ASTC_4x4x4_OES,         NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
371     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_ASTC_5x4x4_OES,         NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
372     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_ASTC_5x5x4_OES,         NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
373     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_ASTC_5x5x5_OES,         NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
374     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_ASTC_6x5x5_OES,         NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
375     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_ASTC_6x6x5_OES,         NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
376     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_ASTC_6x6x6_OES,         NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
377     InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES, NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
378     InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES, NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
379     InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES, NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
380     InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES, NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
381     InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES, NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
382     InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES, NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
383     InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES, NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
384     InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES, NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
385     InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES, NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
386     InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES, NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
387 
388     // From GL_IMG_texture_compression_pvrtc
389     //                       | Format                               | OpenGL texture support                         | Filter           | Render          | OpenGL ES texture support                      | Filter           | OpenGL ES texture attachment support | OpenGL ES renderbuffer support |
390     InsertFormatMapping(&map, GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG,    ExtsOnly("GL_IMG_texture_compression_pvrtc"),     AlwaysSupported(), NeverSupported(), ExtsOnly("GL_IMG_texture_compression_pvrtc"),   AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
391     InsertFormatMapping(&map, GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG,    ExtsOnly("GL_IMG_texture_compression_pvrtc"),     AlwaysSupported(), NeverSupported(), ExtsOnly("GL_IMG_texture_compression_pvrtc"),   AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
392     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG,   ExtsOnly("GL_IMG_texture_compression_pvrtc"),     AlwaysSupported(), NeverSupported(), ExtsOnly("GL_IMG_texture_compression_pvrtc"),   AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
393     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG,   ExtsOnly("GL_IMG_texture_compression_pvrtc"),     AlwaysSupported(), NeverSupported(), ExtsOnly("GL_IMG_texture_compression_pvrtc"),   AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
394 
395     // From GL_EXT_pvrtc_sRGB
396     //                       | Format                                      | OpenGL texture support  | Filter          | Render          | OpenGL ES texture support      | Filter           | OpenGL ES texture attachment support | OpenGL ES renderbuffer support |
397     InsertFormatMapping(&map, GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT,          NeverSupported(),         NeverSupported(), NeverSupported(), ExtsOnly("GL_EXT_pvrtc_sRGB"),   AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
398     InsertFormatMapping(&map, GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT,          NeverSupported(),         NeverSupported(), NeverSupported(), ExtsOnly("GL_EXT_pvrtc_sRGB"),   AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
399     InsertFormatMapping(&map, GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT,    NeverSupported(),         NeverSupported(), NeverSupported(), ExtsOnly("GL_EXT_pvrtc_sRGB"),   AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
400     InsertFormatMapping(&map, GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT,    NeverSupported(),         NeverSupported(), NeverSupported(), ExtsOnly("GL_EXT_pvrtc_sRGB"),   AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
401 
402     // clang-format on
403 
404     return map;
405 }
406 
GetInternalFormatMap()407 static const InternalFormatInfoMap &GetInternalFormatMap()
408 {
409     static const angle::base::NoDestructor<InternalFormatInfoMap> formatMap(
410         BuildInternalFormatInfoMap());
411     return *formatMap;
412 }
413 
GetInternalFormatInfo(GLenum internalFormat,StandardGL standard)414 const InternalFormat &GetInternalFormatInfo(GLenum internalFormat, StandardGL standard)
415 {
416     const InternalFormatInfoMap &formatMap     = GetInternalFormatMap();
417     InternalFormatInfoMap::const_iterator iter = formatMap.find(internalFormat);
418     if (iter != formatMap.end())
419     {
420         const InternalFormatInfo &info = iter->second;
421         switch (standard)
422         {
423             case STANDARD_GL_ES:
424                 return info.glesInfo;
425             case STANDARD_GL_DESKTOP:
426                 return info.glInfo;
427             default:
428                 UNREACHABLE();
429                 break;
430         }
431     }
432 
433     static const angle::base::NoDestructor<InternalFormat> defaultInternalFormat;
434     return *defaultInternalFormat;
435 }
436 
GetNativeInternalFormat(const FunctionsGL * functions,const angle::FeaturesGL & features,const gl::InternalFormat & internalFormat)437 static GLenum GetNativeInternalFormat(const FunctionsGL *functions,
438                                       const angle::FeaturesGL &features,
439                                       const gl::InternalFormat &internalFormat)
440 {
441     GLenum result = internalFormat.internalFormat;
442 
443     if (functions->standard == STANDARD_GL_DESKTOP)
444     {
445         // Use sized internal formats whenever possible to guarantee the requested precision.
446         // On Desktop GL, passing an internal format of GL_RGBA will generate a GL_RGBA8 texture
447         // even if the provided type is GL_FLOAT.
448         result = internalFormat.sizedInternalFormat;
449 
450         if (features.avoid1BitAlphaTextureFormats.enabled && internalFormat.alphaBits == 1)
451         {
452             // Use an 8-bit format instead
453             result = GL_RGBA8;
454         }
455 
456         if (features.rgba4IsNotSupportedForColorRendering.enabled &&
457             internalFormat.sizedInternalFormat == GL_RGBA4)
458         {
459             // Use an 8-bit format instead
460             result = GL_RGBA8;
461         }
462 
463         if (internalFormat.sizedInternalFormat == GL_RGB565 &&
464             !functions->isAtLeastGL(gl::Version(4, 1)) &&
465             !functions->hasGLExtension("GL_ARB_ES2_compatibility"))
466         {
467             // GL_RGB565 is required for basic ES2 functionality but was not added to desktop GL
468             // until 4.1.
469             // Work around this by using an 8-bit format instead.
470             result = GL_RGB8;
471         }
472 
473         if (internalFormat.sizedInternalFormat == GL_BGRA8_EXT)
474         {
475             // GLES accepts GL_BGRA as an internal format but desktop GL only accepts it as a type.
476             // Update the internal format to GL_RGBA.
477             result = GL_RGBA8;
478         }
479 
480         if ((functions->profile & GL_CONTEXT_CORE_PROFILE_BIT) != 0)
481         {
482             // Work around deprecated luminance alpha formats in the OpenGL core profile by backing
483             // them with R or RG textures.
484             if (internalFormat.format == GL_LUMINANCE || internalFormat.format == GL_ALPHA)
485             {
486                 result = gl::GetInternalFormatInfo(GL_RED, internalFormat.type).sizedInternalFormat;
487             }
488 
489             if (internalFormat.format == GL_LUMINANCE_ALPHA)
490             {
491                 result = gl::GetInternalFormatInfo(GL_RG, internalFormat.type).sizedInternalFormat;
492             }
493         }
494     }
495     else if (functions->isAtLeastGLES(gl::Version(3, 0)))
496     {
497         if (internalFormat.componentType == GL_FLOAT && !internalFormat.isLUMA())
498         {
499             // Use sized internal formats for floating point textures.  Extensions such as
500             // EXT_color_buffer_float require the sized formats to be renderable.
501             result = internalFormat.sizedInternalFormat;
502         }
503         else if (internalFormat.format == GL_RED_EXT || internalFormat.format == GL_RG_EXT)
504         {
505             // Workaround Adreno driver not supporting unsized EXT_texture_rg formats
506             result = internalFormat.sizedInternalFormat;
507         }
508         else if (features.unsizedsRGBReadPixelsDoesntTransform.enabled &&
509                  internalFormat.colorEncoding == GL_SRGB)
510         {
511             // Work around some Adreno driver bugs that don't read back SRGB data correctly when
512             // it's in unsized SRGB texture formats.
513             result = internalFormat.sizedInternalFormat;
514         }
515     }
516 
517     return result;
518 }
519 
GetNativeFormat(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum format)520 static GLenum GetNativeFormat(const FunctionsGL *functions,
521                               const angle::FeaturesGL &features,
522                               GLenum format)
523 {
524     GLenum result = format;
525 
526     if (functions->standard == STANDARD_GL_DESKTOP)
527     {
528         // The ES SRGB extensions require that the provided format is GL_SRGB or SRGB_ALPHA but
529         // the desktop GL extensions only accept GL_RGB or GL_RGBA.  Convert them.
530         if (format == GL_SRGB)
531         {
532             result = GL_RGB;
533         }
534 
535         if (format == GL_SRGB_ALPHA)
536         {
537             result = GL_RGBA;
538         }
539 
540         if ((functions->profile & GL_CONTEXT_CORE_PROFILE_BIT) != 0)
541         {
542             // Work around deprecated luminance alpha formats in the OpenGL core profile by backing
543             // them with R or RG textures.
544             if (format == GL_LUMINANCE || format == GL_ALPHA)
545             {
546                 result = GL_RED;
547             }
548 
549             if (format == GL_LUMINANCE_ALPHA)
550             {
551                 result = GL_RG;
552             }
553         }
554     }
555     else if (functions->isAtLeastGLES(gl::Version(3, 0)))
556     {
557         if (features.unsizedsRGBReadPixelsDoesntTransform.enabled)
558         {
559             if (format == GL_SRGB)
560             {
561                 result = GL_RGB;
562             }
563 
564             if (format == GL_SRGB_ALPHA)
565             {
566                 result = GL_RGBA;
567             }
568         }
569     }
570 
571     return result;
572 }
573 
GetNativeCompressedFormat(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum format)574 static GLenum GetNativeCompressedFormat(const FunctionsGL *functions,
575                                         const angle::FeaturesGL &features,
576                                         GLenum format)
577 {
578     GLenum result = format;
579 
580     if (functions->standard == STANDARD_GL_DESKTOP)
581     {
582         if (format == GL_ETC1_RGB8_OES)
583         {
584             // GL_ETC1_RGB8_OES is not available in any desktop GL extension but the compression
585             // format is forwards compatible so just use the ETC2 format.
586             result = GL_COMPRESSED_RGB8_ETC2;
587         }
588     }
589 
590     if (functions->isAtLeastGLES(gl::Version(3, 0)))
591     {
592         if (format == GL_ETC1_RGB8_OES)
593         {
594             // Pass GL_COMPRESSED_RGB8_ETC2 as the target format in ES3 and higher because it
595             // becomes a core format.
596             result = GL_COMPRESSED_RGB8_ETC2;
597         }
598     }
599 
600     if (features.avoidDXT1sRGBTextureFormat.enabled)
601     {
602         if (format == GL_COMPRESSED_SRGB_S3TC_DXT1_EXT)
603         {
604             // Pass GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT instead to workaround driver bug.
605             result = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
606         }
607     }
608 
609     return result;
610 }
611 
GetNativeType(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum format,GLenum type)612 static GLenum GetNativeType(const FunctionsGL *functions,
613                             const angle::FeaturesGL &features,
614                             GLenum format,
615                             GLenum type)
616 {
617     GLenum result = type;
618 
619     if (functions->standard == STANDARD_GL_DESKTOP)
620     {
621         if (type == GL_HALF_FLOAT_OES)
622         {
623             // The enums differ for the OES half float extensions and desktop GL spec.
624             // Update it.
625             result = GL_HALF_FLOAT;
626         }
627     }
628     else if (functions->isAtLeastGLES(gl::Version(3, 0)))
629     {
630         if (type == GL_HALF_FLOAT_OES)
631         {
632             switch (format)
633             {
634                 case GL_LUMINANCE_ALPHA:
635                 case GL_LUMINANCE:
636                 case GL_ALPHA:
637                     // In ES3, these formats come from EXT_texture_storage, which uses
638                     // HALF_FLOAT_OES. Other formats (like RGBA) use HALF_FLOAT (non-OES) in ES3.
639                     break;
640 
641                 default:
642                     result = GL_HALF_FLOAT;
643                     break;
644             }
645         }
646     }
647     else if (functions->standard == STANDARD_GL_ES && functions->version == gl::Version(2, 0))
648     {
649         // On ES2, convert GL_HALF_FLOAT to GL_HALF_FLOAT_OES as a convenience for internal
650         // functions. It should not be possible to get here by a normal glTexImage2D call.
651         if (type == GL_HALF_FLOAT)
652         {
653             ASSERT(functions->hasGLExtension("GL_OES_texture_half_float"));
654             result = GL_HALF_FLOAT_OES;
655         }
656     }
657 
658     return result;
659 }
660 
GetNativeReadType(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum type)661 static GLenum GetNativeReadType(const FunctionsGL *functions,
662                                 const angle::FeaturesGL &features,
663                                 GLenum type)
664 {
665     GLenum result = type;
666 
667     if (functions->standard == STANDARD_GL_DESKTOP || functions->isAtLeastGLES(gl::Version(3, 0)))
668     {
669         if (type == GL_HALF_FLOAT_OES)
670         {
671             // The enums differ for the OES half float extensions and desktop GL spec. Update it.
672             result = GL_HALF_FLOAT;
673         }
674     }
675 
676     return result;
677 }
678 
GetNativeReadFormat(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum attachmentReadFormat,GLenum format,GLenum type)679 static GLenum GetNativeReadFormat(const FunctionsGL *functions,
680                                   const angle::FeaturesGL &features,
681                                   GLenum attachmentReadFormat,
682                                   GLenum format,
683                                   GLenum type)
684 {
685     GLenum result = format;
686     if (features.readPixelsUsingImplementationColorReadFormatForNorm16.enabled &&
687         type == GL_UNSIGNED_SHORT && format == GL_RGBA &&
688         (attachmentReadFormat == GL_RED || attachmentReadFormat == GL_RG))
689     {
690         result = attachmentReadFormat;
691     }
692     return result;
693 }
694 
GetTexImageFormat(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum internalFormat,GLenum format,GLenum type)695 TexImageFormat GetTexImageFormat(const FunctionsGL *functions,
696                                  const angle::FeaturesGL &features,
697                                  GLenum internalFormat,
698                                  GLenum format,
699                                  GLenum type)
700 {
701     TexImageFormat result;
702     result.internalFormat = GetNativeInternalFormat(
703         functions, features, gl::GetInternalFormatInfo(internalFormat, type));
704     result.format = GetNativeFormat(functions, features, format);
705     result.type   = GetNativeType(functions, features, format, type);
706     return result;
707 }
708 
GetTexSubImageFormat(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum format,GLenum type)709 TexSubImageFormat GetTexSubImageFormat(const FunctionsGL *functions,
710                                        const angle::FeaturesGL &features,
711                                        GLenum format,
712                                        GLenum type)
713 {
714     TexSubImageFormat result;
715     result.format = GetNativeFormat(functions, features, format);
716     result.type   = GetNativeType(functions, features, format, type);
717     return result;
718 }
719 
GetCompressedTexImageFormat(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum internalFormat)720 CompressedTexImageFormat GetCompressedTexImageFormat(const FunctionsGL *functions,
721                                                      const angle::FeaturesGL &features,
722                                                      GLenum internalFormat)
723 {
724     CompressedTexImageFormat result;
725     result.internalFormat = GetNativeCompressedFormat(functions, features, internalFormat);
726     return result;
727 }
728 
GetCompressedSubTexImageFormat(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum format)729 CompressedTexSubImageFormat GetCompressedSubTexImageFormat(const FunctionsGL *functions,
730                                                            const angle::FeaturesGL &features,
731                                                            GLenum format)
732 {
733     CompressedTexSubImageFormat result;
734     result.format = GetNativeCompressedFormat(functions, features, format);
735     return result;
736 }
737 
GetCopyTexImageImageFormat(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum internalFormat,GLenum framebufferType)738 CopyTexImageImageFormat GetCopyTexImageImageFormat(const FunctionsGL *functions,
739                                                    const angle::FeaturesGL &features,
740                                                    GLenum internalFormat,
741                                                    GLenum framebufferType)
742 {
743     CopyTexImageImageFormat result;
744     result.internalFormat = GetNativeInternalFormat(
745         functions, features, gl::GetInternalFormatInfo(internalFormat, framebufferType));
746     return result;
747 }
748 
GetTexStorageFormat(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum internalFormat)749 TexStorageFormat GetTexStorageFormat(const FunctionsGL *functions,
750                                      const angle::FeaturesGL &features,
751                                      GLenum internalFormat)
752 {
753     TexStorageFormat result;
754     // TexStorage entrypoints accept both compressed and uncompressed formats.
755     // All compressed formats are sized.
756     gl::InternalFormat sizedFormatInfo = gl::GetSizedInternalFormatInfo(internalFormat);
757     if (sizedFormatInfo.compressed)
758     {
759         result.internalFormat = GetNativeCompressedFormat(functions, features, internalFormat);
760     }
761     else
762     {
763         result.internalFormat = GetNativeInternalFormat(functions, features, sizedFormatInfo);
764     }
765 
766     return result;
767 }
768 
GetRenderbufferFormat(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum internalFormat)769 RenderbufferFormat GetRenderbufferFormat(const FunctionsGL *functions,
770                                          const angle::FeaturesGL &features,
771                                          GLenum internalFormat)
772 {
773     RenderbufferFormat result;
774     result.internalFormat = GetNativeInternalFormat(functions, features,
775                                                     gl::GetSizedInternalFormatInfo(internalFormat));
776     return result;
777 }
GetReadPixelsFormat(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum attachmentReadFormat,GLenum format,GLenum type)778 ReadPixelsFormat GetReadPixelsFormat(const FunctionsGL *functions,
779                                      const angle::FeaturesGL &features,
780                                      GLenum attachmentReadFormat,
781                                      GLenum format,
782                                      GLenum type)
783 {
784     ReadPixelsFormat result;
785     result.format = GetNativeReadFormat(functions, features, attachmentReadFormat, format, type);
786     result.type   = GetNativeReadType(functions, features, type);
787     return result;
788 }
789 }  // namespace nativegl
790 
791 }  // namespace rx
792