• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2014 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 #include "libANGLE/Caps.h"
8 
9 #include "anglebase/no_destructor.h"
10 #include "common/angleutils.h"
11 #include "common/debug.h"
12 
13 #include "libANGLE/formatutils.h"
14 
15 #include "angle_gl.h"
16 
17 #include <algorithm>
18 #include <sstream>
19 
InsertExtensionString(const std::string & extension,bool supported,std::vector<std::string> * extensionVector)20 static void InsertExtensionString(const std::string &extension,
21                                   bool supported,
22                                   std::vector<std::string> *extensionVector)
23 {
24     if (supported)
25     {
26         extensionVector->push_back(extension);
27     }
28 }
29 
30 namespace gl
31 {
32 
33 TextureCaps::TextureCaps() = default;
34 
35 TextureCaps::TextureCaps(const TextureCaps &other) = default;
36 
37 TextureCaps::~TextureCaps() = default;
38 
getMaxSamples() const39 GLuint TextureCaps::getMaxSamples() const
40 {
41     return !sampleCounts.empty() ? *sampleCounts.rbegin() : 0;
42 }
43 
getNearestSamples(GLuint requestedSamples) const44 GLuint TextureCaps::getNearestSamples(GLuint requestedSamples) const
45 {
46     if (requestedSamples == 0)
47     {
48         return 0;
49     }
50 
51     for (SupportedSampleSet::const_iterator i = sampleCounts.begin(); i != sampleCounts.end(); i++)
52     {
53         GLuint samples = *i;
54         if (samples >= requestedSamples)
55         {
56             return samples;
57         }
58     }
59 
60     return 0;
61 }
62 
GenerateMinimumTextureCaps(GLenum sizedInternalFormat,const Version & clientVersion,const Extensions & extensions)63 TextureCaps GenerateMinimumTextureCaps(GLenum sizedInternalFormat,
64                                        const Version &clientVersion,
65                                        const Extensions &extensions)
66 {
67     TextureCaps caps;
68 
69     const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(sizedInternalFormat);
70     caps.texturable        = internalFormatInfo.textureSupport(clientVersion, extensions);
71     caps.filterable        = internalFormatInfo.filterSupport(clientVersion, extensions);
72     caps.textureAttachment = internalFormatInfo.textureAttachmentSupport(clientVersion, extensions);
73     caps.renderbuffer      = internalFormatInfo.renderbufferSupport(clientVersion, extensions);
74     caps.blendable         = internalFormatInfo.blendSupport(clientVersion, extensions);
75 
76     caps.sampleCounts.insert(0);
77     if (internalFormatInfo.isRequiredRenderbufferFormat(clientVersion))
78     {
79         if ((clientVersion.major >= 3 && clientVersion.minor >= 1) ||
80             (clientVersion.major >= 3 && !internalFormatInfo.isInt()))
81         {
82             caps.sampleCounts.insert(4);
83         }
84     }
85 
86     return caps;
87 }
88 
TextureCapsMap()89 TextureCapsMap::TextureCapsMap() {}
90 
~TextureCapsMap()91 TextureCapsMap::~TextureCapsMap() {}
92 
insert(GLenum internalFormat,const TextureCaps & caps)93 void TextureCapsMap::insert(GLenum internalFormat, const TextureCaps &caps)
94 {
95     angle::FormatID formatID = angle::Format::InternalFormatToID(internalFormat);
96     get(formatID)            = caps;
97 }
98 
clear()99 void TextureCapsMap::clear()
100 {
101     mFormatData.fill(TextureCaps());
102 }
103 
get(GLenum internalFormat) const104 const TextureCaps &TextureCapsMap::get(GLenum internalFormat) const
105 {
106     angle::FormatID formatID = angle::Format::InternalFormatToID(internalFormat);
107     return get(formatID);
108 }
109 
get(angle::FormatID formatID) const110 const TextureCaps &TextureCapsMap::get(angle::FormatID formatID) const
111 {
112     return mFormatData[static_cast<size_t>(formatID)];
113 }
114 
get(angle::FormatID formatID)115 TextureCaps &TextureCapsMap::get(angle::FormatID formatID)
116 {
117     return mFormatData[static_cast<size_t>(formatID)];
118 }
119 
set(angle::FormatID formatID,const TextureCaps & caps)120 void TextureCapsMap::set(angle::FormatID formatID, const TextureCaps &caps)
121 {
122     get(formatID) = caps;
123 }
124 
InitMinimumTextureCapsMap(const Version & clientVersion,const Extensions & extensions,TextureCapsMap * capsMap)125 void InitMinimumTextureCapsMap(const Version &clientVersion,
126                                const Extensions &extensions,
127                                TextureCapsMap *capsMap)
128 {
129     for (GLenum internalFormat : GetAllSizedInternalFormats())
130     {
131         capsMap->insert(internalFormat,
132                         GenerateMinimumTextureCaps(internalFormat, clientVersion, extensions));
133     }
134 }
135 
136 Extensions::Extensions() = default;
137 
138 Extensions::Extensions(const Extensions &other) = default;
139 
getStrings() const140 std::vector<std::string> Extensions::getStrings() const
141 {
142     std::vector<std::string> extensionStrings;
143 
144     for (const auto &extensionInfo : GetExtensionInfoMap())
145     {
146         if (this->*(extensionInfo.second.ExtensionsMember))
147         {
148             extensionStrings.push_back(extensionInfo.first);
149         }
150     }
151 
152     return extensionStrings;
153 }
154 
155 Limitations::Limitations() = default;
156 
GetFormatSupportBase(const TextureCapsMap & textureCaps,const GLenum * requiredFormats,size_t requiredFormatsSize,bool requiresTexturing,bool requiresFiltering,bool requiresAttachingTexture,bool requiresRenderbufferSupport,bool requiresBlending)157 static bool GetFormatSupportBase(const TextureCapsMap &textureCaps,
158                                  const GLenum *requiredFormats,
159                                  size_t requiredFormatsSize,
160                                  bool requiresTexturing,
161                                  bool requiresFiltering,
162                                  bool requiresAttachingTexture,
163                                  bool requiresRenderbufferSupport,
164                                  bool requiresBlending)
165 {
166     for (size_t i = 0; i < requiredFormatsSize; i++)
167     {
168         const TextureCaps &cap = textureCaps.get(requiredFormats[i]);
169 
170         if (requiresTexturing && !cap.texturable)
171         {
172             return false;
173         }
174 
175         if (requiresFiltering && !cap.filterable)
176         {
177             return false;
178         }
179 
180         if (requiresAttachingTexture && !cap.textureAttachment)
181         {
182             return false;
183         }
184 
185         if (requiresRenderbufferSupport && !cap.renderbuffer)
186         {
187             return false;
188         }
189 
190         if (requiresBlending && !cap.blendable)
191         {
192             return false;
193         }
194     }
195 
196     return true;
197 }
198 
199 template <size_t N>
GetFormatSupport(const TextureCapsMap & textureCaps,const GLenum (& requiredFormats)[N],bool requiresTexturing,bool requiresFiltering,bool requiresAttachingTexture,bool requiresRenderbufferSupport,bool requiresBlending)200 static bool GetFormatSupport(const TextureCapsMap &textureCaps,
201                              const GLenum (&requiredFormats)[N],
202                              bool requiresTexturing,
203                              bool requiresFiltering,
204                              bool requiresAttachingTexture,
205                              bool requiresRenderbufferSupport,
206                              bool requiresBlending)
207 {
208     return GetFormatSupportBase(textureCaps, requiredFormats, N, requiresTexturing,
209                                 requiresFiltering, requiresAttachingTexture,
210                                 requiresRenderbufferSupport, requiresBlending);
211 }
212 
213 // Check for GL_OES_packed_depth_stencil support
DeterminePackedDepthStencilSupport(const TextureCapsMap & textureCaps)214 static bool DeterminePackedDepthStencilSupport(const TextureCapsMap &textureCaps)
215 {
216     constexpr GLenum requiredFormats[] = {
217         GL_DEPTH24_STENCIL8,
218     };
219 
220     return GetFormatSupport(textureCaps, requiredFormats, false, false, true, true, false);
221 }
222 
223 // Checks for GL_NV_read_depth support
DetermineReadDepthSupport(const TextureCapsMap & textureCaps)224 static bool DetermineReadDepthSupport(const TextureCapsMap &textureCaps)
225 {
226     constexpr GLenum requiredFormats[] = {
227         GL_DEPTH_COMPONENT16,
228     };
229 
230     return GetFormatSupport(textureCaps, requiredFormats, true, false, true, false, false);
231 }
232 
233 // Checks for GL_NV_read_stencil support
DetermineReadStencilSupport(const TextureCapsMap & textureCaps)234 static bool DetermineReadStencilSupport(const TextureCapsMap &textureCaps)
235 {
236     constexpr GLenum requiredFormats[] = {
237         GL_STENCIL_INDEX8,
238     };
239 
240     return GetFormatSupport(textureCaps, requiredFormats, false, false, true, false, false);
241 }
242 
243 // Checks for GL_NV_depth_buffer_float2 support
DetermineDepthBufferFloat2Support(const TextureCapsMap & textureCaps)244 static bool DetermineDepthBufferFloat2Support(const TextureCapsMap &textureCaps)
245 {
246     constexpr GLenum requiredFormats[] = {
247         GL_DEPTH_COMPONENT32F,
248         GL_DEPTH32F_STENCIL8,
249     };
250 
251     return GetFormatSupport(textureCaps, requiredFormats, true, false, true, false, false);
252 }
253 
254 // Checks for GL_OES_rgb8_rgba8 support
DetermineRGB8AndRGBA8TextureSupport(const TextureCapsMap & textureCaps)255 static bool DetermineRGB8AndRGBA8TextureSupport(const TextureCapsMap &textureCaps)
256 {
257     constexpr GLenum requiredFormats[] = {
258         GL_RGB8,
259         GL_RGBA8,
260     };
261 
262     return GetFormatSupport(textureCaps, requiredFormats, false, false, false, true, false);
263 }
264 
265 // Checks for GL_EXT_texture_format_BGRA8888 support
DetermineBGRA8TextureSupport(const TextureCapsMap & textureCaps)266 static bool DetermineBGRA8TextureSupport(const TextureCapsMap &textureCaps)
267 {
268     constexpr GLenum requiredFormats[] = {
269         GL_BGRA8_EXT,
270     };
271 
272     return GetFormatSupport(textureCaps, requiredFormats, true, true, true, true, false);
273 }
274 
275 // Checks for GL_EXT_read_format_bgra support
DetermineBGRAReadFormatSupport(const TextureCapsMap & textureCaps)276 static bool DetermineBGRAReadFormatSupport(const TextureCapsMap &textureCaps)
277 {
278     constexpr GLenum requiredFormats[] = {
279         GL_BGRA8_EXT,
280         // TODO(http://anglebug.com/4302): GL_EXT_read_format_bgra specifies 2 more types, which are
281         // currently ignored. The equivalent formats would be: GL_BGRA4_ANGLEX, GL_BGR5_A1_ANGLEX
282     };
283 
284     return GetFormatSupport(textureCaps, requiredFormats, true, false, true, true, false);
285 }
286 
287 // Checks for GL_OES_color_buffer_half_float support
DetermineColorBufferHalfFloatSupport(const TextureCapsMap & textureCaps)288 static bool DetermineColorBufferHalfFloatSupport(const TextureCapsMap &textureCaps)
289 {
290     // EXT_color_buffer_half_float issue #2 states that an implementation doesn't need to support
291     // rendering to any of the formats but is expected to be able to render to at least one. WebGL
292     // requires that at least RGBA16F is renderable so we make the same requirement.
293     constexpr GLenum requiredFormats[] = {
294         GL_RGBA16F,
295     };
296 
297     return GetFormatSupport(textureCaps, requiredFormats, false, false, true, true, false);
298 }
299 
300 // Checks for GL_OES_texture_half_float support
DetermineHalfFloatTextureSupport(const TextureCapsMap & textureCaps)301 static bool DetermineHalfFloatTextureSupport(const TextureCapsMap &textureCaps)
302 {
303     constexpr GLenum requiredFormats[] = {
304         GL_RGBA16F, GL_RGB16F, GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE16F_EXT, GL_ALPHA16F_EXT,
305     };
306 
307     return GetFormatSupport(textureCaps, requiredFormats, true, false, false, false, false);
308 }
309 
310 // Checks for GL_OES_texture_half_float_linear support
DetermineHalfFloatTextureFilteringSupport(const TextureCapsMap & textureCaps,bool checkLegacyFormats)311 static bool DetermineHalfFloatTextureFilteringSupport(const TextureCapsMap &textureCaps,
312                                                       bool checkLegacyFormats)
313 {
314     constexpr GLenum requiredFormats[] = {GL_RGBA16F, GL_RGB16F};
315     // If GL_OES_texture_half_float is present, this extension must also support legacy formats
316     // introduced by that extension
317     constexpr GLenum requiredFormatsES2[] = {GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE16F_EXT,
318                                              GL_ALPHA16F_EXT};
319 
320     if (checkLegacyFormats &&
321         !GetFormatSupport(textureCaps, requiredFormatsES2, false, true, false, false, false))
322     {
323         return false;
324     }
325 
326     return GetFormatSupport(textureCaps, requiredFormats, false, true, false, false, false);
327 }
328 
329 // Checks for GL_OES_texture_float support
DetermineFloatTextureSupport(const TextureCapsMap & textureCaps)330 static bool DetermineFloatTextureSupport(const TextureCapsMap &textureCaps)
331 {
332     constexpr GLenum requiredFormats[] = {
333         GL_RGBA32F, GL_RGB32F, GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE32F_EXT, GL_ALPHA32F_EXT,
334     };
335 
336     return GetFormatSupport(textureCaps, requiredFormats, true, false, false, false, false);
337 }
338 
339 // Checks for GL_OES_texture_float_linear support
DetermineFloatTextureFilteringSupport(const TextureCapsMap & textureCaps,bool checkLegacyFormats)340 static bool DetermineFloatTextureFilteringSupport(const TextureCapsMap &textureCaps,
341                                                   bool checkLegacyFormats)
342 {
343     constexpr GLenum requiredFormats[] = {
344         GL_RGBA32F,
345         GL_RGB32F,
346     };
347     // If GL_OES_texture_float is present, this extension must also support legacy formats
348     // introduced by that extension
349     constexpr GLenum requiredFormatsES2[] = {
350         GL_LUMINANCE_ALPHA32F_EXT,
351         GL_LUMINANCE32F_EXT,
352         GL_ALPHA32F_EXT,
353     };
354 
355     if (checkLegacyFormats &&
356         !GetFormatSupport(textureCaps, requiredFormatsES2, false, true, false, false, false))
357     {
358         return false;
359     }
360 
361     return GetFormatSupport(textureCaps, requiredFormats, false, true, false, false, false);
362 }
363 
364 // Checks for GL_EXT_texture_rg support
DetermineRGTextureSupport(const TextureCapsMap & textureCaps,bool checkHalfFloatFormats,bool checkFloatFormats)365 static bool DetermineRGTextureSupport(const TextureCapsMap &textureCaps,
366                                       bool checkHalfFloatFormats,
367                                       bool checkFloatFormats)
368 {
369     constexpr GLenum requiredFormats[] = {
370         GL_R8,
371         GL_RG8,
372     };
373     constexpr GLenum requiredHalfFloatFormats[] = {
374         GL_R16F,
375         GL_RG16F,
376     };
377     constexpr GLenum requiredFloatFormats[] = {
378         GL_R32F,
379         GL_RG32F,
380     };
381 
382     if (checkHalfFloatFormats &&
383         !GetFormatSupport(textureCaps, requiredHalfFloatFormats, true, false, false, false, false))
384     {
385         return false;
386     }
387 
388     if (checkFloatFormats &&
389         !GetFormatSupport(textureCaps, requiredFloatFormats, true, false, false, false, false))
390     {
391         return false;
392     }
393 
394     return GetFormatSupport(textureCaps, requiredFormats, true, true, true, true, false);
395 }
396 
397 // Check for GL_EXT_texture_compression_dxt1 support
DetermineDXT1TextureSupport(const TextureCapsMap & textureCaps)398 static bool DetermineDXT1TextureSupport(const TextureCapsMap &textureCaps)
399 {
400     constexpr GLenum requiredFormats[] = {
401         GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
402         GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
403     };
404 
405     return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
406 }
407 
408 // Check for GL_ANGLE_texture_compression_dxt3 support
DetermineDXT3TextureSupport(const TextureCapsMap & textureCaps)409 static bool DetermineDXT3TextureSupport(const TextureCapsMap &textureCaps)
410 {
411     constexpr GLenum requiredFormats[] = {
412         GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE,
413     };
414 
415     return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
416 }
417 
418 // Check for GL_ANGLE_texture_compression_dxt5 support
DetermineDXT5TextureSupport(const TextureCapsMap & textureCaps)419 static bool DetermineDXT5TextureSupport(const TextureCapsMap &textureCaps)
420 {
421     constexpr GLenum requiredFormats[] = {
422         GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE,
423     };
424 
425     return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
426 }
427 
428 // Check for GL_EXT_texture_compression_s3tc_srgb support
DetermineS3TCsRGBTextureSupport(const TextureCapsMap & textureCaps)429 static bool DetermineS3TCsRGBTextureSupport(const TextureCapsMap &textureCaps)
430 {
431     constexpr GLenum requiredFormats[] = {
432         GL_COMPRESSED_SRGB_S3TC_DXT1_EXT,
433         GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT,
434         GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT,
435         GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT,
436     };
437 
438     return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
439 }
440 
441 // Check for GL_KHR_texture_compression_astc_ldr support
DetermineASTCLDRTextureSupport(const TextureCapsMap & textureCaps)442 static bool DetermineASTCLDRTextureSupport(const TextureCapsMap &textureCaps)
443 {
444     constexpr GLenum requiredFormats[] = {
445         GL_COMPRESSED_RGBA_ASTC_4x4_KHR,           GL_COMPRESSED_RGBA_ASTC_5x4_KHR,
446         GL_COMPRESSED_RGBA_ASTC_5x5_KHR,           GL_COMPRESSED_RGBA_ASTC_6x5_KHR,
447         GL_COMPRESSED_RGBA_ASTC_6x6_KHR,           GL_COMPRESSED_RGBA_ASTC_8x5_KHR,
448         GL_COMPRESSED_RGBA_ASTC_8x6_KHR,           GL_COMPRESSED_RGBA_ASTC_8x8_KHR,
449         GL_COMPRESSED_RGBA_ASTC_10x5_KHR,          GL_COMPRESSED_RGBA_ASTC_10x6_KHR,
450         GL_COMPRESSED_RGBA_ASTC_10x8_KHR,          GL_COMPRESSED_RGBA_ASTC_10x10_KHR,
451         GL_COMPRESSED_RGBA_ASTC_12x10_KHR,         GL_COMPRESSED_RGBA_ASTC_12x12_KHR,
452         GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR,   GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR,
453         GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR,   GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR,
454         GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR,   GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR,
455         GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR,   GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR,
456         GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR,  GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR,
457         GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR,  GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR,
458         GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR,
459     };
460 
461     return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
462 }
463 
464 // Check for GL_OES_texture_compression_astc support
DetermineASTCOESTExtureSupport(const TextureCapsMap & textureCaps)465 static bool DetermineASTCOESTExtureSupport(const TextureCapsMap &textureCaps)
466 {
467     if (!DetermineASTCLDRTextureSupport(textureCaps))
468     {
469         return false;
470     }
471 
472     // The OES version of the extension also requires the 3D ASTC formats
473     constexpr GLenum requiredFormats[] = {
474         GL_COMPRESSED_RGBA_ASTC_3x3x3_OES,         GL_COMPRESSED_RGBA_ASTC_4x3x3_OES,
475         GL_COMPRESSED_RGBA_ASTC_4x4x3_OES,         GL_COMPRESSED_RGBA_ASTC_4x4x4_OES,
476         GL_COMPRESSED_RGBA_ASTC_5x4x4_OES,         GL_COMPRESSED_RGBA_ASTC_5x5x4_OES,
477         GL_COMPRESSED_RGBA_ASTC_5x5x5_OES,         GL_COMPRESSED_RGBA_ASTC_6x5x5_OES,
478         GL_COMPRESSED_RGBA_ASTC_6x6x5_OES,         GL_COMPRESSED_RGBA_ASTC_6x6x6_OES,
479         GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES,
480         GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES,
481         GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES,
482         GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES,
483         GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES,
484     };
485 
486     return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
487 }
488 
489 // Check for GL_ETC1_RGB8_OES support
DetermineETC1RGB8TextureSupport(const TextureCapsMap & textureCaps)490 static bool DetermineETC1RGB8TextureSupport(const TextureCapsMap &textureCaps)
491 {
492     constexpr GLenum requiredFormats[] = {
493         GL_ETC1_RGB8_OES,
494     };
495 
496     return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
497 }
498 
499 // Check for OES_compressed_ETC2_RGB8_texture support
DetermineETC2RGB8TextureSupport(const TextureCapsMap & textureCaps)500 static bool DetermineETC2RGB8TextureSupport(const TextureCapsMap &textureCaps)
501 {
502     constexpr GLenum requiredFormats[] = {
503         GL_COMPRESSED_RGB8_ETC2,
504     };
505 
506     return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
507 }
508 
509 // Check for OES_compressed_ETC2_sRGB8_texture support
DetermineETC2sRGB8TextureSupport(const TextureCapsMap & textureCaps)510 static bool DetermineETC2sRGB8TextureSupport(const TextureCapsMap &textureCaps)
511 {
512     constexpr GLenum requiredFormats[] = {
513         GL_COMPRESSED_SRGB8_ETC2,
514     };
515 
516     return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
517 }
518 
519 // Check for OES_compressed_ETC2_punchthroughA_RGBA8_texture support
DetermineETC2PunchthroughARGB8TextureSupport(const TextureCapsMap & textureCaps)520 static bool DetermineETC2PunchthroughARGB8TextureSupport(const TextureCapsMap &textureCaps)
521 {
522     constexpr GLenum requiredFormats[] = {
523         GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
524     };
525 
526     return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
527 }
528 
529 // Check for OES_compressed_ETC2_punchthroughA_sRGB8_alpha_texture support
DetermineETC2PunchthroughAsRGB8AlphaTextureSupport(const TextureCapsMap & textureCaps)530 static bool DetermineETC2PunchthroughAsRGB8AlphaTextureSupport(const TextureCapsMap &textureCaps)
531 {
532     constexpr GLenum requiredFormats[] = {
533         GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
534     };
535 
536     return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
537 }
538 
539 // Check for OES_compressed_ETC2_RGBA8_texture support
DetermineETC2RGBA8TextureSupport(const TextureCapsMap & textureCaps)540 static bool DetermineETC2RGBA8TextureSupport(const TextureCapsMap &textureCaps)
541 {
542     constexpr GLenum requiredFormats[] = {
543         GL_COMPRESSED_RGBA8_ETC2_EAC,
544     };
545 
546     return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
547 }
548 
549 // Check for OES_compressed_ETC2_sRGB8_alpha8_texture support
DetermineETC2sRGB8Alpha8TextureSupport(const TextureCapsMap & textureCaps)550 static bool DetermineETC2sRGB8Alpha8TextureSupport(const TextureCapsMap &textureCaps)
551 {
552     constexpr GLenum requiredFormats[] = {
553         GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,
554     };
555 
556     return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
557 }
558 
559 // Check for OES_compressed_EAC_R11_unsigned_texture support
DetermineEACR11UnsignedTextureSupport(const TextureCapsMap & textureCaps)560 static bool DetermineEACR11UnsignedTextureSupport(const TextureCapsMap &textureCaps)
561 {
562     constexpr GLenum requiredFormats[] = {
563         GL_COMPRESSED_R11_EAC,
564     };
565 
566     return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
567 }
568 
569 // Check for OES_compressed_EAC_R11_signed_texture support
DetermineEACR11SignedTextureSupport(const TextureCapsMap & textureCaps)570 static bool DetermineEACR11SignedTextureSupport(const TextureCapsMap &textureCaps)
571 {
572     constexpr GLenum requiredFormats[] = {
573         GL_COMPRESSED_SIGNED_R11_EAC,
574     };
575 
576     return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
577 }
578 
579 // Check for OES_compressed_EAC_RG11_unsigned_texture support
DetermineEACRG11UnsignedTextureSupport(const TextureCapsMap & textureCaps)580 static bool DetermineEACRG11UnsignedTextureSupport(const TextureCapsMap &textureCaps)
581 {
582     constexpr GLenum requiredFormats[] = {
583         GL_COMPRESSED_RG11_EAC,
584     };
585 
586     return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
587 }
588 
589 // Check for OES_compressed_EAC_RG11_signed_texture support
DetermineEACRG11SignedTextureSupport(const TextureCapsMap & textureCaps)590 static bool DetermineEACRG11SignedTextureSupport(const TextureCapsMap &textureCaps)
591 {
592     constexpr GLenum requiredFormats[] = {
593         GL_COMPRESSED_SIGNED_RG11_EAC,
594     };
595 
596     return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
597 }
598 
599 // Check for GL_EXT_sRGB support
DetermineSRGBTextureSupport(const TextureCapsMap & textureCaps)600 static bool DetermineSRGBTextureSupport(const TextureCapsMap &textureCaps)
601 {
602     constexpr GLenum requiredFilterFormats[] = {
603         GL_SRGB8,
604         GL_SRGB8_ALPHA8,
605     };
606 
607     constexpr GLenum requiredRenderFormats[] = {
608         GL_SRGB8_ALPHA8,
609     };
610 
611     return GetFormatSupport(textureCaps, requiredFilterFormats, true, true, false, false, false) &&
612            GetFormatSupport(textureCaps, requiredRenderFormats, true, false, true, true, false);
613 }
614 
615 // Check for GL_EXT_texture_sRGB_R8 support
DetermineSRGBR8TextureSupport(const TextureCapsMap & textureCaps)616 static bool DetermineSRGBR8TextureSupport(const TextureCapsMap &textureCaps)
617 {
618     constexpr GLenum requiredFilterFormats[] = {GL_SR8_EXT};
619 
620     return GetFormatSupport(textureCaps, requiredFilterFormats, true, true, false, false, false);
621 }
622 
623 // Check for GL_ANGLE_depth_texture support
DetermineDepthTextureANGLESupport(const TextureCapsMap & textureCaps)624 static bool DetermineDepthTextureANGLESupport(const TextureCapsMap &textureCaps)
625 {
626     constexpr GLenum requiredFormats[] = {
627         GL_DEPTH_COMPONENT16,
628         GL_DEPTH_COMPONENT32_OES,
629         GL_DEPTH24_STENCIL8_OES,
630     };
631 
632     return GetFormatSupport(textureCaps, requiredFormats, true, true, true, false, false);
633 }
634 
635 // Check for GL_OES_depth_texture support
DetermineDepthTextureOESSupport(const TextureCapsMap & textureCaps)636 static bool DetermineDepthTextureOESSupport(const TextureCapsMap &textureCaps)
637 {
638     constexpr GLenum requiredFormats[] = {
639         GL_DEPTH_COMPONENT16,
640         GL_DEPTH_COMPONENT32_OES,
641     };
642 
643     return GetFormatSupport(textureCaps, requiredFormats, true, true, true, true, false);
644 }
645 
646 // Check for GL_OES_depth24
DetermineDepth24OESSupport(const TextureCapsMap & textureCaps)647 static bool DetermineDepth24OESSupport(const TextureCapsMap &textureCaps)
648 {
649     constexpr GLenum requiredFormats[] = {
650         GL_DEPTH_COMPONENT24_OES,
651     };
652 
653     return GetFormatSupport(textureCaps, requiredFormats, false, false, false, true, false);
654 }
655 
656 // Check for GL_OES_depth32 support
DetermineDepth32Support(const TextureCapsMap & textureCaps)657 static bool DetermineDepth32Support(const TextureCapsMap &textureCaps)
658 {
659     constexpr GLenum requiredFormats[] = {
660         GL_DEPTH_COMPONENT32_OES,
661     };
662 
663     return GetFormatSupport(textureCaps, requiredFormats, false, false, true, true, false);
664 }
665 
666 // Check for GL_CHROMIUM_color_buffer_float_rgb support
DetermineColorBufferFloatRGBSupport(const TextureCapsMap & textureCaps)667 static bool DetermineColorBufferFloatRGBSupport(const TextureCapsMap &textureCaps)
668 {
669     constexpr GLenum requiredFormats[] = {
670         GL_RGB32F,
671     };
672 
673     return GetFormatSupport(textureCaps, requiredFormats, true, false, true, false, false);
674 }
675 
676 // Check for GL_CHROMIUM_color_buffer_float_rgba support
DetermineColorBufferFloatRGBASupport(const TextureCapsMap & textureCaps)677 static bool DetermineColorBufferFloatRGBASupport(const TextureCapsMap &textureCaps)
678 {
679     constexpr GLenum requiredFormats[] = {
680         GL_RGBA32F,
681     };
682 
683     return GetFormatSupport(textureCaps, requiredFormats, true, false, true, true, false);
684 }
685 
686 // Check for GL_EXT_color_buffer_float support
DetermineColorBufferFloatSupport(const TextureCapsMap & textureCaps)687 static bool DetermineColorBufferFloatSupport(const TextureCapsMap &textureCaps)
688 {
689     constexpr GLenum nonBlendableFormats[] = {
690         GL_R32F,
691         GL_RG32F,
692         GL_RGBA32F,
693     };
694 
695     constexpr GLenum blendableFormats[] = {
696         GL_R16F,
697         GL_RG16F,
698         GL_RGBA16F,
699         GL_R11F_G11F_B10F,
700     };
701 
702     return GetFormatSupport(textureCaps, nonBlendableFormats, true, false, true, true, false) &&
703            GetFormatSupport(textureCaps, blendableFormats, true, false, true, true, true);
704 }
705 
706 // Check for GL_EXT_float_blend support
DetermineFloatBlendSupport(const TextureCapsMap & textureCaps)707 static bool DetermineFloatBlendSupport(const TextureCapsMap &textureCaps)
708 {
709     constexpr GLenum requiredFormats[] = {
710         GL_R32F,
711         GL_RG32F,
712         GL_RGBA32F,
713     };
714 
715     return GetFormatSupport(textureCaps, requiredFormats, true, false, true, true, true);
716 }
717 
718 // Check for GL_EXT_texture_norm16 support
DetermineTextureNorm16Support(const TextureCapsMap & textureCaps)719 static bool DetermineTextureNorm16Support(const TextureCapsMap &textureCaps)
720 {
721     constexpr GLenum requiredFilterFormats[] = {
722         GL_R16_EXT,       GL_RG16_EXT,       GL_RGB16_EXT,       GL_RGBA16_EXT,
723         GL_R16_SNORM_EXT, GL_RG16_SNORM_EXT, GL_RGB16_SNORM_EXT, GL_RGBA16_SNORM_EXT,
724     };
725 
726     constexpr GLenum requiredRenderFormats[] = {
727         GL_R16_EXT,
728         GL_RG16_EXT,
729         GL_RGBA16_EXT,
730     };
731 
732     return GetFormatSupport(textureCaps, requiredFilterFormats, true, true, false, false, false) &&
733            GetFormatSupport(textureCaps, requiredRenderFormats, true, false, true, true, false);
734 }
735 
736 // Check for EXT_texture_compression_rgtc support
DetermineRGTCTextureSupport(const TextureCapsMap & textureCaps)737 static bool DetermineRGTCTextureSupport(const TextureCapsMap &textureCaps)
738 {
739     constexpr GLenum requiredFormats[] = {
740         GL_COMPRESSED_RED_RGTC1_EXT, GL_COMPRESSED_SIGNED_RED_RGTC1_EXT,
741         GL_COMPRESSED_RED_GREEN_RGTC2_EXT, GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT};
742 
743     return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
744 }
745 
746 // Check for EXT_texture_compression_bptc support
DetermineBPTCTextureSupport(const TextureCapsMap & textureCaps)747 static bool DetermineBPTCTextureSupport(const TextureCapsMap &textureCaps)
748 {
749     constexpr GLenum requiredFormats[] = {
750         GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT,
751         GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT};
752 
753     return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
754 }
755 
756 // Check for GL_IMG_texture_compression_pvrtc support
DeterminePVRTCTextureSupport(const TextureCapsMap & textureCaps)757 static bool DeterminePVRTCTextureSupport(const TextureCapsMap &textureCaps)
758 {
759     constexpr GLenum requiredFormats[] = {
760         GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG, GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG,
761         GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG};
762 
763     return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
764 }
765 
766 // Check for GL_EXT_pvrtc_sRGB support
DeterminePVRTCsRGBTextureSupport(const TextureCapsMap & textureCaps)767 static bool DeterminePVRTCsRGBTextureSupport(const TextureCapsMap &textureCaps)
768 {
769     constexpr GLenum requiredFormats[] = {
770         GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT, GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT,
771         GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT, GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT};
772 
773     return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
774 }
775 
DetermineCompressedTextureETCSupport(const TextureCapsMap & textureCaps)776 bool DetermineCompressedTextureETCSupport(const TextureCapsMap &textureCaps)
777 {
778     constexpr GLenum requiredFormats[] = {GL_COMPRESSED_R11_EAC,
779                                           GL_COMPRESSED_SIGNED_R11_EAC,
780                                           GL_COMPRESSED_RG11_EAC,
781                                           GL_COMPRESSED_SIGNED_RG11_EAC,
782                                           GL_COMPRESSED_RGB8_ETC2,
783                                           GL_COMPRESSED_SRGB8_ETC2,
784                                           GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
785                                           GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
786                                           GL_COMPRESSED_RGBA8_ETC2_EAC,
787                                           GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC};
788 
789     return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
790 }
791 
setTextureExtensionSupport(const TextureCapsMap & textureCaps)792 void Extensions::setTextureExtensionSupport(const TextureCapsMap &textureCaps)
793 {
794     // TODO(ynovikov): rgb8rgba8OES, colorBufferHalfFloat, textureHalfFloat, textureHalfFloatLinear,
795     // textureFloatOES, textureFloatLinearOES, textureRG, sRGB, colorBufferFloatRGB,
796     // colorBufferFloatRGBA and colorBufferFloat were verified. Verify the rest.
797     packedDepthStencilOES = DeterminePackedDepthStencilSupport(textureCaps);
798     rgb8rgba8OES          = DetermineRGB8AndRGBA8TextureSupport(textureCaps);
799     readDepthNV           = DetermineReadDepthSupport(textureCaps);
800     readStencilNV         = DetermineReadStencilSupport(textureCaps);
801     depthBufferFloat2NV   = DetermineDepthBufferFloat2Support(textureCaps);
802     textureFormatBGRA8888 = DetermineBGRA8TextureSupport(textureCaps);
803     readFormatBGRA        = DetermineBGRAReadFormatSupport(textureCaps);
804     textureHalfFloat      = DetermineHalfFloatTextureSupport(textureCaps);
805     textureHalfFloatLinear =
806         DetermineHalfFloatTextureFilteringSupport(textureCaps, textureHalfFloat);
807     textureFloatOES       = DetermineFloatTextureSupport(textureCaps);
808     textureFloatLinearOES = DetermineFloatTextureFilteringSupport(textureCaps, textureFloatOES);
809     textureRG = DetermineRGTextureSupport(textureCaps, textureHalfFloat, textureFloatOES);
810     colorBufferHalfFloat   = textureHalfFloat && DetermineColorBufferHalfFloatSupport(textureCaps);
811     textureCompressionDXT1 = DetermineDXT1TextureSupport(textureCaps);
812     textureCompressionDXT3 = DetermineDXT3TextureSupport(textureCaps);
813     textureCompressionDXT5 = DetermineDXT5TextureSupport(textureCaps);
814     textureCompressionS3TCsRGB    = DetermineS3TCsRGBTextureSupport(textureCaps);
815     textureCompressionASTCLDRKHR  = DetermineASTCLDRTextureSupport(textureCaps);
816     textureCompressionASTCOES     = DetermineASTCOESTExtureSupport(textureCaps);
817     compressedETC1RGB8TextureOES  = DetermineETC1RGB8TextureSupport(textureCaps);
818     compressedETC2RGB8TextureOES  = DetermineETC2RGB8TextureSupport(textureCaps);
819     compressedETC2sRGB8TextureOES = DetermineETC2sRGB8TextureSupport(textureCaps);
820     compressedETC2PunchthroughARGB8TextureOES =
821         DetermineETC2PunchthroughARGB8TextureSupport(textureCaps);
822     compressedETC2PunchthroughAsRGB8AlphaTextureOES =
823         DetermineETC2PunchthroughAsRGB8AlphaTextureSupport(textureCaps);
824     compressedETC2RGBA8TextureOES       = DetermineETC2RGBA8TextureSupport(textureCaps);
825     compressedETC2sRGB8Alpha8TextureOES = DetermineETC2sRGB8Alpha8TextureSupport(textureCaps);
826     compressedEACR11UnsignedTextureOES  = DetermineEACR11UnsignedTextureSupport(textureCaps);
827     compressedEACR11SignedTextureOES    = DetermineEACR11SignedTextureSupport(textureCaps);
828     compressedEACRG11UnsignedTextureOES = DetermineEACRG11UnsignedTextureSupport(textureCaps);
829     compressedEACRG11SignedTextureOES   = DetermineEACRG11SignedTextureSupport(textureCaps);
830     sRGB                                = DetermineSRGBTextureSupport(textureCaps);
831     sRGBR8EXT                           = DetermineSRGBR8TextureSupport(textureCaps);
832     depthTextureANGLE                   = DetermineDepthTextureANGLESupport(textureCaps);
833     depthTextureOES                     = DetermineDepthTextureOESSupport(textureCaps);
834     depth24OES                          = DetermineDepth24OESSupport(textureCaps);
835     depth32OES                          = DetermineDepth32Support(textureCaps);
836     colorBufferFloatRGB                 = DetermineColorBufferFloatRGBSupport(textureCaps);
837     colorBufferFloatRGBA                = DetermineColorBufferFloatRGBASupport(textureCaps);
838     colorBufferFloat                    = DetermineColorBufferFloatSupport(textureCaps);
839     floatBlend                          = DetermineFloatBlendSupport(textureCaps);
840     textureNorm16                       = DetermineTextureNorm16Support(textureCaps);
841     textureCompressionRGTC              = DetermineRGTCTextureSupport(textureCaps);
842     textureCompressionBPTC              = DetermineBPTCTextureSupport(textureCaps);
843     compressedTexturePVRTC              = DeterminePVRTCTextureSupport(textureCaps);
844     compressedTexturePVRTCsRGB          = DeterminePVRTCsRGBTextureSupport(textureCaps);
845 }
846 
GetExtensionInfoMap()847 const ExtensionInfoMap &GetExtensionInfoMap()
848 {
849     auto buildExtensionInfoMap = []() {
850         auto enableableExtension = [](ExtensionBool member) {
851             ExtensionInfo info;
852             info.Requestable      = true;
853             info.ExtensionsMember = member;
854             return info;
855         };
856 
857         auto enableableDisablableExtension = [&](ExtensionBool member) {
858             ExtensionInfo info = enableableExtension(member);
859             info.Disablable    = true;
860             return info;
861         };
862 
863         auto esOnlyExtension = [](ExtensionBool member) {
864             ExtensionInfo info;
865             info.ExtensionsMember = member;
866             return info;
867         };
868 
869         // clang-format off
870         ExtensionInfoMap map;
871         map["GL_OES_element_index_uint"] = enableableExtension(&Extensions::elementIndexUintOES);
872         map["GL_OES_packed_depth_stencil"] = esOnlyExtension(&Extensions::packedDepthStencilOES);
873         map["GL_OES_get_program_binary"] = enableableExtension(&Extensions::getProgramBinaryOES);
874         map["GL_OES_rgb8_rgba8"] = enableableExtension(&Extensions::rgb8rgba8OES);
875         map["GL_NV_read_depth"] = enableableExtension(&Extensions::readDepthNV);
876         map["GL_NV_read_stencil"] = enableableExtension(&Extensions::readStencilNV);
877         map["GL_NV_depth_buffer_float2"] = enableableExtension(&Extensions::depthBufferFloat2NV);
878         map["GL_EXT_texture_format_BGRA8888"] = enableableExtension(&Extensions::textureFormatBGRA8888);
879         map["GL_EXT_texture_type_2_10_10_10_REV"] = enableableExtension(&Extensions::textureFormat2101010REV);
880         map["GL_EXT_read_format_bgra"] = enableableExtension(&Extensions::readFormatBGRA);
881         map["GL_NV_pixel_buffer_object"] = enableableExtension(&Extensions::pixelBufferObjectNV);
882         map["GL_ARB_sync"] = enableableExtension(&Extensions::glSyncARB);
883         map["GL_OES_mapbuffer"] = enableableExtension(&Extensions::mapBufferOES);
884         map["GL_EXT_map_buffer_range"] = enableableExtension(&Extensions::mapBufferRange);
885         map["GL_EXT_color_buffer_half_float"] = enableableExtension(&Extensions::colorBufferHalfFloat);
886         map["GL_OES_texture_half_float"] = enableableExtension(&Extensions::textureHalfFloat);
887         map["GL_OES_texture_half_float_linear"] = enableableExtension(&Extensions::textureHalfFloatLinear);
888         map["GL_OES_texture_float"] = enableableExtension(&Extensions::textureFloatOES);
889         map["GL_OES_texture_float_linear"] = enableableExtension(&Extensions::textureFloatLinearOES);
890         map["GL_EXT_texture_rg"] = enableableExtension(&Extensions::textureRG);
891         map["GL_EXT_texture_compression_dxt1"] = enableableExtension(&Extensions::textureCompressionDXT1);
892         map["GL_ANGLE_texture_compression_dxt3"] = enableableExtension(&Extensions::textureCompressionDXT3);
893         map["GL_ANGLE_texture_compression_dxt5"] = enableableExtension(&Extensions::textureCompressionDXT5);
894         map["GL_EXT_texture_compression_s3tc_srgb"] = enableableExtension(&Extensions::textureCompressionS3TCsRGB);
895         map["GL_KHR_texture_compression_astc_ldr"] = enableableExtension(&Extensions::textureCompressionASTCLDRKHR);
896         map["GL_KHR_texture_compression_astc_hdr"] = enableableExtension(&Extensions::textureCompressionASTCHDRKHR);
897         map["GL_KHR_texture_compression_astc_sliced_3d"] = enableableExtension(&Extensions::textureCompressionSliced3dASTCKHR);
898         map["GL_OES_texture_compression_astc"] = enableableExtension(&Extensions::textureCompressionASTCOES);
899         map["GL_EXT_texture_compression_bptc"] = enableableExtension(&Extensions::textureCompressionBPTC);
900         map["GL_EXT_texture_compression_rgtc"] = enableableExtension(&Extensions::textureCompressionRGTC);
901         map["GL_OES_compressed_ETC1_RGB8_texture"] = enableableExtension(&Extensions::compressedETC1RGB8TextureOES);
902         map["GL_EXT_compressed_ETC1_RGB8_sub_texture"] = enableableExtension(&Extensions::compressedETC1RGB8SubTexture);
903         map["GL_OES_compressed_ETC2_RGB8_texture"] = enableableExtension(&Extensions::compressedETC2RGB8TextureOES);
904         map["GL_OES_compressed_ETC2_sRGB8_texture"] = enableableExtension(&Extensions::compressedETC2sRGB8TextureOES);
905         map["GL_OES_compressed_ETC2_punchthroughA_RGBA8_texture"] = enableableExtension(&Extensions::compressedETC2PunchthroughARGB8TextureOES);
906         map["GL_OES_compressed_ETC2_punchthroughA_sRGB8_alpha_texture"] = enableableExtension(&Extensions::compressedETC2PunchthroughAsRGB8AlphaTextureOES);
907         map["GL_OES_compressed_ETC2_RGBA8_texture"] = enableableExtension(&Extensions::compressedETC2RGBA8TextureOES);
908         map["GL_OES_compressed_ETC2_sRGB8_alpha8_texture"] = enableableExtension(&Extensions::compressedETC2sRGB8Alpha8TextureOES);
909         map["GL_OES_compressed_EAC_R11_unsigned_texture"] = enableableExtension(&Extensions::compressedEACR11UnsignedTextureOES);
910         map["GL_OES_compressed_EAC_R11_signed_texture"] = enableableExtension(&Extensions::compressedEACR11SignedTextureOES);
911         map["GL_OES_compressed_EAC_RG11_unsigned_texture"] = enableableExtension(&Extensions::compressedEACRG11UnsignedTextureOES);
912         map["GL_OES_compressed_EAC_RG11_signed_texture"] = enableableExtension(&Extensions::compressedEACRG11SignedTextureOES);
913         map["GL_ANGLE_compressed_texture_etc"] = enableableExtension(&Extensions::compressedTextureETC);
914         map["GL_IMG_texture_compression_pvrtc"] = enableableExtension(&Extensions::compressedTexturePVRTC);
915         map["GL_EXT_pvrtc_sRGB"] = enableableExtension(&Extensions::compressedTexturePVRTCsRGB);
916         map["GL_EXT_sRGB"] = enableableExtension(&Extensions::sRGB);
917         map["GL_EXT_texture_sRGB_R8"] = enableableExtension(&Extensions::sRGBR8EXT);
918         map["GL_ANGLE_depth_texture"] = esOnlyExtension(&Extensions::depthTextureANGLE);
919         map["GL_OES_depth_texture"] = esOnlyExtension(&Extensions::depthTextureOES);
920         map["GL_OES_depth_texture_cube_map"] = enableableExtension(&Extensions::depthTextureCubeMapOES);
921         map["GL_OES_depth24"] = esOnlyExtension(&Extensions::depth24OES);
922         map["GL_OES_depth32"] = esOnlyExtension(&Extensions::depth32OES);
923         map["GL_OES_texture_3D"] = enableableExtension(&Extensions::texture3DOES);
924         map["GL_EXT_texture_storage"] = enableableExtension(&Extensions::textureStorage);
925         map["GL_OES_texture_npot"] = enableableExtension(&Extensions::textureNPOTOES);
926         map["GL_EXT_draw_buffers"] = enableableExtension(&Extensions::drawBuffers);
927         map["GL_EXT_draw_buffers_indexed"] = enableableExtension(&Extensions::drawBuffersIndexedEXT);
928         map["GL_OES_draw_buffers_indexed"] = enableableExtension(&Extensions::drawBuffersIndexedOES);
929         map["GL_EXT_texture_filter_anisotropic"] = enableableExtension(&Extensions::textureFilterAnisotropic);
930         map["GL_EXT_occlusion_query_boolean"] = enableableExtension(&Extensions::occlusionQueryBoolean);
931         map["GL_NV_fence"] = esOnlyExtension(&Extensions::fenceNV);
932         map["GL_EXT_disjoint_timer_query"] = enableableExtension(&Extensions::disjointTimerQuery);
933         map["GL_EXT_robustness"] = esOnlyExtension(&Extensions::robustness);
934         map["GL_KHR_robust_buffer_access_behavior"] = esOnlyExtension(&Extensions::robustBufferAccessBehavior);
935         map["GL_EXT_blend_minmax"] = enableableExtension(&Extensions::blendMinMax);
936         map["GL_ANGLE_framebuffer_blit"] = enableableExtension(&Extensions::framebufferBlit);
937         map["GL_ANGLE_framebuffer_multisample"] = enableableExtension(&Extensions::framebufferMultisample);
938         map["GL_EXT_multisampled_render_to_texture"] = enableableExtension(&Extensions::multisampledRenderToTexture);
939         map["GL_ANGLE_instanced_arrays"] = enableableExtension(&Extensions::instancedArraysANGLE);
940         map["GL_EXT_instanced_arrays"] = enableableExtension(&Extensions::instancedArraysEXT);
941         map["GL_ANGLE_pack_reverse_row_order"] = enableableExtension(&Extensions::packReverseRowOrder);
942         map["GL_OES_standard_derivatives"] = enableableExtension(&Extensions::standardDerivativesOES);
943         map["GL_EXT_shader_texture_lod"] = enableableExtension(&Extensions::shaderTextureLOD);
944         map["GL_EXT_frag_depth"] = enableableExtension(&Extensions::fragDepth);
945         map["GL_OVR_multiview"] = enableableExtension(&Extensions::multiview);
946         map["GL_OVR_multiview2"] = enableableExtension(&Extensions::multiview2);
947         map["GL_ANGLE_texture_usage"] = enableableExtension(&Extensions::textureUsage);
948         map["GL_ANGLE_translated_shader_source"] = esOnlyExtension(&Extensions::translatedShaderSource);
949         map["GL_OES_fbo_render_mipmap"] = enableableExtension(&Extensions::fboRenderMipmapOES);
950         map["GL_EXT_discard_framebuffer"] = esOnlyExtension(&Extensions::discardFramebuffer);
951         map["GL_EXT_debug_marker"] = esOnlyExtension(&Extensions::debugMarker);
952         map["GL_OES_EGL_image"] = enableableExtension(&Extensions::eglImageOES);
953         map["GL_OES_EGL_image_external"] = enableableExtension(&Extensions::eglImageExternalOES);
954         map["GL_OES_EGL_image_external_essl3"] = enableableExtension(&Extensions::eglImageExternalEssl3OES);
955         map["GL_EXT_EGL_image_external_wrap_modes"] = enableableExtension(&Extensions::eglImageExternalWrapModesEXT);
956         map["GL_OES_EGL_sync"] = esOnlyExtension(&Extensions::eglSyncOES);
957         map["GL_EXT_memory_object"] = enableableExtension(&Extensions::memoryObject);
958         map["GL_EXT_memory_object_fd"] = enableableExtension(&Extensions::memoryObjectFd);
959         map["GL_ANGLE_memory_object_fuchsia"] = enableableExtension(&Extensions::memoryObjectFuchsiaANGLE);
960         map["GL_EXT_semaphore"] = enableableExtension(&Extensions::semaphore);
961         map["GL_EXT_semaphore_fd"] = enableableExtension(&Extensions::semaphoreFd);
962         map["GL_NV_EGL_stream_consumer_external"] = enableableExtension(&Extensions::eglStreamConsumerExternalNV);
963         map["GL_NV_shader_noperspective_interpolation"] = enableableExtension(&Extensions::noperspectiveInterpolationNV);
964         map["GL_ANGLE_semaphore_fuchsia"] = enableableExtension(&Extensions::semaphoreFuchsiaANGLE);
965         map["GL_EXT_unpack_subimage"] = enableableExtension(&Extensions::unpackSubimage);
966         map["GL_NV_pack_subimage"] = enableableExtension(&Extensions::packSubimage);
967         map["GL_EXT_color_buffer_float"] = enableableExtension(&Extensions::colorBufferFloat);
968         map["GL_OES_vertex_half_float"] = enableableExtension(&Extensions::vertexHalfFloatOES);
969         map["GL_OES_vertex_array_object"] = enableableExtension(&Extensions::vertexArrayObjectOES);
970         map["GL_OES_vertex_type_10_10_10_2"] = enableableExtension(&Extensions::vertexAttribType1010102OES);
971         map["GL_KHR_debug"] = esOnlyExtension(&Extensions::debug);
972         map["GL_OES_texture_border_clamp"] = enableableExtension(&Extensions::textureBorderClampOES);
973         map["GL_KHR_no_error"] = esOnlyExtension(&Extensions::noError);
974         map["GL_ANGLE_lossy_etc_decode"] = enableableExtension(&Extensions::lossyETCDecode);
975         map["GL_CHROMIUM_bind_uniform_location"] = esOnlyExtension(&Extensions::bindUniformLocation);
976         map["GL_CHROMIUM_sync_query"] = enableableExtension(&Extensions::syncQuery);
977         map["GL_CHROMIUM_copy_texture"] = esOnlyExtension(&Extensions::copyTexture);
978         map["GL_CHROMIUM_copy_compressed_texture"] = esOnlyExtension(&Extensions::copyCompressedTexture);
979         map["GL_ANGLE_copy_texture_3d"] = enableableExtension(&Extensions::copyTexture3d);
980         map["GL_ANGLE_webgl_compatibility"] = esOnlyExtension(&Extensions::webglCompatibility);
981         map["GL_ANGLE_request_extension"] = esOnlyExtension(&Extensions::requestExtension);
982         map["GL_CHROMIUM_bind_generates_resource"] = esOnlyExtension(&Extensions::bindGeneratesResource);
983         map["GL_ANGLE_robust_client_memory"] = esOnlyExtension(&Extensions::robustClientMemory);
984         map["GL_EXT_texture_sRGB_decode"] = esOnlyExtension(&Extensions::textureSRGBDecode);
985         map["GL_EXT_sRGB_write_control"] = esOnlyExtension(&Extensions::sRGBWriteControl);
986         map["GL_CHROMIUM_color_buffer_float_rgb"] = enableableExtension(&Extensions::colorBufferFloatRGB);
987         map["GL_CHROMIUM_color_buffer_float_rgba"] = enableableExtension(&Extensions::colorBufferFloatRGBA);
988         map["GL_EXT_multisample_compatibility"] = esOnlyExtension(&Extensions::multisampleCompatibility);
989         map["GL_CHROMIUM_framebuffer_mixed_samples"] = esOnlyExtension(&Extensions::framebufferMixedSamples);
990         map["GL_EXT_texture_norm16"] = enableableExtension(&Extensions::textureNorm16);
991         map["GL_OES_surfaceless_context"] = esOnlyExtension(&Extensions::surfacelessContextOES);
992         map["GL_ANGLE_client_arrays"] = esOnlyExtension(&Extensions::clientArrays);
993         map["GL_ANGLE_robust_resource_initialization"] = esOnlyExtension(&Extensions::robustResourceInitialization);
994         map["GL_ANGLE_program_cache_control"] = esOnlyExtension(&Extensions::programCacheControl);
995         map["GL_ANGLE_texture_rectangle"] = enableableDisablableExtension(&Extensions::textureRectangle);
996         map["GL_EXT_geometry_shader"] = enableableExtension(&Extensions::geometryShader);
997         map["GL_ANGLE_explicit_context_gles1"] = enableableExtension(&Extensions::explicitContextGles1);
998         map["GL_ANGLE_explicit_context"] = enableableExtension(&Extensions::explicitContext);
999         map["GL_KHR_parallel_shader_compile"] = enableableExtension(&Extensions::parallelShaderCompile);
1000         map["GL_OES_texture_storage_multisample_2d_array"] = enableableExtension(&Extensions::textureStorageMultisample2DArrayOES);
1001         map["GL_ANGLE_multiview_multisample"] = enableableExtension(&Extensions::multiviewMultisample);
1002         map["GL_EXT_blend_func_extended"] = enableableExtension(&Extensions::blendFuncExtended);
1003         map["GL_EXT_float_blend"] = enableableExtension(&Extensions::floatBlend);
1004         map["GL_ANGLE_texture_multisample"] = enableableExtension(&Extensions::textureMultisample);
1005         map["GL_ANGLE_multi_draw"] = enableableExtension(&Extensions::multiDraw);
1006         map["GL_ANGLE_provoking_vertex"] = enableableExtension(&Extensions::provokingVertex);
1007         map["GL_CHROMIUM_lose_context"] = enableableExtension(&Extensions::loseContextCHROMIUM);
1008         map["GL_ANGLE_texture_external_update"] = enableableExtension(&Extensions::textureExternalUpdateANGLE);
1009         map["GL_ANGLE_base_vertex_base_instance"] = enableableExtension(&Extensions::baseVertexBaseInstance);
1010         map["GL_ANGLE_get_image"] = enableableExtension(&Extensions::getImageANGLE);
1011         map["GL_OES_draw_elements_base_vertex"] = enableableExtension(&Extensions::drawElementsBaseVertexOES);
1012         map["GL_EXT_draw_elements_base_vertex"] = enableableExtension(&Extensions::drawElementsBaseVertexEXT);
1013         map["GL_EXT_gpu_shader5"] = enableableExtension(&Extensions::gpuShader5EXT);
1014         // GLES1 extensions
1015         map["GL_OES_point_size_array"] = enableableExtension(&Extensions::pointSizeArrayOES);
1016         map["GL_OES_texture_cube_map"] = enableableExtension(&Extensions::textureCubeMapOES);
1017         map["GL_OES_point_sprite"] = enableableExtension(&Extensions::pointSpriteOES);
1018         map["GL_OES_draw_texture"] = enableableExtension(&Extensions::drawTextureOES);
1019         map["GL_ANGLE_memory_size"] = enableableExtension(&Extensions::memorySize);
1020         map["GL_EXT_shader_non_constant_global_initializers"] = enableableExtension(&Extensions::shaderNonConstGlobalInitializersEXT);
1021         map["GL_WEBGL_video_texture"] = enableableExtension(&Extensions::webglVideoTexture);
1022         // clang-format on
1023 
1024 #if defined(ANGLE_ENABLE_ASSERTS)
1025         // Verify all extension strings start with GL_
1026         for (const auto &extension : map)
1027         {
1028             ASSERT(extension.first.rfind("GL_", 0) == 0);
1029         }
1030 #endif
1031 
1032         return map;
1033     };
1034 
1035     static const angle::base::NoDestructor<ExtensionInfoMap> extensionInfo(buildExtensionInfoMap());
1036     return *extensionInfo;
1037 }
1038 
1039 TypePrecision::TypePrecision() = default;
1040 
1041 TypePrecision::TypePrecision(const TypePrecision &other) = default;
1042 
setIEEEFloat()1043 void TypePrecision::setIEEEFloat()
1044 {
1045     range     = {{127, 127}};
1046     precision = 23;
1047 }
1048 
setTwosComplementInt(unsigned int bits)1049 void TypePrecision::setTwosComplementInt(unsigned int bits)
1050 {
1051     range     = {{static_cast<GLint>(bits) - 1, static_cast<GLint>(bits) - 2}};
1052     precision = 0;
1053 }
1054 
setSimulatedFloat(unsigned int r,unsigned int p)1055 void TypePrecision::setSimulatedFloat(unsigned int r, unsigned int p)
1056 {
1057     range     = {{static_cast<GLint>(r), static_cast<GLint>(r)}};
1058     precision = static_cast<GLint>(p);
1059 }
1060 
setSimulatedInt(unsigned int r)1061 void TypePrecision::setSimulatedInt(unsigned int r)
1062 {
1063     range     = {{static_cast<GLint>(r), static_cast<GLint>(r)}};
1064     precision = 0;
1065 }
1066 
get(GLint * returnRange,GLint * returnPrecision) const1067 void TypePrecision::get(GLint *returnRange, GLint *returnPrecision) const
1068 {
1069     std::copy(range.begin(), range.end(), returnRange);
1070     *returnPrecision = precision;
1071 }
1072 
1073 Caps::Caps()                  = default;
1074 Caps::Caps(const Caps &other) = default;
1075 Caps::~Caps()                 = default;
1076 
GenerateMinimumCaps(const Version & clientVersion,const Extensions & extensions)1077 Caps GenerateMinimumCaps(const Version &clientVersion, const Extensions &extensions)
1078 {
1079     Caps caps;
1080 
1081     // GLES1 emulation (Minimums taken from Table 6.20 / 6.22 (ES 1.1 spec))
1082     if (clientVersion < Version(2, 0))
1083     {
1084         caps.maxMultitextureUnits = 2;
1085         caps.maxLights            = 8;
1086         caps.maxClipPlanes        = 1;
1087 
1088         caps.maxModelviewMatrixStackDepth  = 16;
1089         caps.maxProjectionMatrixStackDepth = 2;
1090         caps.maxTextureMatrixStackDepth    = 2;
1091 
1092         caps.minSmoothPointSize = 1.0f;
1093         caps.maxSmoothPointSize = 1.0f;
1094     }
1095 
1096     if (clientVersion >= Version(2, 0))
1097     {
1098         // Table 6.18
1099         caps.max2DTextureSize      = 64;
1100         caps.maxCubeMapTextureSize = 16;
1101         caps.maxViewportWidth      = caps.max2DTextureSize;
1102         caps.maxViewportHeight     = caps.max2DTextureSize;
1103         caps.minAliasedPointSize   = 1;
1104         caps.maxAliasedPointSize   = 1;
1105         caps.minAliasedLineWidth   = 1;
1106         caps.maxAliasedLineWidth   = 1;
1107 
1108         // Table 6.19
1109         caps.vertexHighpFloat.setSimulatedFloat(62, 16);
1110         caps.vertexMediumpFloat.setSimulatedFloat(14, 10);
1111         caps.vertexLowpFloat.setSimulatedFloat(1, 8);
1112         caps.vertexHighpInt.setSimulatedInt(16);
1113         caps.vertexMediumpInt.setSimulatedInt(10);
1114         caps.vertexLowpInt.setSimulatedInt(8);
1115         caps.fragmentHighpFloat.setSimulatedFloat(62, 16);
1116         caps.fragmentMediumpFloat.setSimulatedFloat(14, 10);
1117         caps.fragmentLowpFloat.setSimulatedFloat(1, 8);
1118         caps.fragmentHighpInt.setSimulatedInt(16);
1119         caps.fragmentMediumpInt.setSimulatedInt(10);
1120         caps.fragmentLowpInt.setSimulatedInt(8);
1121 
1122         // Table 6.20
1123         caps.maxVertexAttributes                              = 8;
1124         caps.maxVertexUniformVectors                          = 128;
1125         caps.maxVaryingVectors                                = 8;
1126         caps.maxCombinedTextureImageUnits                     = 8;
1127         caps.maxShaderTextureImageUnits[ShaderType::Fragment] = 8;
1128         caps.maxFragmentUniformVectors                        = 16;
1129         caps.maxRenderbufferSize                              = 1;
1130 
1131         // Table 3.35
1132         caps.maxSamples = 4;
1133     }
1134 
1135     if (clientVersion >= Version(3, 0))
1136     {
1137         // Table 6.28
1138         caps.maxElementIndex       = (1 << 24) - 1;
1139         caps.max3DTextureSize      = 256;
1140         caps.max2DTextureSize      = 2048;
1141         caps.maxArrayTextureLayers = 256;
1142         caps.maxLODBias            = 2.0f;
1143         caps.maxCubeMapTextureSize = 2048;
1144         caps.maxRenderbufferSize   = 2048;
1145         caps.maxDrawBuffers        = 4;
1146         caps.maxColorAttachments   = 4;
1147         caps.maxViewportWidth      = caps.max2DTextureSize;
1148         caps.maxViewportHeight     = caps.max2DTextureSize;
1149 
1150         // Table 6.29
1151         caps.compressedTextureFormats.push_back(GL_COMPRESSED_R11_EAC);
1152         caps.compressedTextureFormats.push_back(GL_COMPRESSED_SIGNED_R11_EAC);
1153         caps.compressedTextureFormats.push_back(GL_COMPRESSED_RG11_EAC);
1154         caps.compressedTextureFormats.push_back(GL_COMPRESSED_SIGNED_RG11_EAC);
1155         caps.compressedTextureFormats.push_back(GL_COMPRESSED_RGB8_ETC2);
1156         caps.compressedTextureFormats.push_back(GL_COMPRESSED_SRGB8_ETC2);
1157         caps.compressedTextureFormats.push_back(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2);
1158         caps.compressedTextureFormats.push_back(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2);
1159         caps.compressedTextureFormats.push_back(GL_COMPRESSED_RGBA8_ETC2_EAC);
1160         caps.compressedTextureFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC);
1161         caps.vertexHighpFloat.setIEEEFloat();
1162         caps.vertexHighpInt.setTwosComplementInt(32);
1163         caps.vertexMediumpInt.setTwosComplementInt(16);
1164         caps.vertexLowpInt.setTwosComplementInt(8);
1165         caps.fragmentHighpFloat.setIEEEFloat();
1166         caps.fragmentHighpInt.setSimulatedInt(32);
1167         caps.fragmentMediumpInt.setTwosComplementInt(16);
1168         caps.fragmentLowpInt.setTwosComplementInt(8);
1169         caps.maxServerWaitTimeout = 0;
1170 
1171         // Table 6.31
1172         caps.maxVertexAttributes                            = 16;
1173         caps.maxShaderUniformComponents[ShaderType::Vertex] = 1024;
1174         caps.maxVertexUniformVectors                        = 256;
1175         caps.maxShaderUniformBlocks[ShaderType::Vertex]     = limits::kMinimumShaderUniformBlocks;
1176         caps.maxVertexOutputComponents = limits::kMinimumVertexOutputComponents;
1177         caps.maxShaderTextureImageUnits[ShaderType::Vertex] = 16;
1178 
1179         // Table 6.32
1180         caps.maxShaderUniformComponents[ShaderType::Fragment] = 896;
1181         caps.maxFragmentUniformVectors                        = 224;
1182         caps.maxShaderUniformBlocks[ShaderType::Fragment]     = limits::kMinimumShaderUniformBlocks;
1183         caps.maxFragmentInputComponents                       = 60;
1184         caps.maxShaderTextureImageUnits[ShaderType::Fragment] = 16;
1185         caps.minProgramTexelOffset                            = -8;
1186         caps.maxProgramTexelOffset                            = 7;
1187 
1188         // Table 6.33
1189         caps.maxUniformBufferBindings     = 24;
1190         caps.maxUniformBlockSize          = 16384;
1191         caps.uniformBufferOffsetAlignment = 256;
1192         caps.maxCombinedUniformBlocks     = 24;
1193         caps.maxVaryingComponents         = 60;
1194         caps.maxVaryingVectors            = 15;
1195         caps.maxCombinedTextureImageUnits = 32;
1196 
1197         // Table 6.34
1198         caps.maxTransformFeedbackInterleavedComponents = 64;
1199         caps.maxTransformFeedbackSeparateAttributes    = 4;
1200         caps.maxTransformFeedbackSeparateComponents    = 4;
1201     }
1202 
1203     if (clientVersion >= Version(3, 1))
1204     {
1205         // Table 20.40
1206         caps.maxFramebufferWidth    = 2048;
1207         caps.maxFramebufferHeight   = 2048;
1208         caps.maxFramebufferSamples  = 4;
1209         caps.maxSampleMaskWords     = 1;
1210         caps.maxColorTextureSamples = 1;
1211         caps.maxDepthTextureSamples = 1;
1212         caps.maxIntegerSamples      = 1;
1213 
1214         // Table 20.41
1215         caps.maxVertexAttribRelativeOffset = 2047;
1216         caps.maxVertexAttribBindings       = 16;
1217         caps.maxVertexAttribStride         = 2048;
1218 
1219         // Table 20.43
1220         caps.maxShaderAtomicCounterBuffers[ShaderType::Vertex] = 0;
1221         caps.maxShaderAtomicCounters[ShaderType::Vertex]       = 0;
1222         caps.maxShaderImageUniforms[ShaderType::Vertex]        = 0;
1223         caps.maxShaderStorageBlocks[ShaderType::Vertex]        = 0;
1224 
1225         // Table 20.44
1226         caps.maxShaderUniformComponents[ShaderType::Fragment]    = 1024;
1227         caps.maxFragmentUniformVectors                           = 256;
1228         caps.maxShaderAtomicCounterBuffers[ShaderType::Fragment] = 0;
1229         caps.maxShaderAtomicCounters[ShaderType::Fragment]       = 0;
1230         caps.maxShaderImageUniforms[ShaderType::Fragment]        = 0;
1231         caps.maxShaderStorageBlocks[ShaderType::Fragment]        = 0;
1232         caps.minProgramTextureGatherOffset                       = 0;
1233         caps.maxProgramTextureGatherOffset                       = 0;
1234 
1235         // Table 20.45
1236         caps.maxComputeWorkGroupCount                        = {{65535, 65535, 65535}};
1237         caps.maxComputeWorkGroupSize                         = {{128, 128, 64}};
1238         caps.maxComputeWorkGroupInvocations                  = 12;
1239         caps.maxShaderUniformBlocks[ShaderType::Compute]     = limits::kMinimumShaderUniformBlocks;
1240         caps.maxShaderTextureImageUnits[ShaderType::Compute] = 16;
1241         caps.maxComputeSharedMemorySize                      = 16384;
1242         caps.maxShaderUniformComponents[ShaderType::Compute] = 1024;
1243         caps.maxShaderAtomicCounterBuffers[ShaderType::Compute] = 1;
1244         caps.maxShaderAtomicCounters[ShaderType::Compute]       = 8;
1245         caps.maxShaderImageUniforms[ShaderType::Compute]        = 4;
1246         caps.maxShaderStorageBlocks[ShaderType::Compute]        = 4;
1247 
1248         // Table 20.46
1249         caps.maxUniformBufferBindings         = 36;
1250         caps.maxCombinedTextureImageUnits     = 48;
1251         caps.maxCombinedShaderOutputResources = 4;
1252 
1253         // Table 20.47
1254         caps.maxUniformLocations                = 1024;
1255         caps.maxAtomicCounterBufferBindings     = 1;
1256         caps.maxAtomicCounterBufferSize         = 32;
1257         caps.maxCombinedAtomicCounterBuffers    = 1;
1258         caps.maxCombinedAtomicCounters          = 8;
1259         caps.maxImageUnits                      = 4;
1260         caps.maxCombinedImageUniforms           = 4;
1261         caps.maxShaderStorageBufferBindings     = 4;
1262         caps.maxShaderStorageBlockSize          = 1 << 27;
1263         caps.maxCombinedShaderStorageBlocks     = 4;
1264         caps.shaderStorageBufferOffsetAlignment = 256;
1265     }
1266 
1267     if (extensions.textureRectangle)
1268     {
1269         caps.maxRectangleTextureSize = 64;
1270     }
1271 
1272     if (extensions.geometryShader)
1273     {
1274         // Table 20.40 (GL_EXT_geometry_shader)
1275         caps.maxFramebufferLayers = 256;
1276         caps.layerProvokingVertex = GL_LAST_VERTEX_CONVENTION_EXT;
1277 
1278         // Table 20.43gs (GL_EXT_geometry_shader)
1279         caps.maxShaderUniformComponents[ShaderType::Geometry] = 1024;
1280         caps.maxShaderUniformBlocks[ShaderType::Geometry]     = limits::kMinimumShaderUniformBlocks;
1281         caps.maxGeometryInputComponents                       = 64;
1282         caps.maxGeometryOutputComponents                      = 64;
1283         caps.maxGeometryOutputVertices                        = 256;
1284         caps.maxGeometryTotalOutputComponents                 = 1024;
1285         caps.maxShaderTextureImageUnits[ShaderType::Geometry] = 16;
1286         caps.maxShaderAtomicCounterBuffers[ShaderType::Geometry] = 0;
1287         caps.maxShaderAtomicCounters[ShaderType::Geometry]       = 0;
1288         caps.maxShaderStorageBlocks[ShaderType::Geometry]        = 0;
1289         caps.maxGeometryShaderInvocations                        = 32;
1290 
1291         // Table 20.46 (GL_EXT_geometry_shader)
1292         caps.maxShaderImageUniforms[ShaderType::Geometry] = 0;
1293 
1294         // Table 20.46 (GL_EXT_geometry_shader)
1295         caps.maxUniformBufferBindings     = 48;
1296         caps.maxCombinedUniformBlocks     = 36;
1297         caps.maxCombinedTextureImageUnits = 64;
1298     }
1299 
1300     for (ShaderType shaderType : AllShaderTypes())
1301     {
1302         caps.maxCombinedShaderUniformComponents[shaderType] =
1303             caps.maxShaderUniformBlocks[shaderType] *
1304                 static_cast<GLuint>(caps.maxUniformBlockSize / 4) +
1305             caps.maxShaderUniformComponents[shaderType];
1306     }
1307 
1308     return caps;
1309 }
1310 }  // namespace gl
1311 
1312 namespace egl
1313 {
1314 
1315 Caps::Caps() = default;
1316 
1317 DisplayExtensions::DisplayExtensions() = default;
1318 
getStrings() const1319 std::vector<std::string> DisplayExtensions::getStrings() const
1320 {
1321     std::vector<std::string> extensionStrings;
1322 
1323     // clang-format off
1324     //                   | Extension name                                       | Supported flag                    | Output vector   |
1325     InsertExtensionString("EGL_EXT_create_context_robustness",                   createContextRobustness,            &extensionStrings);
1326     InsertExtensionString("EGL_ANGLE_d3d_share_handle_client_buffer",            d3dShareHandleClientBuffer,         &extensionStrings);
1327     InsertExtensionString("EGL_ANGLE_d3d_texture_client_buffer",                 d3dTextureClientBuffer,             &extensionStrings);
1328     InsertExtensionString("EGL_ANGLE_surface_d3d_texture_2d_share_handle",       surfaceD3DTexture2DShareHandle,     &extensionStrings);
1329     InsertExtensionString("EGL_ANGLE_query_surface_pointer",                     querySurfacePointer,                &extensionStrings);
1330     InsertExtensionString("EGL_ANGLE_window_fixed_size",                         windowFixedSize,                    &extensionStrings);
1331     InsertExtensionString("EGL_ANGLE_keyed_mutex",                               keyedMutex,                         &extensionStrings);
1332     InsertExtensionString("EGL_ANGLE_surface_orientation",                       surfaceOrientation,                 &extensionStrings);
1333     InsertExtensionString("EGL_ANGLE_direct_composition",                        directComposition,                  &extensionStrings);
1334     InsertExtensionString("EGL_ANGLE_windows_ui_composition",                    windowsUIComposition,               &extensionStrings);
1335     InsertExtensionString("EGL_NV_post_sub_buffer",                              postSubBuffer,                      &extensionStrings);
1336     InsertExtensionString("EGL_KHR_create_context",                              createContext,                      &extensionStrings);
1337     InsertExtensionString("EGL_EXT_device_query",                                deviceQuery,                        &extensionStrings);
1338     InsertExtensionString("EGL_KHR_image",                                       image,                              &extensionStrings);
1339     InsertExtensionString("EGL_KHR_image_base",                                  imageBase,                          &extensionStrings);
1340     InsertExtensionString("EGL_KHR_image_pixmap",                                imagePixmap,                        &extensionStrings);
1341     InsertExtensionString("EGL_EXT_image_gl_colorspace",                         imageGlColorspace,                  &extensionStrings);
1342     InsertExtensionString("EGL_KHR_gl_colorspace",                               glColorspace,                       &extensionStrings);
1343     InsertExtensionString("EGL_EXT_gl_colorspace_scrgb",                         glColorspaceScrgb,                  &extensionStrings);
1344     InsertExtensionString("EGL_EXT_gl_colorspace_scrgb_linear",                  glColorspaceScrgbLinear,            &extensionStrings);
1345     InsertExtensionString("EGL_EXT_gl_colorspace_display_p3",                    glColorspaceDisplayP3,              &extensionStrings);
1346     InsertExtensionString("EGL_EXT_gl_colorspace_display_p3_linear",             glColorspaceDisplayP3Linear,        &extensionStrings);
1347     InsertExtensionString("EGL_EXT_gl_colorspace_display_p3_passthrough",        glColorspaceDisplayP3Passthrough,   &extensionStrings);
1348     InsertExtensionString("EGL_KHR_gl_texture_2D_image",                         glTexture2DImage,                   &extensionStrings);
1349     InsertExtensionString("EGL_KHR_gl_texture_cubemap_image",                    glTextureCubemapImage,              &extensionStrings);
1350     InsertExtensionString("EGL_KHR_gl_texture_3D_image",                         glTexture3DImage,                   &extensionStrings);
1351     InsertExtensionString("EGL_KHR_gl_renderbuffer_image",                       glRenderbufferImage,                &extensionStrings);
1352     InsertExtensionString("EGL_KHR_get_all_proc_addresses",                      getAllProcAddresses,                &extensionStrings);
1353     InsertExtensionString("EGL_KHR_stream",                                      stream,                             &extensionStrings);
1354     InsertExtensionString("EGL_KHR_stream_consumer_gltexture",                   streamConsumerGLTexture,            &extensionStrings);
1355     InsertExtensionString("EGL_NV_stream_consumer_gltexture_yuv",                streamConsumerGLTextureYUV,         &extensionStrings);
1356     InsertExtensionString("EGL_KHR_fence_sync",                                  fenceSync,                          &extensionStrings);
1357     InsertExtensionString("EGL_KHR_wait_sync",                                   waitSync,                           &extensionStrings);
1358     InsertExtensionString("EGL_ANGLE_flexible_surface_compatibility",            flexibleSurfaceCompatibility,       &extensionStrings);
1359     InsertExtensionString("EGL_ANGLE_stream_producer_d3d_texture",               streamProducerD3DTexture,           &extensionStrings);
1360     InsertExtensionString("EGL_ANGLE_create_context_webgl_compatibility",        createContextWebGLCompatibility,    &extensionStrings);
1361     InsertExtensionString("EGL_CHROMIUM_create_context_bind_generates_resource", createContextBindGeneratesResource, &extensionStrings);
1362     InsertExtensionString("EGL_CHROMIUM_sync_control",                           syncControlCHROMIUM,                &extensionStrings);
1363     InsertExtensionString("EGL_ANGLE_sync_control_rate",                         syncControlRateANGLE,               &extensionStrings);
1364     InsertExtensionString("EGL_KHR_swap_buffers_with_damage",                    swapBuffersWithDamage,              &extensionStrings);
1365     InsertExtensionString("EGL_EXT_pixel_format_float",                          pixelFormatFloat,                   &extensionStrings);
1366     InsertExtensionString("EGL_KHR_surfaceless_context",                         surfacelessContext,                 &extensionStrings);
1367     InsertExtensionString("EGL_ANGLE_display_texture_share_group",               displayTextureShareGroup,           &extensionStrings);
1368     InsertExtensionString("EGL_ANGLE_create_context_client_arrays",              createContextClientArrays,          &extensionStrings);
1369     InsertExtensionString("EGL_ANGLE_program_cache_control",                     programCacheControl,                &extensionStrings);
1370     InsertExtensionString("EGL_ANGLE_robust_resource_initialization",            robustResourceInitialization,       &extensionStrings);
1371     InsertExtensionString("EGL_ANGLE_iosurface_client_buffer",                   iosurfaceClientBuffer,              &extensionStrings);
1372     InsertExtensionString("EGL_ANGLE_create_context_extensions_enabled",         createContextExtensionsEnabled,     &extensionStrings);
1373     InsertExtensionString("EGL_ANDROID_presentation_time",                       presentationTime,                   &extensionStrings);
1374     InsertExtensionString("EGL_ANDROID_blob_cache",                              blobCache,                          &extensionStrings);
1375     InsertExtensionString("EGL_ANDROID_framebuffer_target",                      framebufferTargetANDROID,           &extensionStrings);
1376     InsertExtensionString("EGL_ANDROID_image_native_buffer",                     imageNativeBuffer,                  &extensionStrings);
1377     InsertExtensionString("EGL_ANDROID_get_frame_timestamps",                    getFrameTimestamps,                 &extensionStrings);
1378     InsertExtensionString("EGL_ANDROID_recordable",                              recordable,                         &extensionStrings);
1379     InsertExtensionString("EGL_ANGLE_power_preference",                          powerPreference,                    &extensionStrings);
1380     InsertExtensionString("EGL_ANGLE_image_d3d11_texture",                       imageD3D11Texture,                  &extensionStrings);
1381     InsertExtensionString("EGL_ANDROID_get_native_client_buffer",                getNativeClientBufferANDROID,       &extensionStrings);
1382     InsertExtensionString("EGL_ANDROID_native_fence_sync",                       nativeFenceSyncANDROID,             &extensionStrings);
1383     InsertExtensionString("EGL_ANGLE_create_context_backwards_compatible",       createContextBackwardsCompatible,   &extensionStrings);
1384     InsertExtensionString("EGL_KHR_no_config_context",                           noConfigContext,                    &extensionStrings);
1385     InsertExtensionString("EGL_IMG_context_priority",                            contextPriority,                    &extensionStrings);
1386     InsertExtensionString("EGL_KHR_create_context_no_error",                     createContextNoError,               &extensionStrings);
1387     // clang-format on
1388 
1389     return extensionStrings;
1390 }
1391 
1392 DeviceExtensions::DeviceExtensions() = default;
1393 
getStrings() const1394 std::vector<std::string> DeviceExtensions::getStrings() const
1395 {
1396     std::vector<std::string> extensionStrings;
1397 
1398     // clang-format off
1399     //                   | Extension name                                 | Supported flag                | Output vector   |
1400     InsertExtensionString("EGL_ANGLE_device_d3d",                          deviceD3D,                      &extensionStrings);
1401     InsertExtensionString("EGL_ANGLE_device_cgl",                          deviceCGL,                      &extensionStrings);
1402     // clang-format on
1403 
1404     return extensionStrings;
1405 }
1406 
1407 ClientExtensions::ClientExtensions()                              = default;
1408 ClientExtensions::ClientExtensions(const ClientExtensions &other) = default;
1409 
getStrings() const1410 std::vector<std::string> ClientExtensions::getStrings() const
1411 {
1412     std::vector<std::string> extensionStrings;
1413 
1414     // clang-format off
1415     //                   | Extension name                                    | Supported flag                   | Output vector   |
1416     InsertExtensionString("EGL_EXT_client_extensions",                        clientExtensions,                   &extensionStrings);
1417     InsertExtensionString("EGL_EXT_platform_base",                            platformBase,                       &extensionStrings);
1418     InsertExtensionString("EGL_EXT_platform_device",                          platformDevice,                     &extensionStrings);
1419     InsertExtensionString("EGL_ANGLE_platform_angle",                         platformANGLE,                      &extensionStrings);
1420     InsertExtensionString("EGL_ANGLE_platform_angle_d3d",                     platformANGLED3D,                   &extensionStrings);
1421     InsertExtensionString("EGL_ANGLE_platform_angle_d3d11on12",               platformANGLED3D11ON12,             &extensionStrings);
1422     InsertExtensionString("EGL_ANGLE_platform_angle_device_type_egl_angle",   platformANGLEDeviceTypeEGLANGLE,    &extensionStrings);
1423     InsertExtensionString("EGL_ANGLE_platform_angle_device_type_swiftshader", platformANGLEDeviceTypeSwiftShader, &extensionStrings);
1424     InsertExtensionString("EGL_ANGLE_platform_angle_opengl",                  platformANGLEOpenGL,                &extensionStrings);
1425     InsertExtensionString("EGL_ANGLE_platform_angle_null",                    platformANGLENULL,                  &extensionStrings);
1426     InsertExtensionString("EGL_ANGLE_platform_angle_vulkan",                  platformANGLEVulkan,                &extensionStrings);
1427     InsertExtensionString("EGL_ANGLE_platform_angle_metal",                   platformANGLEMetal,                 &extensionStrings);
1428     InsertExtensionString("EGL_ANGLE_platform_angle_context_virtualization",  platformANGLEContextVirtualization, &extensionStrings);
1429     InsertExtensionString("EGL_ANGLE_device_creation",                        deviceCreation,                     &extensionStrings);
1430     InsertExtensionString("EGL_ANGLE_device_creation_d3d11",                  deviceCreationD3D11,                &extensionStrings);
1431     InsertExtensionString("EGL_ANGLE_x11_visual",                             x11Visual,                          &extensionStrings);
1432     InsertExtensionString("EGL_ANGLE_experimental_present_path",              experimentalPresentPath,            &extensionStrings);
1433     InsertExtensionString("EGL_KHR_client_get_all_proc_addresses",            clientGetAllProcAddresses,          &extensionStrings);
1434     InsertExtensionString("EGL_KHR_debug",                                    debug,                              &extensionStrings);
1435     InsertExtensionString("EGL_ANGLE_explicit_context",                       explicitContext,                    &extensionStrings);
1436     InsertExtensionString("EGL_ANGLE_feature_control",                        featureControlANGLE,                &extensionStrings);
1437     // clang-format on
1438 
1439     return extensionStrings;
1440 }
1441 
1442 }  // namespace egl
1443