xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/gl/formatutilsgl.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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/autogen/FeaturesGL_autogen.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 
33 SupportRequirement &SupportRequirement::operator=(const SupportRequirement &other) = default;
34 
35 SupportRequirement::~SupportRequirement() = default;
36 
InternalFormat()37 InternalFormat::InternalFormat() : texture(), filter(), textureAttachment(), renderbuffer() {}
38 
39 InternalFormat::InternalFormat(const InternalFormat &other) = default;
40 
~InternalFormat()41 InternalFormat::~InternalFormat() {}
42 
43 // supported = version || vertexExt
VersionOrExts(GLuint major,GLuint minor,const std::string & versionExt)44 static inline SupportRequirement VersionOrExts(GLuint major,
45                                                GLuint minor,
46                                                const std::string &versionExt)
47 {
48     SupportRequirement requirement;
49     requirement.version.major = major;
50     requirement.version.minor = minor;
51     angle::SplitStringAlongWhitespace(versionExt, &requirement.versionExtensions);
52     return requirement;
53 }
54 
55 // supported = requiredExt && (version || requiredWithoutVersionExt)
ExtAndVersionOrExt(const std::string & requiredExt,GLuint major,GLuint minor,const std::string & requiredWithoutVersionExt)56 static inline SupportRequirement ExtAndVersionOrExt(const std::string &requiredExt,
57                                                     GLuint major,
58                                                     GLuint minor,
59                                                     const std::string &requiredWithoutVersionExt)
60 {
61     SupportRequirement requirement;
62     requirement.requiredExtensions.resize(1);
63     angle::SplitStringAlongWhitespace(requiredExt, &requirement.requiredExtensions[0]);
64     requirement.version.major = major;
65     requirement.version.minor = minor;
66     angle::SplitStringAlongWhitespace(requiredWithoutVersionExt, &requirement.versionExtensions);
67     return requirement;
68 }
69 
70 // supported = version
VersionOnly(GLuint major,GLuint minor)71 static inline SupportRequirement VersionOnly(GLuint major, GLuint minor)
72 {
73     SupportRequirement requirement;
74     requirement.version.major = major;
75     requirement.version.minor = minor;
76     return requirement;
77 }
78 
79 // supported = any one of sets in exts
ExtsOnly(const std::vector<std::string> & exts)80 static inline SupportRequirement ExtsOnly(const std::vector<std::string> &exts)
81 {
82     SupportRequirement requirement;
83     requirement.version.major = 0;
84     requirement.version.minor = 0;
85     requirement.requiredExtensions.resize(exts.size());
86     for (size_t i = 0; i < exts.size(); i++)
87     {
88         angle::SplitStringAlongWhitespace(exts[i], &requirement.requiredExtensions[i]);
89     }
90     return requirement;
91 }
92 
93 // supported = ext
ExtsOnly(const std::string & ext)94 static inline SupportRequirement ExtsOnly(const std::string &ext)
95 {
96     return ExtsOnly(std::vector<std::string>({ext}));
97 }
98 
99 // supported = ext1 || ext2
ExtsOnly(const std::string & ext1,const std::string & ext2)100 static inline SupportRequirement ExtsOnly(const std::string &ext1, const std::string &ext2)
101 {
102     return ExtsOnly(std::vector<std::string>({ext1, ext2}));
103 }
104 
105 // supported = true
AlwaysSupported()106 static inline SupportRequirement AlwaysSupported()
107 {
108     SupportRequirement requirement;
109     requirement.version.major = 0;
110     requirement.version.minor = 0;
111     return requirement;
112 }
113 
114 // supported = false
NeverSupported()115 static inline SupportRequirement NeverSupported()
116 {
117     SupportRequirement requirement;
118     requirement.version.major = std::numeric_limits<GLuint>::max();
119     requirement.version.minor = std::numeric_limits<GLuint>::max();
120     return requirement;
121 }
122 
123 struct InternalFormatInfo
124 {
125     InternalFormat glesInfo;
126     InternalFormat glInfo;
127 };
128 
129 typedef std::pair<GLenum, InternalFormatInfo> InternalFormatInfoPair;
130 typedef std::map<GLenum, InternalFormatInfo> InternalFormatInfoMap;
131 
132 // 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)133 static inline void InsertFormatMapping(InternalFormatInfoMap *map,
134                                        GLenum internalFormat,
135                                        const SupportRequirement &desktopTexture,
136                                        const SupportRequirement &desktopFilter,
137                                        const SupportRequirement &desktopRender,
138                                        const SupportRequirement &esTexture,
139                                        const SupportRequirement &esFilter,
140                                        const SupportRequirement &esTextureAttachment,
141                                        const SupportRequirement &esRenderbufferAttachment)
142 {
143     InternalFormatInfo formatInfo;
144     formatInfo.glInfo.texture = desktopTexture;
145     formatInfo.glInfo.filter  = desktopFilter;
146     // No difference spotted yet in Desktop GL texture attachment and renderbuffer capabilities
147     formatInfo.glInfo.textureAttachment   = desktopRender;
148     formatInfo.glInfo.renderbuffer        = desktopRender;
149     formatInfo.glesInfo.texture           = esTexture;
150     formatInfo.glesInfo.filter            = esFilter;
151     formatInfo.glesInfo.textureAttachment = esTextureAttachment;
152     formatInfo.glesInfo.renderbuffer      = esRenderbufferAttachment;
153     map->insert(std::make_pair(internalFormat, formatInfo));
154 }
155 
156 // Note 1: This map is used to determine extensions support, which is based on checking support for
157 // sized formats (this is ANGLE implementation limitation - D3D backend supports only sized formats)
158 // In order to determine support for extensions which introduce unsized formats, this map would say
159 // that a corresponding sized format is supported, instead. Thus, if this map says that a sized
160 // format is supported, this means that either the actual sized format or a corresponding unsized
161 // format is supported by the native driver.
162 // For example, GL_EXT_texture_rg provides support for RED_EXT format with UNSIGNED_BYTE type.
163 // Therefore, DetermineRGTextureSupport checks for GL_R8 support. Therefore this map says that
164 // GL_R8 (and not RED_EXT) is supported if GL_EXT_texture_rg is available. GL_R8 itself
165 // is supported in ES3, thus the combined condition is VersionOrExts(3, 0, "GL_EXT_texture_rg").
166 //
167 // Note 2: Texture Attachment support is checked also by SupportsNativeRendering().
168 // Unsized formats appear in this map for this reason. The assumption is
169 // that SupportsNativeRendering() will not check sized formats in the ES2 frontend
170 // and the information in unsized formats is correct, and not merged like for sized formats.
171 // In the ES3 frontend, it could happen that SupportsNativeRendering() would be wrong,
172 // but this will be mitigated by fall back to CPU-readback in TextureGL::copySubTextureHelper().
173 //
174 // Note 3: Because creating renderbuffers with unsized formats is impossible,
175 // the value of renderbuffer support is actually correct for the sized formats.
176 //
177 // Note 4: To determine whether a format is filterable, one must check both "Filter" and "Texture"
178 // support, like it is done in GenerateTextureFormatCaps().
179 // On the other hand, "Texture Attachment" support formula is self-contained.
180 //
181 // TODO(ynovikov): http://anglebug.com/42261549 Verify support fields of BGRA, depth, stencil and
182 // compressed formats, and all formats for Desktop GL.
BuildInternalFormatInfoMap()183 static InternalFormatInfoMap BuildInternalFormatInfoMap()
184 {
185     InternalFormatInfoMap map;
186 
187     // clang-format off
188     //                       | Format              | OpenGL texture support                          | Filter           | OpenGL render support                        | OpenGL ES texture support                 | Filter           | OpenGL ES texture attachment support    | OpenGL ES renderbuffer support           |
189     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")  );
190     InsertFormatMapping(&map, GL_R8_SNORM,          VersionOnly(3, 1),                                AlwaysSupported(), VersionOnly(3, 1),                             VersionOnly(3, 0),                          AlwaysSupported(), ExtsOnly("GL_EXT_render_snorm"),          ExtsOnly("GL_EXT_render_snorm")           );
191     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")  );
192     InsertFormatMapping(&map, GL_RG8_SNORM,         VersionOnly(3, 1),                                AlwaysSupported(), VersionOnly(3, 1),                             VersionOnly(3, 0),                          AlwaysSupported(), ExtsOnly("GL_EXT_render_snorm"),          ExtsOnly("GL_EXT_render_snorm")           );
193     InsertFormatMapping(&map, GL_RGB8,              AlwaysSupported(),                                AlwaysSupported(), AlwaysSupported(),                             AlwaysSupported(),                          AlwaysSupported(), VersionOnly(2, 0),                        VersionOrExts(3, 0, "GL_OES_rgb8_rgba8")  );
194     InsertFormatMapping(&map, GL_RGB8_SNORM,        VersionOnly(3, 1),                                AlwaysSupported(), NeverSupported(),                              VersionOnly(3, 0),                          AlwaysSupported(), NeverSupported(),                         NeverSupported()                          );
195     InsertFormatMapping(&map, GL_RGB565,            AlwaysSupported(),                                AlwaysSupported(), AlwaysSupported(),                             AlwaysSupported(),                          AlwaysSupported(), AlwaysSupported(),                        AlwaysSupported()                         );
196     InsertFormatMapping(&map, GL_RGBA4,             AlwaysSupported(),                                AlwaysSupported(), AlwaysSupported(),                             AlwaysSupported(),                          AlwaysSupported(), AlwaysSupported(),                        AlwaysSupported()                         );
197     InsertFormatMapping(&map, GL_RGB5_A1,           AlwaysSupported(),                                AlwaysSupported(), AlwaysSupported(),                             AlwaysSupported(),                          AlwaysSupported(), AlwaysSupported(),                        AlwaysSupported()                         );
198     InsertFormatMapping(&map, GL_RGBA8,             AlwaysSupported(),                                AlwaysSupported(), AlwaysSupported(),                             AlwaysSupported(),                          AlwaysSupported(), VersionOnly(2, 0),                        VersionOrExts(3, 0, "GL_OES_rgb8_rgba8")  );
199     InsertFormatMapping(&map, GL_RGBA8_SNORM,       VersionOnly(3, 1),                                AlwaysSupported(), VersionOnly(3, 1),                             VersionOnly(3, 0),                          AlwaysSupported(), ExtsOnly("GL_EXT_render_snorm"),          ExtsOnly("GL_EXT_render_snorm")           );
200     InsertFormatMapping(&map, GL_RGB10_A2,          AlwaysSupported(),                                AlwaysSupported(), AlwaysSupported(),                             VersionOnly(3, 0),                          AlwaysSupported(), VersionOnly(3, 0),                        VersionOnly(3, 0)                         );
201     InsertFormatMapping(&map, GL_RGB10_A2UI,        VersionOrExts(3, 3, "GL_ARB_texture_rgb10_a2ui"), NeverSupported(),  AlwaysSupported(),                             VersionOnly(3, 0),                          NeverSupported(),  AlwaysSupported(),                        AlwaysSupported()                         );
202     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()                          );
203     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")        );
204     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)                         );
205     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)                         );
206     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)                         );
207     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)                         );
208     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)                         );
209     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)                         );
210     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)                         );
211     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)                         );
212     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)                         );
213     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)                         );
214     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)                         );
215     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)                         );
216     InsertFormatMapping(&map, GL_RGB8I,             VersionOrExts(3, 0, "GL_EXT_texture_integer"),    NeverSupported(),  NeverSupported(),                              VersionOnly(3, 0),                          NeverSupported(),  NeverSupported(),                         NeverSupported()                          );
217     InsertFormatMapping(&map, GL_RGB8UI,            VersionOrExts(3, 0, "GL_EXT_texture_integer"),    NeverSupported(),  NeverSupported(),                              VersionOnly(3, 0),                          NeverSupported(),  NeverSupported(),                         NeverSupported()                          );
218     InsertFormatMapping(&map, GL_RGB16I,            VersionOrExts(3, 0, "GL_EXT_texture_integer"),    NeverSupported(),  NeverSupported(),                              VersionOnly(3, 0),                          NeverSupported(),  NeverSupported(),                         NeverSupported()                          );
219     InsertFormatMapping(&map, GL_RGB16UI,           VersionOrExts(3, 0, "GL_EXT_texture_integer"),    NeverSupported(),  NeverSupported(),                              VersionOnly(3, 0),                          NeverSupported(),  NeverSupported(),                         NeverSupported()                          );
220     InsertFormatMapping(&map, GL_RGB32I,            VersionOrExts(3, 0, "GL_EXT_texture_integer"),    NeverSupported(),  NeverSupported(),                              VersionOnly(3, 0),                          NeverSupported(),  NeverSupported(),                         NeverSupported()                          );
221     InsertFormatMapping(&map, GL_RGB32UI,           VersionOrExts(3, 0, "GL_EXT_texture_integer"),    NeverSupported(),  NeverSupported(),                              VersionOnly(3, 0),                          NeverSupported(),  NeverSupported(),                         NeverSupported()                          );
222     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)                         );
223     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)                         );
224     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)                         );
225     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)                         );
226     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)                         );
227     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)                         );
228 
229     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")         );
230     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")         );
231     InsertFormatMapping(&map, GL_RGB16,             AlwaysSupported(),                                AlwaysSupported(), NeverSupported(),                              ExtsOnly("GL_EXT_texture_norm16"),          AlwaysSupported(), NeverSupported(),                         NeverSupported()                          );
232     InsertFormatMapping(&map, GL_RGBA16,            AlwaysSupported(),                                AlwaysSupported(), AlwaysSupported(),                             ExtsOnly("GL_EXT_texture_norm16"),          AlwaysSupported(), ExtsOnly("GL_EXT_texture_norm16"),        ExtsOnly("GL_EXT_texture_norm16")         );
233 
234     InsertFormatMapping(&map, GL_R16_SNORM,         VersionOnly(3, 1),                                AlwaysSupported(), VersionOnly(3, 1),                             ExtsOnly("GL_EXT_texture_norm16"),          AlwaysSupported(), ExtsOnly("GL_EXT_texture_norm16 GL_EXT_render_snorm"), ExtsOnly("GL_EXT_texture_norm16 GL_EXT_render_snorm"));
235     InsertFormatMapping(&map, GL_RG16_SNORM,        VersionOnly(3, 1),                                AlwaysSupported(), VersionOnly(3, 1),                             ExtsOnly("GL_EXT_texture_norm16"),          AlwaysSupported(), ExtsOnly("GL_EXT_texture_norm16 GL_EXT_render_snorm"), ExtsOnly("GL_EXT_texture_norm16 GL_EXT_render_snorm"));
236     InsertFormatMapping(&map, GL_RGB16_SNORM,       VersionOnly(3, 1),                                AlwaysSupported(), NeverSupported(),                              ExtsOnly("GL_EXT_texture_norm16"),          AlwaysSupported(), NeverSupported(),                                      NeverSupported()                                     );
237     InsertFormatMapping(&map, GL_RGBA16_SNORM,      VersionOnly(3, 1),                                AlwaysSupported(), VersionOnly(3, 1),                             ExtsOnly("GL_EXT_texture_norm16"),          AlwaysSupported(), ExtsOnly("GL_EXT_texture_norm16 GL_EXT_render_snorm"), ExtsOnly("GL_EXT_texture_norm16 GL_EXT_render_snorm"));
238 
239     // Unsized formats
240     InsertFormatMapping(&map, GL_ALPHA,             NeverSupported(),                                 NeverSupported(),  NeverSupported(),                              AlwaysSupported(),                          AlwaysSupported(), NeverSupported(),                         NeverSupported()                          );
241     InsertFormatMapping(&map, GL_LUMINANCE,         NeverSupported(),                                 NeverSupported(),  NeverSupported(),                              AlwaysSupported(),                          AlwaysSupported(), NeverSupported(),                         NeverSupported()                          );
242     InsertFormatMapping(&map, GL_LUMINANCE_ALPHA,   NeverSupported(),                                 NeverSupported(),  NeverSupported(),                              AlwaysSupported(),                          AlwaysSupported(), NeverSupported(),                         NeverSupported()                          );
243     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()                          );
244     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()                          );
245     InsertFormatMapping(&map, GL_RGB,               AlwaysSupported(),                                AlwaysSupported(), AlwaysSupported(),                             AlwaysSupported(),                          AlwaysSupported(), VersionOnly(2, 0),                        NeverSupported()                          );
246     InsertFormatMapping(&map, GL_RGBA,              AlwaysSupported(),                                AlwaysSupported(), AlwaysSupported(),                             AlwaysSupported(),                          AlwaysSupported(), VersionOnly(2, 0),                        NeverSupported()                          );
247     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()                          );
248     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()                          );
249     InsertFormatMapping(&map, GL_RGB_INTEGER,       VersionOrExts(3, 0, "GL_EXT_texture_integer"),    NeverSupported(),  NeverSupported(),                              VersionOnly(3, 0),                          NeverSupported(),  NeverSupported(),                         NeverSupported()                          );
250     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()                          );
251     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()                          );
252     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()                          );
253 
254     // From GL_EXT_texture_format_BGRA8888
255     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(), ExtsOnly("GL_EXT_texture_format_BGRA8888"), ExtsOnly("GL_EXT_texture_format_BGRA8888")                          );
256     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(), ExtsOnly("GL_EXT_texture_format_BGRA8888"), ExtsOnly("GL_EXT_texture_format_BGRA8888")                          );
257 
258     // From GL_EXT_texture_type_2_10_10_10_REV
259     // Emulated with GL_RGB10_A2 on desktop GL
260     InsertFormatMapping(&map, GL_RGB10_EXT,         AlwaysSupported(),                                AlwaysSupported(), NeverSupported(),                              ExtsOnly("GL_EXT_texture_type_2_10_10_10_REV GL_OES_required_internalformat"), AlwaysSupported(), NeverSupported(), NeverSupported()                         );
261 
262     // Floating point formats
263     // Note 1: GL_EXT_texture_shared_exponent and GL_ARB_color_buffer_float suggest that RGB9_E5
264     // would be renderable, but once support for renderable float textures got rolled into core GL
265     // spec it wasn't intended to be renderable. In practice it's not reliably renderable even
266     // with the extensions, there's a known bug in at least NVIDIA driver version 370.
267     //
268     // Note 2: It's a bit unclear whether texture attachments with GL_RGB16F should be supported
269     // in ES3 with GL_EXT_color_buffer_half_float. Probably not, since in ES3 type is HALF_FLOAT,
270     // but GL_EXT_color_buffer_half_float is applicable only to type HALF_FLOAT_OES.
271     //
272     // Note 3: GL_EXT_color_buffer_float implies that ES3.0 is supported, this simplifies the check.
273     //
274     //                       | Format              | OpenGL texture support                                       | Filter           | OpenGL render support                                                                  | OpenGL ES texture support                                         | Filter                                                 | OpenGL ES texture attachment support                                                                                                      | OpenGL ES renderbuffer support                                                                                    |
275     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")                                                                              );
276     InsertFormatMapping(&map, GL_RGB9_E5,           VersionOrExts(3, 0, "GL_EXT_texture_shared_exponent"),         AlwaysSupported(), NeverSupported(),                                                                        VersionOnly(3, 0),                                                  AlwaysSupported(),                                       ExtsOnly("GL_QCOM_render_shared_exponent"),                                                                                                 ExtsOnly("GL_QCOM_render_shared_exponent")                                                                         );
277     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"));
278     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"));
279     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")                                               );
280     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_EXT_color_buffer_half_float", "GL_EXT_color_buffer_float"),                                                                    ExtsOnly("GL_EXT_color_buffer_half_float", "GL_EXT_color_buffer_float")                                            );
281     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")                                                                              );
282     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")                                                                              );
283     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()                                                                                                   );
284     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")                                                                              );
285 
286     // Depth stencil formats
287     //                       | Format                  | OpenGL texture support                            | Filter                                     | OpenGL render support                             | OpenGL ES texture support                     | Filter                                     | OpenGL ES texture attachment support                                   | OpenGL ES renderbuffer support                                        |
288     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)                                                      );
289     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)                                                      );
290     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")                                             );
291     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)                                                      );
292     InsertFormatMapping(&map, GL_STENCIL_INDEX8,        VersionOrExts(4, 4, "GL_ARB_texture_stencil8"),     NeverSupported(),                            VersionOnly(3, 0),                                  VersionOrExts(3, 2, "GL_OES_texture_stencil8"), NeverSupported(),                            VersionOrExts(3, 2, "GL_OES_texture_stencil8"),                          VersionOnly(2, 0)                                                      );
293     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"));
294     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)                                                      );
295     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)                                                      );
296     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)                                                      );
297 
298     // Luminance alpha formats
299     //                      | Format                   | OpenGL texture support                     | Filter           | Render          | OpenGL ES texture support                       | Filter                                                 | OpenGL ES texture attachment support | OpenGL ES renderbuffer support  |
300     InsertFormatMapping(&map, GL_ALPHA8_EXT,             AlwaysSupported(),                           AlwaysSupported(), NeverSupported(), AlwaysSupported(),                                AlwaysSupported(),                                       NeverSupported(),                      NeverSupported()                );
301     InsertFormatMapping(&map, GL_LUMINANCE8_EXT,         AlwaysSupported(),                           AlwaysSupported(), NeverSupported(), AlwaysSupported(),                                AlwaysSupported(),                                       NeverSupported(),                      NeverSupported()                );
302     InsertFormatMapping(&map, GL_LUMINANCE8_ALPHA8_EXT,  AlwaysSupported(),                           AlwaysSupported(), NeverSupported(), AlwaysSupported(),                                AlwaysSupported(),                                       NeverSupported(),                      NeverSupported()                );
303     InsertFormatMapping(&map, GL_LUMINANCE4_ALPHA4_OES,  AlwaysSupported(),                           AlwaysSupported(), NeverSupported(), ExtsOnly("GL_OES_required_internalformat"),       AlwaysSupported(),                                       NeverSupported(),                      NeverSupported()                );
304     InsertFormatMapping(&map, GL_ALPHA16F_EXT,           VersionOrExts(3, 0, "GL_ARB_texture_float"), AlwaysSupported(), NeverSupported(), VersionOrExts(3, 0, "GL_OES_texture_half_float"), VersionOrExts(3, 0, "GL_OES_texture_half_float_linear"), NeverSupported(),                      NeverSupported()                );
305     InsertFormatMapping(&map, GL_LUMINANCE16F_EXT,       VersionOrExts(3, 0, "GL_ARB_texture_float"), AlwaysSupported(), NeverSupported(), VersionOrExts(3, 0, "GL_OES_texture_half_float"), VersionOrExts(3, 0, "GL_OES_texture_half_float_linear"), NeverSupported(),                      NeverSupported()                );
306     InsertFormatMapping(&map, GL_LUMINANCE_ALPHA16F_EXT, VersionOrExts(3, 0, "GL_ARB_texture_float"), AlwaysSupported(), NeverSupported(), VersionOrExts(3, 0, "GL_OES_texture_half_float"), VersionOrExts(3, 0, "GL_OES_texture_half_float_linear"), NeverSupported(),                      NeverSupported()                );
307     InsertFormatMapping(&map, GL_ALPHA32F_EXT,           VersionOrExts(3, 0, "GL_ARB_texture_float"), AlwaysSupported(), NeverSupported(), VersionOrExts(3, 0, "GL_OES_texture_float"),      ExtsOnly("GL_OES_texture_float_linear"),                 NeverSupported(),                      NeverSupported()                );
308     InsertFormatMapping(&map, GL_LUMINANCE32F_EXT,       VersionOrExts(3, 0, "GL_ARB_texture_float"), AlwaysSupported(), NeverSupported(), VersionOrExts(3, 0, "GL_OES_texture_float"),      ExtsOnly("GL_OES_texture_float_linear"),                 NeverSupported(),                      NeverSupported()                );
309     InsertFormatMapping(&map, GL_LUMINANCE_ALPHA32F_EXT, VersionOrExts(3, 0, "GL_ARB_texture_float"), AlwaysSupported(), NeverSupported(), VersionOrExts(3, 0, "GL_OES_texture_float"),      ExtsOnly("GL_OES_texture_float_linear"),                 NeverSupported(),                      NeverSupported()                );
310 
311     // GL_EXT_texture_sRGB_R8 and GL_EXT_texture_sRGB_RG8 formats
312     //                      | Format     | OpenGL texture support             | Filter           | Render          | OpenGL ES texture support          | Filter           | OpenGL ES texture attachment support | OpenGL ES renderbuffer support  |
313     InsertFormatMapping(&map, GL_SR8_EXT,  ExtsOnly("GL_EXT_texture_sRGB_R8"),  AlwaysSupported(), NeverSupported(), ExtsOnly("GL_EXT_texture_sRGB_R8"),  AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
314     InsertFormatMapping(&map, GL_SRG8_EXT, ExtsOnly("GL_EXT_texture_sRGB_RG8"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_EXT_texture_sRGB_RG8"), AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
315 
316     // EXT_texture_compression_rgtc formats
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_RED_RGTC1_EXT,              VersionOrExts(3, 0, "GL_ARB_texture_compression_rgtc"), AlwaysSupported(), NeverSupported(), ExtsOnly("GL_EXT_texture_compression_rgtc"), AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
319     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()                );
320     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()                );
321     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()                );
322 
323     // EXT_texture_compression_bptc formats
324     //                       | Format                                   | OpenGL texture support                                | Filter           | Render          | OpenGL ES texture support                  | Filter           | OpenGL ES texture attachment support | OpenGL ES renderbuffer support |
325     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()                );
326     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()                );
327     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()                );
328     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()                 );
329 
330     // Compressed formats, From ES 3.0.1 spec, table 3.16
331     //                       | Format                                      | OpenGL texture support                         | Filter           | Render          | OpenGL ES texture support                                                   | Filter           | OpenGL ES texture attachment support | OpenGL ES renderbuffer support |
332     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()                );
333     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()                );
334     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()                );
335     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()                );
336     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()                );
337     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()                );
338     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()                );
339     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()                );
340     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()                );
341     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()                );
342 
343     // From GL_EXT_texture_compression_dxt1
344     //                       | Format                            | OpenGL texture support                         | Filter           | Render          | OpenGL ES texture support                                                       | Filter           | OpenGL ES texture attachment support | OpenGL ES renderbuffer support |
345     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()                );
346     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()                );
347 
348     // From GL_ANGLE_texture_compression_dxt3
349     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()                );
350 
351     // From GL_ANGLE_texture_compression_dxt5
352     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()                );
353 
354     // From GL_EXT_texture_compression_s3tc_srgb
355     //                       | Format                                | OpenGL texture support                                                            | Filter           | Render          | OpenGL ES texture support                                                                             | Filter           | OpenGL ES texture attachment support | OpenGL ES renderbuffer support |
356     InsertFormatMapping(&map, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT,       ExtAndVersionOrExt("GL_EXT_texture_compression_s3tc", 2, 1, "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()                );
357     InsertFormatMapping(&map, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, ExtAndVersionOrExt("GL_EXT_texture_compression_s3tc", 2, 1, "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()                );
358     InsertFormatMapping(&map, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, ExtAndVersionOrExt("GL_EXT_texture_compression_s3tc", 2, 1, "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()                );
359     InsertFormatMapping(&map, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, ExtAndVersionOrExt("GL_EXT_texture_compression_s3tc", 2, 1, "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()                );
360 
361     // From GL_OES_compressed_ETC1_RGB8_texture
362     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()                );
363 
364     // From GL_OES_texture_compression_astc
365     //                       | Format                                   | OpenGL texture                                 | Filter           | Render          | OpenGL ES texture support                      | Filter           | ES attachment   | ES renderbuffer |
366     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());
367     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());
368     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());
369     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());
370     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());
371     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());
372     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());
373     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());
374     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());
375     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());
376     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());
377     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());
378     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());
379     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());
380     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());
381     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());
382     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());
383     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());
384     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());
385     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());
386     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());
387     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());
388     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());
389     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());
390     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());
391     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());
392     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());
393     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());
394     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_ASTC_3x3x3_OES,         NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
395     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_ASTC_4x3x3_OES,         NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
396     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_ASTC_4x4x3_OES,         NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
397     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_ASTC_4x4x4_OES,         NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
398     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_ASTC_5x4x4_OES,         NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
399     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_ASTC_5x5x4_OES,         NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
400     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_ASTC_5x5x5_OES,         NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
401     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_ASTC_6x5x5_OES,         NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
402     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_ASTC_6x6x5_OES,         NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
403     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_ASTC_6x6x6_OES,         NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
404     InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES, NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
405     InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES, NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
406     InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES, NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
407     InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES, NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
408     InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES, NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
409     InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES, NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
410     InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES, NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
411     InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES, NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
412     InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES, NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
413     InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES, NeverSupported(), NeverSupported(), NeverSupported(), ExtsOnly("GL_OES_texture_compression_astc"),     AlwaysSupported(), NeverSupported(), NeverSupported());
414 
415     // From GL_IMG_texture_compression_pvrtc
416     //                       | Format                               | OpenGL texture support                         | Filter           | Render          | OpenGL ES texture support                      | Filter           | OpenGL ES texture attachment support | OpenGL ES renderbuffer support |
417     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()                );
418     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()                );
419     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()                );
420     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()                );
421 
422     // From GL_EXT_pvrtc_sRGB
423     //                       | Format                                      | OpenGL texture support  | Filter          | Render          | OpenGL ES texture support                                      | Filter           | OpenGL ES texture attachment support | OpenGL ES renderbuffer support |
424     InsertFormatMapping(&map, GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT,          NeverSupported(),         NeverSupported(), NeverSupported(), ExtsOnly("GL_IMG_texture_compression_pvrtc GL_EXT_pvrtc_sRGB"),   AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
425     InsertFormatMapping(&map, GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT,          NeverSupported(),         NeverSupported(), NeverSupported(), ExtsOnly("GL_IMG_texture_compression_pvrtc GL_EXT_pvrtc_sRGB"),   AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
426     InsertFormatMapping(&map, GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT,    NeverSupported(),         NeverSupported(), NeverSupported(), ExtsOnly("GL_IMG_texture_compression_pvrtc GL_EXT_pvrtc_sRGB"),   AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
427     InsertFormatMapping(&map, GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT,    NeverSupported(),         NeverSupported(), NeverSupported(), ExtsOnly("GL_IMG_texture_compression_pvrtc GL_EXT_pvrtc_sRGB"),   AlwaysSupported(), NeverSupported(),                      NeverSupported()                );
428 
429     // clang-format on
430 
431     return map;
432 }
433 
GetInternalFormatMap()434 static const InternalFormatInfoMap &GetInternalFormatMap()
435 {
436     static const angle::base::NoDestructor<InternalFormatInfoMap> formatMap(
437         BuildInternalFormatInfoMap());
438     return *formatMap;
439 }
440 
GetInternalFormatInfo(GLenum internalFormat,StandardGL standard)441 const InternalFormat &GetInternalFormatInfo(GLenum internalFormat, StandardGL standard)
442 {
443     const InternalFormatInfoMap &formatMap     = GetInternalFormatMap();
444     InternalFormatInfoMap::const_iterator iter = formatMap.find(internalFormat);
445     if (iter != formatMap.end())
446     {
447         const InternalFormatInfo &info = iter->second;
448         switch (standard)
449         {
450             case STANDARD_GL_ES:
451                 return info.glesInfo;
452             case STANDARD_GL_DESKTOP:
453                 return info.glInfo;
454             default:
455                 UNREACHABLE();
456                 break;
457         }
458     }
459 
460     static const angle::base::NoDestructor<InternalFormat> defaultInternalFormat;
461     return *defaultInternalFormat;
462 }
463 
IsLUMAFormat(GLenum format)464 static bool IsLUMAFormat(GLenum format)
465 {
466     return (format == GL_LUMINANCE || format == GL_ALPHA || format == GL_LUMINANCE_ALPHA);
467 }
468 
EmulateLUMAFormat(const GLenum format)469 static GLenum EmulateLUMAFormat(const GLenum format)
470 {
471     // This is needed separately from EmulateLUMA because some format/type combinations that come in
472     // to GetNativeFormat don't have entries in the internal format map.
473 
474     ASSERT(IsLUMAFormat(format));
475 
476     if (format == GL_LUMINANCE || format == GL_ALPHA)
477         return GL_RED;
478 
479     return GL_RG;
480 }
481 
EmulateLUMA(const gl::InternalFormat & internalFormat)482 static const gl::InternalFormat &EmulateLUMA(const gl::InternalFormat &internalFormat)
483 {
484     ASSERT(IsLUMAFormat(internalFormat.format));
485 
486     // Work around deprecated luminance/alpha formats in the OpenGL core profile, and OpenGL ES 3.0
487     // and greater, by backing them with R or RG textures.
488     return gl::GetInternalFormatInfo(EmulateLUMAFormat(internalFormat.format), internalFormat.type);
489 }
490 
GetNativeInternalFormat(const FunctionsGL * functions,const angle::FeaturesGL & features,const gl::InternalFormat & internalFormat)491 static GLenum GetNativeInternalFormat(const FunctionsGL *functions,
492                                       const angle::FeaturesGL &features,
493                                       const gl::InternalFormat &internalFormat)
494 {
495     GLenum result = internalFormat.internalFormat;
496 
497     if (functions->standard == STANDARD_GL_DESKTOP)
498     {
499         // Use sized internal formats whenever possible to guarantee the requested precision.
500         // On Desktop GL, passing an internal format of GL_RGBA will generate a GL_RGBA8 texture
501         // even if the provided type is GL_FLOAT.
502         result = internalFormat.sizedInternalFormat;
503 
504         if (features.avoid1BitAlphaTextureFormats.enabled && internalFormat.alphaBits == 1)
505         {
506             // Use an 8-bit format instead
507             result = GL_RGBA8;
508         }
509 
510         if (internalFormat.sizedInternalFormat == GL_RGBA4 &&
511             (features.RGBA4IsNotSupportedForColorRendering.enabled ||
512              features.promotePackedFormatsTo8BitPerChannel.enabled))
513         {
514             // Use an 8-bit format instead
515             result = GL_RGBA8;
516         }
517 
518         if (internalFormat.sizedInternalFormat == GL_RGB565 &&
519             ((!functions->isAtLeastGL(gl::Version(4, 1)) &&
520               !functions->hasGLExtension("GL_ARB_ES2_compatibility")) ||
521              features.promotePackedFormatsTo8BitPerChannel.enabled))
522         {
523             // GL_RGB565 is required for basic ES2 functionality but was not added to desktop GL
524             // until 4.1.
525             // Work around this by using an 8-bit format instead.
526             result = GL_RGB8;
527         }
528 
529         if (internalFormat.sizedInternalFormat == GL_BGRA8_EXT)
530         {
531             // GLES accepts GL_BGRA as an internal format but desktop GL only accepts it as a type.
532             // Update the internal format to GL_RGBA.
533             result = GL_RGBA8;
534         }
535 
536         if ((functions->profile & GL_CONTEXT_CORE_PROFILE_BIT) != 0)
537         {
538             if (IsLUMAFormat(internalFormat.format))
539             {
540                 result = EmulateLUMA(internalFormat).sizedInternalFormat;
541             }
542         }
543 
544         if (internalFormat.sizedInternalFormat == GL_RGB10_EXT)
545         {
546             ASSERT(features.emulateRGB10.enabled);
547             result = GL_RGB10_A2;
548         }
549     }
550     else if (functions->isAtLeastGLES(gl::Version(3, 0)))
551     {
552         if (internalFormat.componentType == GL_FLOAT)
553         {
554             if (!internalFormat.isLUMA())
555             {
556                 // Use sized internal formats for floating point textures.  Extensions such as
557                 // EXT_color_buffer_float require the sized formats to be renderable.
558                 result = internalFormat.sizedInternalFormat;
559             }
560             else if ((internalFormat.type == GL_FLOAT &&
561                       !functions->hasGLESExtension("GL_OES_texture_float")) ||
562                      (internalFormat.type == GL_HALF_FLOAT_OES &&
563                       !functions->hasGLESExtension("GL_OES_texture_half_float")))
564             {
565                 // The legacy luminance/alpha formats from OES_texture_float are emulated with R/RG
566                 // textures.
567                 if (IsLUMAFormat(internalFormat.format))
568                 {
569                     result = EmulateLUMA(internalFormat).sizedInternalFormat;
570                 }
571             }
572         }
573         else if (internalFormat.format == GL_RED_EXT || internalFormat.format == GL_RG_EXT)
574         {
575             // Workaround Adreno driver not supporting unsized EXT_texture_rg formats
576             result = internalFormat.sizedInternalFormat;
577         }
578         else if (internalFormat.colorEncoding == GL_SRGB)
579         {
580             if (features.unsizedSRGBReadPixelsDoesntTransform.enabled)
581             {
582                 // Work around some Adreno driver bugs that don't read back SRGB data correctly when
583                 // it's in unsized SRGB texture formats.
584                 result = internalFormat.sizedInternalFormat;
585             }
586             else if (!functions->hasGLESExtension("GL_EXT_sRGB"))
587             {
588                 // Unsized sRGB internal formats are unlikely to be supported by the
589                 // driver. Transform them to sized internal formats.
590                 if (internalFormat.internalFormat == GL_SRGB ||
591                     internalFormat.internalFormat == GL_SRGB_ALPHA_EXT)
592                 {
593                     result = internalFormat.sizedInternalFormat;
594                 }
595             }
596         }
597         else if ((internalFormat.internalFormat == GL_DEPTH_COMPONENT ||
598                   internalFormat.internalFormat == GL_DEPTH_STENCIL) &&
599                  !functions->hasGLESExtension("GL_OES_depth_texture"))
600         {
601             // Use ES 3.0 sized internal formats for depth/stencil textures when the driver doesn't
602             // advertise GL_OES_depth_texture, since it's likely the driver will reject unsized
603             // internal formats.
604             if (internalFormat.internalFormat == GL_DEPTH_COMPONENT &&
605                 internalFormat.type == GL_UNSIGNED_INT &&
606                 !functions->hasGLESExtension("GL_OES_depth32"))
607             {
608                 // Best-effort attempt to provide as many bits as possible.
609                 result = GL_DEPTH_COMPONENT24;
610                 // Note: could also consider promoting GL_DEPTH_COMPONENT / GL_UNSIGNED_SHORT to a
611                 // higher precision.
612             }
613             else
614             {
615                 result = internalFormat.sizedInternalFormat;
616             }
617         }
618     }
619 
620     return result;
621 }
622 
GetNativeFormat(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum format,GLenum type)623 static GLenum GetNativeFormat(const FunctionsGL *functions,
624                               const angle::FeaturesGL &features,
625                               GLenum format,
626                               GLenum type)
627 {
628     GLenum result = format;
629 
630     if (functions->standard == STANDARD_GL_DESKTOP)
631     {
632         // The ES SRGB extensions require that the provided format is GL_SRGB or SRGB_ALPHA but
633         // the desktop GL extensions only accept GL_RGB or GL_RGBA.  Convert them.
634         if (format == GL_SRGB)
635         {
636             result = GL_RGB;
637         }
638 
639         if (format == GL_SRGB_ALPHA)
640         {
641             result = GL_RGBA;
642         }
643 
644         if ((functions->profile & GL_CONTEXT_CORE_PROFILE_BIT) != 0)
645         {
646             // Work around deprecated luminance alpha formats in the OpenGL core profile by backing
647             // them with R or RG textures.
648             if (IsLUMAFormat(format))
649             {
650                 result = EmulateLUMAFormat(format);
651             }
652         }
653     }
654     else if (functions->isAtLeastGLES(gl::Version(3, 0)))
655     {
656         // Transform sRGB formats to RGB if either the GLES driver doesn't support GL_EXT_sRGB, or
657         // to work around Adreno driver bugs reading back unsized sRGB texture data.
658         if (!functions->hasGLESExtension("GL_EXT_sRGB") ||
659             features.unsizedSRGBReadPixelsDoesntTransform.enabled)
660         {
661             if (format == GL_SRGB)
662             {
663                 result = GL_RGB;
664             }
665 
666             if (format == GL_SRGB_ALPHA_EXT)
667             {
668                 result = GL_RGBA;
669             }
670         }
671 
672         if ((type == GL_FLOAT && !functions->hasGLESExtension("GL_OES_texture_float")) ||
673             (type == GL_HALF_FLOAT_OES &&
674              !functions->hasGLESExtension("GL_OES_texture_half_float")))
675         {
676             // On ES 3.0 systems that don't have GL_OES_texture_float or OES_texture_half_float, the
677             // LUMINANCE/ALPHA formats from those extensions must be emulated with R/RG textures.
678             if (IsLUMAFormat(format))
679             {
680                 result = EmulateLUMAFormat(format);
681             }
682         }
683     }
684 
685     // Emulate RGB10 with RGB10_A2.
686     if (type == GL_UNSIGNED_INT_2_10_10_10_REV && format == GL_RGB && features.emulateRGB10.enabled)
687     {
688         result = GL_RGBA;
689     }
690 
691     return result;
692 }
693 
GetNativeCompressedFormat(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum format)694 static GLenum GetNativeCompressedFormat(const FunctionsGL *functions,
695                                         const angle::FeaturesGL &features,
696                                         GLenum format)
697 {
698     GLenum result = format;
699 
700     if (gl::IsETC1Format(format))
701     {
702         // GL_ETC1_RGB8_OES is not available in any desktop GL extension but the compression
703         // format is forwards compatible so just use the ETC2 format. Pass GL_COMPRESSED_RGB8_ETC2
704         // as the target format in ES3 and higher because it becomes a core format.
705 
706         if (functions->standard == STANDARD_GL_DESKTOP ||
707             functions->isAtLeastGLES(gl::Version(3, 0)))
708         {
709             result = GL_COMPRESSED_RGB8_ETC2;
710         }
711     }
712 
713     return result;
714 }
715 
GetNativeType(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum format,GLenum type)716 static GLenum GetNativeType(const FunctionsGL *functions,
717                             const angle::FeaturesGL &features,
718                             GLenum format,
719                             GLenum type)
720 {
721     GLenum result = type;
722 
723     if (functions->standard == STANDARD_GL_DESKTOP)
724     {
725         if (type == GL_HALF_FLOAT_OES)
726         {
727             // The enums differ for the OES half float extensions and desktop GL spec.
728             // Update it.
729             result = GL_HALF_FLOAT;
730         }
731     }
732     else if (functions->isAtLeastGLES(gl::Version(3, 0)))
733     {
734         if (type == GL_HALF_FLOAT_OES)
735         {
736             if (!IsLUMAFormat(format) || !functions->hasGLESExtension("GL_OES_texture_half_float"))
737             {
738                 // In ES3, the luminance formats come from OES_texture_half_float, which uses
739                 // HALF_FLOAT_OES. Other formats (like RGBA) use HALF_FLOAT (non-OES) in ES3.
740                 // If they're emulated (see above), use HALF_FLOAT.
741                 result = GL_HALF_FLOAT;
742             }
743         }
744     }
745     else if (functions->isAtLeastGLES(gl::Version(2, 0)))
746     {
747         // On ES2, convert GL_HALF_FLOAT to GL_HALF_FLOAT_OES as a convenience for internal
748         // functions. It should not be possible to get here by a normal glTexImage2D call.
749         if (type == GL_HALF_FLOAT)
750         {
751             ASSERT(functions->hasGLESExtension("GL_OES_texture_half_float"));
752             result = GL_HALF_FLOAT_OES;
753         }
754     }
755 
756     return result;
757 }
758 
GetNativeReadType(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum type)759 static GLenum GetNativeReadType(const FunctionsGL *functions,
760                                 const angle::FeaturesGL &features,
761                                 GLenum type)
762 {
763     GLenum result = type;
764 
765     if (functions->standard == STANDARD_GL_DESKTOP || functions->isAtLeastGLES(gl::Version(3, 0)))
766     {
767         if (type == GL_HALF_FLOAT_OES)
768         {
769             // The enums differ for the OES half float extensions and desktop GL spec. Update it.
770             result = GL_HALF_FLOAT;
771         }
772     }
773 
774     return result;
775 }
776 
GetNativeReadFormat(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum attachmentReadFormat,GLenum format,GLenum type)777 static GLenum GetNativeReadFormat(const FunctionsGL *functions,
778                                   const angle::FeaturesGL &features,
779                                   GLenum attachmentReadFormat,
780                                   GLenum format,
781                                   GLenum type)
782 {
783     GLenum result = format;
784     if (features.readPixelsUsingImplementationColorReadFormatForNorm16.enabled &&
785         type == GL_UNSIGNED_SHORT && format == GL_RGBA &&
786         (attachmentReadFormat == GL_RED || attachmentReadFormat == GL_RG))
787     {
788         result = attachmentReadFormat;
789     }
790     return result;
791 }
792 
GetTexImageFormat(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum internalFormat,GLenum format,GLenum type)793 TexImageFormat GetTexImageFormat(const FunctionsGL *functions,
794                                  const angle::FeaturesGL &features,
795                                  GLenum internalFormat,
796                                  GLenum format,
797                                  GLenum type)
798 {
799     TexImageFormat result;
800     result.internalFormat = GetNativeInternalFormat(
801         functions, features, gl::GetInternalFormatInfo(internalFormat, type));
802     result.format = GetNativeFormat(functions, features, format, type);
803     result.type   = GetNativeType(functions, features, format, type);
804     return result;
805 }
806 
GetTexSubImageFormat(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum format,GLenum type)807 TexSubImageFormat GetTexSubImageFormat(const FunctionsGL *functions,
808                                        const angle::FeaturesGL &features,
809                                        GLenum format,
810                                        GLenum type)
811 {
812     TexSubImageFormat result;
813     result.format = GetNativeFormat(functions, features, format, type);
814     result.type   = GetNativeType(functions, features, format, type);
815     return result;
816 }
817 
GetCompressedTexImageFormat(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum internalFormat)818 CompressedTexImageFormat GetCompressedTexImageFormat(const FunctionsGL *functions,
819                                                      const angle::FeaturesGL &features,
820                                                      GLenum internalFormat)
821 {
822     CompressedTexImageFormat result;
823     result.internalFormat = GetNativeCompressedFormat(functions, features, internalFormat);
824     return result;
825 }
826 
GetCompressedSubTexImageFormat(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum format)827 CompressedTexSubImageFormat GetCompressedSubTexImageFormat(const FunctionsGL *functions,
828                                                            const angle::FeaturesGL &features,
829                                                            GLenum format)
830 {
831     CompressedTexSubImageFormat result;
832     result.format = GetNativeCompressedFormat(functions, features, format);
833     return result;
834 }
835 
GetCopyTexImageImageFormat(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum internalFormat,GLenum framebufferType)836 CopyTexImageImageFormat GetCopyTexImageImageFormat(const FunctionsGL *functions,
837                                                    const angle::FeaturesGL &features,
838                                                    GLenum internalFormat,
839                                                    GLenum framebufferType)
840 {
841     CopyTexImageImageFormat result;
842     result.internalFormat = GetNativeInternalFormat(
843         functions, features, gl::GetInternalFormatInfo(internalFormat, framebufferType));
844     return result;
845 }
846 
GetTexStorageFormat(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum internalFormat)847 TexStorageFormat GetTexStorageFormat(const FunctionsGL *functions,
848                                      const angle::FeaturesGL &features,
849                                      GLenum internalFormat)
850 {
851     TexStorageFormat result;
852     // TexStorage entrypoints accept both compressed and uncompressed formats.
853     // All compressed formats are sized.
854     gl::InternalFormat sizedFormatInfo = gl::GetSizedInternalFormatInfo(internalFormat);
855     if (sizedFormatInfo.compressed)
856     {
857         result.internalFormat = GetNativeCompressedFormat(functions, features, internalFormat);
858     }
859     else
860     {
861         result.internalFormat = GetNativeInternalFormat(functions, features, sizedFormatInfo);
862     }
863 
864     return result;
865 }
866 
GetRenderbufferFormat(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum internalFormat)867 RenderbufferFormat GetRenderbufferFormat(const FunctionsGL *functions,
868                                          const angle::FeaturesGL &features,
869                                          GLenum internalFormat)
870 {
871     RenderbufferFormat result;
872     result.internalFormat = GetNativeInternalFormat(functions, features,
873                                                     gl::GetSizedInternalFormatInfo(internalFormat));
874     return result;
875 }
GetReadPixelsFormat(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum attachmentReadFormat,GLenum format,GLenum type)876 ReadPixelsFormat GetReadPixelsFormat(const FunctionsGL *functions,
877                                      const angle::FeaturesGL &features,
878                                      GLenum attachmentReadFormat,
879                                      GLenum format,
880                                      GLenum type)
881 {
882     ReadPixelsFormat result;
883     result.format = GetNativeReadFormat(functions, features, attachmentReadFormat, format, type);
884     result.type   = GetNativeReadType(functions, features, type);
885     return result;
886 }
887 }  // namespace nativegl
888 
889 }  // namespace rx
890