1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "vulkan_utilities.h"
6
7#include <algorithm>
8#include <unordered_set>
9
10#include "flutter/fml/build_config.h"
11
12namespace vulkan {
13
14// Whether to show Vulkan validation layer info messages in addition
15// to the error messages.
16bool ValidationLayerInfoMessagesEnabled() {
17 return false;
18}
19
20bool ValidationErrorsFatal() {
21#if OS_FUCHSIA
22 return false;
23#endif
24 return true;
25}
26
27static std::vector<std::string> InstanceOrDeviceLayersToEnable(
28 const VulkanProcTable& vk,
29 VkPhysicalDevice physical_device,
30 bool enable_validation_layers) {
31 if (!enable_validation_layers) {
32 return {};
33 }
34
35 // NOTE: The loader is sensitive to the ordering here. Please do not rearrange
36 // this list.
37#if OS_FUCHSIA
38 // The other layers in the Fuchsia SDK seem to have a bug right now causing
39 // crashes, so it is only recommended that we use VK_LAYER_KHRONOS_validation
40 // until we have a confirmation that they are fixed.
41 const std::vector<std::string> candidates = {"VK_LAYER_KHRONOS_validation"};
42#else
43 const std::vector<std::string> candidates = {
44 "VK_LAYER_GOOGLE_threading", "VK_LAYER_LUNARG_parameter_validation",
45 "VK_LAYER_LUNARG_object_tracker", "VK_LAYER_LUNARG_core_validation",
46 "VK_LAYER_LUNARG_device_limits", "VK_LAYER_LUNARG_image",
47 "VK_LAYER_LUNARG_swapchain", "VK_LAYER_GOOGLE_unique_objects"};
48#endif
49
50 uint32_t count = 0;
51
52 if (physical_device == VK_NULL_HANDLE) {
53 if (VK_CALL_LOG_ERROR(vk.EnumerateInstanceLayerProperties(
54 &count, nullptr)) != VK_SUCCESS) {
55 return {};
56 }
57 } else {
58 if (VK_CALL_LOG_ERROR(vk.EnumerateDeviceLayerProperties(
59 physical_device, &count, nullptr)) != VK_SUCCESS) {
60 return {};
61 }
62 }
63
64 std::vector<VkLayerProperties> properties;
65 properties.resize(sz: count);
66
67 if (physical_device == VK_NULL_HANDLE) {
68 if (VK_CALL_LOG_ERROR(vk.EnumerateInstanceLayerProperties(
69 &count, properties.data())) != VK_SUCCESS) {
70 return {};
71 }
72 } else {
73 if (VK_CALL_LOG_ERROR(vk.EnumerateDeviceLayerProperties(
74 physical_device, &count, properties.data())) != VK_SUCCESS) {
75 return {};
76 }
77 }
78
79 std::unordered_set<std::string> available_extensions;
80
81 for (size_t i = 0; i < count; i++) {
82 available_extensions.emplace(args&: properties[i].layerName);
83 }
84
85 std::vector<std::string> available_candidates;
86
87 for (const auto& candidate : candidates) {
88 auto found = available_extensions.find(k: candidate);
89 if (found != available_extensions.end()) {
90 available_candidates.emplace_back(args: candidate);
91 }
92 }
93
94 return available_candidates;
95}
96
97std::vector<std::string> InstanceLayersToEnable(const VulkanProcTable& vk,
98 bool enable_validation_layers) {
99 return InstanceOrDeviceLayersToEnable(vk, VK_NULL_HANDLE,
100 enable_validation_layers);
101}
102
103std::vector<std::string> DeviceLayersToEnable(
104 const VulkanProcTable& vk,
105 const VulkanHandle<VkPhysicalDevice>& physical_device,
106 bool enable_validation_layers) {
107 if (!physical_device) {
108 return {};
109 }
110
111 return InstanceOrDeviceLayersToEnable(vk, physical_device,
112 enable_validation_layers);
113}
114
115} // namespace vulkan
116

source code of flutter_engine/flutter/vulkan/vulkan_utilities.cc