#include #include "vulkan_engine/vulkan/graphics.h" #include "vulkan_engine/utilities.h" namespace veng { gsl::span Graphics::GetSuggestedInstanceExtentions() { std::uint32_t glfw_extention_count = 0; gsl::czstring* glfw_extentions = glfwGetRequiredInstanceExtensions(&glfw_extention_count); return {glfw_extentions, glfw_extention_count}; } std::vector Graphics::GetRequiredInstanceExtentions() { gsl::span suggested_extentions = GetSuggestedInstanceExtentions(); std::vector required_extentions(suggested_extentions.size()); std::copy(suggested_extentions.begin(), suggested_extentions.end(), required_extentions.begin()); if (validation_enabled_) required_extentions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); if (!AreAllExtensionsSupported(suggested_extentions)) std::exit(EXIT_FAILURE); return required_extentions; } std::vector Graphics::GetSupprotedInstanceExtensions() { std::uint32_t count; vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr); if (count == 0) return {}; std::vector properties(count); vkEnumerateInstanceExtensionProperties(nullptr, &count, properties.data()); return properties; } bool ExtentionMatchesName(gsl::czstring name, const VkExtensionProperties& properties) { return streq(properties.extensionName, name); } bool IsExtensionSupported(gsl::span extensions, gsl::czstring name) { return std::any_of(extensions.begin(), extensions.end(), std::bind_front(ExtentionMatchesName, name)); } bool Graphics::AreAllExtensionsSupported(gsl::span extensions) { std::vector supported_extensions = GetSupprotedInstanceExtensions(); return std::all_of( extensions.begin(), extensions.end(), std::bind_front(IsExtensionSupported, supported_extensions)); } void Graphics::CreateInstance() { std::array validation_layers = { "VK_LAYER_KHRONOS_validation"}; if (!AreAllLayersSupported(validation_layers)) validation_enabled_ = false; std::vector required_extentions = GetRequiredInstanceExtentions(); VkApplicationInfo app_info = {}; app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; app_info.pNext = nullptr; app_info.pApplicationName = "Asteroid"; app_info.applicationVersion = VK_MAKE_API_VERSION(0, 0, 0, 0); app_info.pEngineName = "VEng"; app_info.engineVersion = VK_MAKE_API_VERSION(0, 1, 0, 0); app_info.apiVersion = VK_API_VERSION_1_0; VkInstanceCreateInfo instance_creation_info = {}; instance_creation_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; instance_creation_info.pNext = nullptr; instance_creation_info.pApplicationInfo = &app_info; instance_creation_info.enabledExtensionCount = required_extentions.size(); instance_creation_info.ppEnabledExtensionNames = required_extentions.data(); VkDebugUtilsMessengerCreateInfoEXT messenger_create_info = GetCreateMessengerInfo(); if (validation_enabled_) { instance_creation_info.pNext = &messenger_create_info; instance_creation_info.enabledLayerCount = validation_layers.size(); instance_creation_info.ppEnabledLayerNames = validation_layers.data(); } else { instance_creation_info.enabledLayerCount = 0; instance_creation_info.ppEnabledLayerNames = nullptr; } VkResult result = vkCreateInstance(&instance_creation_info, nullptr, &instance_); if (result != VK_SUCCESS) std::exit(EXIT_FAILURE); } } // namespace veng