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 // FeaturesVk.h: Optional features for the Vulkan renderer.
7 //
8 
9 #ifndef ANGLE_PLATFORM_FEATURESVK_H_
10 #define ANGLE_PLATFORM_FEATURESVK_H_
11 
12 #include "platform/Feature.h"
13 
14 #include <array>
15 
16 namespace angle
17 {
18 
19 struct FeaturesVk : FeatureSetBase
20 {
21     FeaturesVk();
22     ~FeaturesVk();
23 
24     // Line segment rasterization must follow OpenGL rules. This means using an algorithm similar
25     // to Bresenham's. Vulkan uses a different algorithm. This feature enables the use of pixel
26     // shader patching to implement OpenGL basic line rasterization rules. This feature will
27     // normally always be enabled. Exposing it as an option enables performance testing.
28     Feature basicGLLineRasterization = {
29         "basicGLLineRasterization", FeatureCategory::VulkanFeatures,
30         "Enable the use of pixel shader patching to implement OpenGL basic line "
31         "rasterization rules",
32         &members};
33 
34     // If the VK_EXT_line_rasterization extension is available we'll use it to get
35     // Bresenham line rasterization.
36     Feature bresenhamLineRasterization = {
37         "bresenhamLineRasterization", FeatureCategory::VulkanFeatures,
38         "Enable Bresenham line rasterization via VK_EXT_line_rasterization extension", &members};
39 
40     // If the VK_EXT_provoking_vertex extension is available, we'll use it to set
41     // the provoking vertex mode
42     Feature provokingVertex = {"provokingVertex", FeatureCategory::VulkanFeatures,
43                                "Enable provoking vertex mode via VK_EXT_provoking_vertex extension",
44                                &members};
45 
46     // Add an extra copy region when using vkCmdCopyBuffer as the Windows Intel driver seems
47     // to have a bug where the last region is ignored.
48     Feature extraCopyBufferRegion = {
49         "extraCopyBufferRegion", FeatureCategory::VulkanWorkarounds,
50         "Some drivers seem to have a bug where the last copy region in vkCmdCopyBuffer is ignored",
51         &members};
52 
53     // This flag is added for the sole purpose of end2end tests, to test the correctness
54     // of various algorithms when a fallback format is used, such as using a packed format to
55     // emulate a depth- or stencil-only format.
56     Feature forceFallbackFormat = {"forceFallbackFormat", FeatureCategory::VulkanWorkarounds,
57                                    "Force a fallback format for angle_end2end_tests", &members};
58 
59     // On some NVIDIA drivers the point size range reported from the API is inconsistent with the
60     // actual behavior. Clamp the point size to the value from the API to fix this.
61     // Tracked in http://anglebug.com/2970.
62     Feature clampPointSize = {
63         "clampPointSize", FeatureCategory::VulkanWorkarounds,
64         "The point size range reported from the API is inconsistent with the actual behavior",
65         &members, "http://anglebug.com/2970"};
66 
67     // On some NVIDIA drivers the depth value is not clamped to [0,1] for floating point depth
68     // buffers. This is NVIDIA bug 3171019, see http://anglebug.com/3970 for details.
69     Feature depthClamping = {
70         "depth_clamping", FeatureCategory::VulkanWorkarounds,
71         "The depth value is not clamped to [0,1] for floating point depth buffers.", &members,
72         "http://anglebug.com/3970"};
73 
74     // On some android devices, the memory barrier between the compute shader that converts vertex
75     // attributes and the vertex shader that reads from it is ineffective.  Only known workaround is
76     // to perform a flush after the conversion.  http://anglebug.com/3016
77     Feature flushAfterVertexConversion = {
78         "flushAfterVertexConversion", FeatureCategory::VulkanWorkarounds,
79         "The memory barrier between the compute shader that converts vertex attributes and the "
80         "vertex shader that reads from it is ineffective",
81         &members, "http://anglebug.com/3016"};
82 
83     Feature supportsRenderpass2 = {"supportsRenderpass2", FeatureCategory::VulkanFeatures,
84                                    "VkDevice supports the VK_KHR_create_renderpass2 extension",
85                                    &members};
86 
87     // Whether the VkDevice supports the VK_KHR_incremental_present extension, on which the
88     // EGL_KHR_swap_buffers_with_damage extension can be layered.
89     Feature supportsIncrementalPresent = {
90         "supportsIncrementalPresent", FeatureCategory::VulkanFeatures,
91         "VkDevice supports the VK_KHR_incremental_present extension", &members};
92 
93     // Whether texture copies on cube map targets should be done on GPU.  This is a workaround for
94     // Intel drivers on windows that have an issue with creating single-layer views on cube map
95     // textures.
96     Feature forceCPUPathForCubeMapCopy = {
97         "forceCPUPathForCubeMapCopy", FeatureCategory::VulkanWorkarounds,
98         "Some drivers have an issue with creating single-layer views on cube map textures",
99         &members};
100 
101     // Whether the VkDevice supports the VK_ANDROID_external_memory_android_hardware_buffer
102     // extension, on which the EGL_ANDROID_image_native_buffer extension can be layered.
103     Feature supportsAndroidHardwareBuffer = {
104         "supportsAndroidHardwareBuffer", FeatureCategory::VulkanFeatures,
105         "VkDevice supports the VK_ANDROID_external_memory_android_hardware_buffer extension",
106         &members};
107 
108     // Whether the VkDevice supports the VK_GGP_frame_token extension, on which
109     // the EGL_ANGLE_swap_with_frame_token extension can be layered.
110     Feature supportsGGPFrameToken = {"supportsGGPFrameToken", FeatureCategory::VulkanFeatures,
111                                      "VkDevice supports the VK_GGP_frame_token extension",
112                                      &members};
113 
114     // Whether the VkDevice supports the VK_KHR_external_memory_fd extension, on which the
115     // GL_EXT_memory_object_fd extension can be layered.
116     Feature supportsExternalMemoryFd = {"supportsExternalMemoryFd", FeatureCategory::VulkanFeatures,
117                                         "VkDevice supports the VK_KHR_external_memory_fd extension",
118                                         &members};
119 
120     // Whether the VkDevice supports the VK_FUCHSIA_external_memory
121     // extension, on which the GL_ANGLE_memory_object_fuchsia extension can be layered.
122     Feature supportsExternalMemoryFuchsia = {
123         "supportsExternalMemoryFuchsia", FeatureCategory::VulkanFeatures,
124         "VkDevice supports the VK_FUCHSIA_external_memory extension", &members};
125 
126     Feature supportsFilteringPrecision = {
127         "supportsFilteringPrecision", FeatureCategory::VulkanFeatures,
128         "VkDevice supports the VK_GOOGLE_sampler_filtering_precision extension", &members};
129 
130     // Whether the VkDevice supports the VK_KHR_external_fence_capabilities extension.
131     Feature supportsExternalFenceCapabilities = {
132         "supportsExternalFenceCapabilities", FeatureCategory::VulkanFeatures,
133         "VkDevice supports the VK_KHR_external_fence_capabilities extension", &members};
134 
135     // Whether the VkDevice supports the VK_KHR_external_semaphore_capabilities extension.
136     Feature supportsExternalSemaphoreCapabilities = {
137         "supportsExternalSemaphoreCapabilities", FeatureCategory::VulkanFeatures,
138         "VkDevice supports the VK_KHR_external_semaphore_capabilities extension", &members};
139 
140     // Whether the VkDevice supports the VK_KHR_external_semaphore_fd extension, on which the
141     // GL_EXT_semaphore_fd extension can be layered.
142     Feature supportsExternalSemaphoreFd = {
143         "supportsExternalSemaphoreFd", FeatureCategory::VulkanFeatures,
144         "VkDevice supports the VK_KHR_external_semaphore_fd extension", &members};
145 
146     // Whether the VkDevice supports the VK_FUCHSIA_external_semaphore
147     // extension, on which the GL_ANGLE_semaphore_fuchsia extension can be layered.
148     angle::Feature supportsExternalSemaphoreFuchsia = {
149         "supportsExternalSemaphoreFuchsia", FeatureCategory::VulkanFeatures,
150         "VkDevice supports the VK_FUCHSIA_external_semaphore extension", &members};
151 
152     // Whether the VkDevice supports the VK_KHR_external_fence_fd extension, on which the
153     // EGL_ANDROID_native_fence extension can be layered.
154     Feature supportsExternalFenceFd = {"supportsExternalFenceFd", FeatureCategory::VulkanFeatures,
155                                        "VkDevice supports the VK_KHR_external_fence_fd extension",
156                                        &members, "http://anglebug.com/2517"};
157 
158     // Whether the VkDevice can support EGL_ANDROID_native_fence_sync extension.
159     Feature supportsAndroidNativeFenceSync = {
160         "supportsAndroidNativeFenceSync", FeatureCategory::VulkanFeatures,
161         "VkDevice supports the EGL_ANDROID_native_fence_sync extension", &members,
162         "http://anglebug.com/2517"};
163 
164     // Whether the VkDevice can support the imageCubeArray feature properly.
165     Feature supportsImageCubeArray = {"supportsImageCubeArray", FeatureCategory::VulkanFeatures,
166                                       "VkDevice supports the imageCubeArray feature properly",
167                                       &members, "http://anglebug.com/3584"};
168 
169     // Whether the VkDevice supports the pipelineStatisticsQuery feature.
170     Feature supportsPipelineStatisticsQuery = {
171         "supportsPipelineStatisticsQuery", FeatureCategory::VulkanFeatures,
172         "VkDevice supports the pipelineStatisticsQuery feature", &members,
173         "http://anglebug.com/5430"};
174 
175     // Whether the VkDevice supports the VK_EXT_shader_stencil_export extension, which is used to
176     // perform multisampled resolve of stencil buffer.  A multi-step workaround is used instead if
177     // this extension is not available.
178     Feature supportsShaderStencilExport = {
179         "supportsShaderStencilExport", FeatureCategory::VulkanFeatures,
180         "VkDevice supports the VK_EXT_shader_stencil_export extension", &members};
181 
182     // Whether the VkDevice supports the VK_KHR_sampler_ycbcr_conversion extension, which is needed
183     // to support Ycbcr conversion with external images.
184     Feature supportsYUVSamplerConversion = {
185         "supportsYUVSamplerConversion", FeatureCategory::VulkanFeatures,
186         "VkDevice supports the VK_KHR_sampler_ycbcr_conversion extension", &members};
187 
188     // Where VK_EXT_transform_feedback is not support, an emulation path is used.
189     // http://anglebug.com/3205
190     Feature emulateTransformFeedback = {
191         "emulateTransformFeedback", FeatureCategory::VulkanFeatures,
192         "Emulate transform feedback as the VK_EXT_transform_feedback is not present.", &members,
193         "http://anglebug.com/3205"};
194 
195     // Where VK_EXT_transform_feedback is supported, it's preferred over an emulation path.
196     // http://anglebug.com/3206
197     Feature supportsTransformFeedbackExtension = {
198         "supportsTransformFeedbackExtension", FeatureCategory::VulkanFeatures,
199         "Transform feedback uses the VK_EXT_transform_feedback extension.", &members,
200         "http://anglebug.com/3206"};
201 
202     // Whether the VkDevice supports the VK_EXT_index_type_uint8 extension
203     // http://anglebug.com/4405
204     Feature supportsIndexTypeUint8 = {"supportsIndexTypeUint8", FeatureCategory::VulkanFeatures,
205                                       "VkDevice supports the VK_EXT_index_type_uint8 extension",
206                                       &members, "http://anglebug.com/4405"};
207 
208     // Whether the VkDevice supports the VK_EXT_custom_border_color extension
209     // http://anglebug.com/3577
210     Feature supportsCustomBorderColorEXT = {
211         "supports_custom_border_color", FeatureCategory::VulkanFeatures,
212         "VkDevice supports the VK_EXT_custom_border_color extension", &members,
213         "http://anglebug.com/3577"};
214 
215     // Whether the VkDevice supports the VK_KHR_depth_stencil_resolve extension with the
216     // independentResolveNone feature.
217     // http://anglebug.com/4836
218     Feature supportsDepthStencilResolve = {"supportsDepthStencilResolve",
219                                            FeatureCategory::VulkanFeatures,
220                                            "VkDevice supports the VK_KHR_depth_stencil_resolve "
221                                            "extension with the independentResolveNone feature",
222                                            &members, "http://anglebug.com/4836"};
223 
224     // Whether the VkDevice supports the VK_EXT_multisampled_render_to_single_sampled extension.
225     // http://anglebug.com/4836
226     Feature supportsMultisampledRenderToSingleSampled = {
227         "supportsMultisampledRenderToSingleSampled", FeatureCategory::VulkanFeatures,
228         "VkDevice supports the VK_EXT_multisampled_render_to_single_sampled extension", &members,
229         "http://anglebug.com/4836"};
230 
231     // Whether the VkDevice supports the VK_KHR_multiview extension.  http://anglebug.com/6048
232     Feature supportsMultiview = {"supportsMultiview", FeatureCategory::VulkanFeatures,
233                                  "VkDevice supports the VK_KHR_multiview extension", &members,
234                                  "http://anglebug.com/6048"};
235 
236     // VK_PRESENT_MODE_FIFO_KHR causes random timeouts on Linux Intel. http://anglebug.com/3153
237     Feature disableFifoPresentMode = {"disableFifoPresentMode", FeatureCategory::VulkanWorkarounds,
238                                       "VK_PRESENT_MODE_FIFO_KHR causes random timeouts", &members,
239                                       "http://anglebug.com/3153"};
240 
241     // On Qualcomm, gaps in bound descriptor set indices causes the post-gap sets to misbehave.
242     // For example, binding only descriptor set 3 results in zero being read from a uniform buffer
243     // object within that set.  This flag results in empty descriptor sets being bound for any
244     // unused descriptor set to work around this issue.  http://anglebug.com/2727
245     Feature bindEmptyForUnusedDescriptorSets = {
246         "bindEmptyForUnusedDescriptorSets", FeatureCategory::VulkanWorkarounds,
247         "Gaps in bound descriptor set indices causes the post-gap sets to misbehave", &members,
248         "http://anglebug.com/2727"};
249 
250     // OES_depth_texture is a commonly expected feature on Android. However it
251     // requires that D16_UNORM support texture filtering
252     // (e.g. VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) and some devices
253     // do not. Work-around this by setting saying D16_UNORM supports filtering
254     // anyway.
255     Feature forceD16TexFilter = {
256         "forceD16TexFilter", FeatureCategory::VulkanWorkarounds,
257         "VK_FORMAT_D16_UNORM does not support VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT, "
258         "which prevents OES_depth_texture from being supported.",
259         &members, "http://anglebug.com/3452"};
260 
261     // On some android devices, vkCmdBlitImage with flipped coordinates blits incorrectly.  This
262     // workaround makes sure this path is avoided.  http://anglebug.com/3498
263     Feature disableFlippingBlitWithCommand = {
264         "disableFlippingBlitWithCommand", FeatureCategory::VulkanWorkarounds,
265         "vkCmdBlitImage with flipped coordinates blits incorrectly.", &members,
266         "http://anglebug.com/3498"};
267 
268     // On platform with Intel or AMD GPU, a window resizing would not trigger the vulkan driver to
269     // return VK_ERROR_OUT_OF_DATE on swapchain present.  Work-around by query current window extent
270     // every frame to detect a window resizing.
271     // http://anglebug.com/3623, http://anglebug.com/3624, http://anglebug.com/3625
272     Feature perFrameWindowSizeQuery = {
273         "perFrameWindowSizeQuery", FeatureCategory::VulkanWorkarounds,
274         "Vulkan swapchain is not returning VK_ERROR_OUT_OF_DATE when window resizing", &members,
275         "http://anglebug.com/3623, http://anglebug.com/3624, http://anglebug.com/3625"};
276 
277     // Seamful cube map emulation misbehaves on the AMD windows driver, so it's disallowed.
278     Feature disallowSeamfulCubeMapEmulation = {
279         "disallowSeamfulCubeMapEmulation", FeatureCategory::VulkanWorkarounds,
280         "Seamful cube map emulation misbehaves on some drivers, so it's disallowed", &members,
281         "http://anglebug.com/3243"};
282 
283     // Vulkan considers vertex attribute accesses to count up to the last multiple of the stride.
284     // This additional access supports AMD's robust buffer access implementation.
285     // AMDVLK in particular will return incorrect values when the vertex access extends into the
286     // range that would be the stride padding and the buffer is too small.
287     // This workaround limits GL_MAX_VERTEX_ATTRIB_STRIDE to a reasonable value and pads out
288     // every buffer allocation size to be large enough to support a maximum vertex stride.
289     // http://anglebug.com/4428
290     Feature padBuffersToMaxVertexAttribStride = {
291         "padBuffersToMaxVertexAttribStride", FeatureCategory::VulkanWorkarounds,
292         "Vulkan considers vertex attribute accesses to count up to the last multiple of the "
293         "stride. This additional access supports AMD's robust buffer access implementation. "
294         "AMDVLK in particular will return incorrect values when the vertex access extends into "
295         "the range that would be the stride padding and the buffer is too small. "
296         "This workaround limits GL_MAX_VERTEX_ATTRIB_STRIDE to a maximum value and "
297         "pads up every buffer allocation size to be a multiple of the maximum stride.",
298         &members, "http://anglebug.com/4428"};
299 
300     // Whether the VkDevice supports the VK_EXT_swapchain_colorspace extension
301     // http://anglebug.com/2514
302     Feature supportsSwapchainColorspace = {
303         "supportsSwapchainColorspace", FeatureCategory::VulkanFeatures,
304         "VkDevice supports the VK_EXT_swapchain_colorspace extension", &members,
305         "http://anglebug.com/2514"};
306 
307     // Whether the VkDevice supports the VK_EXT_external_memory_host extension, on which the
308     // ANGLE_iosurface_client_buffer extension can be layered.
309     Feature supportsExternalMemoryHost = {
310         "supportsExternalMemoryHost", FeatureCategory::VulkanFeatures,
311         "VkDevice supports the VK_EXT_external_memory_host extension", &members};
312 
313     // Whether to fill new buffers and textures with nonzero data to sanitize robust resource
314     // initialization and flush out assumptions about zero init.
315     Feature allocateNonZeroMemory = {
316         "allocateNonZeroMemory", FeatureCategory::VulkanFeatures,
317         "Fill new allocations with non-zero values to flush out errors.", &members,
318         "http://anglebug.com/4384"};
319 
320     // Whether to log each callback from the VK_EXT_device_memory_report extension.  This feature is
321     // used for trying to debug GPU memory leaks.
322     Feature logMemoryReportCallbacks = {"logMemoryReportCallbacks", FeatureCategory::VulkanFeatures,
323                                         "Log each callback from VK_EXT_device_memory_report",
324                                         &members};
325 
326     // Whether to log statistics from the VK_EXT_device_memory_report extension each eglSwapBuffer.
327     Feature logMemoryReportStats = {"logMemoryReportStats", FeatureCategory::VulkanFeatures,
328                                     "Log stats from VK_EXT_device_memory_report each swap",
329                                     &members};
330 
331     // Allocate a "shadow" buffer for GL buffer objects. For GPU-read only buffers
332     // glMap* latency can be reduced by maintaining a copy of the buffer which is
333     // writeable only by the CPU. We then return this shadow buffer on glMap* calls.
334     Feature shadowBuffers = {
335         "shadowBuffers", FeatureCategory::VulkanFeatures,
336         "Allocate a shadow buffer for GL buffer objects to reduce glMap* latency.", &members,
337         "http://anglebug.com/4339"};
338 
339     // Persistently map buffer memory until destroy, saves on map/unmap IOCTL overhead
340     // for buffers that are updated frequently.
341     Feature persistentlyMappedBuffers = {
342         "persistentlyMappedBuffers", FeatureCategory::VulkanFeatures,
343         "Persistently map buffer memory to reduce map/unmap IOCTL overhead.", &members,
344         "http://anglebug.com/2162"};
345 
346     // Android needs to pre-rotate surfaces that are not oriented per the native device's
347     // orientation (e.g. a landscape application on a Pixel phone).  This feature works for
348     // full-screen applications. http://anglebug.com/3502
349     Feature enablePreRotateSurfaces = {"enablePreRotateSurfaces", FeatureCategory::VulkanFeatures,
350                                        "Enable Android pre-rotation for landscape applications",
351                                        &members, "http://anglebug.com/3502"};
352 
353     // Enable precision qualifiers for shaders generated by Vulkan backend http://anglebug.com/3078
354     Feature enablePrecisionQualifiers = {
355         "enablePrecisionQualifiers", FeatureCategory::VulkanFeatures,
356         "Enable precision qualifiers in shaders", &members, "http://anglebug.com/3078"};
357 
358     // Desktop (at least NVIDIA) drivers prefer combining barriers into one vkCmdPipelineBarrier
359     // call over issuing multiple barrier calls with fine grained dependency information to have
360     // better performance. http://anglebug.com/4633
361     Feature preferAggregateBarrierCalls = {
362         "preferAggregateBarrierCalls", FeatureCategory::VulkanWorkarounds,
363         "Single barrier call is preferred over multiple calls with "
364         "fine grained pipeline stage dependency information",
365         &members, "http://anglebug.com/4633"};
366 
367     // Tell the Vulkan back-end to use the async command queue to dispatch work to the GPU. Command
368     // buffer work will happened in a worker thread. Otherwise use Renderer::CommandQueue directly.
369     Feature asyncCommandQueue = {"asyncCommandQueue", FeatureCategory::VulkanFeatures,
370                                  "Use CommandQueue worker thread to dispatch work to GPU.",
371                                  &members, "http://anglebug.com/4324"};
372 
373     // Whether the VkDevice supports the VK_KHR_shader_float16_int8 extension and has the
374     // shaderFloat16 feature.
375     Feature supportsShaderFloat16 = {"supportsShaderFloat16", FeatureCategory::VulkanFeatures,
376                                      "VkDevice supports the VK_KHR_shader_float16_int8 extension "
377                                      "and has the shaderFloat16 feature",
378                                      &members, "http://anglebug.com/4551"};
379 
380     // Some devices don't meet the limits required to perform mipmap generation using the built-in
381     // compute shader.  On some other devices, VK_IMAGE_USAGE_STORAGE_BIT is detrimental to
382     // performance, making this solution impractical.
383     Feature allowGenerateMipmapWithCompute = {
384         "allowGenerateMipmapWithCompute", FeatureCategory::VulkanFeatures,
385         "Use the compute path to generate mipmaps on devices that meet the minimum requirements, "
386         "and the performance is better.",
387         &members, "http://anglebug.com/4551"};
388 
389     // Whether the VkDevice supports the VK_QCOM_render_pass_store_ops extension
390     // http://anglebug.com/5505
391     Feature supportsRenderPassStoreOpNoneQCOM = {
392         "supportsRenderPassStoreOpNoneQCOM", FeatureCategory::VulkanFeatures,
393         "VkDevice supports VK_QCOM_render_pass_store_ops extension.", &members,
394         "http://anglebug.com/5055"};
395 
396     // Force maxUniformBufferSize to 16K on Qualcomm's Adreno 540. Pixel2's Adreno540 reports
397     // maxUniformBufferSize 64k but various tests failed with that size. For that specific
398     // device, we set to 16k for now which is known to pass all tests.
399     // https://issuetracker.google.com/161903006
400     Feature forceMaxUniformBufferSize16KB = {
401         "forceMaxUniformBufferSize16KB", FeatureCategory::VulkanWorkarounds,
402         "Force max uniform buffer size to 16K on some device due to bug", &members,
403         "https://issuetracker.google.com/161903006"};
404 
405     // Enable mutable bit by default for ICD's that support VK_KHR_image_format_list.
406     // http://anglebug.com/5281
407     Feature supportsImageFormatList = {
408         "supportsImageFormatList", FeatureCategory::VulkanFeatures,
409         "Enable VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT by default for ICDs "
410         "that support VK_KHR_image_format_list",
411         &members, "http://anglebug.com/5281"};
412 
413     // Swiftshader on mac fails to initialize WebGL context when EXT_multisampled_render_to_texture
414     // is used by Chromium.
415     // http://anglebug.com/4937
416     Feature enableMultisampledRenderToTexture = {
417         "enableMultisampledRenderToTexture", FeatureCategory::VulkanWorkarounds,
418         "Expose EXT_multisampled_render_to_texture", &members, "http://anglebug.com/4937"};
419 
420     // Qualcomm fails some tests when reducing the preferred block size to 4M.
421     // http://anglebug.com/4995
422     Feature preferredLargeHeapBlockSize4MB = {
423         "preferredLargeHeapBlockSize4MB", FeatureCategory::VulkanWorkarounds,
424         "Use 4 MB preferred large heap block size with AMD allocator", &members,
425         "http://anglebug.com/4995"};
426 
427     // Manhattan is calling glFlush in the middle of renderpass which breaks renderpass and hurts
428     // performance on tile based GPU. When this is enabled, we will defer the glFlush call made in
429     // the middle of renderpass to the end of renderpass.
430     // https://issuetracker.google.com/issues/166475273
431     Feature deferFlushUntilEndRenderPass = {
432         "deferFlushUntilEndRenderPass", FeatureCategory::VulkanWorkarounds,
433         "Allow glFlush to be deferred until renderpass ends", &members,
434         "https://issuetracker.google.com/issues/166475273"};
435 
436     // Android mistakenly destroys oldSwapchain passed to vkCreateSwapchainKHR, causing crashes on
437     // certain drivers.  http://anglebug.com/5061
438     Feature waitIdleBeforeSwapchainRecreation = {
439         "waitIdleBeforeSwapchainRecreation", FeatureCategory::VulkanWorkarounds,
440         "Before passing an oldSwapchain to VkSwapchainCreateInfoKHR, wait for queue to be idle. "
441         "Works around a bug on platforms which destroy oldSwapchain in vkCreateSwapchainKHR.",
442         &members, "http://anglebug.com/5061"};
443 
444     // Allow forcing an LOD offset on all sampling operations for performance comparisons. ANGLE is
445     // non-conformant if this feature is enabled.
446     std::array<angle::Feature, 4> forceTextureLODOffset = {
447         angle::Feature{"force_texture_lod_offset_1", angle::FeatureCategory::VulkanWorkarounds,
448                        "Increase the minimum texture level-of-detail by 1 when sampling.",
449                        &members},
450         angle::Feature{"force_texture_lod_offset_2", angle::FeatureCategory::VulkanWorkarounds,
451                        "Increase the minimum texture level-of-detail by 2 when sampling.",
452                        &members},
453         angle::Feature{"force_texture_lod_offset_3", angle::FeatureCategory::VulkanWorkarounds,
454                        "Increase the minimum texture level-of-detail by 3 when sampling.",
455                        &members},
456         angle::Feature{"force_texture_lod_offset_4", angle::FeatureCategory::VulkanWorkarounds,
457                        "Increase the minimum texture level-of-detail by 4 when sampling.",
458                        &members},
459     };
460 
461     // Translate non-nearest filtering modes to nearest for all samplers for performance
462     // comparisons. ANGLE is non-conformant if this feature is enabled.
463     Feature forceNearestFiltering = {"force_nearest_filtering", FeatureCategory::VulkanWorkarounds,
464                                      "Force nearest filtering when sampling.", &members};
465 
466     // Translate  non-nearest mip filtering modes to nearest mip for all samplers for performance
467     // comparisons. ANGLE is non-conformant if this feature is enabled.
468     Feature forceNearestMipFiltering = {"forceNearestMipFiltering",
469                                         FeatureCategory::VulkanWorkarounds,
470                                         "Force nearest mip filtering when sampling.", &members};
471 
472     // Compress float32 vertices in static buffers to float16 at draw time. ANGLE is non-conformant
473     // if this feature is enabled.
474     angle::Feature compressVertexData = {"compress_vertex_data",
475                                          angle::FeatureCategory::VulkanWorkarounds,
476                                          "Compress vertex data to smaller data types when "
477                                          "possible. Using this feature makes ANGLE non-conformant.",
478                                          &members};
479 
480     // Qualcomm missynchronizes vkCmdClearAttachments in the middle of render pass.
481     // https://issuetracker.google.com/166809097
482     Feature preferDrawClearOverVkCmdClearAttachments = {
483         "preferDrawClearOverVkCmdClearAttachments", FeatureCategory::VulkanWorkarounds,
484         "On some hardware, clear using a draw call instead of vkCmdClearAttachments in the middle "
485         "of render pass due to bugs",
486         &members, "https://issuetracker.google.com/166809097"};
487 
488     // Whether prerotation is being emulated for testing.  90 degree rotation.
489     Feature emulatedPrerotation90 = {"emulatedPrerotation90", FeatureCategory::VulkanFeatures,
490                                      "Emulate 90-degree prerotation.", &members,
491                                      "http://anglebug.com/4901"};
492 
493     // Whether prerotation is being emulated for testing.  180 degree rotation.
494     Feature emulatedPrerotation180 = {"emulatedPrerotation180", FeatureCategory::VulkanFeatures,
495                                       "Emulate 180-degree prerotation.", &members,
496                                       "http://anglebug.com/4901"};
497 
498     // Whether prerotation is being emulated for testing.  270 degree rotation.
499     Feature emulatedPrerotation270 = {"emulatedPrerotation270", FeatureCategory::VulkanFeatures,
500                                       "Emulate 270-degree prerotation.", &members,
501                                       "http://anglebug.com/4901"};
502 
503     // Whether SPIR-V should be generated directly instead of through glslang.  Transitory feature
504     // until the work is complete.
505     Feature directSPIRVGeneration = {"directSPIRVGeneration", FeatureCategory::VulkanFeatures,
506                                      "Direct translation to SPIR-V.", &members,
507                                      "http://anglebug.com/4889"};
508 
509     // Whether SPIR-V should be generated with workarounds for buggy drivers.
510     Feature directSPIRVGenerationWorkarounds = {
511         "directSPIRVGenerationWorkarounds", FeatureCategory::VulkanWorkarounds,
512         "Work around driver bugs when translating to SPIR-V.", &members,
513         "http://anglebug.com/6110"};
514 
515     // Whether we should use driver uniforms over specialization constants for some shader
516     // modifications like yflip and rotation.
517     Feature forceDriverUniformOverSpecConst = {
518         "forceDriverUniformOverSpecConst", FeatureCategory::VulkanWorkarounds,
519         "Forces using driver uniforms instead of specialization constants.", &members,
520         "http://issuetracker.google.com/173636783"};
521 
522     // Whether non-conformant configurations and extensions should be exposed.  When an extension is
523     // in development, or a GLES version is not supported on a device, we may still want to expose
524     // them for partial testing.  This feature is enabled by our test harness.
525     Feature exposeNonConformantExtensionsAndVersions = {
526         "exposeNonConformantExtensionsAndVersions", FeatureCategory::VulkanWorkarounds,
527         "Expose GLES versions and extensions that are not conformant.", &members,
528         "http://anglebug.com/5375"};
529 
530     // imageAtomicExchange is expected to work for r32f formats, but support for atomic operations
531     // for VK_FORMAT_R32_SFLOAT is rare.  This support is emulated by using an r32ui format for such
532     // images instead.
533     Feature emulateR32fImageAtomicExchange = {
534         "emulateR32fImageAtomicExchange", FeatureCategory::VulkanWorkarounds,
535         "Emulate r32f images with r32ui to support imageAtomicExchange.", &members,
536         "http://anglebug.com/5535"};
537 
538     Feature supportsNegativeViewport = {
539         "supportsNegativeViewport", FeatureCategory::VulkanFeatures,
540         "The driver supports inverting the viewport with a negative height.", &members};
541 
542     // Whether we should force any highp precision in the fragment shader to mediump.
543     // ANGLE is non-conformant if this feature is enabled.
544     Feature forceFragmentShaderPrecisionHighpToMediump = {
545         "forceFragmentShaderPrecisionHighpToMediump", FeatureCategory::VulkanWorkarounds,
546         "Forces highp precision in fragment shader to mediump.", &members,
547         "https://issuetracker.google.com/184850002"};
548 
549     // Whether we should submit at each FBO boundary.
550     Feature preferSubmitAtFBOBoundary = {
551         "preferSubmitAtFBOBoundary", FeatureCategory::VulkanWorkarounds,
552         "Submit commands to driver at each FBO boundary for performance improvements.", &members,
553         "https://issuetracker.google.com/187425444"};
554 
555     // Workaround for gap in Vulkan spec related to querying descriptor count for immutable samplers
556     // tied to an external format.
557     Feature useMultipleDescriptorsForExternalFormats = {
558         "useMultipleDescriptorsForExternalFormats", FeatureCategory::VulkanWorkarounds,
559         "Return a default descriptor count for external formats.", &members,
560         "http://anglebug.com/6141"};
561 
562     // Whether the VkDevice can support Protected Memory.
563     Feature supportsProtectedMemory = {"supports_protected_memory", FeatureCategory::VulkanFeatures,
564                                        "VkDevice supports protected memory", &members,
565                                        "http://anglebug.com/3965"};
566 
567     // Whether the VkInstance supports the VK_KHR_get_surface_capabilities2 extension.
568     Feature supportsSurfaceCapabilities2Extension = {
569         "supportsSurfaceCapabilities2Extension", FeatureCategory::VulkanFeatures,
570         "VkInstance supports the VK_KHR_get_surface_capabilities2 extension", &members};
571 
572     // Whether the VkInstance supports the VK_KHR_surface_protected_capabilities extension.
573     Feature supportsSurfaceProtectedCapabilitiesExtension = {
574         "supportsSurfaceProtectedCapabilitiesExtension", FeatureCategory::VulkanFeatures,
575         "VkInstance supports the VK_KHR_surface_protected_capabilities extension", &members};
576 
577     // Whether the VkSurface supports protected swapchains from
578     // supportsSurfaceProtectedCapabilitiesExtension.
579     Feature supportsSurfaceProtectedSwapchains = {
580         "supportsSurfaceProtectedSwapchains", FeatureCategory::VulkanFeatures,
581         "VkSurface supportsProtected for protected swapchains", &members};
582 };
583 
584 inline FeaturesVk::FeaturesVk()  = default;
585 inline FeaturesVk::~FeaturesVk() = default;
586 
587 }  // namespace angle
588 
589 #endif  // ANGLE_PLATFORM_FEATURESVK_H_
590