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