18 auto extensions = vk::enumerateInstanceExtensionProperties();
19 auto layers = vk::enumerateInstanceLayerProperties();
21 if (extensions.result != vk::Result::eSuccess ||
22 layers.result != vk::Result::eSuccess) {
26 for (
const auto& ext : extensions.value) {
30 for (
const auto& layer : layers.value) {
31 const std::string layer_name = layer.layerName;
32 auto layer_exts = vk::enumerateInstanceExtensionProperties(layer_name);
33 if (layer_exts.result != vk::Result::eSuccess) {
36 for (
const auto& layer_ext : layer_exts.value) {
37 exts_[layer_name].insert(layer_ext.extensionName);
41 validations_enabled_ =
42 enable_validations && HasLayer(
"VK_LAYER_KHRONOS_validation");
43 if (enable_validations && !validations_enabled_) {
45 <<
"Requested Impeller context creation with validations but the "
46 "validation layers could not be found. Expect no Vulkan validation "
49 if (validations_enabled_) {
50 FML_LOG(INFO) <<
"Vulkan validations are enabled.";
62 return validations_enabled_;
67 std::vector<std::string> required;
69 if (validations_enabled_) {
71 required.push_back(
"VK_LAYER_KHRONOS_validation");
77 std::optional<std::vector<std::string>>
79 std::vector<std::string> required;
81 if (!HasExtension(
"VK_KHR_surface")) {
87 required.push_back(
"VK_KHR_surface");
90 if (HasExtension(
"VK_MVK_macos_surface")) {
91 required.push_back(
"VK_MVK_macos_surface");
95 if (HasExtension(
"VK_EXT_metal_surface")) {
96 required.push_back(
"VK_EXT_metal_surface");
100 if (HasExtension(
"VK_KHR_portability_enumeration")) {
101 required.push_back(
"VK_KHR_portability_enumeration");
105 if (HasExtension(
"VK_KHR_win32_surface")) {
106 required.push_back(
"VK_KHR_win32_surface");
110 if (HasExtension(
"VK_KHR_android_surface")) {
111 required.push_back(
"VK_KHR_android_surface");
115 if (HasExtension(
"VK_KHR_xcb_surface")) {
116 required.push_back(
"VK_KHR_xcb_surface");
120 if (HasExtension(
"VK_KHR_xlib_surface")) {
121 required.push_back(
"VK_KHR_xlib_surface");
125 if (HasExtension(
"VK_KHR_wayland_surface")) {
126 required.push_back(
"VK_KHR_wayland_surface");
137 if (validations_enabled_) {
138 if (!HasExtension(
"VK_EXT_debug_utils")) {
140 "VK_EXT_debug_utils extension.";
143 required.push_back(
"VK_EXT_debug_utils");
145 if (HasExtension(
"VK_EXT_validation_features")) {
148 required.push_back(
"VK_EXT_validation_features");
158 return VK_EXT_PIPELINE_CREATION_FEEDBACK_EXTENSION_NAME;
177 const vk::PhysicalDevice& physical_device) {
178 auto device_extensions = physical_device.enumerateDeviceExtensionProperties();
179 if (device_extensions.result != vk::Result::eSuccess) {
183 std::set<std::string> exts;
184 for (
const auto& device_extension : device_extensions.value) {
185 exts.insert(device_extension.extensionName);
191 std::optional<std::vector<std::string>>
193 const vk::PhysicalDevice& physical_device)
const {
196 if (!exts.has_value()) {
200 std::vector<std::string> enabled;
202 if (exts->find(
"VK_KHR_swapchain") == exts->end()) {
203 VALIDATION_LOG <<
"Device does not support the swapchain extension.";
206 enabled.push_back(
"VK_KHR_swapchain");
209 if (exts->find(
"VK_KHR_portability_subset") != exts->end()) {
210 enabled.push_back(
"VK_KHR_portability_subset");
213 #ifdef FML_OS_ANDROID
214 if (exts->find(
"VK_ANDROID_external_memory_android_hardware_buffer") ==
217 <<
"Device does not support "
218 "VK_ANDROID_external_memory_android_hardware_buffer extension.";
221 enabled.push_back(
"VK_ANDROID_external_memory_android_hardware_buffer");
222 enabled.push_back(
"VK_EXT_queue_family_foreign");
228 if (exts->find(ext_name) != exts->end()) {
229 enabled.push_back(ext_name);
238 const auto props = device.getFormatProperties(format);
240 return !!(props.optimalTilingFeatures &
241 vk::FormatFeatureFlagBits::eColorAttachment);
246 const auto props = device.getFormatProperties(format);
247 return !!(props.optimalTilingFeatures &
248 vk::FormatFeatureFlagBits::eDepthStencilAttachment);
252 const vk::PhysicalDevice& device) {
253 const auto has_color_format =
255 const auto has_stencil_format =
259 return has_color_format && has_stencil_format;
263 auto properties = physical_device.getProperties();
264 if (!(properties.limits.framebufferColorSampleCounts &
265 (vk::SampleCountFlagBits::e1 | vk::SampleCountFlagBits::e4))) {
272 auto queue_flags = vk::QueueFlags{};
273 for (
const auto& queue : physical_device.getQueueFamilyProperties()) {
274 if (queue.queueCount == 0) {
277 queue_flags |= queue.queueFlags;
279 return static_cast<VkQueueFlags
>(queue_flags &
280 (vk::QueueFlagBits::eGraphics |
281 vk::QueueFlagBits::eCompute |
282 vk::QueueFlagBits::eTransfer));
285 std::optional<vk::PhysicalDeviceFeatures>
287 const vk::PhysicalDevice& device)
const {
294 VALIDATION_LOG <<
"Device doesn't support the required properties.";
308 const auto device_features = device.getFeatures();
310 vk::PhysicalDeviceFeatures required;
314 required.fillModeNonSolid = device_features.fillModeNonSolid;
319 bool CapabilitiesVK::HasLayer(
const std::string& layer)
const {
320 for (
const auto& [found_layer, exts] : exts_) {
321 if (found_layer == layer) {
328 bool CapabilitiesVK::HasExtension(
const std::string& ext)
const {
329 for (
const auto& [layer, exts] : exts_) {
330 if (exts.find(ext) != exts.end()) {
338 default_color_format_ = pixel_format;
345 vk::Format::eD24UnormS8Uint)) {
354 default_stencil_format_ = default_depth_stencil_format_;
359 device_properties_ = device.getProperties();
361 auto physical_properties_2 =
362 device.getProperties2<vk::PhysicalDeviceProperties2,
363 vk::PhysicalDeviceSubgroupProperties>();
369 supports_compute_subgroups_ =
370 !!(physical_properties_2.get<vk::PhysicalDeviceSubgroupProperties>()
371 .supportedOperations &
372 vk::SubgroupFeatureFlagBits::eArithmetic);
378 vk::PhysicalDeviceMemoryProperties memory_properties;
379 device.getMemoryProperties(&memory_properties);
381 for (
auto i = 0u; i < memory_properties.memoryTypeCount; i++) {
382 if (memory_properties.memoryTypes[i].propertyFlags &
383 vk::MemoryPropertyFlagBits::eLazilyAllocated) {
384 supports_device_transient_textures_ =
true;
391 optional_device_extensions_.clear();
393 if (!exts.has_value()) {
398 if (exts->find(ext_name) != exts->end()) {
399 optional_device_extensions_.insert(ext);
441 return supports_compute_subgroups_;
460 return supports_device_transient_textures_;
465 return default_color_format_;
470 return default_stencil_format_;
475 return default_depth_stencil_format_;
478 const vk::PhysicalDeviceProperties&
480 return device_properties_;
485 return optional_device_extensions_.find(extension) !=
486 optional_device_extensions_.end();