xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/vulkan/vk_caps_utils.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2018 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 // vk_utils:
7 //    Helper functions for the Vulkan Caps.
8 //
9 
10 #include "libANGLE/renderer/vulkan/vk_caps_utils.h"
11 
12 #include <type_traits>
13 
14 #include "common/system_utils.h"
15 #include "common/utilities.h"
16 #include "libANGLE/Caps.h"
17 #include "libANGLE/formatutils.h"
18 #include "libANGLE/renderer/driver_utils.h"
19 #include "libANGLE/renderer/vulkan/DisplayVk.h"
20 #include "libANGLE/renderer/vulkan/vk_cache_utils.h"
21 #include "libANGLE/renderer/vulkan/vk_renderer.h"
22 #include "vk_format_utils.h"
23 
24 namespace
25 {
26 constexpr unsigned int kComponentsPerVector         = 4;
27 constexpr bool kEnableLogMissingExtensionsForGLES32 = false;
28 }  // anonymous namespace
29 
30 namespace rx
31 {
32 
33 namespace vk
34 {
35 namespace
36 {
37 // Checks to see if each format can be reinterpreted to an equivalent format in a different
38 // colorspace. If all supported formats can be reinterpreted, it returns true. Formats which are not
39 // supported at all are ignored and not counted as failures.
FormatReinterpretationSupported(const std::vector<GLenum> & optionalSizedFormats,const Renderer * renderer,bool checkLinearColorspace)40 bool FormatReinterpretationSupported(const std::vector<GLenum> &optionalSizedFormats,
41                                      const Renderer *renderer,
42                                      bool checkLinearColorspace)
43 {
44     for (GLenum glFormat : optionalSizedFormats)
45     {
46         const gl::TextureCaps &baseCaps = renderer->getNativeTextureCaps().get(glFormat);
47         if (baseCaps.texturable && baseCaps.filterable)
48         {
49             const Format &vkFormat = renderer->getFormat(glFormat);
50             // For capability query, we use the renderable format since that is what we are capable
51             // of when we fallback.
52             angle::FormatID imageFormatID = vkFormat.getActualRenderableImageFormatID();
53 
54             angle::FormatID reinterpretedFormatID = checkLinearColorspace
55                                                         ? ConvertToLinear(imageFormatID)
56                                                         : ConvertToSRGB(imageFormatID);
57 
58             const Format &reinterpretedVkFormat = renderer->getFormat(reinterpretedFormatID);
59 
60             if (reinterpretedVkFormat.getActualRenderableImageFormatID() != reinterpretedFormatID)
61             {
62                 return false;
63             }
64 
65             if (!renderer->haveSameFormatFeatureBits(imageFormatID, reinterpretedFormatID))
66             {
67                 return false;
68             }
69         }
70     }
71 
72     return true;
73 }
74 
GetTextureSRGBDecodeSupport(const Renderer * renderer)75 bool GetTextureSRGBDecodeSupport(const Renderer *renderer)
76 {
77     static constexpr bool kLinearColorspace = true;
78 
79     // GL_SRGB and GL_SRGB_ALPHA unsized formats are also required by the spec, but the only valid
80     // type for them is GL_UNSIGNED_BYTE, so they are fully included in the sized formats listed
81     // here
82     std::vector<GLenum> optionalSizedSRGBFormats = {
83         GL_SRGB8,
84         GL_SRGB8_ALPHA8_EXT,
85         GL_COMPRESSED_SRGB_S3TC_DXT1_EXT,
86         GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT,
87         GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT,
88         GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT,
89     };
90 
91     if (!FormatReinterpretationSupported(optionalSizedSRGBFormats, renderer, kLinearColorspace))
92     {
93         return false;
94     }
95 
96     return true;
97 }
98 
GetTextureSRGBOverrideSupport(const Renderer * renderer,const gl::Extensions & supportedExtensions)99 bool GetTextureSRGBOverrideSupport(const Renderer *renderer,
100                                    const gl::Extensions &supportedExtensions)
101 {
102     static constexpr bool kNonLinearColorspace = false;
103 
104     // If the given linear format is supported, we also need to support its corresponding nonlinear
105     // format. If the given linear format is NOT supported, we don't care about its corresponding
106     // nonlinear format.
107     std::vector<GLenum> optionalLinearFormats     = {GL_RGB8,
108                                                      GL_RGBA8,
109                                                      GL_COMPRESSED_RGB8_ETC2,
110                                                      GL_COMPRESSED_RGBA8_ETC2_EAC,
111                                                      GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
112                                                      GL_COMPRESSED_RGBA_ASTC_4x4,
113                                                      GL_COMPRESSED_RGBA_ASTC_5x4,
114                                                      GL_COMPRESSED_RGBA_ASTC_5x5,
115                                                      GL_COMPRESSED_RGBA_ASTC_6x5,
116                                                      GL_COMPRESSED_RGBA_ASTC_6x6,
117                                                      GL_COMPRESSED_RGBA_ASTC_8x5,
118                                                      GL_COMPRESSED_RGBA_ASTC_8x6,
119                                                      GL_COMPRESSED_RGBA_ASTC_8x8,
120                                                      GL_COMPRESSED_RGBA_ASTC_10x5,
121                                                      GL_COMPRESSED_RGBA_ASTC_10x6,
122                                                      GL_COMPRESSED_RGBA_ASTC_10x8,
123                                                      GL_COMPRESSED_RGBA_ASTC_10x10,
124                                                      GL_COMPRESSED_RGBA_ASTC_12x10,
125                                                      GL_COMPRESSED_RGBA_ASTC_12x12};
126     std::vector<GLenum> optionalS3TCLinearFormats = {
127         GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
128         GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT};
129     std::vector<GLenum> optionalR8LinearFormats   = {GL_R8};
130     std::vector<GLenum> optionalRG8LinearFormats  = {GL_RG8};
131     std::vector<GLenum> optionalBPTCLinearFormats = {GL_COMPRESSED_RGBA_BPTC_UNORM_EXT};
132 
133     if (!FormatReinterpretationSupported(optionalLinearFormats, renderer, kNonLinearColorspace))
134     {
135         return false;
136     }
137 
138     if (supportedExtensions.textureCompressionS3tcSrgbEXT)
139     {
140         if (!FormatReinterpretationSupported(optionalS3TCLinearFormats, renderer,
141                                              kNonLinearColorspace))
142         {
143             return false;
144         }
145     }
146 
147     if (supportedExtensions.textureSRGBR8EXT)
148     {
149         if (!FormatReinterpretationSupported(optionalR8LinearFormats, renderer,
150                                              kNonLinearColorspace))
151         {
152             return false;
153         }
154     }
155 
156     if (supportedExtensions.textureSRGBRG8EXT)
157     {
158         if (!FormatReinterpretationSupported(optionalRG8LinearFormats, renderer,
159                                              kNonLinearColorspace))
160         {
161             return false;
162         }
163     }
164 
165     if (supportedExtensions.textureCompressionBptcEXT)
166     {
167         if (!FormatReinterpretationSupported(optionalBPTCLinearFormats, renderer,
168                                              kNonLinearColorspace))
169         {
170             return false;
171         }
172     }
173 
174     return true;
175 }
176 
CanSupportYuvInternalFormat(const Renderer * renderer)177 bool CanSupportYuvInternalFormat(const Renderer *renderer)
178 {
179     // The following formats are not mandatory in Vulkan, even when VK_KHR_sampler_ycbcr_conversion
180     // is supported. GL_ANGLE_yuv_internal_format requires support for sampling only the
181     // 8-bit 2-plane YUV format (VK_FORMAT_G8_B8R8_2PLANE_420_UNORM), if the ICD supports that we
182     // can expose the extension.
183     //
184     // Various test cases need multiple YUV formats. It would be preferrable to have support for the
185     // 3 plane 8 bit YUV format (VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM) as well.
186 
187     const Format &twoPlane8bitYuvFormat = renderer->getFormat(GL_G8_B8R8_2PLANE_420_UNORM_ANGLE);
188     bool twoPlane8bitYuvFormatSupported = renderer->hasImageFormatFeatureBits(
189         twoPlane8bitYuvFormat.getActualImageFormatID(vk::ImageAccess::SampleOnly),
190         VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT);
191 
192     const Format &threePlane8bitYuvFormat = renderer->getFormat(GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE);
193     bool threePlane8bitYuvFormatSupported = renderer->hasImageFormatFeatureBits(
194         threePlane8bitYuvFormat.getActualImageFormatID(vk::ImageAccess::SampleOnly),
195         VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT);
196 
197     return twoPlane8bitYuvFormatSupported && threePlane8bitYuvFormatSupported;
198 }
199 
GetTimestampValidBits(const std::vector<VkQueueFamilyProperties> & queueFamilyProperties,uint32_t queueFamilyIndex)200 uint32_t GetTimestampValidBits(const std::vector<VkQueueFamilyProperties> &queueFamilyProperties,
201                                uint32_t queueFamilyIndex)
202 {
203     ASSERT(!queueFamilyProperties.empty());
204 
205     if (queueFamilyIndex < queueFamilyProperties.size())
206     {
207         // If a queue family is already selected (which is only currently the case if there is only
208         // one family), get the timestamp valid bits from that queue.
209         return queueFamilyProperties[queueFamilyIndex].timestampValidBits;
210     }
211 
212     // If a queue family is not already selected, we cannot know which queue family will end up
213     // being used until a surface is used.  Take the minimum valid bits from all queues as a safe
214     // measure.
215     uint32_t timestampValidBits = queueFamilyProperties[0].timestampValidBits;
216     for (const VkQueueFamilyProperties &properties : queueFamilyProperties)
217     {
218         timestampValidBits = std::min(timestampValidBits, properties.timestampValidBits);
219     }
220     return timestampValidBits;
221 }
222 
CanSupportGPUShader5(const VkPhysicalDeviceFeatures & features)223 bool CanSupportGPUShader5(const VkPhysicalDeviceFeatures &features)
224 {
225     // We use the following Vulkan features to implement EXT_gpu_shader5 and OES_gpu_shader5:
226     // - shaderImageGatherExtended: textureGatherOffset with non-constant offset and
227     //   textureGatherOffsets family of functions.
228     // - shaderSampledImageArrayDynamicIndexing and shaderUniformBufferArrayDynamicIndexing:
229     //   dynamically uniform indices for samplers and uniform buffers.
230     return features.shaderImageGatherExtended && features.shaderSampledImageArrayDynamicIndexing &&
231            features.shaderUniformBufferArrayDynamicIndexing;
232 }
233 
GetRequiredGLES32ExtensionList(const gl::Extensions & nativeExtensions)234 ANGLE_INLINE std::vector<bool> GetRequiredGLES32ExtensionList(
235     const gl::Extensions &nativeExtensions)
236 {
237     // From the GLES 3.2 spec: Almost all features of [ANDROID_extension_pack_es31a], incorporating
238     // by reference all of the following features - with the exception of the sRGB decode features
239     // of EXT_texture_sRGB_decode.
240 
241     // The extension debugKHR (also required for the Android extension pack) is a frontend feature
242     // and is unconditionally enabled as a supported feature (in generateSupportedExtensions()).
243     // Therefore, it is not included here.
244     return {
245         // From ANDROID_extension_pack_es31a
246         nativeExtensions.textureCompressionAstcLdrKHR,
247         nativeExtensions.blendEquationAdvancedKHR,
248         nativeExtensions.sampleShadingOES,
249         nativeExtensions.sampleVariablesOES,
250         nativeExtensions.shaderImageAtomicOES,
251         nativeExtensions.shaderMultisampleInterpolationOES,
252         nativeExtensions.textureStencil8OES,
253         nativeExtensions.textureStorageMultisample2dArrayOES,
254         nativeExtensions.copyImageEXT,
255         nativeExtensions.drawBuffersIndexedEXT,
256         nativeExtensions.geometryShaderEXT,
257         nativeExtensions.gpuShader5EXT,
258         nativeExtensions.primitiveBoundingBoxEXT,
259         nativeExtensions.shaderIoBlocksEXT,
260         nativeExtensions.tessellationShaderEXT,
261         nativeExtensions.textureBorderClampEXT,
262         nativeExtensions.textureBufferEXT,
263         nativeExtensions.textureCubeMapArrayEXT,
264 
265         // Other extensions
266         nativeExtensions.drawElementsBaseVertexOES,
267         nativeExtensions.colorBufferFloatEXT,
268         nativeExtensions.robustnessKHR,
269     };
270 }
271 
LogMissingExtensionsForGLES32(const gl::Extensions & nativeExtensions)272 void LogMissingExtensionsForGLES32(const gl::Extensions &nativeExtensions)
273 {
274     if (!kEnableLogMissingExtensionsForGLES32)
275     {
276         return;
277     }
278     std::vector<bool> requiredExtensions = GetRequiredGLES32ExtensionList(nativeExtensions);
279 
280     constexpr const char *kRequiredExtensionNames[] = {
281         // From ANDROID_extension_pack_es31a
282         "textureCompressionAstcLdrKHR",
283         "blendEquationAdvancedKHR",
284         "sampleShadingOES",
285         "sampleVariablesOES",
286         "shaderImageAtomicOES",
287         "shaderMultisampleInterpolationOES",
288         "textureStencil8OES",
289         "textureStorageMultisample2dArrayOES",
290         "copyImageEXT",
291         "drawBuffersIndexedEXT",
292         "geometryShaderEXT",
293         "gpuShader5EXT",
294         "primitiveBoundingBoxEXT",
295         "shaderIoBlocksEXT",
296         "tessellationShaderEXT",
297         "textureBorderClampEXT",
298         "textureBufferEXT",
299         "textureCubeMapArrayEXT",
300 
301         // Other extensions
302         "drawElementsBaseVertexOES",
303         "colorBufferFloatEXT",
304         "robustnessKHR",
305     };
306     ASSERT(std::end(kRequiredExtensionNames) - std::begin(kRequiredExtensionNames) ==
307            requiredExtensions.size());
308 
309     for (uint32_t index = 0; index < requiredExtensions.size(); index++)
310     {
311         if (!requiredExtensions[index])
312         {
313             INFO() << "The following extension is required for GLES 3.2: "
314                    << kRequiredExtensionNames[index];
315         }
316     }
317 }
318 
319 }  // namespace
320 
ensureCapsInitialized() const321 void Renderer::ensureCapsInitialized() const
322 {
323     if (mCapsInitialized)
324     {
325         return;
326     }
327     mCapsInitialized = true;
328 
329     const VkPhysicalDeviceLimits &limitsVk = mPhysicalDeviceProperties.limits;
330 
331     mNativeExtensions.setTextureExtensionSupport(mNativeTextureCaps);
332 
333     // Enable GL_EXT_buffer_storage
334     mNativeExtensions.bufferStorageEXT = true;
335 
336     // When ETC2/EAC formats are natively supported, enable ANGLE-specific extension string to
337     // expose them to WebGL. In other case, mark potentially-available ETC1 extension as emulated.
338     if ((mPhysicalDeviceFeatures.textureCompressionETC2 == VK_TRUE) &&
339         gl::DetermineCompressedTextureETCSupport(mNativeTextureCaps))
340     {
341         mNativeExtensions.compressedTextureEtcANGLE = true;
342     }
343     else
344     {
345         mNativeLimitations.emulatedEtc1 = true;
346     }
347 
348     // When ASTC formats are not natively supported
349     // mark potentially-available ASTC extension as emulated.
350     if (mPhysicalDeviceFeatures.textureCompressionASTC_LDR == VK_FALSE)
351     {
352         mNativeLimitations.emulatedAstc = true;
353     }
354 
355     // Vulkan doesn't support ASTC 3D block textures, which are required by
356     // GL_OES_texture_compression_astc.
357     mNativeExtensions.textureCompressionAstcOES = false;
358     // Enable KHR_texture_compression_astc_sliced_3d
359     mNativeExtensions.textureCompressionAstcSliced3dKHR =
360         mNativeExtensions.textureCompressionAstcLdrKHR &&
361         getFeatures().supportsAstcSliced3d.enabled;
362 
363     // Enable KHR_texture_compression_astc_hdr
364     mNativeExtensions.textureCompressionAstcHdrKHR =
365         mNativeExtensions.textureCompressionAstcLdrKHR &&
366         getFeatures().supportsTextureCompressionAstcHdr.enabled;
367 
368     // Enable EXT_compressed_ETC1_RGB8_sub_texture
369     mNativeExtensions.compressedETC1RGB8SubTextureEXT =
370         mNativeExtensions.compressedETC1RGB8TextureOES;
371 
372     // Enable this for simple buffer readback testing, but some functionality is missing.
373     // TODO(jmadill): Support full mapBufferRangeEXT extension.
374     mNativeExtensions.mapbufferOES                = true;
375     mNativeExtensions.mapBufferRangeEXT           = true;
376     mNativeExtensions.textureStorageEXT           = true;
377     mNativeExtensions.drawBuffersEXT              = true;
378     mNativeExtensions.fragDepthEXT                = true;
379     mNativeExtensions.conservativeDepthEXT        = true;
380     mNativeExtensions.framebufferBlitANGLE        = true;
381     mNativeExtensions.framebufferBlitNV           = true;
382     mNativeExtensions.framebufferMultisampleANGLE = true;
383     mNativeExtensions.textureMultisampleANGLE     = true;
384     mNativeExtensions.multisampledRenderToTextureEXT =
385         getFeatures().enableMultisampledRenderToTexture.enabled;
386     mNativeExtensions.multisampledRenderToTexture2EXT =
387         getFeatures().enableMultisampledRenderToTexture.enabled;
388     mNativeExtensions.textureStorageMultisample2dArrayOES =
389         (limitsVk.standardSampleLocations == VK_TRUE);
390     mNativeExtensions.copyTextureCHROMIUM           = true;
391     mNativeExtensions.copyTexture3dANGLE            = true;
392     mNativeExtensions.copyCompressedTextureCHROMIUM = true;
393     mNativeExtensions.debugMarkerEXT                = true;
394     mNativeExtensions.robustnessEXT                 = true;
395     mNativeExtensions.robustnessKHR                 = true;
396     mNativeExtensions.translatedShaderSourceANGLE   = true;
397     mNativeExtensions.discardFramebufferEXT         = true;
398     mNativeExtensions.stencilTexturingANGLE         = true;
399     mNativeExtensions.packReverseRowOrderANGLE      = true;
400     mNativeExtensions.textureBorderClampOES = getFeatures().supportsCustomBorderColor.enabled;
401     mNativeExtensions.textureBorderClampEXT = getFeatures().supportsCustomBorderColor.enabled;
402     mNativeExtensions.polygonModeNV         = mPhysicalDeviceFeatures.fillModeNonSolid == VK_TRUE;
403     mNativeExtensions.polygonModeANGLE      = mPhysicalDeviceFeatures.fillModeNonSolid == VK_TRUE;
404     mNativeExtensions.polygonOffsetClampEXT = mPhysicalDeviceFeatures.depthBiasClamp == VK_TRUE;
405     mNativeExtensions.depthClampEXT         = mPhysicalDeviceFeatures.depthClamp == VK_TRUE;
406     // Enable EXT_texture_type_2_10_10_10_REV
407     mNativeExtensions.textureType2101010REVEXT = true;
408 
409     // Enable EXT_texture_mirror_clamp_to_edge
410     mNativeExtensions.textureMirrorClampToEdgeEXT =
411         getFeatures().supportsSamplerMirrorClampToEdge.enabled;
412 
413     // Enable EXT_texture_shadow_lod
414     mNativeExtensions.textureShadowLodEXT = true;
415 
416     // Enable EXT_multi_draw_indirect
417     mNativeExtensions.multiDrawIndirectEXT = true;
418 
419     // Enable EXT_base_instance
420     mNativeExtensions.baseInstanceEXT = true;
421 
422     // Enable ANGLE_base_vertex_base_instance
423     mNativeExtensions.baseVertexBaseInstanceANGLE              = true;
424     mNativeExtensions.baseVertexBaseInstanceShaderBuiltinANGLE = true;
425 
426     // Enable OES/EXT_draw_elements_base_vertex
427     mNativeExtensions.drawElementsBaseVertexOES = true;
428     mNativeExtensions.drawElementsBaseVertexEXT = true;
429 
430     // Enable EXT_blend_minmax
431     mNativeExtensions.blendMinmaxEXT = true;
432 
433     // Enable OES/EXT_draw_buffers_indexed
434     mNativeExtensions.drawBuffersIndexedOES = mPhysicalDeviceFeatures.independentBlend == VK_TRUE;
435     mNativeExtensions.drawBuffersIndexedEXT = mNativeExtensions.drawBuffersIndexedOES;
436 
437     mNativeExtensions.EGLImageOES                  = true;
438     mNativeExtensions.EGLImageExternalOES          = true;
439     mNativeExtensions.EGLImageExternalWrapModesEXT = true;
440     mNativeExtensions.EGLImageExternalEssl3OES     = true;
441     mNativeExtensions.EGLImageArrayEXT             = true;
442     mNativeExtensions.EGLImageStorageEXT           = true;
443     mNativeExtensions.memoryObjectEXT              = true;
444     mNativeExtensions.memoryObjectFdEXT            = getFeatures().supportsExternalMemoryFd.enabled;
445     mNativeExtensions.memoryObjectFlagsANGLE       = true;
446     mNativeExtensions.memoryObjectFuchsiaANGLE =
447         getFeatures().supportsExternalMemoryFuchsia.enabled;
448 
449     mNativeExtensions.semaphoreEXT   = true;
450     mNativeExtensions.semaphoreFdEXT = getFeatures().supportsExternalSemaphoreFd.enabled;
451     mNativeExtensions.semaphoreFuchsiaANGLE =
452         getFeatures().supportsExternalSemaphoreFuchsia.enabled;
453 
454     mNativeExtensions.vertexHalfFloatOES = true;
455 
456     // Enabled in HW if VK_EXT_vertex_attribute_divisor available, otherwise emulated
457     mNativeExtensions.instancedArraysANGLE = true;
458     mNativeExtensions.instancedArraysEXT   = true;
459 
460     // Only expose robust buffer access if the physical device supports it.
461     mNativeExtensions.robustBufferAccessBehaviorKHR =
462         (mPhysicalDeviceFeatures.robustBufferAccess == VK_TRUE);
463 
464     mNativeExtensions.EGLSyncOES = true;
465 
466     mNativeExtensions.vertexType1010102OES = true;
467 
468     // Occlusion queries are natively supported in Vulkan.  ANGLE only issues this query inside a
469     // render pass, so there is no dependency to `inheritedQueries`.
470     mNativeExtensions.occlusionQueryBooleanEXT = true;
471 
472     // From the Vulkan specs:
473     // > The number of valid bits in a timestamp value is determined by the
474     // > VkQueueFamilyProperties::timestampValidBits property of the queue on which the timestamp is
475     // > written. Timestamps are supported on any queue which reports a non-zero value for
476     // > timestampValidBits via vkGetPhysicalDeviceQueueFamilyProperties.
477     //
478     // This query is applicable to render passes, but the `inheritedQueries` feature may not be
479     // present.  The extension is not exposed in that case.
480     // We use secondary command buffers almost everywhere and they require a feature to be
481     // able to execute in the presence of queries.  As a result, we won't support timestamp queries
482     // unless that feature is available.
483     if (vk::OutsideRenderPassCommandBuffer::SupportsQueries(mPhysicalDeviceFeatures) &&
484         vk::RenderPassCommandBuffer::SupportsQueries(mPhysicalDeviceFeatures))
485     {
486         const uint32_t timestampValidBits =
487             vk::GetTimestampValidBits(mQueueFamilyProperties, mCurrentQueueFamilyIndex);
488 
489         mNativeExtensions.disjointTimerQueryEXT = timestampValidBits > 0;
490         mNativeCaps.queryCounterBitsTimeElapsed = timestampValidBits;
491         mNativeCaps.queryCounterBitsTimestamp   = timestampValidBits;
492     }
493 
494     mNativeExtensions.textureFilterAnisotropicEXT =
495         mPhysicalDeviceFeatures.samplerAnisotropy && limitsVk.maxSamplerAnisotropy > 1.0f;
496     mNativeCaps.maxTextureAnisotropy =
497         mNativeExtensions.textureFilterAnisotropicEXT ? limitsVk.maxSamplerAnisotropy : 0.0f;
498 
499     // Vulkan natively supports non power-of-two textures
500     mNativeExtensions.textureNpotOES = true;
501 
502     mNativeExtensions.texture3DOES = true;
503 
504     // Vulkan natively supports standard derivatives
505     mNativeExtensions.standardDerivativesOES = true;
506 
507     // Vulkan natively supports texture LOD
508     mNativeExtensions.shaderTextureLodEXT = true;
509 
510     // Vulkan natively supports noperspective interpolation
511     mNativeExtensions.shaderNoperspectiveInterpolationNV = true;
512 
513     // Vulkan natively supports 32-bit indices, entry in kIndexTypeMap
514     mNativeExtensions.elementIndexUintOES = true;
515 
516     mNativeExtensions.fboRenderMipmapOES = true;
517 
518     // We support getting image data for Textures and Renderbuffers.
519     mNativeExtensions.getImageANGLE = true;
520 
521     // Implemented in the translator
522     mNativeExtensions.shaderNonConstantGlobalInitializersEXT = true;
523 
524     // Implemented in the front end. Enable SSO if not explicitly disabled.
525     mNativeExtensions.separateShaderObjectsEXT =
526         !getFeatures().disableSeparateShaderObjects.enabled;
527 
528     // Vulkan has no restrictions of the format of cubemaps, so if the proper formats are supported,
529     // creating a cube of any of these formats should be implicitly supported.
530     mNativeExtensions.depthTextureCubeMapOES =
531         mNativeExtensions.depthTextureOES && mNativeExtensions.packedDepthStencilOES;
532 
533     // Vulkan natively supports format reinterpretation, but we still require support for all
534     // formats we may reinterpret to
535     mNativeExtensions.textureFormatSRGBOverrideEXT =
536         vk::GetTextureSRGBOverrideSupport(this, mNativeExtensions);
537     mNativeExtensions.textureSRGBDecodeEXT = vk::GetTextureSRGBDecodeSupport(this);
538 
539     // EXT_srgb_write_control requires image_format_list
540     mNativeExtensions.sRGBWriteControlEXT = getFeatures().supportsImageFormatList.enabled;
541 
542     // Vulkan natively supports io interface block.
543     mNativeExtensions.shaderIoBlocksOES = true;
544     mNativeExtensions.shaderIoBlocksEXT = true;
545 
546     bool gpuShader5Support          = vk::CanSupportGPUShader5(mPhysicalDeviceFeatures);
547     mNativeExtensions.gpuShader5EXT = gpuShader5Support;
548     mNativeExtensions.gpuShader5OES = gpuShader5Support;
549 
550     // Only expose texture cubemap array if the physical device supports it.
551     mNativeExtensions.textureCubeMapArrayOES = getFeatures().supportsImageCubeArray.enabled;
552     mNativeExtensions.textureCubeMapArrayEXT = mNativeExtensions.textureCubeMapArrayOES;
553 
554     mNativeExtensions.shadowSamplersEXT = true;
555 
556     // Enable EXT_external_buffer on Android. External buffers are implemented using Android
557     // hardware buffer (struct AHardwareBuffer).
558     mNativeExtensions.externalBufferEXT = IsAndroid() && GetAndroidSDKVersion() >= 26;
559 
560     // From the Vulkan specs:
561     // sampleRateShading specifies whether Sample Shading and multisample interpolation are
562     // supported. If this feature is not enabled, the sampleShadingEnable member of the
563     // VkPipelineMultisampleStateCreateInfo structure must be set to VK_FALSE and the
564     // minSampleShading member is ignored. This also specifies whether shader modules can declare
565     // the SampleRateShading capability
566     bool supportSampleRateShading      = mPhysicalDeviceFeatures.sampleRateShading == VK_TRUE;
567     mNativeExtensions.sampleShadingOES = supportSampleRateShading;
568 
569     // From the SPIR-V spec at 3.21. BuiltIn, SampleId and SamplePosition needs
570     // SampleRateShading. https://www.khronos.org/registry/spir-v/specs/unified1/SPIRV.html
571     // To replace non-constant index to constant 0 index, this extension assumes that ANGLE only
572     // supports the number of samples less than or equal to 32.
573     constexpr unsigned int kNotSupportedSampleCounts = VK_SAMPLE_COUNT_64_BIT;
574     mNativeExtensions.sampleVariablesOES =
575         supportSampleRateShading && vk_gl::GetMaxSampleCount(kNotSupportedSampleCounts) == 0;
576 
577     // EXT_multisample_compatibility is necessary for GLES1 conformance so calls like
578     // glDisable(GL_MULTISAMPLE) don't fail.  This is not actually implemented in Vulkan.  However,
579     // no CTS tests actually test this extension.  GL_SAMPLE_ALPHA_TO_ONE requires the Vulkan
580     // alphaToOne feature.
581     mNativeExtensions.multisampleCompatibilityEXT =
582         mPhysicalDeviceFeatures.alphaToOne ||
583         mFeatures.exposeNonConformantExtensionsAndVersions.enabled;
584 
585     // GL_KHR_blend_equation_advanced.  According to the spec, only color attachment zero can be
586     // used with advanced blend:
587     //
588     // > Advanced blending equations are supported only when rendering to a single
589     // > color buffer using fragment color zero.
590     //
591     // Vulkan requires advancedBlendMaxColorAttachments to be at least one, so we can support
592     // advanced blend as long as the Vulkan extension is supported.  Otherwise, the extension is
593     // emulated where possible.
594     // GL_EXT_blend_minmax is required for this extension, which is always enabled (hence omitted).
595     mNativeExtensions.blendEquationAdvancedKHR = mFeatures.supportsBlendOperationAdvanced.enabled ||
596                                                  mFeatures.emulateAdvancedBlendEquations.enabled;
597 
598     mNativeExtensions.blendEquationAdvancedCoherentKHR =
599         mFeatures.supportsBlendOperationAdvancedCoherent.enabled ||
600         (mFeatures.emulateAdvancedBlendEquations.enabled && mIsColorFramebufferFetchCoherent);
601 
602     // Enable EXT_unpack_subimage
603     mNativeExtensions.unpackSubimageEXT = true;
604 
605     // Enable NV_pack_subimage
606     mNativeExtensions.packSubimageNV = true;
607 
608     mNativeCaps.minInterpolationOffset          = limitsVk.minInterpolationOffset;
609     mNativeCaps.maxInterpolationOffset          = limitsVk.maxInterpolationOffset;
610     mNativeCaps.subPixelInterpolationOffsetBits = limitsVk.subPixelInterpolationOffsetBits;
611 
612     // Enable GL_ANGLE_robust_fragment_shader_output
613     mNativeExtensions.robustFragmentShaderOutputANGLE = true;
614 
615     // From the Vulkan spec:
616     //
617     // > The values minInterpolationOffset and maxInterpolationOffset describe the closed interval
618     // > of supported interpolation offsets : [ minInterpolationOffset, maxInterpolationOffset ].
619     // > The ULP is determined by subPixelInterpolationOffsetBits. If
620     // > subPixelInterpolationOffsetBits is 4, this provides increments of(1 / 2^4) = 0.0625, and
621     // > thus the range of supported interpolation offsets would be[-0.5, 0.4375]
622     //
623     // OES_shader_multisample_interpolation requires a maximum value of -0.5 for
624     // MIN_FRAGMENT_INTERPOLATION_OFFSET_OES and minimum 0.5 for
625     // MAX_FRAGMENT_INTERPOLATION_OFFSET_OES.  Vulkan has an identical limit for
626     // minInterpolationOffset, but its limit for maxInterpolationOffset is 0.5-(1/ULP).
627     // OES_shader_multisample_interpolation is therefore only supported if
628     // maxInterpolationOffset is at least 0.5.
629     //
630     // The GL spec is not as precise as Vulkan's in this regard and that the requirements really
631     // meant to match.  This is rectified in the GL spec.
632     // https://gitlab.khronos.org/opengl/API/-/issues/149
633     mNativeExtensions.shaderMultisampleInterpolationOES = mNativeExtensions.sampleVariablesOES;
634 
635     // Always enable ANGLE_rgbx_internal_format to expose GL_RGBX8_ANGLE.
636     mNativeExtensions.rgbxInternalFormatANGLE = true;
637 
638     // https://vulkan.lunarg.com/doc/view/1.0.30.0/linux/vkspec.chunked/ch31s02.html
639     mNativeCaps.maxElementIndex  = std::numeric_limits<GLuint>::max() - 1;
640     mNativeCaps.max3DTextureSize = rx::LimitToInt(limitsVk.maxImageDimension3D);
641     mNativeCaps.max2DTextureSize =
642         std::min(limitsVk.maxFramebufferWidth, limitsVk.maxImageDimension2D);
643     mNativeCaps.maxArrayTextureLayers = rx::LimitToInt(limitsVk.maxImageArrayLayers);
644     mNativeCaps.maxLODBias            = limitsVk.maxSamplerLodBias;
645     mNativeCaps.maxCubeMapTextureSize = rx::LimitToInt(limitsVk.maxImageDimensionCube);
646     mNativeCaps.maxRenderbufferSize =
647         std::min({limitsVk.maxImageDimension2D, limitsVk.maxFramebufferWidth,
648                   limitsVk.maxFramebufferHeight});
649     mNativeCaps.minAliasedPointSize = std::max(1.0f, limitsVk.pointSizeRange[0]);
650     mNativeCaps.maxAliasedPointSize = limitsVk.pointSizeRange[1];
651 
652     // Line width ranges and granularity
653     if (mPhysicalDeviceFeatures.wideLines && mFeatures.bresenhamLineRasterization.enabled)
654     {
655         mNativeCaps.minAliasedLineWidth = std::max(1.0f, limitsVk.lineWidthRange[0]);
656         mNativeCaps.maxAliasedLineWidth = limitsVk.lineWidthRange[1];
657     }
658     else
659     {
660         mNativeCaps.minAliasedLineWidth = 1.0f;
661         mNativeCaps.maxAliasedLineWidth = 1.0f;
662     }
663     mNativeCaps.minMultisampleLineWidth = mNativeCaps.minAliasedLineWidth;
664     mNativeCaps.maxMultisampleLineWidth = mNativeCaps.maxAliasedLineWidth;
665     mNativeCaps.lineWidthGranularity    = limitsVk.lineWidthGranularity;
666 
667     mNativeCaps.maxDrawBuffers =
668         std::min(limitsVk.maxColorAttachments, limitsVk.maxFragmentOutputAttachments);
669     mNativeCaps.maxFramebufferWidth  = rx::LimitToInt(limitsVk.maxFramebufferWidth);
670     mNativeCaps.maxFramebufferHeight = rx::LimitToInt(limitsVk.maxFramebufferHeight);
671     mNativeCaps.maxColorAttachments  = rx::LimitToInt(limitsVk.maxColorAttachments);
672     mNativeCaps.maxViewportWidth     = rx::LimitToInt(limitsVk.maxViewportDimensions[0]);
673     mNativeCaps.maxViewportHeight    = rx::LimitToInt(limitsVk.maxViewportDimensions[1]);
674     mNativeCaps.maxSampleMaskWords   = rx::LimitToInt(limitsVk.maxSampleMaskWords);
675     mNativeCaps.maxColorTextureSamples =
676         vk_gl::GetMaxSampleCount(limitsVk.sampledImageColorSampleCounts);
677     mNativeCaps.maxDepthTextureSamples =
678         vk_gl::GetMaxSampleCount(limitsVk.sampledImageDepthSampleCounts);
679     mNativeCaps.maxIntegerSamples =
680         vk_gl::GetMaxSampleCount(limitsVk.sampledImageIntegerSampleCounts);
681 
682     mNativeCaps.maxVertexAttributes     = rx::LimitToInt(limitsVk.maxVertexInputAttributes);
683     mNativeCaps.maxVertexAttribBindings = rx::LimitToInt(limitsVk.maxVertexInputBindings);
684     // Offset and stride are stored as uint16_t in PackedAttribDesc.
685     mNativeCaps.maxVertexAttribRelativeOffset =
686         std::min((1u << kAttributeOffsetMaxBits) - 1, limitsVk.maxVertexInputAttributeOffset);
687     mNativeCaps.maxVertexAttribStride =
688         std::min(static_cast<uint32_t>(std::numeric_limits<uint16_t>::max()),
689                  limitsVk.maxVertexInputBindingStride);
690 
691     mNativeCaps.maxElementsIndices  = std::numeric_limits<GLint>::max();
692     mNativeCaps.maxElementsVertices = std::numeric_limits<GLint>::max();
693 
694     // Looks like all floats are IEEE according to the docs here:
695     // https://www.khronos.org/registry/vulkan/specs/1.0-wsi_extensions/html/vkspec.html#spirvenv-precision-operation
696     mNativeCaps.vertexHighpFloat.setIEEEFloat();
697     mNativeCaps.vertexMediumpFloat.setIEEEHalfFloat();
698     mNativeCaps.vertexLowpFloat.setIEEEHalfFloat();
699     mNativeCaps.fragmentHighpFloat.setIEEEFloat();
700     mNativeCaps.fragmentMediumpFloat.setIEEEHalfFloat();
701     mNativeCaps.fragmentLowpFloat.setIEEEHalfFloat();
702 
703     // Vulkan doesn't provide such information.  We provide the spec-required minimum here.
704     mNativeCaps.vertexHighpInt.setTwosComplementInt(32);
705     mNativeCaps.vertexMediumpInt.setTwosComplementInt(16);
706     mNativeCaps.vertexLowpInt.setTwosComplementInt(16);
707     mNativeCaps.fragmentHighpInt.setTwosComplementInt(32);
708     mNativeCaps.fragmentMediumpInt.setTwosComplementInt(16);
709     mNativeCaps.fragmentLowpInt.setTwosComplementInt(16);
710 
711     // Compute shader limits.
712     mNativeCaps.maxComputeWorkGroupCount[0] = rx::LimitToInt(limitsVk.maxComputeWorkGroupCount[0]);
713     mNativeCaps.maxComputeWorkGroupCount[1] = rx::LimitToInt(limitsVk.maxComputeWorkGroupCount[1]);
714     mNativeCaps.maxComputeWorkGroupCount[2] = rx::LimitToInt(limitsVk.maxComputeWorkGroupCount[2]);
715     mNativeCaps.maxComputeWorkGroupSize[0]  = rx::LimitToInt(limitsVk.maxComputeWorkGroupSize[0]);
716     mNativeCaps.maxComputeWorkGroupSize[1]  = rx::LimitToInt(limitsVk.maxComputeWorkGroupSize[1]);
717     mNativeCaps.maxComputeWorkGroupSize[2]  = rx::LimitToInt(limitsVk.maxComputeWorkGroupSize[2]);
718     mNativeCaps.maxComputeWorkGroupInvocations =
719         rx::LimitToInt(limitsVk.maxComputeWorkGroupInvocations);
720     mNativeCaps.maxComputeSharedMemorySize = rx::LimitToInt(limitsVk.maxComputeSharedMemorySize);
721 
722     GLuint maxUniformBlockSize = limitsVk.maxUniformBufferRange;
723 
724     // Clamp the maxUniformBlockSize to 64KB (majority of devices support up to this size
725     // currently), on AMD the maxUniformBufferRange is near uint32_t max.
726     maxUniformBlockSize = std::min(0x10000u, maxUniformBlockSize);
727 
728     const GLuint maxUniformVectors = maxUniformBlockSize / (sizeof(GLfloat) * kComponentsPerVector);
729     const GLuint maxUniformComponents = maxUniformVectors * kComponentsPerVector;
730 
731     // Uniforms are implemented using a uniform buffer, so the max number of uniforms we can
732     // support is the max buffer range divided by the size of a single uniform (4X float).
733     mNativeCaps.maxVertexUniformVectors   = maxUniformVectors;
734     mNativeCaps.maxFragmentUniformVectors = maxUniformVectors;
735     for (gl::ShaderType shaderType : gl::AllShaderTypes())
736     {
737         mNativeCaps.maxShaderUniformComponents[shaderType] = maxUniformComponents;
738     }
739     mNativeCaps.maxUniformLocations = maxUniformVectors;
740 
741     const int32_t maxPerStageUniformBuffers = rx::LimitToInt(
742         limitsVk.maxPerStageDescriptorUniformBuffers - kReservedPerStageDefaultUniformBindingCount);
743     for (gl::ShaderType shaderType : gl::AllShaderTypes())
744     {
745         mNativeCaps.maxShaderUniformBlocks[shaderType] = maxPerStageUniformBuffers;
746     }
747 
748     // Reserved uniform buffer count depends on number of stages.  Vertex and fragment shaders are
749     // always supported.  The limit needs to be adjusted based on whether geometry and tessellation
750     // is supported.
751     int32_t maxCombinedUniformBuffers = rx::LimitToInt(limitsVk.maxDescriptorSetUniformBuffers) -
752                                         2 * kReservedPerStageDefaultUniformBindingCount;
753 
754     mNativeCaps.maxUniformBlockSize = maxUniformBlockSize;
755     mNativeCaps.uniformBufferOffsetAlignment =
756         static_cast<GLint>(limitsVk.minUniformBufferOffsetAlignment);
757 
758     // Note that Vulkan currently implements textures as combined image+samplers, so the limit is
759     // the minimum of supported samplers and sampled images.
760     const uint32_t maxPerStageTextures = std::min(limitsVk.maxPerStageDescriptorSamplers,
761                                                   limitsVk.maxPerStageDescriptorSampledImages);
762     const uint32_t maxCombinedTextures =
763         std::min(limitsVk.maxDescriptorSetSamplers, limitsVk.maxDescriptorSetSampledImages);
764     for (gl::ShaderType shaderType : gl::AllShaderTypes())
765     {
766         mNativeCaps.maxShaderTextureImageUnits[shaderType] = rx::LimitToInt(maxPerStageTextures);
767     }
768     mNativeCaps.maxCombinedTextureImageUnits = rx::LimitToInt(maxCombinedTextures);
769 
770     uint32_t maxPerStageStorageBuffers    = limitsVk.maxPerStageDescriptorStorageBuffers;
771     uint32_t maxVertexStageStorageBuffers = maxPerStageStorageBuffers;
772     uint32_t maxCombinedStorageBuffers    = limitsVk.maxDescriptorSetStorageBuffers;
773 
774     // A number of storage buffer slots are used in the vertex shader to emulate transform feedback.
775     // Note that Vulkan requires maxPerStageDescriptorStorageBuffers to be at least 4 (i.e. the same
776     // as gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS).
777     // TODO(syoussefi): This should be conditioned to transform feedback extension not being
778     // present.  http://anglebug.com/42261882.
779     // TODO(syoussefi): If geometry shader is supported, emulation will be done at that stage, and
780     // so the reserved storage buffers should be accounted in that stage.
781     // http://anglebug.com/42262271
782     static_assert(
783         gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS == 4,
784         "Limit to ES2.0 if supported SSBO count < supporting transform feedback buffer count");
785     if (mPhysicalDeviceFeatures.vertexPipelineStoresAndAtomics)
786     {
787         ASSERT(maxVertexStageStorageBuffers >= gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS);
788         maxVertexStageStorageBuffers -= gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS;
789         maxCombinedStorageBuffers -= gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS;
790 
791         // Cap the per-stage limit of the other stages to the combined limit, in case the combined
792         // limit is now lower than that.
793         maxPerStageStorageBuffers = std::min(maxPerStageStorageBuffers, maxCombinedStorageBuffers);
794     }
795 
796     // Reserve up to IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFERS storage buffers in the fragment and
797     // compute stages for atomic counters.  This is only possible if the number of per-stage storage
798     // buffers is greater than 4, which is the required GLES minimum for compute.
799     //
800     // For each stage, we'll either not support atomic counter buffers, or support exactly
801     // IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFERS.  This is due to restrictions in the shader
802     // translator where we can't know how many atomic counter buffers we would really need after
803     // linking so we can't create a packed buffer array.
804     //
805     // For the vertex stage, we could support atomic counters without storage buffers, but that's
806     // likely not very useful, so we use the same limit (4 + MAX_ATOMIC_COUNTER_BUFFERS) for the
807     // vertex stage to determine if we would want to add support for atomic counter buffers.
808     constexpr uint32_t kMinimumStorageBuffersForAtomicCounterBufferSupport =
809         gl::limits::kMinimumComputeStorageBuffers +
810         gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS;
811     uint32_t maxVertexStageAtomicCounterBuffers = 0;
812     uint32_t maxPerStageAtomicCounterBuffers    = 0;
813     uint32_t maxCombinedAtomicCounterBuffers    = 0;
814 
815     if (maxPerStageStorageBuffers >= kMinimumStorageBuffersForAtomicCounterBufferSupport)
816     {
817         maxPerStageAtomicCounterBuffers = gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS;
818         maxCombinedAtomicCounterBuffers = gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS;
819     }
820 
821     if (maxVertexStageStorageBuffers >= kMinimumStorageBuffersForAtomicCounterBufferSupport)
822     {
823         maxVertexStageAtomicCounterBuffers = gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS;
824     }
825 
826     maxVertexStageStorageBuffers -= maxVertexStageAtomicCounterBuffers;
827     maxPerStageStorageBuffers -= maxPerStageAtomicCounterBuffers;
828     maxCombinedStorageBuffers -= maxCombinedAtomicCounterBuffers;
829 
830     mNativeCaps.maxShaderStorageBlocks[gl::ShaderType::Vertex] =
831         mPhysicalDeviceFeatures.vertexPipelineStoresAndAtomics
832             ? rx::LimitToInt(maxVertexStageStorageBuffers)
833             : 0;
834     mNativeCaps.maxShaderStorageBlocks[gl::ShaderType::Fragment] =
835         mPhysicalDeviceFeatures.fragmentStoresAndAtomics ? rx::LimitToInt(maxPerStageStorageBuffers)
836                                                          : 0;
837     mNativeCaps.maxShaderStorageBlocks[gl::ShaderType::Compute] =
838         rx::LimitToInt(maxPerStageStorageBuffers);
839     mNativeCaps.maxCombinedShaderStorageBlocks = rx::LimitToInt(maxCombinedStorageBuffers);
840 
841     // Emulated as storage buffers, atomic counter buffers have the same size limit.  However, the
842     // limit is a signed integer and values above int max will end up as a negative size.  The
843     // storage buffer size is just capped to int unconditionally.
844     uint32_t maxStorageBufferRange = rx::LimitToInt(limitsVk.maxStorageBufferRange);
845     if (mFeatures.limitMaxStorageBufferSize.enabled)
846     {
847         constexpr uint32_t kStorageBufferLimit = 256 * 1024 * 1024;
848         maxStorageBufferRange = std::min(maxStorageBufferRange, kStorageBufferLimit);
849     }
850 
851     mNativeCaps.maxShaderStorageBufferBindings = rx::LimitToInt(maxCombinedStorageBuffers);
852     mNativeCaps.maxShaderStorageBlockSize      = maxStorageBufferRange;
853     mNativeCaps.shaderStorageBufferOffsetAlignment =
854         rx::LimitToInt(static_cast<uint32_t>(limitsVk.minStorageBufferOffsetAlignment));
855 
856     mNativeCaps.maxShaderAtomicCounterBuffers[gl::ShaderType::Vertex] =
857         mPhysicalDeviceFeatures.vertexPipelineStoresAndAtomics
858             ? rx::LimitToInt(maxVertexStageAtomicCounterBuffers)
859             : 0;
860     mNativeCaps.maxShaderAtomicCounterBuffers[gl::ShaderType::Fragment] =
861         mPhysicalDeviceFeatures.fragmentStoresAndAtomics
862             ? rx::LimitToInt(maxPerStageAtomicCounterBuffers)
863             : 0;
864     mNativeCaps.maxShaderAtomicCounterBuffers[gl::ShaderType::Compute] =
865         rx::LimitToInt(maxPerStageAtomicCounterBuffers);
866     mNativeCaps.maxCombinedAtomicCounterBuffers = rx::LimitToInt(maxCombinedAtomicCounterBuffers);
867 
868     mNativeCaps.maxAtomicCounterBufferBindings = rx::LimitToInt(maxCombinedAtomicCounterBuffers);
869     mNativeCaps.maxAtomicCounterBufferSize     = maxStorageBufferRange;
870 
871     // There is no particular limit to how many atomic counters there can be, other than the size of
872     // a storage buffer.  We nevertheless limit this to something reasonable (4096 arbitrarily).
873     const int32_t maxAtomicCounters =
874         std::min<int32_t>(4096, maxStorageBufferRange / sizeof(uint32_t));
875     for (gl::ShaderType shaderType : gl::AllShaderTypes())
876     {
877         mNativeCaps.maxShaderAtomicCounters[shaderType] = maxAtomicCounters;
878     }
879 
880     // Set maxShaderAtomicCounters to zero if atomic is not supported.
881     if (!mPhysicalDeviceFeatures.vertexPipelineStoresAndAtomics)
882     {
883         mNativeCaps.maxShaderAtomicCounters[gl::ShaderType::Vertex]         = 0;
884         mNativeCaps.maxShaderAtomicCounters[gl::ShaderType::Geometry]       = 0;
885         mNativeCaps.maxShaderAtomicCounters[gl::ShaderType::TessControl]    = 0;
886         mNativeCaps.maxShaderAtomicCounters[gl::ShaderType::TessEvaluation] = 0;
887     }
888     if (!mPhysicalDeviceFeatures.fragmentStoresAndAtomics)
889     {
890         mNativeCaps.maxShaderAtomicCounters[gl::ShaderType::Fragment] = 0;
891     }
892 
893     mNativeCaps.maxCombinedAtomicCounters = maxAtomicCounters;
894 
895     // GL Images correspond to Vulkan Storage Images.
896     const int32_t maxPerStageImages = rx::LimitToInt(limitsVk.maxPerStageDescriptorStorageImages);
897     const int32_t maxCombinedImages = rx::LimitToInt(limitsVk.maxDescriptorSetStorageImages);
898     const int32_t maxVertexPipelineImages =
899         mPhysicalDeviceFeatures.vertexPipelineStoresAndAtomics ? maxPerStageImages : 0;
900 
901     mNativeCaps.maxShaderImageUniforms[gl::ShaderType::Vertex]         = maxVertexPipelineImages;
902     mNativeCaps.maxShaderImageUniforms[gl::ShaderType::TessControl]    = maxVertexPipelineImages;
903     mNativeCaps.maxShaderImageUniforms[gl::ShaderType::TessEvaluation] = maxVertexPipelineImages;
904     mNativeCaps.maxShaderImageUniforms[gl::ShaderType::Geometry]       = maxVertexPipelineImages;
905     mNativeCaps.maxShaderImageUniforms[gl::ShaderType::Fragment] =
906         mPhysicalDeviceFeatures.fragmentStoresAndAtomics ? maxPerStageImages : 0;
907     mNativeCaps.maxShaderImageUniforms[gl::ShaderType::Compute] = maxPerStageImages;
908 
909     mNativeCaps.maxCombinedImageUniforms = maxCombinedImages;
910     mNativeCaps.maxImageUnits            = maxCombinedImages;
911 
912     mNativeCaps.minProgramTexelOffset         = limitsVk.minTexelOffset;
913     mNativeCaps.maxProgramTexelOffset         = limitsVk.maxTexelOffset;
914     mNativeCaps.minProgramTextureGatherOffset = limitsVk.minTexelGatherOffset;
915     mNativeCaps.maxProgramTextureGatherOffset = limitsVk.maxTexelGatherOffset;
916 
917     // There is no additional limit to the combined number of components.  We can have up to a
918     // maximum number of uniform buffers, each having the maximum number of components.  Note that
919     // this limit includes both components in and out of uniform buffers.
920     //
921     // This value is limited to INT_MAX to avoid overflow when queried from glGetIntegerv().
922     const uint64_t maxCombinedUniformComponents =
923         std::min<uint64_t>(static_cast<uint64_t>(maxPerStageUniformBuffers +
924                                                  kReservedPerStageDefaultUniformBindingCount) *
925                                maxUniformComponents,
926                            std::numeric_limits<GLint>::max());
927     for (gl::ShaderType shaderType : gl::AllShaderTypes())
928     {
929         mNativeCaps.maxCombinedShaderUniformComponents[shaderType] = maxCombinedUniformComponents;
930     }
931 
932     // Total number of resources available to the user are as many as Vulkan allows minus everything
933     // that ANGLE uses internally.  That is, one dynamic uniform buffer used per stage for default
934     // uniforms.  Additionally, Vulkan uses up to IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS + 1
935     // buffers for transform feedback (Note: +1 is for the "counter" buffer of
936     // VK_EXT_transform_feedback).
937     constexpr uint32_t kReservedPerStageUniformBufferCount = 1;
938     constexpr uint32_t kReservedPerStageBindingCount =
939         kReservedPerStageUniformBufferCount + gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS + 1;
940 
941     // Note: maxPerStageResources is required to be at least the sum of per stage UBOs, SSBOs etc
942     // which total a minimum of 44 resources, so no underflow is possible here.  Limit the total
943     // number of resources reported by Vulkan to 2 billion though to avoid seeing negative numbers
944     // in applications that take the value as signed int (including dEQP).
945     const uint32_t maxPerStageResources = limitsVk.maxPerStageResources;
946     mNativeCaps.maxCombinedShaderOutputResources =
947         rx::LimitToInt(maxPerStageResources - kReservedPerStageBindingCount);
948 
949     // Reserve 1 extra varying for transform feedback capture of gl_Position.
950     constexpr GLint kReservedVaryingComponentsForTransformFeedbackExtension = 4;
951 
952     GLint reservedVaryingComponentCount = 0;
953 
954     if (getFeatures().supportsTransformFeedbackExtension.enabled)
955     {
956         reservedVaryingComponentCount += kReservedVaryingComponentsForTransformFeedbackExtension;
957     }
958 
959     // The max varying vectors should not include gl_Position.
960     // The gles2.0 section 2.10 states that "gl_Position is not a varying variable and does
961     // not count against this limit.", but the Vulkan spec has no such mention in its Built-in
962     // vars section. It is implicit that we need to actually reserve it for Vulkan in that case.
963     //
964     // Note that this exception for gl_Position does not apply to MAX_VERTEX_OUTPUT_COMPONENTS and
965     // similar limits.
966     //
967     // Note also that the reserved components are for transform feedback capture only, so they don't
968     // apply to the _input_ component limit.
969     const GLint reservedVaryingVectorCount = reservedVaryingComponentCount / 4 + 1;
970 
971     const GLint maxVaryingCount =
972         std::min(limitsVk.maxVertexOutputComponents, limitsVk.maxFragmentInputComponents);
973     mNativeCaps.maxVaryingVectors =
974         rx::LimitToInt((maxVaryingCount / kComponentsPerVector) - reservedVaryingVectorCount);
975     mNativeCaps.maxVertexOutputComponents =
976         rx::LimitToInt(limitsVk.maxVertexOutputComponents) - reservedVaryingComponentCount;
977     mNativeCaps.maxFragmentInputComponents = rx::LimitToInt(limitsVk.maxFragmentInputComponents);
978 
979     mNativeCaps.maxTransformFeedbackInterleavedComponents =
980         gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS;
981     mNativeCaps.maxTransformFeedbackSeparateAttributes =
982         gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS;
983     mNativeCaps.maxTransformFeedbackSeparateComponents =
984         gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS;
985 
986     mNativeCaps.minProgramTexelOffset = limitsVk.minTexelOffset;
987     mNativeCaps.maxProgramTexelOffset = rx::LimitToInt(limitsVk.maxTexelOffset);
988 
989     const uint32_t sampleCounts =
990         limitsVk.framebufferColorSampleCounts & limitsVk.framebufferDepthSampleCounts &
991         limitsVk.framebufferStencilSampleCounts & vk_gl::kSupportedSampleCounts;
992 
993     mNativeCaps.maxSamples            = rx::LimitToInt(vk_gl::GetMaxSampleCount(sampleCounts));
994     mNativeCaps.maxFramebufferSamples = mNativeCaps.maxSamples;
995 
996     mNativeCaps.subPixelBits = limitsVk.subPixelPrecisionBits;
997 
998     if (getFeatures().supportsShaderFramebufferFetch.enabled)
999     {
1000         mNativeExtensions.shaderFramebufferFetchEXT = true;
1001         mNativeExtensions.shaderFramebufferFetchARM = true;
1002         // ANGLE correctly maps gl_LastFragColorARM to input attachment 0 and has no problem with
1003         // MRT.
1004         mNativeCaps.fragmentShaderFramebufferFetchMRT = true;
1005     }
1006 
1007     if (getFeatures().supportsShaderFramebufferFetchNonCoherent.enabled)
1008     {
1009         mNativeExtensions.shaderFramebufferFetchNonCoherentEXT = true;
1010     }
1011 
1012     // Enable Program Binary extension.
1013     mNativeExtensions.getProgramBinaryOES = true;
1014     mNativeCaps.programBinaryFormats.push_back(GL_PROGRAM_BINARY_ANGLE);
1015 
1016     // Enable Shader Binary extension.
1017     mNativeCaps.shaderBinaryFormats.push_back(GL_SHADER_BINARY_ANGLE);
1018 
1019     // Enable GL_NV_pixel_buffer_object extension.
1020     mNativeExtensions.pixelBufferObjectNV = true;
1021 
1022     // Enable GL_NV_fence extension.
1023     mNativeExtensions.fenceNV = true;
1024 
1025     // Enable GL_EXT_copy_image
1026     mNativeExtensions.copyImageEXT = true;
1027     mNativeExtensions.copyImageOES = true;
1028 
1029     // GL_EXT_clip_control
1030     mNativeExtensions.clipControlEXT = true;
1031 
1032     // GL_ANGLE_read_only_depth_stencil_feedback_loops
1033     mNativeExtensions.readOnlyDepthStencilFeedbackLoopsANGLE = true;
1034 
1035     // Enable GL_EXT_texture_buffer and OES variant.  Nearly all formats required for this extension
1036     // are also required to have the UNIFORM_TEXEL_BUFFER feature bit in Vulkan, except for
1037     // R32G32B32_SFLOAT/UINT/SINT which are optional.  For many formats, the STORAGE_TEXEL_BUFFER
1038     // feature is optional though.  This extension is exposed only if the formats specified in
1039     // EXT_texture_buffer support the necessary feature bits.
1040     //
1041     //  glTexBuffer page 187 table 8.18.
1042     //  glBindImageTexture page 216 table 8.24.
1043     //  https://www.khronos.org/registry/OpenGL/specs/es/3.2/es_spec_3.2.pdf.
1044     //  https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/chap43.html#features-required-format-support
1045     //  required image and texture access for texture buffer formats are
1046     //                         texture access                image access
1047     //    8-bit components, all required by vulkan.
1048     //
1049     //    GL_R8                        Y                           N
1050     //    GL_R8I                       Y                           N
1051     //    GL_R8UI                      Y                           N
1052     //    GL_RG8                       Y                           N
1053     //    GL_RG8I                      Y                           N
1054     //    GL_RG8UI                     Y                           N
1055     //    GL_RGBA8                     Y                           Y
1056     //    GL_RGBA8I                    Y                           Y
1057     //    GL_RGBA8UI                   Y                           Y
1058     //    GL_RGBA8_SNORM               N                           Y
1059     //
1060     //    16-bit components,  all required by vulkan.
1061     //
1062     //    GL_R16F                      Y                           N
1063     //    GL_R16I                      Y                           N
1064     //    GL_R16UI                     Y                           N
1065     //    GL_RG16F                     Y                           N
1066     //    GL_RG16I                     Y                           N
1067     //    GL_RG16UI                    Y                           N
1068     //    GL_RGBA16F                   Y                           Y
1069     //    GL_RGBA16I                   Y                           Y
1070     //    GL_RGBA16UI                  Y                           Y
1071     //
1072     //    32-bit components, except RGB32 all others required by vulkan.
1073     //                       RGB32 is emulated by ANGLE
1074     //
1075     //    GL_R32F                      Y                           Y
1076     //    GL_R32I                      Y                           Y
1077     //    GL_R32UI                     Y                           Y
1078     //    GL_RG32F                     Y                           N
1079     //    GL_RG32I                     Y                           N
1080     //    GL_RG32UI                    Y                           N
1081     //    GL_RGB32F                    Y                           N
1082     //    GL_RGB32I                    Y                           N
1083     //    GL_RGB32UI                   Y                           N
1084     //    GL_RGBA32F                   Y                           Y
1085     //    GL_RGBA32I                   Y                           Y
1086     //    GL_RGBA32UI                  Y                           Y
1087     mNativeExtensions.textureBufferOES = true;
1088     mNativeExtensions.textureBufferEXT = true;
1089     mNativeCaps.maxTextureBufferSize   = rx::LimitToInt(limitsVk.maxTexelBufferElements);
1090     mNativeCaps.textureBufferOffsetAlignment =
1091         rx::LimitToInt(limitsVk.minTexelBufferOffsetAlignment);
1092 
1093     // Atomic image operations in the vertex and fragment shaders require the
1094     // vertexPipelineStoresAndAtomics and fragmentStoresAndAtomics Vulkan features respectively.
1095     // If either of these features is not present, the number of image uniforms for that stage is
1096     // advertised as zero, so image atomic operations support can be agnostic of shader stages.
1097     //
1098     // GL_OES_shader_image_atomic requires that image atomic functions have support for r32i and
1099     // r32ui formats.  These formats have mandatory support for STORAGE_IMAGE_ATOMIC and
1100     // STORAGE_TEXEL_BUFFER_ATOMIC features in Vulkan.  Additionally, it requires that
1101     // imageAtomicExchange supports r32f, which is emulated in ANGLE transforming the shader to
1102     // expect r32ui instead.
1103     mNativeExtensions.shaderImageAtomicOES = true;
1104 
1105     // Tessellation shaders are required for ES 3.2.
1106     if (mPhysicalDeviceFeatures.tessellationShader)
1107     {
1108         constexpr uint32_t kReservedTessellationDefaultUniformBindingCount = 2;
1109 
1110         bool tessellationShaderEnabled =
1111             mFeatures.supportsTransformFeedbackExtension.enabled &&
1112             (mFeatures.supportsPrimitivesGeneratedQuery.enabled ||
1113              mFeatures.exposeNonConformantExtensionsAndVersions.enabled);
1114         mNativeExtensions.tessellationShaderEXT = tessellationShaderEnabled;
1115         mNativeExtensions.tessellationShaderOES = tessellationShaderEnabled;
1116         mNativeCaps.maxPatchVertices            = rx::LimitToInt(limitsVk.maxTessellationPatchSize);
1117         mNativeCaps.maxTessPatchComponents =
1118             rx::LimitToInt(limitsVk.maxTessellationControlPerPatchOutputComponents);
1119         mNativeCaps.maxTessGenLevel = rx::LimitToInt(limitsVk.maxTessellationGenerationLevel);
1120 
1121         mNativeCaps.maxTessControlInputComponents =
1122             rx::LimitToInt(limitsVk.maxTessellationControlPerVertexInputComponents);
1123         mNativeCaps.maxTessControlOutputComponents =
1124             rx::LimitToInt(limitsVk.maxTessellationControlPerVertexOutputComponents);
1125         mNativeCaps.maxTessControlTotalOutputComponents =
1126             rx::LimitToInt(limitsVk.maxTessellationControlTotalOutputComponents);
1127         mNativeCaps.maxTessEvaluationInputComponents =
1128             rx::LimitToInt(limitsVk.maxTessellationEvaluationInputComponents);
1129         mNativeCaps.maxTessEvaluationOutputComponents =
1130             rx::LimitToInt(limitsVk.maxTessellationEvaluationOutputComponents) -
1131             reservedVaryingComponentCount;
1132 
1133         // There is 1 default uniform binding used per tessellation stages.
1134         mNativeCaps.maxCombinedUniformBlocks = rx::LimitToInt(
1135             mNativeCaps.maxCombinedUniformBlocks + kReservedTessellationDefaultUniformBindingCount);
1136         mNativeCaps.maxUniformBufferBindings = rx::LimitToInt(
1137             mNativeCaps.maxUniformBufferBindings + kReservedTessellationDefaultUniformBindingCount);
1138 
1139         if (mPhysicalDeviceFeatures.vertexPipelineStoresAndAtomics)
1140         {
1141             mNativeCaps.maxShaderStorageBlocks[gl::ShaderType::TessControl] =
1142                 mNativeCaps.maxCombinedShaderOutputResources;
1143             mNativeCaps.maxShaderAtomicCounterBuffers[gl::ShaderType::TessControl] =
1144                 maxCombinedAtomicCounterBuffers;
1145 
1146             mNativeCaps.maxShaderStorageBlocks[gl::ShaderType::TessEvaluation] =
1147                 mNativeCaps.maxCombinedShaderOutputResources;
1148             mNativeCaps.maxShaderAtomicCounterBuffers[gl::ShaderType::TessEvaluation] =
1149                 maxCombinedAtomicCounterBuffers;
1150         }
1151 
1152         mNativeCaps.primitiveRestartForPatchesSupported =
1153             mPrimitiveTopologyListRestartFeatures.primitiveTopologyPatchListRestart == VK_TRUE;
1154 
1155         // Reserve a uniform buffer binding for each tessellation stage
1156         if (tessellationShaderEnabled)
1157         {
1158             maxCombinedUniformBuffers -= 2 * kReservedPerStageDefaultUniformBindingCount;
1159         }
1160     }
1161 
1162     // Geometry shaders are required for ES 3.2.
1163     if (mPhysicalDeviceFeatures.geometryShader)
1164     {
1165         bool geometryShaderEnabled = mFeatures.supportsTransformFeedbackExtension.enabled &&
1166                                      (mFeatures.supportsPrimitivesGeneratedQuery.enabled ||
1167                                       mFeatures.exposeNonConformantExtensionsAndVersions.enabled);
1168         mNativeExtensions.geometryShaderEXT = geometryShaderEnabled;
1169         mNativeExtensions.geometryShaderOES = geometryShaderEnabled;
1170         mNativeCaps.maxFramebufferLayers    = rx::LimitToInt(limitsVk.maxFramebufferLayers);
1171 
1172         // Use "undefined" which means APP would have to set gl_Layer identically.
1173         mNativeCaps.layerProvokingVertex = GL_UNDEFINED_VERTEX_EXT;
1174 
1175         mNativeCaps.maxGeometryInputComponents =
1176             rx::LimitToInt(limitsVk.maxGeometryInputComponents);
1177         mNativeCaps.maxGeometryOutputComponents =
1178             rx::LimitToInt(limitsVk.maxGeometryOutputComponents) - reservedVaryingComponentCount;
1179         mNativeCaps.maxGeometryOutputVertices = rx::LimitToInt(limitsVk.maxGeometryOutputVertices);
1180         mNativeCaps.maxGeometryTotalOutputComponents =
1181             rx::LimitToInt(limitsVk.maxGeometryTotalOutputComponents);
1182         if (mPhysicalDeviceFeatures.vertexPipelineStoresAndAtomics)
1183         {
1184             mNativeCaps.maxShaderStorageBlocks[gl::ShaderType::Geometry] =
1185                 mNativeCaps.maxCombinedShaderOutputResources;
1186             mNativeCaps.maxShaderAtomicCounterBuffers[gl::ShaderType::Geometry] =
1187                 maxCombinedAtomicCounterBuffers;
1188         }
1189         mNativeCaps.maxGeometryShaderInvocations =
1190             rx::LimitToInt(limitsVk.maxGeometryShaderInvocations);
1191 
1192         // Cap maxGeometryInputComponents by maxVertexOutputComponents and
1193         // maxTessellationEvaluationOutputComponents; there can't be more inputs than there are
1194         // outputs in the previous stage.
1195         mNativeCaps.maxGeometryInputComponents =
1196             std::min(mNativeCaps.maxGeometryInputComponents,
1197                      std::min(mNativeCaps.maxVertexOutputComponents,
1198                               mNativeCaps.maxTessEvaluationOutputComponents));
1199 
1200         // Reserve a uniform buffer binding for the geometry stage
1201         if (geometryShaderEnabled)
1202         {
1203             maxCombinedUniformBuffers -= kReservedPerStageDefaultUniformBindingCount;
1204         }
1205     }
1206 
1207     mNativeCaps.maxCombinedUniformBlocks = maxCombinedUniformBuffers;
1208     mNativeCaps.maxUniformBufferBindings = maxCombinedUniformBuffers;
1209 
1210     // GL_APPLE_clip_distance / GL_EXT_clip_cull_distance / GL_ANGLE_clip_cull_distance
1211     // From the EXT_clip_cull_distance extension spec:
1212     //
1213     // > Modify Section 7.2, "Built-In Constants" (p. 126)
1214     // >
1215     // > const mediump int gl_MaxClipDistances = 8;
1216     // > const mediump int gl_MaxCullDistances = 8;
1217     // > const mediump int gl_MaxCombinedClipAndCullDistances = 8;
1218     constexpr uint32_t kMaxClipDistancePerSpec                = 8;
1219     constexpr uint32_t kMaxCullDistancePerSpec                = 8;
1220     constexpr uint32_t kMaxCombinedClipAndCullDistancePerSpec = 8;
1221 
1222     // TODO: http://anglebug.com/42264006
1223     // After implementing EXT_geometry_shader, EXT_clip_cull_distance should be additionally
1224     // implemented to support the geometry shader. Until then, EXT_clip_cull_distance is enabled
1225     // only in the experimental cases.
1226     if (mPhysicalDeviceFeatures.shaderClipDistance &&
1227         limitsVk.maxClipDistances >= kMaxClipDistancePerSpec)
1228     {
1229         mNativeExtensions.clipDistanceAPPLE     = true;
1230         mNativeExtensions.clipCullDistanceANGLE = true;
1231         mNativeCaps.maxClipDistances            = limitsVk.maxClipDistances;
1232 
1233         if (mPhysicalDeviceFeatures.shaderCullDistance &&
1234             limitsVk.maxCullDistances >= kMaxCullDistancePerSpec &&
1235             limitsVk.maxCombinedClipAndCullDistances >= kMaxCombinedClipAndCullDistancePerSpec)
1236         {
1237             mNativeExtensions.clipCullDistanceEXT       = true;
1238             mNativeCaps.maxCullDistances                = limitsVk.maxCullDistances;
1239             mNativeCaps.maxCombinedClipAndCullDistances = limitsVk.maxCombinedClipAndCullDistances;
1240         }
1241     }
1242 
1243     // GL_EXT_blend_func_extended
1244     mNativeExtensions.blendFuncExtendedEXT = mPhysicalDeviceFeatures.dualSrcBlend == VK_TRUE;
1245     mNativeCaps.maxDualSourceDrawBuffers   = rx::LimitToInt(limitsVk.maxFragmentDualSrcAttachments);
1246 
1247     // GL_ANGLE_relaxed_vertex_attribute_type
1248     mNativeExtensions.relaxedVertexAttributeTypeANGLE = true;
1249 
1250     // GL_OVR_multiview*.  Bresenham line emulation does not work with multiview.  There's no
1251     // limitation in Vulkan to restrict an application to multiview 1.
1252     mNativeExtensions.multiviewOVR =
1253         mFeatures.supportsMultiview.enabled && mFeatures.bresenhamLineRasterization.enabled;
1254     mNativeExtensions.multiview2OVR = mNativeExtensions.multiviewOVR;
1255     // Max views affects the number of Vulkan queries per GL query in render pass, and
1256     // SecondaryCommandBuffer's ResetQueryPoolParams would like this to have an upper limit (of
1257     // 255).
1258     mNativeCaps.maxViews = std::min(mMultiviewProperties.maxMultiviewViewCount, 8u);
1259 
1260     // GL_ANGLE_yuv_internal_format
1261     mNativeExtensions.yuvInternalFormatANGLE =
1262         getFeatures().supportsYUVSamplerConversion.enabled && vk::CanSupportYuvInternalFormat(this);
1263 
1264     // GL_EXT_primitive_bounding_box
1265     mNativeExtensions.primitiveBoundingBoxEXT = true;
1266 
1267     // GL_OES_primitive_bounding_box
1268     mNativeExtensions.primitiveBoundingBoxOES = true;
1269 
1270     // GL_EXT_protected_textures
1271     mNativeExtensions.protectedTexturesEXT = mFeatures.supportsProtectedMemory.enabled;
1272 
1273     // GL_ANGLE_vulkan_image
1274     mNativeExtensions.vulkanImageANGLE = true;
1275 
1276     // GL_ANGLE_texture_usage
1277     mNativeExtensions.textureUsageANGLE = true;
1278 
1279     // GL_KHR_parallel_shader_compile
1280     mNativeExtensions.parallelShaderCompileKHR = mFeatures.enableParallelCompileAndLink.enabled;
1281 
1282     // GL_NV_read_depth, GL_NV_read_depth_stencil, GL_NV_read_stencil
1283     mNativeExtensions.readDepthNV        = true;
1284     mNativeExtensions.readDepthStencilNV = true;
1285     mNativeExtensions.readStencilNV      = true;
1286 
1287     // GL_EXT_clear_texture
1288     mNativeExtensions.clearTextureEXT = true;
1289 
1290     // GL_QCOM_shading_rate
1291     mNativeExtensions.shadingRateQCOM = mFeatures.supportsFragmentShadingRate.enabled;
1292 
1293     // GL_QCOM_framebuffer_foveated
1294     mNativeExtensions.framebufferFoveatedQCOM = mFeatures.supportsFoveatedRendering.enabled;
1295     // GL_QCOM_texture_foveated
1296     mNativeExtensions.textureFoveatedQCOM = mFeatures.supportsFoveatedRendering.enabled;
1297 
1298     // GL_ANGLE_shader_pixel_local_storage
1299     mNativeExtensions.shaderPixelLocalStorageANGLE = true;
1300     if (getFeatures().supportsShaderFramebufferFetch.enabled && mIsColorFramebufferFetchCoherent)
1301     {
1302         mNativeExtensions.shaderPixelLocalStorageCoherentANGLE = true;
1303         mNativePLSOptions.type             = ShPixelLocalStorageType::FramebufferFetch;
1304         mNativePLSOptions.fragmentSyncType = ShFragmentSynchronizationType::Automatic;
1305     }
1306     else if (getFeatures().supportsFragmentShaderPixelInterlock.enabled)
1307     {
1308         // Use shader images with VK_EXT_fragment_shader_interlock, instead of attachments, if
1309         // they're our only option to be coherent.
1310         mNativeExtensions.shaderPixelLocalStorageCoherentANGLE = true;
1311         mNativePLSOptions.type = ShPixelLocalStorageType::ImageLoadStore;
1312         // GL_ARB_fragment_shader_interlock compiles to SPV_EXT_fragment_shader_interlock.
1313         mNativePLSOptions.fragmentSyncType =
1314             ShFragmentSynchronizationType::FragmentShaderInterlock_ARB_GL;
1315         mNativePLSOptions.supportsNativeRGBA8ImageFormats = true;
1316     }
1317     else
1318     {
1319         mNativePLSOptions.type = ShPixelLocalStorageType::FramebufferFetch;
1320         ASSERT(mNativePLSOptions.fragmentSyncType == ShFragmentSynchronizationType::NotSupported);
1321     }
1322 
1323     // If framebuffer fetch is to be enabled/used, cap maxColorAttachments/maxDrawBuffers to
1324     // maxPerStageDescriptorInputAttachments.  Note that 4 is the minimum required value for
1325     // maxColorAttachments and maxDrawBuffers in GL, and also happens to be the minimum required
1326     // value for maxPerStageDescriptorInputAttachments in Vulkan.  This means that capping the color
1327     // attachment count to maxPerStageDescriptorInputAttachments can never lead to an invalid value.
1328     const bool hasMRTFramebufferFetch =
1329         mNativeExtensions.shaderFramebufferFetchEXT ||
1330         mNativeExtensions.shaderFramebufferFetchNonCoherentEXT ||
1331         mNativePLSOptions.type == ShPixelLocalStorageType::FramebufferFetch;
1332     if (hasMRTFramebufferFetch)
1333     {
1334         mNativeCaps.maxColorAttachments = std::min<uint32_t>(
1335             mNativeCaps.maxColorAttachments, limitsVk.maxPerStageDescriptorInputAttachments);
1336         mNativeCaps.maxDrawBuffers = std::min<uint32_t>(
1337             mNativeCaps.maxDrawBuffers, limitsVk.maxPerStageDescriptorInputAttachments);
1338 
1339         // Make sure no more than the allowed input attachments bindings are used by descriptor set
1340         // layouts.  This number matches the number of color attachments because of framebuffer
1341         // fetch, and that limit is later capped to IMPLEMENTATION_MAX_DRAW_BUFFERS in Context.cpp.
1342         mMaxColorInputAttachmentCount = std::min<uint32_t>(mNativeCaps.maxColorAttachments,
1343                                                            gl::IMPLEMENTATION_MAX_DRAW_BUFFERS);
1344     }
1345     else if (mFeatures.emulateAdvancedBlendEquations.enabled)
1346     {
1347         // ANGLE may also use framebuffer fetch to emulate KHR_blend_equation_advanced, which needs
1348         // a single input attachment.
1349         mMaxColorInputAttachmentCount = 1;
1350     }
1351     else
1352     {
1353         // mMaxColorInputAttachmentCount is left as 0 to catch bugs if a future user of framebuffer
1354         // fetch functionality does not update the logic in this if/else chain.
1355     }
1356 
1357     // Enable the ARM_shader_framebuffer_fetch_depth_stencil extension only if the number of input
1358     // descriptor exceeds the color attachment count by at least 2 (for depth and stencil), or if
1359     // the number of color attachments can be reduced to accomodate for the 2 depth/stencil images.
1360     if (mFeatures.supportsShaderFramebufferFetchDepthStencil.enabled)
1361     {
1362         const uint32_t maxColorAttachmentsWithDepthStencilInput = std::min<uint32_t>(
1363             mNativeCaps.maxColorAttachments, limitsVk.maxPerStageDescriptorInputAttachments - 2);
1364         const uint32_t maxDrawBuffersWithDepthStencilInput = std::min<uint32_t>(
1365             mNativeCaps.maxDrawBuffers, limitsVk.maxPerStageDescriptorInputAttachments - 2);
1366 
1367         // As long as the minimum required color attachments (4) is satisfied, the extension can be
1368         // exposed.
1369         if (maxColorAttachmentsWithDepthStencilInput >= 4 &&
1370             maxDrawBuffersWithDepthStencilInput >= 4)
1371         {
1372             mNativeExtensions.shaderFramebufferFetchDepthStencilARM = true;
1373             mNativeCaps.maxColorAttachments = maxColorAttachmentsWithDepthStencilInput;
1374             mNativeCaps.maxDrawBuffers      = maxDrawBuffersWithDepthStencilInput;
1375             mMaxColorInputAttachmentCount =
1376                 std::min<uint32_t>(mMaxColorInputAttachmentCount, mNativeCaps.maxColorAttachments);
1377         }
1378     }
1379 
1380     mNativeExtensions.logicOpANGLE = mPhysicalDeviceFeatures.logicOp == VK_TRUE;
1381 
1382     mNativeExtensions.YUVTargetEXT = mFeatures.supportsExternalFormatResolve.enabled;
1383 
1384     mNativeExtensions.textureStorageCompressionEXT =
1385         mFeatures.supportsImageCompressionControl.enabled;
1386     mNativeExtensions.EGLImageStorageCompressionEXT =
1387         mFeatures.supportsImageCompressionControl.enabled;
1388 
1389     // Log any missing extensions required for GLES 3.2.
1390     LogMissingExtensionsForGLES32(mNativeExtensions);
1391 }
1392 
CanSupportGLES32(const gl::Extensions & nativeExtensions)1393 bool CanSupportGLES32(const gl::Extensions &nativeExtensions)
1394 {
1395     std::vector<bool> requiredExtensions = GetRequiredGLES32ExtensionList(nativeExtensions);
1396     for (uint32_t index = 0; index < requiredExtensions.size(); index++)
1397     {
1398         if (!requiredExtensions[index])
1399         {
1400             return false;
1401         }
1402     }
1403 
1404     return true;
1405 }
1406 
CanSupportTransformFeedbackExtension(const VkPhysicalDeviceTransformFeedbackFeaturesEXT & xfbFeatures)1407 bool CanSupportTransformFeedbackExtension(
1408     const VkPhysicalDeviceTransformFeedbackFeaturesEXT &xfbFeatures)
1409 {
1410     return xfbFeatures.transformFeedback == VK_TRUE;
1411 }
1412 
CanSupportTransformFeedbackEmulation(const VkPhysicalDeviceFeatures & features)1413 bool CanSupportTransformFeedbackEmulation(const VkPhysicalDeviceFeatures &features)
1414 {
1415     return features.vertexPipelineStoresAndAtomics == VK_TRUE;
1416 }
1417 
1418 }  // namespace vk
1419 
1420 namespace egl_vk
1421 {
1422 
1423 namespace
1424 {
1425 
ComputeMaximumPBufferPixels(const VkPhysicalDeviceProperties & physicalDeviceProperties)1426 EGLint ComputeMaximumPBufferPixels(const VkPhysicalDeviceProperties &physicalDeviceProperties)
1427 {
1428     // EGLints are signed 32-bit integers, it's fairly easy to overflow them, especially since
1429     // Vulkan's minimum guaranteed VkImageFormatProperties::maxResourceSize is 2^31 bytes.
1430     constexpr uint64_t kMaxValueForEGLint =
1431         static_cast<uint64_t>(std::numeric_limits<EGLint>::max());
1432 
1433     // TODO(geofflang): Compute the maximum size of a pbuffer by using the maxResourceSize result
1434     // from vkGetPhysicalDeviceImageFormatProperties for both the color and depth stencil format and
1435     // the exact image creation parameters that would be used to create the pbuffer. Because it is
1436     // always safe to return out-of-memory errors on pbuffer allocation, it's fine to simply return
1437     // the number of pixels in a max width by max height pbuffer for now.
1438     // http://anglebug.com/42261335
1439 
1440     // Storing the result of squaring a 32-bit unsigned int in a 64-bit unsigned int is safe.
1441     static_assert(std::is_same<decltype(physicalDeviceProperties.limits.maxImageDimension2D),
1442                                uint32_t>::value,
1443                   "physicalDeviceProperties.limits.maxImageDimension2D expected to be a uint32_t.");
1444     const uint64_t maxDimensionsSquared =
1445         static_cast<uint64_t>(physicalDeviceProperties.limits.maxImageDimension2D) *
1446         static_cast<uint64_t>(physicalDeviceProperties.limits.maxImageDimension2D);
1447 
1448     return static_cast<EGLint>(std::min(maxDimensionsSquared, kMaxValueForEGLint));
1449 }
1450 
GetMatchFormat(GLenum internalFormat)1451 EGLint GetMatchFormat(GLenum internalFormat)
1452 {
1453     // Lock Surface match format
1454     switch (internalFormat)
1455     {
1456         case GL_RGBA8:
1457             return EGL_FORMAT_RGBA_8888_KHR;
1458         case GL_BGRA8_EXT:
1459             return EGL_FORMAT_RGBA_8888_EXACT_KHR;
1460         case GL_RGB565:
1461             return EGL_FORMAT_RGB_565_EXACT_KHR;
1462         default:
1463             return EGL_NONE;
1464     }
1465 }
1466 
1467 // Generates a basic config for a combination of color format, depth stencil format and sample
1468 // count.
GenerateDefaultConfig(DisplayVk * display,const gl::InternalFormat & colorFormat,const gl::InternalFormat & depthStencilFormat,EGLint sampleCount)1469 egl::Config GenerateDefaultConfig(DisplayVk *display,
1470                                   const gl::InternalFormat &colorFormat,
1471                                   const gl::InternalFormat &depthStencilFormat,
1472                                   EGLint sampleCount)
1473 {
1474     const vk::Renderer *renderer = display->getRenderer();
1475 
1476     const VkPhysicalDeviceProperties &physicalDeviceProperties =
1477         renderer->getPhysicalDeviceProperties();
1478     gl::Version maxSupportedESVersion = renderer->getMaxSupportedESVersion();
1479 
1480     // ES3 features are required to emulate ES1
1481     EGLint es1Support = (maxSupportedESVersion.major >= 3 ? EGL_OPENGL_ES_BIT : 0);
1482     EGLint es2Support = (maxSupportedESVersion.major >= 2 ? EGL_OPENGL_ES2_BIT : 0);
1483     EGLint es3Support = (maxSupportedESVersion.major >= 3 ? EGL_OPENGL_ES3_BIT : 0);
1484 
1485     egl::Config config;
1486 
1487     config.renderTargetFormat = colorFormat.internalFormat;
1488     config.depthStencilFormat = depthStencilFormat.internalFormat;
1489     config.bufferSize         = colorFormat.getEGLConfigBufferSize();
1490     config.redSize            = colorFormat.redBits;
1491     config.greenSize          = colorFormat.greenBits;
1492     config.blueSize           = colorFormat.blueBits;
1493     config.alphaSize          = colorFormat.alphaBits;
1494     config.alphaMaskSize      = 0;
1495     config.bindToTextureRGB   = colorFormat.format == GL_RGB;
1496     config.bindToTextureRGBA  = colorFormat.format == GL_RGBA || colorFormat.format == GL_BGRA_EXT;
1497     config.colorBufferType    = EGL_RGB_BUFFER;
1498     config.configCaveat       = GetConfigCaveat(colorFormat.internalFormat);
1499     config.conformant         = es1Support | es2Support | es3Support;
1500     config.depthSize          = depthStencilFormat.depthBits;
1501     config.stencilSize        = depthStencilFormat.stencilBits;
1502     config.level              = 0;
1503     config.matchNativePixmap  = EGL_NONE;
1504     config.maxPBufferWidth    = physicalDeviceProperties.limits.maxImageDimension2D;
1505     config.maxPBufferHeight   = physicalDeviceProperties.limits.maxImageDimension2D;
1506     config.maxPBufferPixels   = ComputeMaximumPBufferPixels(physicalDeviceProperties);
1507     config.maxSwapInterval    = 1;
1508     config.minSwapInterval    = 0;
1509     config.nativeRenderable   = EGL_TRUE;
1510     config.nativeVisualID     = static_cast<EGLint>(GetNativeVisualID(colorFormat));
1511     config.nativeVisualType   = EGL_NONE;
1512     config.renderableType     = es1Support | es2Support | es3Support;
1513     config.sampleBuffers      = (sampleCount > 0) ? 1 : 0;
1514     config.samples            = sampleCount;
1515     config.surfaceType        = EGL_WINDOW_BIT | EGL_PBUFFER_BIT;
1516     if (display->getExtensions().mutableRenderBufferKHR)
1517     {
1518         config.surfaceType |= EGL_MUTABLE_RENDER_BUFFER_BIT_KHR;
1519     }
1520     // Vulkan surfaces use a different origin than OpenGL, always prefer to be flipped vertically if
1521     // possible.
1522     config.optimalOrientation    = EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE;
1523     config.transparentType       = EGL_NONE;
1524     config.transparentRedValue   = 0;
1525     config.transparentGreenValue = 0;
1526     config.transparentBlueValue  = 0;
1527     config.colorComponentType =
1528         gl_egl::GLComponentTypeToEGLColorComponentType(colorFormat.componentType);
1529     // LockSurface matching
1530     config.matchFormat = GetMatchFormat(colorFormat.internalFormat);
1531     if (config.matchFormat != EGL_NONE)
1532     {
1533         config.surfaceType |= EGL_LOCK_SURFACE_BIT_KHR;
1534     }
1535 
1536     // Vulkan always supports off-screen rendering.  Check the config with display to see if it can
1537     // also have window support.  If not, the following call should automatically remove
1538     // EGL_WINDOW_BIT.
1539     display->checkConfigSupport(&config);
1540 
1541     return config;
1542 }
1543 
1544 }  // anonymous namespace
1545 
GenerateConfigs(const GLenum * colorFormats,size_t colorFormatsCount,const GLenum * depthStencilFormats,size_t depthStencilFormatCount,DisplayVk * display)1546 egl::ConfigSet GenerateConfigs(const GLenum *colorFormats,
1547                                size_t colorFormatsCount,
1548                                const GLenum *depthStencilFormats,
1549                                size_t depthStencilFormatCount,
1550                                DisplayVk *display)
1551 {
1552     ASSERT(colorFormatsCount > 0);
1553     ASSERT(display != nullptr);
1554 
1555     gl::SupportedSampleSet colorSampleCounts;
1556     gl::SupportedSampleSet depthStencilSampleCounts;
1557     gl::SupportedSampleSet sampleCounts;
1558 
1559     const VkPhysicalDeviceLimits &limits =
1560         display->getRenderer()->getPhysicalDeviceProperties().limits;
1561     const uint32_t depthStencilSampleCountsLimit = limits.framebufferDepthSampleCounts &
1562                                                    limits.framebufferStencilSampleCounts &
1563                                                    vk_gl::kSupportedSampleCounts;
1564 
1565     vk_gl::AddSampleCounts(limits.framebufferColorSampleCounts & vk_gl::kSupportedSampleCounts,
1566                            &colorSampleCounts);
1567     vk_gl::AddSampleCounts(depthStencilSampleCountsLimit, &depthStencilSampleCounts);
1568 
1569     // Always support 0 samples
1570     colorSampleCounts.insert(0);
1571     depthStencilSampleCounts.insert(0);
1572 
1573     std::set_intersection(colorSampleCounts.begin(), colorSampleCounts.end(),
1574                           depthStencilSampleCounts.begin(), depthStencilSampleCounts.end(),
1575                           std::inserter(sampleCounts, sampleCounts.begin()));
1576 
1577     egl::ConfigSet configSet;
1578 
1579     for (size_t colorFormatIdx = 0; colorFormatIdx < colorFormatsCount; colorFormatIdx++)
1580     {
1581         const gl::InternalFormat &colorFormatInfo =
1582             gl::GetSizedInternalFormatInfo(colorFormats[colorFormatIdx]);
1583         ASSERT(colorFormatInfo.sized);
1584 
1585         for (size_t depthStencilFormatIdx = 0; depthStencilFormatIdx < depthStencilFormatCount;
1586              depthStencilFormatIdx++)
1587         {
1588             const gl::InternalFormat &depthStencilFormatInfo =
1589                 gl::GetSizedInternalFormatInfo(depthStencilFormats[depthStencilFormatIdx]);
1590             ASSERT(depthStencilFormats[depthStencilFormatIdx] == GL_NONE ||
1591                    depthStencilFormatInfo.sized);
1592 
1593             const gl::SupportedSampleSet *configSampleCounts = &sampleCounts;
1594             // If there is no depth/stencil buffer, use the color samples set.
1595             if (depthStencilFormats[depthStencilFormatIdx] == GL_NONE)
1596             {
1597                 configSampleCounts = &colorSampleCounts;
1598             }
1599             // If there is no color buffer, use the depth/stencil samples set.
1600             else if (colorFormats[colorFormatIdx] == GL_NONE)
1601             {
1602                 configSampleCounts = &depthStencilSampleCounts;
1603             }
1604 
1605             for (EGLint sampleCount : *configSampleCounts)
1606             {
1607                 egl::Config config = GenerateDefaultConfig(display, colorFormatInfo,
1608                                                            depthStencilFormatInfo, sampleCount);
1609                 configSet.add(config);
1610             }
1611         }
1612     }
1613 
1614     return configSet;
1615 }
1616 
1617 }  // namespace egl_vk
1618 
1619 }  // namespace rx
1620