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