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