• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     mNativeLimitations.multidrawEmulated   = false;
419 
420     // Enable EXT_base_instance
421     mNativeExtensions.baseInstanceEXT       = true;
422     mNativeLimitations.baseInstanceEmulated = false;
423 
424     // Enable ANGLE_base_vertex_base_instance
425     mNativeExtensions.baseVertexBaseInstanceANGLE              = true;
426     mNativeExtensions.baseVertexBaseInstanceShaderBuiltinANGLE = true;
427 
428     // Enable OES/EXT_draw_elements_base_vertex
429     mNativeExtensions.drawElementsBaseVertexOES = true;
430     mNativeExtensions.drawElementsBaseVertexEXT = true;
431 
432     // Enable EXT_blend_minmax
433     mNativeExtensions.blendMinmaxEXT = true;
434 
435     // Enable OES/EXT_draw_buffers_indexed
436     mNativeExtensions.drawBuffersIndexedOES = mPhysicalDeviceFeatures.independentBlend == VK_TRUE;
437     mNativeExtensions.drawBuffersIndexedEXT = mNativeExtensions.drawBuffersIndexedOES;
438 
439     mNativeExtensions.EGLImageOES                  = true;
440     mNativeExtensions.EGLImageExternalOES          = true;
441     mNativeExtensions.EGLImageExternalWrapModesEXT = true;
442     mNativeExtensions.EGLImageExternalEssl3OES     = true;
443     mNativeExtensions.EGLImageArrayEXT             = true;
444     mNativeExtensions.EGLImageStorageEXT           = true;
445     mNativeExtensions.memoryObjectEXT              = true;
446     mNativeExtensions.memoryObjectFdEXT            = getFeatures().supportsExternalMemoryFd.enabled;
447     mNativeExtensions.memoryObjectFlagsANGLE       = true;
448     mNativeExtensions.memoryObjectFuchsiaANGLE =
449         getFeatures().supportsExternalMemoryFuchsia.enabled;
450 
451     mNativeExtensions.semaphoreEXT   = true;
452     mNativeExtensions.semaphoreFdEXT = getFeatures().supportsExternalSemaphoreFd.enabled;
453     mNativeExtensions.semaphoreFuchsiaANGLE =
454         getFeatures().supportsExternalSemaphoreFuchsia.enabled;
455 
456     mNativeExtensions.vertexHalfFloatOES = true;
457 
458     // Enabled in HW if VK_EXT_vertex_attribute_divisor available, otherwise emulated
459     mNativeExtensions.instancedArraysANGLE = true;
460     mNativeExtensions.instancedArraysEXT   = true;
461 
462     // Only expose robust buffer access if the physical device supports it.
463     mNativeExtensions.robustBufferAccessBehaviorKHR =
464         (mPhysicalDeviceFeatures.robustBufferAccess == VK_TRUE);
465 
466     mNativeExtensions.EGLSyncOES = true;
467 
468     mNativeExtensions.vertexType1010102OES = true;
469 
470     // Occlusion queries are natively supported in Vulkan.  ANGLE only issues this query inside a
471     // render pass, so there is no dependency to `inheritedQueries`.
472     mNativeExtensions.occlusionQueryBooleanEXT = true;
473 
474     // From the Vulkan specs:
475     // > The number of valid bits in a timestamp value is determined by the
476     // > VkQueueFamilyProperties::timestampValidBits property of the queue on which the timestamp is
477     // > written. Timestamps are supported on any queue which reports a non-zero value for
478     // > timestampValidBits via vkGetPhysicalDeviceQueueFamilyProperties.
479     //
480     // This query is applicable to render passes, but the `inheritedQueries` feature may not be
481     // present.  The extension is not exposed in that case.
482     // We use secondary command buffers almost everywhere and they require a feature to be
483     // able to execute in the presence of queries.  As a result, we won't support timestamp queries
484     // unless that feature is available.
485     if (vk::OutsideRenderPassCommandBuffer::SupportsQueries(mPhysicalDeviceFeatures) &&
486         vk::RenderPassCommandBuffer::SupportsQueries(mPhysicalDeviceFeatures))
487     {
488         const uint32_t timestampValidBits =
489             vk::GetTimestampValidBits(mQueueFamilyProperties, mCurrentQueueFamilyIndex);
490 
491         mNativeExtensions.disjointTimerQueryEXT = timestampValidBits > 0;
492         mNativeCaps.queryCounterBitsTimeElapsed = timestampValidBits;
493         mNativeCaps.queryCounterBitsTimestamp   = timestampValidBits;
494     }
495 
496     mNativeExtensions.textureFilterAnisotropicEXT =
497         mPhysicalDeviceFeatures.samplerAnisotropy && limitsVk.maxSamplerAnisotropy > 1.0f;
498     mNativeCaps.maxTextureAnisotropy =
499         mNativeExtensions.textureFilterAnisotropicEXT ? limitsVk.maxSamplerAnisotropy : 0.0f;
500 
501     // Vulkan natively supports non power-of-two textures
502     mNativeExtensions.textureNpotOES = true;
503 
504     mNativeExtensions.texture3DOES = true;
505 
506     // Vulkan natively supports standard derivatives
507     mNativeExtensions.standardDerivativesOES = true;
508 
509     // Vulkan natively supports texture LOD
510     mNativeExtensions.shaderTextureLodEXT = true;
511 
512     // Vulkan natively supports noperspective interpolation
513     mNativeExtensions.shaderNoperspectiveInterpolationNV = true;
514 
515     // Vulkan natively supports 32-bit indices, entry in kIndexTypeMap
516     mNativeExtensions.elementIndexUintOES = true;
517 
518     mNativeExtensions.fboRenderMipmapOES = true;
519 
520     // We support getting image data for Textures and Renderbuffers.
521     mNativeExtensions.getImageANGLE = true;
522 
523     // Implemented in the translator
524     mNativeExtensions.shaderNonConstantGlobalInitializersEXT = true;
525 
526     // Implemented in the front end. Enable SSO if not explicitly disabled.
527     mNativeExtensions.separateShaderObjectsEXT =
528         !getFeatures().disableSeparateShaderObjects.enabled;
529 
530     // Vulkan has no restrictions of the format of cubemaps, so if the proper formats are supported,
531     // creating a cube of any of these formats should be implicitly supported.
532     mNativeExtensions.depthTextureCubeMapOES =
533         mNativeExtensions.depthTextureOES && mNativeExtensions.packedDepthStencilOES;
534 
535     // Vulkan natively supports format reinterpretation, but we still require support for all
536     // formats we may reinterpret to
537     mNativeExtensions.textureFormatSRGBOverrideEXT =
538         vk::GetTextureSRGBOverrideSupport(this, mNativeExtensions);
539     mNativeExtensions.textureSRGBDecodeEXT = vk::GetTextureSRGBDecodeSupport(this);
540 
541     // EXT_srgb_write_control requires image_format_list
542     mNativeExtensions.sRGBWriteControlEXT = getFeatures().supportsImageFormatList.enabled;
543 
544     // Vulkan natively supports io interface block.
545     mNativeExtensions.shaderIoBlocksOES = true;
546     mNativeExtensions.shaderIoBlocksEXT = true;
547 
548     bool gpuShader5Support          = vk::CanSupportGPUShader5(mPhysicalDeviceFeatures);
549     mNativeExtensions.gpuShader5EXT = gpuShader5Support;
550     mNativeExtensions.gpuShader5OES = gpuShader5Support;
551 
552     // Only expose texture cubemap array if the physical device supports it.
553     mNativeExtensions.textureCubeMapArrayOES = getFeatures().supportsImageCubeArray.enabled;
554     mNativeExtensions.textureCubeMapArrayEXT = mNativeExtensions.textureCubeMapArrayOES;
555 
556     mNativeExtensions.shadowSamplersEXT = true;
557 
558     // Enable EXT_external_buffer on Android. External buffers are implemented using Android
559     // hardware buffer (struct AHardwareBuffer).
560     mNativeExtensions.externalBufferEXT = IsAndroid() && GetAndroidSDKVersion() >= 26;
561 
562     // From the Vulkan specs:
563     // sampleRateShading specifies whether Sample Shading and multisample interpolation are
564     // supported. If this feature is not enabled, the sampleShadingEnable member of the
565     // VkPipelineMultisampleStateCreateInfo structure must be set to VK_FALSE and the
566     // minSampleShading member is ignored. This also specifies whether shader modules can declare
567     // the SampleRateShading capability
568     bool supportSampleRateShading      = mPhysicalDeviceFeatures.sampleRateShading == VK_TRUE;
569     mNativeExtensions.sampleShadingOES = supportSampleRateShading;
570 
571     // From the SPIR-V spec at 3.21. BuiltIn, SampleId and SamplePosition needs
572     // SampleRateShading. https://www.khronos.org/registry/spir-v/specs/unified1/SPIRV.html
573     // To replace non-constant index to constant 0 index, this extension assumes that ANGLE only
574     // supports the number of samples less than or equal to 32.
575     constexpr unsigned int kNotSupportedSampleCounts = VK_SAMPLE_COUNT_64_BIT;
576     mNativeExtensions.sampleVariablesOES =
577         supportSampleRateShading && vk_gl::GetMaxSampleCount(kNotSupportedSampleCounts) == 0;
578 
579     // EXT_multisample_compatibility is necessary for GLES1 conformance so calls like
580     // glDisable(GL_MULTISAMPLE) don't fail.  This is not actually implemented in Vulkan.  However,
581     // no CTS tests actually test this extension.  GL_SAMPLE_ALPHA_TO_ONE requires the Vulkan
582     // alphaToOne feature.
583     mNativeExtensions.multisampleCompatibilityEXT =
584         mPhysicalDeviceFeatures.alphaToOne ||
585         mFeatures.exposeNonConformantExtensionsAndVersions.enabled;
586 
587     // GL_KHR_blend_equation_advanced.  According to the spec, only color attachment zero can be
588     // used with advanced blend:
589     //
590     // > Advanced blending equations are supported only when rendering to a single
591     // > color buffer using fragment color zero.
592     //
593     // Vulkan requires advancedBlendMaxColorAttachments to be at least one, so we can support
594     // advanced blend as long as the Vulkan extension is supported.  Otherwise, the extension is
595     // emulated where possible.
596     // GL_EXT_blend_minmax is required for this extension, which is always enabled (hence omitted).
597     mNativeExtensions.blendEquationAdvancedKHR = mFeatures.supportsBlendOperationAdvanced.enabled ||
598                                                  mFeatures.emulateAdvancedBlendEquations.enabled;
599 
600     mNativeExtensions.blendEquationAdvancedCoherentKHR =
601         mFeatures.supportsBlendOperationAdvancedCoherent.enabled ||
602         (mFeatures.emulateAdvancedBlendEquations.enabled && mIsColorFramebufferFetchCoherent);
603 
604     // Enable EXT_unpack_subimage
605     mNativeExtensions.unpackSubimageEXT = true;
606 
607     // Enable NV_pack_subimage
608     mNativeExtensions.packSubimageNV = true;
609 
610     mNativeCaps.minInterpolationOffset          = limitsVk.minInterpolationOffset;
611     mNativeCaps.maxInterpolationOffset          = limitsVk.maxInterpolationOffset;
612     mNativeCaps.subPixelInterpolationOffsetBits = limitsVk.subPixelInterpolationOffsetBits;
613 
614     // Enable GL_ANGLE_robust_fragment_shader_output
615     mNativeExtensions.robustFragmentShaderOutputANGLE = true;
616 
617     // From the Vulkan spec:
618     //
619     // > The values minInterpolationOffset and maxInterpolationOffset describe the closed interval
620     // > of supported interpolation offsets : [ minInterpolationOffset, maxInterpolationOffset ].
621     // > The ULP is determined by subPixelInterpolationOffsetBits. If
622     // > subPixelInterpolationOffsetBits is 4, this provides increments of(1 / 2^4) = 0.0625, and
623     // > thus the range of supported interpolation offsets would be[-0.5, 0.4375]
624     //
625     // OES_shader_multisample_interpolation requires a maximum value of -0.5 for
626     // MIN_FRAGMENT_INTERPOLATION_OFFSET_OES and minimum 0.5 for
627     // MAX_FRAGMENT_INTERPOLATION_OFFSET_OES.  Vulkan has an identical limit for
628     // minInterpolationOffset, but its limit for maxInterpolationOffset is 0.5-(1/ULP).
629     // OES_shader_multisample_interpolation is therefore only supported if
630     // maxInterpolationOffset is at least 0.5.
631     //
632     // The GL spec is not as precise as Vulkan's in this regard and that the requirements really
633     // meant to match.  This is rectified in the GL spec.
634     // https://gitlab.khronos.org/opengl/API/-/issues/149
635     mNativeExtensions.shaderMultisampleInterpolationOES = mNativeExtensions.sampleVariablesOES;
636 
637     // Always enable ANGLE_rgbx_internal_format to expose GL_RGBX8_ANGLE except for Samsung.
638     mNativeExtensions.rgbxInternalFormatANGLE = mFeatures.supportsAngleRgbxInternalFormat.enabled;
639 
640     // https://vulkan.lunarg.com/doc/view/1.0.30.0/linux/vkspec.chunked/ch31s02.html
641     mNativeCaps.maxElementIndex  = std::numeric_limits<GLuint>::max() - 1;
642     mNativeCaps.max3DTextureSize = rx::LimitToInt(limitsVk.maxImageDimension3D);
643     mNativeCaps.max2DTextureSize =
644         std::min(limitsVk.maxFramebufferWidth, limitsVk.maxImageDimension2D);
645     mNativeCaps.maxArrayTextureLayers = rx::LimitToInt(limitsVk.maxImageArrayLayers);
646     mNativeCaps.maxLODBias            = limitsVk.maxSamplerLodBias;
647     mNativeCaps.maxCubeMapTextureSize = rx::LimitToInt(limitsVk.maxImageDimensionCube);
648     mNativeCaps.maxRenderbufferSize =
649         std::min({limitsVk.maxImageDimension2D, limitsVk.maxFramebufferWidth,
650                   limitsVk.maxFramebufferHeight});
651     mNativeCaps.minAliasedPointSize = std::max(1.0f, limitsVk.pointSizeRange[0]);
652     mNativeCaps.maxAliasedPointSize = limitsVk.pointSizeRange[1];
653 
654     // Line width ranges and granularity
655     if (mPhysicalDeviceFeatures.wideLines && mFeatures.bresenhamLineRasterization.enabled)
656     {
657         mNativeCaps.minAliasedLineWidth = std::max(1.0f, limitsVk.lineWidthRange[0]);
658         mNativeCaps.maxAliasedLineWidth = limitsVk.lineWidthRange[1];
659     }
660     else
661     {
662         mNativeCaps.minAliasedLineWidth = 1.0f;
663         mNativeCaps.maxAliasedLineWidth = 1.0f;
664     }
665     mNativeCaps.minMultisampleLineWidth = mNativeCaps.minAliasedLineWidth;
666     mNativeCaps.maxMultisampleLineWidth = mNativeCaps.maxAliasedLineWidth;
667     mNativeCaps.lineWidthGranularity    = limitsVk.lineWidthGranularity;
668 
669     mNativeCaps.maxDrawBuffers =
670         std::min(limitsVk.maxColorAttachments, limitsVk.maxFragmentOutputAttachments);
671     mNativeCaps.maxFramebufferWidth  = rx::LimitToInt(limitsVk.maxFramebufferWidth);
672     mNativeCaps.maxFramebufferHeight = rx::LimitToInt(limitsVk.maxFramebufferHeight);
673     mNativeCaps.maxColorAttachments  = rx::LimitToInt(limitsVk.maxColorAttachments);
674     mNativeCaps.maxViewportWidth     = rx::LimitToInt(limitsVk.maxViewportDimensions[0]);
675     mNativeCaps.maxViewportHeight    = rx::LimitToInt(limitsVk.maxViewportDimensions[1]);
676     mNativeCaps.maxSampleMaskWords   = rx::LimitToInt(limitsVk.maxSampleMaskWords);
677     mNativeCaps.maxColorTextureSamples =
678         vk_gl::GetMaxSampleCount(limitsVk.sampledImageColorSampleCounts);
679     mNativeCaps.maxDepthTextureSamples =
680         vk_gl::GetMaxSampleCount(limitsVk.sampledImageDepthSampleCounts);
681     mNativeCaps.maxIntegerSamples =
682         vk_gl::GetMaxSampleCount(limitsVk.sampledImageIntegerSampleCounts);
683 
684     mNativeCaps.maxVertexAttributes     = rx::LimitToInt(limitsVk.maxVertexInputAttributes);
685     mNativeCaps.maxVertexAttribBindings = rx::LimitToInt(limitsVk.maxVertexInputBindings);
686     // Offset and stride are stored as uint16_t in PackedAttribDesc.
687     mNativeCaps.maxVertexAttribRelativeOffset =
688         std::min((1u << kAttributeOffsetMaxBits) - 1, limitsVk.maxVertexInputAttributeOffset);
689     mNativeCaps.maxVertexAttribStride =
690         std::min(static_cast<uint32_t>(std::numeric_limits<uint16_t>::max()),
691                  limitsVk.maxVertexInputBindingStride);
692 
693     mNativeCaps.maxElementsIndices  = std::numeric_limits<GLint>::max();
694     mNativeCaps.maxElementsVertices = std::numeric_limits<GLint>::max();
695 
696     // Looks like all floats are IEEE according to the docs here:
697     // https://www.khronos.org/registry/vulkan/specs/1.0-wsi_extensions/html/vkspec.html#spirvenv-precision-operation
698     mNativeCaps.vertexHighpFloat.setIEEEFloat();
699     mNativeCaps.vertexMediumpFloat.setIEEEHalfFloat();
700     mNativeCaps.vertexLowpFloat.setIEEEHalfFloat();
701     mNativeCaps.fragmentHighpFloat.setIEEEFloat();
702     mNativeCaps.fragmentMediumpFloat.setIEEEHalfFloat();
703     mNativeCaps.fragmentLowpFloat.setIEEEHalfFloat();
704 
705     // Vulkan doesn't provide such information.  We provide the spec-required minimum here.
706     mNativeCaps.vertexHighpInt.setTwosComplementInt(32);
707     mNativeCaps.vertexMediumpInt.setTwosComplementInt(16);
708     mNativeCaps.vertexLowpInt.setTwosComplementInt(16);
709     mNativeCaps.fragmentHighpInt.setTwosComplementInt(32);
710     mNativeCaps.fragmentMediumpInt.setTwosComplementInt(16);
711     mNativeCaps.fragmentLowpInt.setTwosComplementInt(16);
712 
713     // Compute shader limits.
714     mNativeCaps.maxComputeWorkGroupCount[0] = rx::LimitToInt(limitsVk.maxComputeWorkGroupCount[0]);
715     mNativeCaps.maxComputeWorkGroupCount[1] = rx::LimitToInt(limitsVk.maxComputeWorkGroupCount[1]);
716     mNativeCaps.maxComputeWorkGroupCount[2] = rx::LimitToInt(limitsVk.maxComputeWorkGroupCount[2]);
717     mNativeCaps.maxComputeWorkGroupSize[0]  = rx::LimitToInt(limitsVk.maxComputeWorkGroupSize[0]);
718     mNativeCaps.maxComputeWorkGroupSize[1]  = rx::LimitToInt(limitsVk.maxComputeWorkGroupSize[1]);
719     mNativeCaps.maxComputeWorkGroupSize[2]  = rx::LimitToInt(limitsVk.maxComputeWorkGroupSize[2]);
720     mNativeCaps.maxComputeWorkGroupInvocations =
721         rx::LimitToInt(limitsVk.maxComputeWorkGroupInvocations);
722     mNativeCaps.maxComputeSharedMemorySize = rx::LimitToInt(limitsVk.maxComputeSharedMemorySize);
723 
724     GLuint maxUniformBlockSize =
725         rx::LimitToIntAnd(limitsVk.maxUniformBufferRange, mMaxBufferMemorySizeLimit);
726 
727     // Clamp the maxUniformBlockSize to 64KB (majority of devices support up to this size
728     // currently), on AMD the maxUniformBufferRange is near uint32_t max.
729     maxUniformBlockSize = std::min(0x10000u, maxUniformBlockSize);
730 
731     const GLuint maxUniformVectors = maxUniformBlockSize / (sizeof(GLfloat) * kComponentsPerVector);
732     const GLuint maxUniformComponents = maxUniformVectors * kComponentsPerVector;
733 
734     // Uniforms are implemented using a uniform buffer, so the max number of uniforms we can
735     // support is the max buffer range divided by the size of a single uniform (4X float).
736     mNativeCaps.maxVertexUniformVectors   = maxUniformVectors;
737     mNativeCaps.maxFragmentUniformVectors = maxUniformVectors;
738     for (gl::ShaderType shaderType : gl::AllShaderTypes())
739     {
740         mNativeCaps.maxShaderUniformComponents[shaderType] = maxUniformComponents;
741     }
742     mNativeCaps.maxUniformLocations = maxUniformVectors;
743 
744     const int32_t maxPerStageUniformBuffers = rx::LimitToInt(
745         limitsVk.maxPerStageDescriptorUniformBuffers - kReservedPerStageDefaultUniformBindingCount);
746     for (gl::ShaderType shaderType : gl::AllShaderTypes())
747     {
748         mNativeCaps.maxShaderUniformBlocks[shaderType] = maxPerStageUniformBuffers;
749     }
750 
751     // Reserved uniform buffer count depends on number of stages.  Vertex and fragment shaders are
752     // always supported.  The limit needs to be adjusted based on whether geometry and tessellation
753     // is supported.
754     int32_t maxCombinedUniformBuffers = rx::LimitToInt(limitsVk.maxDescriptorSetUniformBuffers) -
755                                         2 * kReservedPerStageDefaultUniformBindingCount;
756 
757     mNativeCaps.maxUniformBlockSize = maxUniformBlockSize;
758     mNativeCaps.uniformBufferOffsetAlignment =
759         static_cast<GLint>(limitsVk.minUniformBufferOffsetAlignment);
760 
761     // Note that Vulkan currently implements textures as combined image+samplers, so the limit is
762     // the minimum of supported samplers and sampled images.
763     const uint32_t maxPerStageTextures = std::min(limitsVk.maxPerStageDescriptorSamplers,
764                                                   limitsVk.maxPerStageDescriptorSampledImages);
765     const uint32_t maxCombinedTextures =
766         std::min(limitsVk.maxDescriptorSetSamplers, limitsVk.maxDescriptorSetSampledImages);
767     for (gl::ShaderType shaderType : gl::AllShaderTypes())
768     {
769         mNativeCaps.maxShaderTextureImageUnits[shaderType] = rx::LimitToInt(maxPerStageTextures);
770     }
771     mNativeCaps.maxCombinedTextureImageUnits = rx::LimitToInt(maxCombinedTextures);
772 
773     uint32_t maxPerStageStorageBuffers    = limitsVk.maxPerStageDescriptorStorageBuffers;
774     uint32_t maxVertexStageStorageBuffers = maxPerStageStorageBuffers;
775     uint32_t maxCombinedStorageBuffers    = limitsVk.maxDescriptorSetStorageBuffers;
776 
777     // A number of storage buffer slots are used in the vertex shader to emulate transform feedback.
778     // Note that Vulkan requires maxPerStageDescriptorStorageBuffers to be at least 4 (i.e. the same
779     // as gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS).
780     // TODO(syoussefi): This should be conditioned to transform feedback extension not being
781     // present.  http://anglebug.com/42261882.
782     // TODO(syoussefi): If geometry shader is supported, emulation will be done at that stage, and
783     // so the reserved storage buffers should be accounted in that stage.
784     // http://anglebug.com/42262271
785     static_assert(
786         gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS == 4,
787         "Limit to ES2.0 if supported SSBO count < supporting transform feedback buffer count");
788     if (mPhysicalDeviceFeatures.vertexPipelineStoresAndAtomics)
789     {
790         ASSERT(maxVertexStageStorageBuffers >= gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS);
791         maxVertexStageStorageBuffers -= gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS;
792         maxCombinedStorageBuffers -= gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS;
793 
794         // Cap the per-stage limit of the other stages to the combined limit, in case the combined
795         // limit is now lower than that.
796         maxPerStageStorageBuffers = std::min(maxPerStageStorageBuffers, maxCombinedStorageBuffers);
797     }
798 
799     // Reserve up to IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFERS storage buffers in the fragment and
800     // compute stages for atomic counters.  This is only possible if the number of per-stage storage
801     // buffers is greater than 4, which is the required GLES minimum for compute.
802     //
803     // For each stage, we'll either not support atomic counter buffers, or support exactly
804     // IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFERS.  This is due to restrictions in the shader
805     // translator where we can't know how many atomic counter buffers we would really need after
806     // linking so we can't create a packed buffer array.
807     //
808     // For the vertex stage, we could support atomic counters without storage buffers, but that's
809     // likely not very useful, so we use the same limit (4 + MAX_ATOMIC_COUNTER_BUFFERS) for the
810     // vertex stage to determine if we would want to add support for atomic counter buffers.
811     constexpr uint32_t kMinimumStorageBuffersForAtomicCounterBufferSupport =
812         gl::limits::kMinimumComputeStorageBuffers +
813         gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS;
814     uint32_t maxVertexStageAtomicCounterBuffers = 0;
815     uint32_t maxPerStageAtomicCounterBuffers    = 0;
816     uint32_t maxCombinedAtomicCounterBuffers    = 0;
817 
818     if (maxPerStageStorageBuffers >= kMinimumStorageBuffersForAtomicCounterBufferSupport)
819     {
820         maxPerStageAtomicCounterBuffers = gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS;
821         maxCombinedAtomicCounterBuffers = gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS;
822     }
823 
824     if (maxVertexStageStorageBuffers >= kMinimumStorageBuffersForAtomicCounterBufferSupport)
825     {
826         maxVertexStageAtomicCounterBuffers = gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS;
827     }
828 
829     maxVertexStageStorageBuffers -= maxVertexStageAtomicCounterBuffers;
830     maxPerStageStorageBuffers -= maxPerStageAtomicCounterBuffers;
831     maxCombinedStorageBuffers -= maxCombinedAtomicCounterBuffers;
832 
833     mNativeCaps.maxShaderStorageBlocks[gl::ShaderType::Vertex] =
834         mPhysicalDeviceFeatures.vertexPipelineStoresAndAtomics
835             ? rx::LimitToInt(maxVertexStageStorageBuffers)
836             : 0;
837     mNativeCaps.maxShaderStorageBlocks[gl::ShaderType::Fragment] =
838         mPhysicalDeviceFeatures.fragmentStoresAndAtomics ? rx::LimitToInt(maxPerStageStorageBuffers)
839                                                          : 0;
840     mNativeCaps.maxShaderStorageBlocks[gl::ShaderType::Compute] =
841         rx::LimitToInt(maxPerStageStorageBuffers);
842     mNativeCaps.maxCombinedShaderStorageBlocks = rx::LimitToInt(maxCombinedStorageBuffers);
843 
844     // Emulated as storage buffers, atomic counter buffers have the same size limit.  However, the
845     // limit is a signed integer and values above int max will end up as a negative size.  The
846     // storage buffer size is just capped to int unconditionally.
847     uint32_t maxStorageBufferRange =
848         rx::LimitToIntAnd(limitsVk.maxStorageBufferRange, mMaxBufferMemorySizeLimit);
849     if (mFeatures.limitMaxStorageBufferSize.enabled)
850     {
851         constexpr uint32_t kStorageBufferLimit = 256 * 1024 * 1024;
852         maxStorageBufferRange = std::min(maxStorageBufferRange, kStorageBufferLimit);
853     }
854 
855     mNativeCaps.maxShaderStorageBufferBindings = rx::LimitToInt(maxCombinedStorageBuffers);
856     mNativeCaps.maxShaderStorageBlockSize      = maxStorageBufferRange;
857     mNativeCaps.shaderStorageBufferOffsetAlignment =
858         rx::LimitToInt(static_cast<uint32_t>(limitsVk.minStorageBufferOffsetAlignment));
859 
860     mNativeCaps.maxShaderAtomicCounterBuffers[gl::ShaderType::Vertex] =
861         mPhysicalDeviceFeatures.vertexPipelineStoresAndAtomics
862             ? rx::LimitToInt(maxVertexStageAtomicCounterBuffers)
863             : 0;
864     mNativeCaps.maxShaderAtomicCounterBuffers[gl::ShaderType::Fragment] =
865         mPhysicalDeviceFeatures.fragmentStoresAndAtomics
866             ? rx::LimitToInt(maxPerStageAtomicCounterBuffers)
867             : 0;
868     mNativeCaps.maxShaderAtomicCounterBuffers[gl::ShaderType::Compute] =
869         rx::LimitToInt(maxPerStageAtomicCounterBuffers);
870     mNativeCaps.maxCombinedAtomicCounterBuffers = rx::LimitToInt(maxCombinedAtomicCounterBuffers);
871 
872     mNativeCaps.maxAtomicCounterBufferBindings = rx::LimitToInt(maxCombinedAtomicCounterBuffers);
873     mNativeCaps.maxAtomicCounterBufferSize     = maxStorageBufferRange;
874 
875     // There is no particular limit to how many atomic counters there can be, other than the size of
876     // a storage buffer.  We nevertheless limit this to something reasonable (4096 arbitrarily).
877     const int32_t maxAtomicCounters =
878         std::min<int32_t>(4096, maxStorageBufferRange / sizeof(uint32_t));
879     for (gl::ShaderType shaderType : gl::AllShaderTypes())
880     {
881         mNativeCaps.maxShaderAtomicCounters[shaderType] = maxAtomicCounters;
882     }
883 
884     // Set maxShaderAtomicCounters to zero if atomic is not supported.
885     if (!mPhysicalDeviceFeatures.vertexPipelineStoresAndAtomics)
886     {
887         mNativeCaps.maxShaderAtomicCounters[gl::ShaderType::Vertex]         = 0;
888         mNativeCaps.maxShaderAtomicCounters[gl::ShaderType::Geometry]       = 0;
889         mNativeCaps.maxShaderAtomicCounters[gl::ShaderType::TessControl]    = 0;
890         mNativeCaps.maxShaderAtomicCounters[gl::ShaderType::TessEvaluation] = 0;
891     }
892     if (!mPhysicalDeviceFeatures.fragmentStoresAndAtomics)
893     {
894         mNativeCaps.maxShaderAtomicCounters[gl::ShaderType::Fragment] = 0;
895     }
896 
897     mNativeCaps.maxCombinedAtomicCounters = maxAtomicCounters;
898 
899     // GL Images correspond to Vulkan Storage Images.
900     const int32_t maxPerStageImages = rx::LimitToInt(limitsVk.maxPerStageDescriptorStorageImages);
901     const int32_t maxCombinedImages = rx::LimitToInt(limitsVk.maxDescriptorSetStorageImages);
902     const int32_t maxVertexPipelineImages =
903         mPhysicalDeviceFeatures.vertexPipelineStoresAndAtomics ? maxPerStageImages : 0;
904 
905     mNativeCaps.maxShaderImageUniforms[gl::ShaderType::Vertex]         = maxVertexPipelineImages;
906     mNativeCaps.maxShaderImageUniforms[gl::ShaderType::TessControl]    = maxVertexPipelineImages;
907     mNativeCaps.maxShaderImageUniforms[gl::ShaderType::TessEvaluation] = maxVertexPipelineImages;
908     mNativeCaps.maxShaderImageUniforms[gl::ShaderType::Geometry]       = maxVertexPipelineImages;
909     mNativeCaps.maxShaderImageUniforms[gl::ShaderType::Fragment] =
910         mPhysicalDeviceFeatures.fragmentStoresAndAtomics ? maxPerStageImages : 0;
911     mNativeCaps.maxShaderImageUniforms[gl::ShaderType::Compute] = maxPerStageImages;
912 
913     mNativeCaps.maxCombinedImageUniforms = maxCombinedImages;
914     mNativeCaps.maxImageUnits            = maxCombinedImages;
915 
916     mNativeCaps.minProgramTexelOffset         = limitsVk.minTexelOffset;
917     mNativeCaps.maxProgramTexelOffset         = limitsVk.maxTexelOffset;
918     mNativeCaps.minProgramTextureGatherOffset = limitsVk.minTexelGatherOffset;
919     mNativeCaps.maxProgramTextureGatherOffset = limitsVk.maxTexelGatherOffset;
920 
921     // There is no additional limit to the combined number of components.  We can have up to a
922     // maximum number of uniform buffers, each having the maximum number of components.  Note that
923     // this limit includes both components in and out of uniform buffers.
924     //
925     // This value is limited to INT_MAX to avoid overflow when queried from glGetIntegerv().
926     const uint64_t maxCombinedUniformComponents =
927         std::min<uint64_t>(static_cast<uint64_t>(maxPerStageUniformBuffers +
928                                                  kReservedPerStageDefaultUniformBindingCount) *
929                                maxUniformComponents,
930                            std::numeric_limits<GLint>::max());
931     for (gl::ShaderType shaderType : gl::AllShaderTypes())
932     {
933         mNativeCaps.maxCombinedShaderUniformComponents[shaderType] = maxCombinedUniformComponents;
934     }
935 
936     // Total number of resources available to the user are as many as Vulkan allows minus everything
937     // that ANGLE uses internally.  That is, one dynamic uniform buffer used per stage for default
938     // uniforms.  Additionally, Vulkan uses up to IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS + 1
939     // buffers for transform feedback (Note: +1 is for the "counter" buffer of
940     // VK_EXT_transform_feedback).
941     constexpr uint32_t kReservedPerStageUniformBufferCount = 1;
942     constexpr uint32_t kReservedPerStageBindingCount =
943         kReservedPerStageUniformBufferCount + gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS + 1;
944 
945     // Note: maxPerStageResources is required to be at least the sum of per stage UBOs, SSBOs etc
946     // which total a minimum of 44 resources, so no underflow is possible here.  Limit the total
947     // number of resources reported by Vulkan to 2 billion though to avoid seeing negative numbers
948     // in applications that take the value as signed int (including dEQP).
949     const uint32_t maxPerStageResources = limitsVk.maxPerStageResources;
950     mNativeCaps.maxCombinedShaderOutputResources =
951         rx::LimitToInt(maxPerStageResources - kReservedPerStageBindingCount);
952 
953     // Reserve 1 extra varying for transform feedback capture of gl_Position.
954     constexpr GLint kReservedVaryingComponentsForTransformFeedbackExtension = 4;
955 
956     GLint reservedVaryingComponentCount = 0;
957 
958     if (getFeatures().supportsTransformFeedbackExtension.enabled)
959     {
960         reservedVaryingComponentCount += kReservedVaryingComponentsForTransformFeedbackExtension;
961     }
962 
963     // The max varying vectors should not include gl_Position.
964     // The gles2.0 section 2.10 states that "gl_Position is not a varying variable and does
965     // not count against this limit.", but the Vulkan spec has no such mention in its Built-in
966     // vars section. It is implicit that we need to actually reserve it for Vulkan in that case.
967     //
968     // Note that this exception for gl_Position does not apply to MAX_VERTEX_OUTPUT_COMPONENTS and
969     // similar limits.
970     //
971     // Note also that the reserved components are for transform feedback capture only, so they don't
972     // apply to the _input_ component limit.
973     const GLint reservedVaryingVectorCount = reservedVaryingComponentCount / 4 + 1;
974 
975     const GLint maxVaryingCount =
976         std::min(limitsVk.maxVertexOutputComponents, limitsVk.maxFragmentInputComponents);
977     mNativeCaps.maxVaryingVectors =
978         rx::LimitToInt((maxVaryingCount / kComponentsPerVector) - reservedVaryingVectorCount);
979     mNativeCaps.maxVertexOutputComponents =
980         rx::LimitToInt(limitsVk.maxVertexOutputComponents) - reservedVaryingComponentCount;
981     mNativeCaps.maxFragmentInputComponents = rx::LimitToInt(limitsVk.maxFragmentInputComponents);
982 
983     mNativeCaps.maxTransformFeedbackInterleavedComponents =
984         gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS;
985     mNativeCaps.maxTransformFeedbackSeparateAttributes =
986         gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS;
987     mNativeCaps.maxTransformFeedbackSeparateComponents =
988         gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS;
989 
990     mNativeCaps.minProgramTexelOffset = limitsVk.minTexelOffset;
991     mNativeCaps.maxProgramTexelOffset = rx::LimitToInt(limitsVk.maxTexelOffset);
992 
993     const uint32_t sampleCounts =
994         limitsVk.framebufferColorSampleCounts & limitsVk.framebufferDepthSampleCounts &
995         limitsVk.framebufferStencilSampleCounts & vk_gl::kSupportedSampleCounts;
996 
997     mNativeCaps.maxSamples            = rx::LimitToInt(vk_gl::GetMaxSampleCount(sampleCounts));
998     mNativeCaps.maxFramebufferSamples = mNativeCaps.maxSamples;
999 
1000     mNativeCaps.subPixelBits = limitsVk.subPixelPrecisionBits;
1001 
1002     if (getFeatures().supportsShaderFramebufferFetch.enabled)
1003     {
1004         mNativeExtensions.shaderFramebufferFetchEXT = true;
1005         mNativeExtensions.shaderFramebufferFetchARM = true;
1006         // ANGLE correctly maps gl_LastFragColorARM to input attachment 0 and has no problem with
1007         // MRT.
1008         mNativeCaps.fragmentShaderFramebufferFetchMRT = true;
1009     }
1010 
1011     if (getFeatures().supportsShaderFramebufferFetchNonCoherent.enabled)
1012     {
1013         mNativeExtensions.shaderFramebufferFetchNonCoherentEXT = true;
1014     }
1015 
1016     // Enable Program Binary extension.
1017     mNativeExtensions.getProgramBinaryOES = true;
1018     mNativeCaps.programBinaryFormats.push_back(GL_PROGRAM_BINARY_ANGLE);
1019 
1020     // Enable Shader Binary extension.
1021     mNativeCaps.shaderBinaryFormats.push_back(GL_SHADER_BINARY_ANGLE);
1022 
1023     // Enable GL_NV_pixel_buffer_object extension.
1024     mNativeExtensions.pixelBufferObjectNV = true;
1025 
1026     // Enable GL_NV_fence extension.
1027     mNativeExtensions.fenceNV = true;
1028 
1029     // Enable GL_EXT_copy_image
1030     mNativeExtensions.copyImageEXT = true;
1031     mNativeExtensions.copyImageOES = true;
1032 
1033     // GL_EXT_clip_control
1034     mNativeExtensions.clipControlEXT = true;
1035 
1036     // GL_ANGLE_read_only_depth_stencil_feedback_loops
1037     mNativeExtensions.readOnlyDepthStencilFeedbackLoopsANGLE = true;
1038 
1039     // Enable GL_EXT_texture_buffer and OES variant.  Nearly all formats required for this extension
1040     // are also required to have the UNIFORM_TEXEL_BUFFER feature bit in Vulkan, except for
1041     // R32G32B32_SFLOAT/UINT/SINT which are optional.  For many formats, the STORAGE_TEXEL_BUFFER
1042     // feature is optional though.  This extension is exposed only if the formats specified in
1043     // EXT_texture_buffer support the necessary feature bits.
1044     //
1045     //  glTexBuffer page 187 table 8.18.
1046     //  glBindImageTexture page 216 table 8.24.
1047     //  https://www.khronos.org/registry/OpenGL/specs/es/3.2/es_spec_3.2.pdf.
1048     //  https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/chap43.html#features-required-format-support
1049     //  required image and texture access for texture buffer formats are
1050     //                         texture access                image access
1051     //    8-bit components, all required by vulkan.
1052     //
1053     //    GL_R8                        Y                           N
1054     //    GL_R8I                       Y                           N
1055     //    GL_R8UI                      Y                           N
1056     //    GL_RG8                       Y                           N
1057     //    GL_RG8I                      Y                           N
1058     //    GL_RG8UI                     Y                           N
1059     //    GL_RGBA8                     Y                           Y
1060     //    GL_RGBA8I                    Y                           Y
1061     //    GL_RGBA8UI                   Y                           Y
1062     //    GL_RGBA8_SNORM               N                           Y
1063     //
1064     //    16-bit components,  all required by vulkan.
1065     //
1066     //    GL_R16F                      Y                           N
1067     //    GL_R16I                      Y                           N
1068     //    GL_R16UI                     Y                           N
1069     //    GL_RG16F                     Y                           N
1070     //    GL_RG16I                     Y                           N
1071     //    GL_RG16UI                    Y                           N
1072     //    GL_RGBA16F                   Y                           Y
1073     //    GL_RGBA16I                   Y                           Y
1074     //    GL_RGBA16UI                  Y                           Y
1075     //
1076     //    32-bit components, except RGB32 all others required by vulkan.
1077     //                       RGB32 is emulated by ANGLE
1078     //
1079     //    GL_R32F                      Y                           Y
1080     //    GL_R32I                      Y                           Y
1081     //    GL_R32UI                     Y                           Y
1082     //    GL_RG32F                     Y                           N
1083     //    GL_RG32I                     Y                           N
1084     //    GL_RG32UI                    Y                           N
1085     //    GL_RGB32F                    Y                           N
1086     //    GL_RGB32I                    Y                           N
1087     //    GL_RGB32UI                   Y                           N
1088     //    GL_RGBA32F                   Y                           Y
1089     //    GL_RGBA32I                   Y                           Y
1090     //    GL_RGBA32UI                  Y                           Y
1091     mNativeExtensions.textureBufferOES = true;
1092     mNativeExtensions.textureBufferEXT = true;
1093 
1094     mNativeCaps.maxTextureBufferSize =
1095         rx::LimitToIntAnd(limitsVk.maxTexelBufferElements, mMaxBufferMemorySizeLimit);
1096 
1097     mNativeCaps.textureBufferOffsetAlignment =
1098         rx::LimitToInt(limitsVk.minTexelBufferOffsetAlignment);
1099 
1100     // From the GL_EXT_texture_norm16 spec: Accepted by the <internalFormat> parameter of
1101     // TexImage2D,TexImage3D, TexStorage2D, TexStorage3D and TexStorage2DMultisample,
1102     // TexStorage3DMultisampleOES, TexBufferEXT, TexBufferRangeEXT, TextureViewEXT,
1103     // RenderbufferStorage and RenderbufferStorageMultisample:
1104     //   - R16_EXT
1105     //   - RG16_EXT
1106     //   - RGBA16_EXT
1107     bool norm16FormatsSupportedForBufferTexture =
1108         hasBufferFormatFeatureBits(angle::FormatID::R16_UNORM,
1109                                    VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT) &&
1110         hasBufferFormatFeatureBits(angle::FormatID::R16G16_UNORM,
1111                                    VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT) &&
1112         hasBufferFormatFeatureBits(angle::FormatID::R16G16B16A16_UNORM,
1113                                    VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT);
1114 
1115     if (!norm16FormatsSupportedForBufferTexture)
1116     {
1117         mNativeExtensions.textureNorm16EXT = false;
1118 
1119         // With textureNorm16EXT disabled, renderSnormEXT will skip checking support for the 16-bit
1120         // normalized formats.
1121         mNativeExtensions.renderSnormEXT =
1122             DetermineRenderSnormSupport(mNativeTextureCaps, mNativeExtensions.textureNorm16EXT);
1123     }
1124 
1125     // Atomic image operations in the vertex and fragment shaders require the
1126     // vertexPipelineStoresAndAtomics and fragmentStoresAndAtomics Vulkan features respectively.
1127     // If either of these features is not present, the number of image uniforms for that stage is
1128     // advertised as zero, so image atomic operations support can be agnostic of shader stages.
1129     //
1130     // GL_OES_shader_image_atomic requires that image atomic functions have support for r32i and
1131     // r32ui formats.  These formats have mandatory support for STORAGE_IMAGE_ATOMIC and
1132     // STORAGE_TEXEL_BUFFER_ATOMIC features in Vulkan.  Additionally, it requires that
1133     // imageAtomicExchange supports r32f, which is emulated in ANGLE transforming the shader to
1134     // expect r32ui instead.
1135     mNativeExtensions.shaderImageAtomicOES = true;
1136 
1137     // Tessellation shaders are required for ES 3.2.
1138     if (mPhysicalDeviceFeatures.tessellationShader)
1139     {
1140         constexpr uint32_t kReservedTessellationDefaultUniformBindingCount = 2;
1141 
1142         bool tessellationShaderEnabled =
1143             mFeatures.supportsTransformFeedbackExtension.enabled &&
1144             (mFeatures.supportsPrimitivesGeneratedQuery.enabled ||
1145              mFeatures.allowPipelineStatisticsForPrimitivesGeneratedQuery.enabled ||
1146              mFeatures.exposeNonConformantExtensionsAndVersions.enabled);
1147         mNativeExtensions.tessellationShaderEXT = tessellationShaderEnabled;
1148         mNativeExtensions.tessellationShaderOES = tessellationShaderEnabled;
1149         mNativeCaps.maxPatchVertices            = rx::LimitToInt(limitsVk.maxTessellationPatchSize);
1150         mNativeCaps.maxTessPatchComponents =
1151             rx::LimitToInt(limitsVk.maxTessellationControlPerPatchOutputComponents);
1152         mNativeCaps.maxTessGenLevel = rx::LimitToInt(limitsVk.maxTessellationGenerationLevel);
1153 
1154         mNativeCaps.maxTessControlInputComponents =
1155             rx::LimitToInt(limitsVk.maxTessellationControlPerVertexInputComponents);
1156         mNativeCaps.maxTessControlOutputComponents =
1157             rx::LimitToInt(limitsVk.maxTessellationControlPerVertexOutputComponents);
1158         mNativeCaps.maxTessControlTotalOutputComponents =
1159             rx::LimitToInt(limitsVk.maxTessellationControlTotalOutputComponents);
1160         mNativeCaps.maxTessEvaluationInputComponents =
1161             rx::LimitToInt(limitsVk.maxTessellationEvaluationInputComponents);
1162         mNativeCaps.maxTessEvaluationOutputComponents =
1163             rx::LimitToInt(limitsVk.maxTessellationEvaluationOutputComponents) -
1164             reservedVaryingComponentCount;
1165 
1166         // There is 1 default uniform binding used per tessellation stages.
1167         mNativeCaps.maxCombinedUniformBlocks = rx::LimitToInt(
1168             mNativeCaps.maxCombinedUniformBlocks + kReservedTessellationDefaultUniformBindingCount);
1169         mNativeCaps.maxUniformBufferBindings = rx::LimitToInt(
1170             mNativeCaps.maxUniformBufferBindings + kReservedTessellationDefaultUniformBindingCount);
1171 
1172         if (mPhysicalDeviceFeatures.vertexPipelineStoresAndAtomics)
1173         {
1174             mNativeCaps.maxShaderStorageBlocks[gl::ShaderType::TessControl] =
1175                 mNativeCaps.maxCombinedShaderOutputResources;
1176             mNativeCaps.maxShaderAtomicCounterBuffers[gl::ShaderType::TessControl] =
1177                 maxCombinedAtomicCounterBuffers;
1178 
1179             mNativeCaps.maxShaderStorageBlocks[gl::ShaderType::TessEvaluation] =
1180                 mNativeCaps.maxCombinedShaderOutputResources;
1181             mNativeCaps.maxShaderAtomicCounterBuffers[gl::ShaderType::TessEvaluation] =
1182                 maxCombinedAtomicCounterBuffers;
1183         }
1184 
1185         mNativeCaps.primitiveRestartForPatchesSupported =
1186             mPrimitiveTopologyListRestartFeatures.primitiveTopologyPatchListRestart == VK_TRUE;
1187 
1188         // Reserve a uniform buffer binding for each tessellation stage
1189         if (tessellationShaderEnabled)
1190         {
1191             maxCombinedUniformBuffers -= 2 * kReservedPerStageDefaultUniformBindingCount;
1192         }
1193     }
1194 
1195     // Geometry shaders are required for ES 3.2.
1196     if (mPhysicalDeviceFeatures.geometryShader)
1197     {
1198         bool geometryShaderEnabled =
1199             mFeatures.supportsTransformFeedbackExtension.enabled &&
1200             (mFeatures.supportsPrimitivesGeneratedQuery.enabled ||
1201              mFeatures.allowPipelineStatisticsForPrimitivesGeneratedQuery.enabled ||
1202              mFeatures.exposeNonConformantExtensionsAndVersions.enabled);
1203         mNativeExtensions.geometryShaderEXT = geometryShaderEnabled;
1204         mNativeExtensions.geometryShaderOES = geometryShaderEnabled;
1205         mNativeCaps.maxFramebufferLayers    = rx::LimitToInt(limitsVk.maxFramebufferLayers);
1206 
1207         // Use "undefined" which means APP would have to set gl_Layer identically.
1208         mNativeCaps.layerProvokingVertex = GL_UNDEFINED_VERTEX_EXT;
1209 
1210         mNativeCaps.maxGeometryInputComponents =
1211             rx::LimitToInt(limitsVk.maxGeometryInputComponents);
1212         mNativeCaps.maxGeometryOutputComponents =
1213             rx::LimitToInt(limitsVk.maxGeometryOutputComponents) - reservedVaryingComponentCount;
1214         mNativeCaps.maxGeometryOutputVertices = rx::LimitToInt(limitsVk.maxGeometryOutputVertices);
1215         mNativeCaps.maxGeometryTotalOutputComponents =
1216             rx::LimitToInt(limitsVk.maxGeometryTotalOutputComponents);
1217         if (mPhysicalDeviceFeatures.vertexPipelineStoresAndAtomics)
1218         {
1219             mNativeCaps.maxShaderStorageBlocks[gl::ShaderType::Geometry] =
1220                 mNativeCaps.maxCombinedShaderOutputResources;
1221             mNativeCaps.maxShaderAtomicCounterBuffers[gl::ShaderType::Geometry] =
1222                 maxCombinedAtomicCounterBuffers;
1223         }
1224         mNativeCaps.maxGeometryShaderInvocations =
1225             rx::LimitToInt(limitsVk.maxGeometryShaderInvocations);
1226 
1227         // Cap maxGeometryInputComponents by maxVertexOutputComponents and
1228         // maxTessellationEvaluationOutputComponents; there can't be more inputs than there are
1229         // outputs in the previous stage.
1230         mNativeCaps.maxGeometryInputComponents =
1231             std::min(mNativeCaps.maxGeometryInputComponents,
1232                      std::min(mNativeCaps.maxVertexOutputComponents,
1233                               mNativeCaps.maxTessEvaluationOutputComponents));
1234 
1235         // Reserve a uniform buffer binding for the geometry stage
1236         if (geometryShaderEnabled)
1237         {
1238             maxCombinedUniformBuffers -= kReservedPerStageDefaultUniformBindingCount;
1239         }
1240     }
1241 
1242     mNativeCaps.maxCombinedUniformBlocks = maxCombinedUniformBuffers;
1243     mNativeCaps.maxUniformBufferBindings = maxCombinedUniformBuffers;
1244 
1245     // GL_APPLE_clip_distance / GL_EXT_clip_cull_distance / GL_ANGLE_clip_cull_distance
1246     // From the EXT_clip_cull_distance extension spec:
1247     //
1248     // > Modify Section 7.2, "Built-In Constants" (p. 126)
1249     // >
1250     // > const mediump int gl_MaxClipDistances = 8;
1251     // > const mediump int gl_MaxCullDistances = 8;
1252     // > const mediump int gl_MaxCombinedClipAndCullDistances = 8;
1253     constexpr uint32_t kMaxClipDistancePerSpec                = 8;
1254     constexpr uint32_t kMaxCullDistancePerSpec                = 8;
1255     constexpr uint32_t kMaxCombinedClipAndCullDistancePerSpec = 8;
1256 
1257     // TODO: http://anglebug.com/42264006
1258     // After implementing EXT_geometry_shader, EXT_clip_cull_distance should be additionally
1259     // implemented to support the geometry shader. Until then, EXT_clip_cull_distance is enabled
1260     // only in the experimental cases.
1261     if (mPhysicalDeviceFeatures.shaderClipDistance &&
1262         limitsVk.maxClipDistances >= kMaxClipDistancePerSpec)
1263     {
1264         // Do not enable GL_APPLE_clip_distance for Samsung devices.
1265         mNativeExtensions.clipDistanceAPPLE     = mFeatures.supportsAppleClipDistance.enabled;
1266         mNativeExtensions.clipCullDistanceANGLE = true;
1267         mNativeCaps.maxClipDistances            = limitsVk.maxClipDistances;
1268 
1269         if (mPhysicalDeviceFeatures.shaderCullDistance &&
1270             limitsVk.maxCullDistances >= kMaxCullDistancePerSpec &&
1271             limitsVk.maxCombinedClipAndCullDistances >= kMaxCombinedClipAndCullDistancePerSpec)
1272         {
1273             mNativeExtensions.clipCullDistanceEXT       = true;
1274             mNativeCaps.maxCullDistances                = limitsVk.maxCullDistances;
1275             mNativeCaps.maxCombinedClipAndCullDistances = limitsVk.maxCombinedClipAndCullDistances;
1276         }
1277     }
1278 
1279     // GL_EXT_blend_func_extended
1280     mNativeExtensions.blendFuncExtendedEXT = mPhysicalDeviceFeatures.dualSrcBlend == VK_TRUE;
1281     mNativeCaps.maxDualSourceDrawBuffers   = rx::LimitToInt(limitsVk.maxFragmentDualSrcAttachments);
1282 
1283     // GL_ANGLE_relaxed_vertex_attribute_type
1284     mNativeExtensions.relaxedVertexAttributeTypeANGLE = true;
1285 
1286     // GL_OVR_multiview*.  Bresenham line emulation does not work with multiview.  There's no
1287     // limitation in Vulkan to restrict an application to multiview 1.
1288     mNativeExtensions.multiviewOVR =
1289         mFeatures.supportsMultiview.enabled && mFeatures.bresenhamLineRasterization.enabled;
1290     mNativeExtensions.multiview2OVR = mNativeExtensions.multiviewOVR;
1291     // Max views affects the number of Vulkan queries per GL query in render pass, and
1292     // SecondaryCommandBuffer's ResetQueryPoolParams would like this to have an upper limit (of
1293     // 255).
1294     mNativeCaps.maxViews = std::min(mMultiviewProperties.maxMultiviewViewCount, 8u);
1295 
1296     // GL_ANGLE_yuv_internal_format
1297     mNativeExtensions.yuvInternalFormatANGLE =
1298         getFeatures().supportsYUVSamplerConversion.enabled && vk::CanSupportYuvInternalFormat(this);
1299 
1300     // GL_EXT_primitive_bounding_box
1301     mNativeExtensions.primitiveBoundingBoxEXT = true;
1302 
1303     // GL_OES_primitive_bounding_box
1304     mNativeExtensions.primitiveBoundingBoxOES = true;
1305 
1306     // GL_EXT_protected_textures
1307     mNativeExtensions.protectedTexturesEXT = mFeatures.supportsProtectedMemory.enabled;
1308 
1309     // GL_ANGLE_vulkan_image
1310     mNativeExtensions.vulkanImageANGLE = true;
1311 
1312     // GL_ANGLE_texture_usage
1313     mNativeExtensions.textureUsageANGLE = true;
1314 
1315     // GL_KHR_parallel_shader_compile
1316     mNativeExtensions.parallelShaderCompileKHR = mFeatures.enableParallelCompileAndLink.enabled;
1317 
1318     // GL_NV_read_depth, GL_NV_read_depth_stencil, GL_NV_read_stencil
1319     mNativeExtensions.readDepthNV        = true;
1320     mNativeExtensions.readDepthStencilNV = true;
1321     mNativeExtensions.readStencilNV      = true;
1322 
1323     // GL_EXT_clear_texture
1324     mNativeExtensions.clearTextureEXT = true;
1325 
1326     // GL_QCOM_shading_rate
1327     mNativeExtensions.shadingRateQCOM = mFeatures.supportsFragmentShadingRate.enabled;
1328 
1329     // GL_QCOM_framebuffer_foveated
1330     mNativeExtensions.framebufferFoveatedQCOM = mFeatures.supportsFoveatedRendering.enabled;
1331     // GL_QCOM_texture_foveated
1332     mNativeExtensions.textureFoveatedQCOM = mFeatures.supportsFoveatedRendering.enabled;
1333 
1334     // GL_ANGLE_shader_pixel_local_storage
1335     //
1336     // NOTE:
1337     //   * The Vulkan backend limits the ES version to 2.0 when drawBuffersIndexed is not supported.
1338     //   * The frontend disables all ES 3.x extensions when the context version is too low for them.
1339     //   * This means it is impossible on Vulkan to have pixel local storage without DBI.
1340     if (mNativeExtensions.drawBuffersIndexedAny())
1341     {
1342         // With drawBuffersIndexed, we can always at least support non-coherent PLS with input
1343         // attachments.
1344         mNativeExtensions.shaderPixelLocalStorageANGLE = true;
1345 
1346         if (!mIsColorFramebufferFetchCoherent &&
1347             getFeatures().supportsFragmentShaderPixelInterlock.enabled)
1348         {
1349             // Use shader images with VK_EXT_fragment_shader_interlock, instead of input
1350             // attachments, if they're our only option to be coherent.
1351             mNativeExtensions.shaderPixelLocalStorageCoherentANGLE = true;
1352             mNativePLSOptions.type = ShPixelLocalStorageType::ImageLoadStore;
1353             // GL_ARB_fragment_shader_interlock compiles to SPV_EXT_fragment_shader_interlock.
1354             mNativePLSOptions.fragmentSyncType =
1355                 ShFragmentSynchronizationType::FragmentShaderInterlock_ARB_GL;
1356             mNativePLSOptions.supportsNativeRGBA8ImageFormats = true;
1357         }
1358         else
1359         {
1360             // Input attachments are the preferred implementation for PLS on Vulkan.
1361             mNativeExtensions.shaderPixelLocalStorageCoherentANGLE =
1362                 mIsColorFramebufferFetchCoherent;
1363             mNativePLSOptions.type             = ShPixelLocalStorageType::FramebufferFetch;
1364             mNativePLSOptions.fragmentSyncType = mIsColorFramebufferFetchCoherent
1365                                                      ? ShFragmentSynchronizationType::Automatic
1366                                                      : ShFragmentSynchronizationType::NotSupported;
1367         }
1368     }
1369 
1370     // If framebuffer fetch is to be enabled/used, cap maxColorAttachments/maxDrawBuffers to
1371     // maxPerStageDescriptorInputAttachments.  Note that 4 is the minimum required value for
1372     // maxColorAttachments and maxDrawBuffers in GL, and also happens to be the minimum required
1373     // value for maxPerStageDescriptorInputAttachments in Vulkan.  This means that capping the color
1374     // attachment count to maxPerStageDescriptorInputAttachments can never lead to an invalid value.
1375     const bool hasMRTFramebufferFetch =
1376         mNativeExtensions.shaderFramebufferFetchEXT ||
1377         mNativeExtensions.shaderFramebufferFetchNonCoherentEXT ||
1378         mNativePLSOptions.type == ShPixelLocalStorageType::FramebufferFetch;
1379     if (hasMRTFramebufferFetch)
1380     {
1381         mNativeCaps.maxColorAttachments = std::min<uint32_t>(
1382             mNativeCaps.maxColorAttachments, limitsVk.maxPerStageDescriptorInputAttachments);
1383         mNativeCaps.maxDrawBuffers = std::min<uint32_t>(
1384             mNativeCaps.maxDrawBuffers, limitsVk.maxPerStageDescriptorInputAttachments);
1385 
1386         // Make sure no more than the allowed input attachments bindings are used by descriptor set
1387         // layouts.  This number matches the number of color attachments because of framebuffer
1388         // fetch, and that limit is later capped to IMPLEMENTATION_MAX_DRAW_BUFFERS in Context.cpp.
1389         mMaxColorInputAttachmentCount = std::min<uint32_t>(mNativeCaps.maxColorAttachments,
1390                                                            gl::IMPLEMENTATION_MAX_DRAW_BUFFERS);
1391     }
1392     else if (mFeatures.emulateAdvancedBlendEquations.enabled)
1393     {
1394         // ANGLE may also use framebuffer fetch to emulate KHR_blend_equation_advanced, which needs
1395         // a single input attachment.
1396         mMaxColorInputAttachmentCount = 1;
1397     }
1398     else
1399     {
1400         // mMaxColorInputAttachmentCount is left as 0 to catch bugs if a future user of framebuffer
1401         // fetch functionality does not update the logic in this if/else chain.
1402     }
1403 
1404     // Enable the ARM_shader_framebuffer_fetch_depth_stencil extension only if the number of input
1405     // descriptor exceeds the color attachment count by at least 2 (for depth and stencil), or if
1406     // the number of color attachments can be reduced to accomodate for the 2 depth/stencil images.
1407     if (mFeatures.supportsShaderFramebufferFetchDepthStencil.enabled)
1408     {
1409         const uint32_t maxColorAttachmentsWithDepthStencilInput = std::min<uint32_t>(
1410             mNativeCaps.maxColorAttachments, limitsVk.maxPerStageDescriptorInputAttachments - 2);
1411         const uint32_t maxDrawBuffersWithDepthStencilInput = std::min<uint32_t>(
1412             mNativeCaps.maxDrawBuffers, limitsVk.maxPerStageDescriptorInputAttachments - 2);
1413 
1414         // As long as the minimum required color attachments (4) is satisfied, the extension can be
1415         // exposed.
1416         if (maxColorAttachmentsWithDepthStencilInput >= 4 &&
1417             maxDrawBuffersWithDepthStencilInput >= 4)
1418         {
1419             mNativeExtensions.shaderFramebufferFetchDepthStencilARM = true;
1420             mNativeCaps.maxColorAttachments = maxColorAttachmentsWithDepthStencilInput;
1421             mNativeCaps.maxDrawBuffers      = maxDrawBuffersWithDepthStencilInput;
1422             mMaxColorInputAttachmentCount =
1423                 std::min<uint32_t>(mMaxColorInputAttachmentCount, mNativeCaps.maxColorAttachments);
1424         }
1425     }
1426 
1427     mNativeExtensions.logicOpANGLE = mPhysicalDeviceFeatures.logicOp == VK_TRUE;
1428 
1429     mNativeExtensions.YUVTargetEXT = mFeatures.supportsYuvTarget.enabled;
1430 
1431     mNativeExtensions.textureStorageCompressionEXT =
1432         mFeatures.supportsImageCompressionControl.enabled;
1433     mNativeExtensions.EGLImageStorageCompressionEXT =
1434         mFeatures.supportsImageCompressionControl.enabled;
1435 
1436     // Log any missing extensions required for GLES 3.2.
1437     LogMissingExtensionsForGLES32(mNativeExtensions);
1438 }
1439 
CanSupportGLES32(const gl::Extensions & nativeExtensions)1440 bool CanSupportGLES32(const gl::Extensions &nativeExtensions)
1441 {
1442     std::vector<bool> requiredExtensions = GetRequiredGLES32ExtensionList(nativeExtensions);
1443     for (uint32_t index = 0; index < requiredExtensions.size(); index++)
1444     {
1445         if (!requiredExtensions[index])
1446         {
1447             return false;
1448         }
1449     }
1450 
1451     return true;
1452 }
1453 
CanSupportTransformFeedbackExtension(const VkPhysicalDeviceTransformFeedbackFeaturesEXT & xfbFeatures)1454 bool CanSupportTransformFeedbackExtension(
1455     const VkPhysicalDeviceTransformFeedbackFeaturesEXT &xfbFeatures)
1456 {
1457     return xfbFeatures.transformFeedback == VK_TRUE;
1458 }
1459 
CanSupportTransformFeedbackEmulation(const VkPhysicalDeviceFeatures & features)1460 bool CanSupportTransformFeedbackEmulation(const VkPhysicalDeviceFeatures &features)
1461 {
1462     return features.vertexPipelineStoresAndAtomics == VK_TRUE;
1463 }
1464 
1465 }  // namespace vk
1466 
1467 namespace egl_vk
1468 {
1469 
1470 namespace
1471 {
1472 
ComputeMaximumPBufferPixels(const VkPhysicalDeviceProperties & physicalDeviceProperties)1473 EGLint ComputeMaximumPBufferPixels(const VkPhysicalDeviceProperties &physicalDeviceProperties)
1474 {
1475     // EGLints are signed 32-bit integers, it's fairly easy to overflow them, especially since
1476     // Vulkan's minimum guaranteed VkImageFormatProperties::maxResourceSize is 2^31 bytes.
1477     constexpr uint64_t kMaxValueForEGLint =
1478         static_cast<uint64_t>(std::numeric_limits<EGLint>::max());
1479 
1480     // TODO(geofflang): Compute the maximum size of a pbuffer by using the maxResourceSize result
1481     // from vkGetPhysicalDeviceImageFormatProperties for both the color and depth stencil format and
1482     // the exact image creation parameters that would be used to create the pbuffer. Because it is
1483     // always safe to return out-of-memory errors on pbuffer allocation, it's fine to simply return
1484     // the number of pixels in a max width by max height pbuffer for now.
1485     // http://anglebug.com/42261335
1486 
1487     // Storing the result of squaring a 32-bit unsigned int in a 64-bit unsigned int is safe.
1488     static_assert(std::is_same<decltype(physicalDeviceProperties.limits.maxImageDimension2D),
1489                                uint32_t>::value,
1490                   "physicalDeviceProperties.limits.maxImageDimension2D expected to be a uint32_t.");
1491     const uint64_t maxDimensionsSquared =
1492         static_cast<uint64_t>(physicalDeviceProperties.limits.maxImageDimension2D) *
1493         static_cast<uint64_t>(physicalDeviceProperties.limits.maxImageDimension2D);
1494 
1495     return static_cast<EGLint>(std::min(maxDimensionsSquared, kMaxValueForEGLint));
1496 }
1497 
GetMatchFormat(GLenum internalFormat)1498 EGLint GetMatchFormat(GLenum internalFormat)
1499 {
1500     // Lock Surface match format
1501     switch (internalFormat)
1502     {
1503         case GL_RGBA8:
1504             return EGL_FORMAT_RGBA_8888_KHR;
1505         case GL_BGRA8_EXT:
1506             return EGL_FORMAT_RGBA_8888_EXACT_KHR;
1507         case GL_RGB565:
1508             return EGL_FORMAT_RGB_565_EXACT_KHR;
1509         default:
1510             return EGL_NONE;
1511     }
1512 }
1513 
1514 // Generates a basic config for a combination of color format, depth stencil format and sample
1515 // count.
GenerateDefaultConfig(DisplayVk * display,const gl::InternalFormat & colorFormat,const gl::InternalFormat & depthStencilFormat,EGLint sampleCount)1516 egl::Config GenerateDefaultConfig(DisplayVk *display,
1517                                   const gl::InternalFormat &colorFormat,
1518                                   const gl::InternalFormat &depthStencilFormat,
1519                                   EGLint sampleCount)
1520 {
1521     const vk::Renderer *renderer = display->getRenderer();
1522 
1523     const VkPhysicalDeviceProperties &physicalDeviceProperties =
1524         renderer->getPhysicalDeviceProperties();
1525     gl::Version maxSupportedESVersion = renderer->getMaxSupportedESVersion();
1526 
1527     // ES3 features are required to emulate ES1
1528     EGLint es1Support = (maxSupportedESVersion.major >= 3 ? EGL_OPENGL_ES_BIT : 0);
1529     EGLint es2Support = (maxSupportedESVersion.major >= 2 ? EGL_OPENGL_ES2_BIT : 0);
1530     EGLint es3Support = (maxSupportedESVersion.major >= 3 ? EGL_OPENGL_ES3_BIT : 0);
1531 
1532     egl::Config config;
1533 
1534     config.renderTargetFormat = colorFormat.internalFormat;
1535     config.depthStencilFormat = depthStencilFormat.internalFormat;
1536     config.bufferSize         = colorFormat.getEGLConfigBufferSize();
1537     config.redSize            = colorFormat.redBits;
1538     config.greenSize          = colorFormat.greenBits;
1539     config.blueSize           = colorFormat.blueBits;
1540     config.alphaSize          = colorFormat.alphaBits;
1541     config.alphaMaskSize      = 0;
1542     config.bindToTextureRGB   = colorFormat.format == GL_RGB;
1543     config.bindToTextureRGBA  = colorFormat.format == GL_RGBA || colorFormat.format == GL_BGRA_EXT;
1544     config.colorBufferType    = EGL_RGB_BUFFER;
1545     config.configCaveat       = GetConfigCaveat(colorFormat.internalFormat);
1546     config.conformant         = es1Support | es2Support | es3Support;
1547     config.depthSize          = depthStencilFormat.depthBits;
1548     config.stencilSize        = depthStencilFormat.stencilBits;
1549     config.level              = 0;
1550     config.matchNativePixmap  = EGL_NONE;
1551     config.maxPBufferWidth    = physicalDeviceProperties.limits.maxImageDimension2D;
1552     config.maxPBufferHeight   = physicalDeviceProperties.limits.maxImageDimension2D;
1553     config.maxPBufferPixels   = ComputeMaximumPBufferPixels(physicalDeviceProperties);
1554     config.maxSwapInterval    = 1;
1555     config.minSwapInterval    = 0;
1556     config.nativeRenderable   = EGL_TRUE;
1557     config.nativeVisualID     = static_cast<EGLint>(GetNativeVisualID(colorFormat));
1558     config.nativeVisualType   = EGL_NONE;
1559     config.renderableType     = es1Support | es2Support | es3Support;
1560     config.sampleBuffers      = (sampleCount > 0) ? 1 : 0;
1561     config.samples            = sampleCount;
1562     config.surfaceType        = EGL_WINDOW_BIT | EGL_PBUFFER_BIT;
1563     if (display->getExtensions().mutableRenderBufferKHR)
1564     {
1565         config.surfaceType |= EGL_MUTABLE_RENDER_BUFFER_BIT_KHR;
1566     }
1567     // Vulkan surfaces use a different origin than OpenGL, always prefer to be flipped vertically if
1568     // possible.
1569     config.optimalOrientation    = EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE;
1570     config.transparentType       = EGL_NONE;
1571     config.transparentRedValue   = 0;
1572     config.transparentGreenValue = 0;
1573     config.transparentBlueValue  = 0;
1574     config.colorComponentType =
1575         gl_egl::GLComponentTypeToEGLColorComponentType(colorFormat.componentType);
1576     // LockSurface matching
1577     config.matchFormat = GetMatchFormat(colorFormat.internalFormat);
1578     if (config.matchFormat != EGL_NONE)
1579     {
1580         config.surfaceType |= EGL_LOCK_SURFACE_BIT_KHR;
1581     }
1582 
1583     // Vulkan always supports off-screen rendering.  Check the config with display to see if it can
1584     // also have window support.  If not, the following call should automatically remove
1585     // EGL_WINDOW_BIT.
1586     display->checkConfigSupport(&config);
1587 
1588     return config;
1589 }
1590 
1591 }  // anonymous namespace
1592 
GenerateConfigs(const GLenum * colorFormats,size_t colorFormatsCount,const GLenum * depthStencilFormats,size_t depthStencilFormatCount,DisplayVk * display)1593 egl::ConfigSet GenerateConfigs(const GLenum *colorFormats,
1594                                size_t colorFormatsCount,
1595                                const GLenum *depthStencilFormats,
1596                                size_t depthStencilFormatCount,
1597                                DisplayVk *display)
1598 {
1599     ASSERT(colorFormatsCount > 0);
1600     ASSERT(display != nullptr);
1601 
1602     gl::SupportedSampleSet colorSampleCounts;
1603     gl::SupportedSampleSet depthStencilSampleCounts;
1604     gl::SupportedSampleSet sampleCounts;
1605 
1606     const VkPhysicalDeviceLimits &limits =
1607         display->getRenderer()->getPhysicalDeviceProperties().limits;
1608     const uint32_t depthStencilSampleCountsLimit = limits.framebufferDepthSampleCounts &
1609                                                    limits.framebufferStencilSampleCounts &
1610                                                    vk_gl::kSupportedSampleCounts;
1611 
1612     vk_gl::AddSampleCounts(limits.framebufferColorSampleCounts & vk_gl::kSupportedSampleCounts,
1613                            &colorSampleCounts);
1614     vk_gl::AddSampleCounts(depthStencilSampleCountsLimit, &depthStencilSampleCounts);
1615 
1616     // Always support 0 samples
1617     colorSampleCounts.insert(0);
1618     depthStencilSampleCounts.insert(0);
1619 
1620     std::set_intersection(colorSampleCounts.begin(), colorSampleCounts.end(),
1621                           depthStencilSampleCounts.begin(), depthStencilSampleCounts.end(),
1622                           std::inserter(sampleCounts, sampleCounts.begin()));
1623 
1624     egl::ConfigSet configSet;
1625 
1626     for (size_t colorFormatIdx = 0; colorFormatIdx < colorFormatsCount; colorFormatIdx++)
1627     {
1628         const gl::InternalFormat &colorFormatInfo =
1629             gl::GetSizedInternalFormatInfo(colorFormats[colorFormatIdx]);
1630         ASSERT(colorFormatInfo.sized);
1631 
1632         for (size_t depthStencilFormatIdx = 0; depthStencilFormatIdx < depthStencilFormatCount;
1633              depthStencilFormatIdx++)
1634         {
1635             const gl::InternalFormat &depthStencilFormatInfo =
1636                 gl::GetSizedInternalFormatInfo(depthStencilFormats[depthStencilFormatIdx]);
1637             ASSERT(depthStencilFormats[depthStencilFormatIdx] == GL_NONE ||
1638                    depthStencilFormatInfo.sized);
1639 
1640             const gl::SupportedSampleSet *configSampleCounts = &sampleCounts;
1641             // If there is no depth/stencil buffer, use the color samples set.
1642             if (depthStencilFormats[depthStencilFormatIdx] == GL_NONE)
1643             {
1644                 configSampleCounts = &colorSampleCounts;
1645             }
1646             // If there is no color buffer, use the depth/stencil samples set.
1647             else if (colorFormats[colorFormatIdx] == GL_NONE)
1648             {
1649                 configSampleCounts = &depthStencilSampleCounts;
1650             }
1651 
1652             for (EGLint sampleCount : *configSampleCounts)
1653             {
1654                 egl::Config config = GenerateDefaultConfig(display, colorFormatInfo,
1655                                                            depthStencilFormatInfo, sampleCount);
1656                 configSet.add(config);
1657             }
1658         }
1659     }
1660 
1661     return configSet;
1662 }
1663 
1664 }  // namespace egl_vk
1665 
1666 }  // namespace rx
1667