blob: 23b69f999834e20fc89e159dc3e06fc205da38dd [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "garnet/public/lib/escher/util/check_vulkan_support.h"
#include <vulkan/vulkan.hpp>
namespace escher {
namespace {
vk::Instance CreateVulkanInstance() {
vk::InstanceCreateInfo instance_info;
instance_info.enabledLayerCount = 0;
instance_info.ppEnabledLayerNames = nullptr;
instance_info.enabledExtensionCount = 0;
instance_info.ppEnabledExtensionNames = nullptr;
vk::Instance instance;
if (vk::Result::eSuccess ==
vk::createInstance(&instance_info, nullptr, &instance)) {
return instance;
}
return vk::Instance();
}
vk::Device CreateVulkanDevice(vk::Instance instance) {
constexpr uint32_t kMaxPhysicalDevices = 100;
vk::PhysicalDevice physical_devices[kMaxPhysicalDevices];
uint32_t num_physical_devices = kMaxPhysicalDevices;
if (vk::Result::eSuccess != instance.enumeratePhysicalDevices(
&num_physical_devices, physical_devices)) {
return vk::Device();
}
const auto kRequiredQueueFlags = vk::QueueFlagBits::eTransfer |
vk::QueueFlagBits::eGraphics |
vk::QueueFlagBits::eCompute;
for (uint32_t i = 0; i < num_physical_devices; ++i) {
auto& physical_device = physical_devices[i];
auto queues = physical_device.getQueueFamilyProperties();
for (size_t i = 0; i < queues.size(); ++i) {
if (kRequiredQueueFlags == (queues[i].queueFlags & kRequiredQueueFlags)) {
vk::DeviceQueueCreateInfo queue_info;
const float kQueuePriority = 0;
queue_info.queueFamilyIndex = i;
queue_info.queueCount = 1;
queue_info.pQueuePriorities = &kQueuePriority;
vk::DeviceCreateInfo device_info;
device_info.queueCreateInfoCount = 1;
device_info.pQueueCreateInfos = &queue_info;
device_info.enabledExtensionCount = 0;
device_info.ppEnabledExtensionNames = nullptr;
vk::Device device;
if (vk::Result::eSuccess ==
physical_device.createDevice(&device_info, nullptr, &device)) {
return device;
}
}
}
}
return vk::Device();
}
bool CheckIfVulkanIsSupported() {
vk::Instance instance = CreateVulkanInstance();
if (!instance) {
return false;
}
vk::Device device = CreateVulkanDevice(instance);
if (!device) {
instance.destroy();
return false;
}
device.destroy();
instance.destroy();
return true;
}
} // anonymous namespace
bool VulkanIsSupported() {
static bool is_supported = CheckIfVulkanIsSupported();
return is_supported;
}
} // namespace escher