Files

129 lines
4.3 KiB
C++
Raw Permalink Normal View History

2026-07-18 14:31:15 +02:00
#pragma once
#include <iterator>
#include <volk.h>
#include <iostream>
#include <string>
#include <vector>
#include <set>
#include <algorithm>
#include <vulkan/vulkan_core.h>
#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<std::string> extensions,
std::vector<std::string> layers,
lft::dbg::lft_log_callback callback);
static std::vector<std::string> find_unsupported_layers(
std::vector<std::string>& required_layers
) {
uint32_t available_layers_count = 0;
vkEnumerateInstanceLayerProperties(&available_layers_count, nullptr);
if(available_layers_count == 0) {
return required_layers;
}
std::vector<VkLayerProperties> available_layers(available_layers_count);
vkEnumerateInstanceLayerProperties(&available_layers_count, available_layers.data());
std::vector<std::string> 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<std::string> 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<std::string> check_extensions(const std::vector<std::string>& requiredExtensions) {
auto supportedExtensions = list_extensions();
std::vector<std::string> 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<VkPhysicalDevice> list_physical_devices() const {
uint32_t numDevices = 0;
vkEnumeratePhysicalDevices(m_instance, &numDevices, nullptr);
std::vector<VkPhysicalDevice> 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<std::string> list_extensions() {
uint32_t numExtensions = 0;
vkEnumerateInstanceExtensionProperties(nullptr, &numExtensions, nullptr);
std::vector<VkExtensionProperties> extensions(numExtensions);
vkEnumerateInstanceExtensionProperties(nullptr, &numExtensions, extensions.data());
std::vector<std::string> extension_names(numExtensions);
std::transform(extensions.begin(), extensions.end(),
extension_names.begin(),
[](const VkExtensionProperties& props) {
return std::string(props.extensionName);
});
return extension_names;
}
};