vulkan-test/src/init/vulkan_instance.cpp
2024-11-18 17:45:41 -05:00

99 lines
2.8 KiB
C++

#define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1
#include <fmt/format.h>
#include "vulkan_instance.hpp"
#include "../util/constants.hpp"
using namespace constants;
fn VulkanInstance::create() -> vk::UniqueInstance {
#ifndef NDEBUG
// Make sure validation layers are supported
if (!checkValidationLayerSupport())
throw std::runtime_error("Validation layers requested, but not available!");
#endif
// Application metadata
vk::ApplicationInfo appInfo {
.pApplicationName = "Vulkan App",
.applicationVersion = 1,
.pEngineName = "No Engine",
.engineVersion = 1,
.apiVersion = vk::ApiVersion13,
};
// Get required extensions
std::vector<const char*> extensions = getRequiredExtensions();
#ifndef NDEBUG
fmt::println("Available extensions:");
for (const char* extension : extensions) { fmt::println("\t{}", extension); }
#endif
// Create the instance
vk::InstanceCreateInfo createInfo {
#ifdef __APPLE__
.flags = vk::InstanceCreateFlagBits::eEnumeratePortabilityKHR,
#endif
.pApplicationInfo = &appInfo,
#ifdef NDEBUG
.enabledLayerCount = 0,
.ppEnabledLayerNames = nullptr,
#else
.enabledLayerCount = static_cast<u32>(validationLayers.size()),
.ppEnabledLayerNames = validationLayers.data(),
#endif
.enabledExtensionCount = static_cast<u32>(extensions.size()),
.ppEnabledExtensionNames = extensions.data()
};
vk::UniqueInstance instance = vk::createInstanceUnique(createInfo);
// Initialize the dynamic dispatcher with the instance
VULKAN_HPP_DEFAULT_DISPATCHER.init(instance.get());
return instance;
}
fn VulkanInstance::getRequiredExtensions() -> std::vector<const char*> {
// Get the required extensions from GLFW
std::span<const char*> extensionsSpan = vkfw::getRequiredInstanceExtensions();
std::vector<const char*> extensions(extensionsSpan.begin(), extensionsSpan.end());
#ifndef NDEBUG
// Add debug utils extension in debug mode
extensions.push_back(vk::EXTDebugUtilsExtensionName);
#endif
#ifdef __APPLE__
// Add required macOS extensions
extensions.push_back(vk::KHRPortabilityEnumerationExtensionName);
extensions.push_back("VK_KHR_get_physical_device_properties2");
#endif
return extensions;
}
fn VulkanInstance::checkValidationLayerSupport() -> bool {
// Get available layers
std::vector<vk::LayerProperties> availableLayers = vk::enumerateInstanceLayerProperties();
// Check if all requested validation layers are available
for (const char* layerName : validationLayers) {
bool layerFound = false;
for (const vk::LayerProperties& layerProperties : availableLayers)
if (strcmp(layerName, layerProperties.layerName) == 0) {
layerFound = true;
break;
}
if (!layerFound)
return false;
}
return true;
}