blob: ef3915b531e6017a835f32fdf155a83863ddbd01 [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 "vulkan_physical_device.h"
#include "utils.h"
#include "vulkan_swapchain.h"
namespace {
const char *kMagmaLayer = "VK_LAYER_FUCHSIA_imagepipe_swapchain_fb";
static const std::vector<const char *> s_required_phys_device_props = {
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
#ifdef __Fuchsia__
VK_FUCHSIA_EXTERNAL_MEMORY_EXTENSION_NAME,
VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME,
VK_FUCHSIA_EXTERNAL_SEMAPHORE_EXTENSION_NAME,
VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME,
#endif
};
bool ChooseGraphicsDevice(const vk::PhysicalDevice &phys_device, const VkSurfaceKHR &surface,
vk::PhysicalDevice *phys_device_out) {
if (FindMatchingProperties(s_required_phys_device_props, vkp::PHYS_DEVICE_EXT_PROP, &phys_device,
kMagmaLayer, nullptr /* missing_props */)) {
return false;
}
VulkanSwapchain::Info swapchain_info;
if (!VulkanSwapchain::QuerySwapchainSupport(phys_device, surface, &swapchain_info)) {
return false;
}
if (!vkp::FindGraphicsQueueFamilies(phys_device, surface, nullptr)) {
RTN_MSG(false, "No graphics queue families.\n");
}
*phys_device_out = phys_device;
return true;
}
} // namespace
VulkanPhysicalDevice::VulkanPhysicalDevice(std::shared_ptr<VulkanInstance> instance,
const VkSurfaceKHR &surface)
: initialized_(false), instance_(instance) {
params_ = std::make_unique<InitParams>(surface);
}
VulkanPhysicalDevice::InitParams::InitParams(const VkSurfaceKHR &surface) : surface_(surface) {}
bool VulkanPhysicalDevice::Init() {
if (initialized_) {
RTN_MSG(false, "VulkanPhysicalDevice already initialized.\n");
}
auto [result, phys_devices] = instance_->instance()->enumeratePhysicalDevices();
if (vk::Result::eSuccess != result || phys_devices.empty()) {
RTN_MSG(false, "VK Error: 0x%x - No physical device found.\n", result);
}
for (const auto &phys_device : phys_devices) {
if (ChooseGraphicsDevice(phys_device, params_->surface_, &phys_device_)) {
initialized_ = true;
break;
}
}
if (!initialized_) {
RTN_MSG(false, "Couldn't find graphics family device.\n");
}
params_.reset();
return initialized_;
}
void VulkanPhysicalDevice::AppendRequiredPhysDeviceExts(std::vector<const char *> *exts) {
exts->insert(exts->end(), s_required_phys_device_props.begin(),
s_required_phys_device_props.end());
}
vk::PhysicalDevice VulkanPhysicalDevice::phys_device() const {
if (!initialized_) {
RTN_MSG(nullptr, "%s", "Request for uninitialized instance.\n");
}
return phys_device_;
}