#include "renderer.h" #include #include #include #include Renderer::Renderer() { createInstance(); #ifdef DEBUG if(enableDebug) createDebugMessenger(); #endif createLogicalDevice(); } Renderer::~Renderer() { #ifdef DEBUG destroyMessenger_(instance_, messenger_, nullptr); #endif vkDestroyDevice(device_, nullptr); vkDestroyInstance(instance_, nullptr); } void Renderer::createInstance() { uint32_t layerCount = 0; vkEnumerateInstanceLayerProperties(&layerCount, nullptr); VkLayerProperties* availableLayers = new VkLayerProperties[layerCount]; vkEnumerateInstanceLayerProperties(&layerCount, availableLayers); std::vector enabledLayers; #ifdef DEBUG for(uint32_t i = 0; i < layerCount; i++) { if(!strcmp(availableLayers[i].layerName, "VK_LAYER_LUNARG_standard_validation")) enabledLayers.push_back("VK_LAYER_LUNARG_standard_validation"); } #endif delete[] availableLayers; uint32_t extensionCount = 0; vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr); VkExtensionProperties* availableExtensions = new VkExtensionProperties[extensionCount]; vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, availableExtensions); std::vector enabledExtensions; #ifdef DEBUG for(uint32_t i = 0; i < extensionCount; i++) { if(!strcmp(availableExtensions[i].extensionName, "VK_EXT_debug_utils")) { enabledExtensions.push_back("VK_EXT_debug_utils"); enableDebug = true; } } #endif delete[] availableExtensions; VkInstanceCreateInfo instanceCreateInfo = {}; instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; instanceCreateInfo.enabledLayerCount = enabledLayers.size(); instanceCreateInfo.ppEnabledLayerNames = enabledLayers.data(); instanceCreateInfo.enabledExtensionCount = enabledExtensions.size(); instanceCreateInfo.ppEnabledExtensionNames = enabledExtensions.data(); vkCreateInstance(&instanceCreateInfo, nullptr, &instance_); } #ifdef DEBUG void Renderer::createDebugMessenger() { createMessenger_ = (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance_, "vkCreateDebugUtilsMessengerEXT"); destroyMessenger_ = (PFN_vkDestroyDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance_, "vkDestroyDebugUtilsMessengerEXT"); VkDebugUtilsMessengerCreateInfoEXT messengerCreateInfo = {}; messengerCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; messengerCreateInfo.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT; messengerCreateInfo.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; messengerCreateInfo.pfnUserCallback = [](VkDebugUtilsMessageSeverityFlagBitsEXT, unsigned int, const VkDebugUtilsMessengerCallbackDataEXT* callback, void*) -> unsigned int { std::cout << callback->pMessage << std::endl; return VK_SUCCESS; }; createMessenger_(instance_, &messengerCreateInfo, nullptr, &messenger_); } #endif void Renderer::createLogicalDevice() { uint32_t physicalDeviceCount = 0; vkEnumeratePhysicalDevices(instance_, &physicalDeviceCount, nullptr); VkPhysicalDevice* physicalDevices = new VkPhysicalDevice[physicalDeviceCount]; vkEnumeratePhysicalDevices(instance_, &physicalDeviceCount, physicalDevices); VkPhysicalDevice physicalDevice = nullptr; for(uint32_t i = 0; i < physicalDeviceCount; i++) { VkPhysicalDeviceProperties properties = {}; vkGetPhysicalDeviceProperties(physicalDevices[i], &properties); physicalDevice = physicalDevices[i]; } delete[] physicalDevices; uint32_t queueFamilyPropertiesCount = 0; vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyPropertiesCount, nullptr); VkQueueFamilyProperties* queueFamilyProperties = new VkQueueFamilyProperties[queueFamilyPropertiesCount]; vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyPropertiesCount, queueFamilyProperties); uint32_t graphicsFamilyIndex = 0; for(uint32_t i = 0; i < queueFamilyPropertiesCount; i++) { if(queueFamilyProperties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) graphicsFamilyIndex = i; } delete[] queueFamilyProperties; const std::set queueFamilyIndices = {graphicsFamilyIndex}; std::vector deviceQueueCreateInfos; for(auto queueFamilyIndex : queueFamilyIndices) { const float priority = 1.0f; VkDeviceQueueCreateInfo queueCreateInfo = {}; queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; queueCreateInfo.queueFamilyIndex = queueFamilyIndex; queueCreateInfo.queueCount = 1; queueCreateInfo.pQueuePriorities = &priority; deviceQueueCreateInfos.push_back(queueCreateInfo); } VkDeviceCreateInfo deviceCreateInfo = {}; deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; deviceCreateInfo.queueCreateInfoCount = deviceQueueCreateInfos.size(); deviceCreateInfo.pQueueCreateInfos = deviceQueueCreateInfos.data(); vkCreateDevice(physicalDevice, &deviceCreateInfo, nullptr, &device_); vkGetDeviceQueue(device_, graphicsFamilyIndex, 0, &graphicsQueue_); }