#pragma once #include #include #include #include #include #include #include #include #include "props.hpp" #include "debug/Debug.hpp" /** * Maintains a connection to a GPU driver */ class Instance { private: VkInstance m_instance; public: GET(m_instance, instance); // disable copy Instance(const Instance&) = delete; Instance() = delete; Instance(const Instance&& other) { this->m_instance = other.m_instance; } /** * Creates new instance and initializes a connection to a GPU driver * @param applicationName Name of the application * @param engineName Name of the rendering engine * @param extensions Additional Vulkan extensions you might want to enable * @param callback Debug log callback */ Instance(const std::string applicationName, const std::string engineName, std::vector extensions, std::vector layers, lft::dbg::lft_log_callback callback); static std::vector find_unsupported_layers( std::vector& required_layers ) { uint32_t available_layers_count = 0; vkEnumerateInstanceLayerProperties(&available_layers_count, nullptr); if(available_layers_count == 0) { return required_layers; } std::vector available_layers(available_layers_count); vkEnumerateInstanceLayerProperties(&available_layers_count, available_layers.data()); std::vector available_layer_names(available_layers_count); std::transform(available_layers.begin(), available_layers.end(), available_layer_names.begin(), [](const VkLayerProperties& props) { return std::string(props.layerName); }); std::sort(available_layer_names.begin(), available_layer_names.end()); std::sort(required_layers.begin(), required_layers.end()); std::vector unsupported_layers; std::set_difference(required_layers.begin(), required_layers.end(), available_layer_names.begin(), available_layer_names.end(), std::back_inserter(unsupported_layers)); return unsupported_layers; } /** * Checks if the required extensions are available * @return A vector of indices of not available extensionse */ static std::vector check_extensions(const std::vector& requiredExtensions) { auto supportedExtensions = list_extensions(); std::vector unsupported_extensions; std::set_difference(requiredExtensions.begin(), requiredExtensions.end(), supportedExtensions.begin(), supportedExtensions.end(), std::back_inserter(unsupported_extensions)); return unsupported_extensions; } /** * Gets a list of available physical devices * @return A vector of VkPhysicalDevice objects representing available physical devices */ [[nodiscard]] inline std::vector list_physical_devices() const { uint32_t numDevices = 0; vkEnumeratePhysicalDevices(m_instance, &numDevices, nullptr); std::vector devices(numDevices); vkEnumeratePhysicalDevices(m_instance, &numDevices, devices.data()); return devices; } /** * Gets a list of available instance extensions * @return A vector of strings representing available instance extensions */ [[nodiscard]] static inline std::vector list_extensions() { uint32_t numExtensions = 0; vkEnumerateInstanceExtensionProperties(nullptr, &numExtensions, nullptr); std::vector extensions(numExtensions); vkEnumerateInstanceExtensionProperties(nullptr, &numExtensions, extensions.data()); std::vector extension_names(numExtensions); std::transform(extensions.begin(), extensions.end(), extension_names.begin(), [](const VkExtensionProperties& props) { return std::string(props.extensionName); }); return extension_names; } };