blob: 00299e644e4ae88c0a842c7dd2f7ad02478a78a6 [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_instance.h"
#include <vector>
#include "utils.h"
#include "vulkan_layer.h"
namespace {
static const std::vector<const char *> s_required_props = {
VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME,
VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME,
VK_KHR_SURFACE_EXTENSION_NAME,
VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
#ifdef __Fuchsia__
VK_FUCHSIA_IMAGEPIPE_SURFACE_EXTENSION_NAME,
#endif
};
static const std::vector<const char *> s_desired_props = {
VK_EXT_DEBUG_REPORT_EXTENSION_NAME,
};
static void PrintProps(const std::vector<const char *> &props) {
for (const auto &prop : props) {
printf("\t%s\n", prop);
}
printf("\n");
}
#if USE_GLFW
std::vector<const char *> GetExtensionsGLFW() {
uint32_t num_extensions = 0;
const char **glfw_extensions;
glfw_extensions = glfwGetRequiredInstanceExtensions(&num_extensions);
std::vector<const char *> extensions(glfw_extensions, glfw_extensions + num_extensions);
extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
return extensions;
}
#else
std::vector<const char *> GetExtensions_Private(std::vector<const char *> *layers) {
const char *kMagmaLayer = "VK_LAYER_FUCHSIA_imagepipe_swapchain_fb";
std::vector<const char *> extensions;
std::vector<std::string> missing_props;
if (!FindMatchingProperties(s_required_props, vkp::INSTANCE_EXT_PROP, nullptr /* device */,
kMagmaLayer, &missing_props)) {
extensions.insert(extensions.end(), s_required_props.begin(), s_required_props.end());
}
return extensions;
}
#endif
} // namespace
VulkanInstance::~VulkanInstance() { initialized_ = false; }
#if USE_GLFW
bool VulkanInstance::Init(bool enable_validation, GLFWwindow *window) {
window_ = window;
#else
bool VulkanInstance::Init(bool enable_validation) {
#endif
if (enable_validation && !VulkanLayer::CheckValidationLayerSupport()) {
RTN_MSG(false, "Validation layers requested, but not available!");
}
// Application Info
vk::ApplicationInfo app_info;
app_info.apiVersion = VK_MAKE_VERSION(1, 0, 0);
app_info.pApplicationName = "VkPrimer";
app_info.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
app_info.pEngineName = "No Engine";
app_info.engineVersion = VK_MAKE_VERSION(1, 0, 0);
// Instance Create Info
vk::InstanceCreateInfo create_info;
create_info.pApplicationInfo = &app_info;
// Extensions
extensions_ = GetExtensions();
VulkanLayer::AppendRequiredInstanceExtensions(&extensions_);
create_info.enabledExtensionCount = static_cast<uint32_t>(extensions_.size());
create_info.ppEnabledExtensionNames = extensions_.data();
// Layers
VulkanLayer::AppendRequiredInstanceLayers(&layers_);
if (enable_validation) {
VulkanLayer::AppendValidationInstanceLayers(&layers_);
}
create_info.enabledLayerCount = static_cast<uint32_t>(layers_.size());
create_info.ppEnabledLayerNames = layers_.data();
fprintf(stderr, "Enabled Instance Extensions:\n");
PrintProps(extensions_);
fprintf(stderr, "Enabled layers:\n");
for (auto &layer : layers_) {
fprintf(stderr, "\t%s\n", layer);
}
fprintf(stderr, "\n");
auto rv = vk::createInstanceUnique(create_info);
if (vk::Result::eSuccess != rv.result) {
RTN_MSG(false, "VK Error: 0x%x - Failed to create instance.", rv.result);
}
instance_ = std::move(rv.value);
initialized_ = true;
return true;
}
std::vector<const char *> VulkanInstance::GetExtensions() {
#if USE_GLFW
extensions_ = GetExtensionsGLFW();
#else
extensions_ = GetExtensions_Private(&layers_);
#endif
return extensions_;
}
const vk::UniqueInstance &VulkanInstance::instance() const { return instance_; }