111 lines
4.3 KiB
C++
111 lines
4.3 KiB
C++
#include "instance.h"
|
|
|
|
#include "engine.h"
|
|
|
|
Engine::Instance::Instance(Engine* eng) :
|
|
validationLayersEnabledAndSupported(false),
|
|
engine(eng),
|
|
vk(),
|
|
debugMessenger()
|
|
{
|
|
VkApplicationInfo appInfo {};
|
|
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
|
appInfo.pApplicationName = "Hello Triangle";
|
|
appInfo.applicationVersion = VK_MAKE_VERSION(0, 0, 1);
|
|
appInfo.pEngineName = "Stories";
|
|
appInfo.engineVersion = VK_MAKE_VERSION(0, 0, 1);
|
|
appInfo.apiVersion = VK_API_VERSION_1_0;
|
|
appInfo.pNext = nullptr;
|
|
|
|
//TODO handle exception
|
|
Support exts = getVulkanExtensions(engine->instanceExtensionNames, engine->getRequiredVulkanExtensions());
|
|
if (exts.unsupportedCritical.size() > 0) {
|
|
std::string error("Unable to create Vulkan instance, following critical extensions are unsupported:\n");
|
|
for (const char* ext : exts.unsupportedCritical) {
|
|
error += "\t" + std::string(ext) + "\n";
|
|
}
|
|
throw std::runtime_error(error);
|
|
}
|
|
//TODO log unsupported;
|
|
exts.logSupported("Applying extensions:");
|
|
|
|
//TODO handle exception
|
|
Support layers = getVulkanLayers(engine->layerNames);
|
|
//TODO log unsupported
|
|
layers.logSupported("Applying layers:");
|
|
|
|
VkInstanceCreateInfo createInfo {};
|
|
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
|
createInfo.pApplicationInfo = &appInfo;
|
|
createInfo.flags = 0;
|
|
createInfo.enabledExtensionCount = static_cast<uint32_t>(exts.supported.size());
|
|
createInfo.ppEnabledExtensionNames = exts.supported.data();
|
|
createInfo.enabledLayerCount = static_cast<uint32_t>(layers.supported.size());
|
|
createInfo.ppEnabledLayerNames = layers.supported.data();
|
|
|
|
VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo {};
|
|
if (engine->enableValidationLayers()) {
|
|
validationLayersEnabledAndSupported = true; //TODO make sure it's actually supported, this shows that they are just enabled;
|
|
populateDebugMessengerCreateInfo(debugCreateInfo, debugCallback);
|
|
createInfo.pNext = (VkDebugUtilsMessengerCreateInfoEXT*) &debugCreateInfo;
|
|
}
|
|
|
|
VkResult res = vkCreateInstance(&createInfo, nullptr, &vk);
|
|
switch (res) {
|
|
case VK_SUCCESS:
|
|
break;
|
|
case VK_ERROR_INCOMPATIBLE_DRIVER:
|
|
throw std::runtime_error("unable to create vulkan instance, cannot find a compatible Vulkan ICD");
|
|
case VK_ERROR_OUT_OF_HOST_MEMORY:
|
|
throw std::runtime_error("unable to create vulkan instance, out of host memory");
|
|
case VK_ERROR_OUT_OF_DEVICE_MEMORY:
|
|
throw std::runtime_error("unable to create vulkan instance, out of device memory");
|
|
case VK_ERROR_INITIALIZATION_FAILED:
|
|
throw std::runtime_error("unable to create vulkan instance, initialization failed");
|
|
case VK_ERROR_LAYER_NOT_PRESENT:
|
|
throw std::runtime_error("unable to create vulkan instance, layer not present");
|
|
case VK_ERROR_EXTENSION_NOT_PRESENT:
|
|
throw std::runtime_error("unable to create vulkan instance, extension not present");
|
|
default:
|
|
throw std::runtime_error("unable to create Vulkan instance: unknown error");
|
|
}
|
|
|
|
if (validationLayersEnabledAndSupported)
|
|
setupDebugMessenger();
|
|
}
|
|
|
|
Engine::Instance::~Instance() {
|
|
if (validationLayersEnabledAndSupported)
|
|
destroyDebugUtilsMessengerEXT(vk, debugMessenger, nullptr);
|
|
|
|
vkDestroyInstance(vk, nullptr);
|
|
}
|
|
|
|
void Engine::Instance::setupDebugMessenger() {
|
|
VkDebugUtilsMessengerCreateInfoEXT createInfo{};
|
|
populateDebugMessengerCreateInfo(createInfo, debugCallback);
|
|
|
|
VkResult res = createDebugUtilsMessengerEXT(vk, &createInfo, nullptr, &debugMessenger);
|
|
switch (res) {
|
|
case VK_SUCCESS:
|
|
break;
|
|
case VK_ERROR_EXTENSION_NOT_PRESENT:
|
|
throw std::runtime_error("failed to set up debug messenger: extension not present");
|
|
break;
|
|
default:
|
|
throw std::runtime_error("failed to set up debug messenger");
|
|
}
|
|
}
|
|
|
|
std::vector<VkPhysicalDevice> Engine::Instance::enumeratePhysicalDevices() const {
|
|
uint32_t deviceCount = 0;
|
|
vkEnumeratePhysicalDevices(vk, &deviceCount, nullptr);
|
|
|
|
std::vector<VkPhysicalDevice> devices(deviceCount);
|
|
if (deviceCount > 0)
|
|
vkEnumeratePhysicalDevices(vk, &deviceCount, devices.data());
|
|
|
|
return devices;
|
|
}
|
|
|