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