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