diff --git a/src/window.cpp b/src/window.cpp index 3fca4da..3952a7f 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -7,6 +7,7 @@ #include "yolo/yolo.hpp" +#include #include #include #include @@ -32,222 +33,116 @@ void glfwErrorCallback(int error, const char* description) yolo::error("[GLFW {}] {}", error, description); } -void setupGLFW(std::string title) +static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback( + VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, + VkDebugUtilsMessageTypeFlagsEXT messageType, + const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, + void* pUserData) { - glfwSetErrorCallback(glfwErrorCallback); - if (!glfwInit()) - throw std::runtime_error("Failed to initialize GLFW"); + yolo::warn("[VULKAN] {}", pCallbackData->pMessage); - glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); + return VK_FALSE; +} - uint32_t ext = 0; - vkEnumerateInstanceExtensionProperties(nullptr, &ext, nullptr); - yolo::info("Vulkan {} extensions supported", ext); - - // Create window with graphics context - Window = glfwCreateWindow(1280, 720, title.c_str(), NULL, NULL); - if (Window == NULL) - throw std::runtime_error("Could not create window"); - - if (!glfwVulkanSupported()) { - yolo::error("Vulkan not supported"); - exit(1); - } - - // Vulkan Init - VkApplicationInfo appInfo {}; - appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; - appInfo.pApplicationName = INFERNO_VERSION; - appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0); - appInfo.pEngineName = "Inferno"; - appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0); - appInfo.apiVersion = VK_API_VERSION_1_0; - - VkInstanceCreateInfo instInfo {}; - instInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; - instInfo.pApplicationInfo = &appInfo; - - uint32_t glfwExtCount = 0; - const char** exts = glfwGetRequiredInstanceExtensions(&ext); - // add VK_KHR_xcb_surface to the list of extensions - // TODO: This is a massive fuck off hack - SOLVE IT!!!! - exts[glfwExtCount++] = "VK_KHR_xcb_surface"; - instInfo.enabledExtensionCount = glfwExtCount; - instInfo.ppEnabledExtensionNames = exts; - instInfo.enabledLayerCount = 0; - yolo::info("GLFW requested {} extensions: {}", glfwExtCount, exts[0]); - - if (vkCreateInstance(&instInfo, nullptr, &VulkanInstance) != VK_SUCCESS) { - yolo::error("Could not create Vulkan instance"); - exit(1); - } - - // Physical Device - uint32_t deviceCount = 0; - vkEnumeratePhysicalDevices(VulkanInstance, &deviceCount, nullptr); - if (deviceCount == 0) { - yolo::error("No Vulkan devices found"); - exit(1); - } - - std::vector devices(deviceCount); - vkEnumeratePhysicalDevices(VulkanInstance, &deviceCount, devices.data()); - - // TODO: We need to do device suitability in a much better way - const std::vector deviceExtensions { - VK_KHR_SWAPCHAIN_EXTENSION_NAME, - }; - - for (const auto& device : devices) { - if (window_evaluate_device(device, deviceExtensions, nullptr)) { - VulkanPhysicalDevice = device; - break; - } - } - - if (VulkanPhysicalDevice == VK_NULL_HANDLE) { - yolo::error("No discrete Vulkan devices found"); - exit(1); - } - - // Logical Device - yolo::debug("1"); - QueueFamilyIndices indices = window_get_queue_families(VulkanPhysicalDevice); - yolo::debug("2"); - std::vector queueCreateInfos; - yolo::debug("3"); - std::set uniqueQueueFamilies = { indices.graphicsFamily.value_or(0), indices.presentFamily.value_or(0) }; - - float queuePriority = 1.0f; - for (uint32_t queueFamily : uniqueQueueFamilies) { - VkDeviceQueueCreateInfo queueCreateInfo {}; - queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - queueCreateInfo.queueFamilyIndex = queueFamily; - queueCreateInfo.queueCount = 1; - queueCreateInfo.pQueuePriorities = &queuePriority; - queueCreateInfos.push_back(queueCreateInfo); - } - - VkPhysicalDeviceFeatures deviceFeatures {}; - VkDeviceCreateInfo createInfo {}; - createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; - createInfo.queueCreateInfoCount = static_cast(queueCreateInfos.size()); - createInfo.pQueueCreateInfos = queueCreateInfos.data(); - createInfo.pEnabledFeatures = &deviceFeatures; - createInfo.enabledExtensionCount = 0; - createInfo.enabledLayerCount = 0; - createInfo.enabledExtensionCount = static_cast(deviceExtensions.size()); - createInfo.ppEnabledExtensionNames = deviceExtensions.data(); - - if (vkCreateDevice(VulkanPhysicalDevice, &createInfo, nullptr, &VulkanDevice) != VK_SUCCESS) { - yolo::error("Could not create Vulkan logical device"); - exit(1); - } - - vkGetDeviceQueue(VulkanDevice, indices.graphicsFamily.value(), 0, &VulkanPresentQueue); - - VkPhysicalDeviceProperties deviceProperties; - vkGetPhysicalDeviceProperties(VulkanPhysicalDevice, &deviceProperties); - yolo::info("Vulkan running on {}", deviceProperties.deviceName); - - // "Surface" creation - VkResult result = glfwCreateWindowSurface(VulkanInstance, Window, nullptr, &VulkanSurface); - if (result != VK_SUCCESS) { - yolo::error("Could not create Vulkan surface (code: {})", result); - exit(1); - } - - // Swapchainnnnn - const auto chooseSwapSurfaceFormat = [&](const std::vector& available) { - for (const auto& availableFormat : available) { - if (availableFormat.format == VK_FORMAT_B8G8R8A8_SRGB - && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) { - return availableFormat; - } - } - - return available[0]; - }; - - const auto chooseSwapPresentMode = [&](const std::vector& available) { - for (const auto& availablePresentMode : available) { - if (availablePresentMode == VK_PRESENT_MODE_MAILBOX_KHR) { - return availablePresentMode; - } - } - - return VK_PRESENT_MODE_FIFO_KHR; - }; - - const auto chooseSwapExtent = [&](const VkSurfaceCapabilitiesKHR& capabilities) { - if (capabilities.currentExtent.width != UINT32_MAX) { - return capabilities.currentExtent; - } else { - int width, height; - glfwGetFramebufferSize(Window, &width, &height); - - VkExtent2D actualExtent = { - static_cast(width), - static_cast(height) - }; - - actualExtent.width = std::max( - capabilities.minImageExtent.width, - std::min(capabilities.maxImageExtent.width, actualExtent.width)); - - actualExtent.height = std::max( - capabilities.minImageExtent.height, - std::min(capabilities.maxImageExtent.height, actualExtent.height)); - - return actualExtent; - } - }; - - SwapChainSupportDetails swapChainSupport = window_get_swap_chain_support(VulkanPhysicalDevice); - VkSurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(swapChainSupport.formats); - VkPresentModeKHR presentMode = chooseSwapPresentMode(swapChainSupport.presentModes); - VkExtent2D extent = chooseSwapExtent(swapChainSupport.capabilities); - - uint32_t imageCount = swapChainSupport.capabilities.minImageCount + 1; - if ( - swapChainSupport.capabilities.maxImageCount > 0 - && imageCount > swapChainSupport.capabilities.maxImageCount) { - imageCount = swapChainSupport.capabilities.maxImageCount; - } - - VkSwapchainCreateInfoKHR swapCreateInfo {}; - swapCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; - swapCreateInfo.surface = VulkanSurface; - swapCreateInfo.minImageCount = imageCount; - swapCreateInfo.imageFormat = surfaceFormat.format; - swapCreateInfo.imageColorSpace = surfaceFormat.colorSpace; - swapCreateInfo.imageExtent = extent; - swapCreateInfo.imageArrayLayers = 1; - swapCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; - - QueueFamilyIndices indices2 = window_get_queue_families(VulkanPhysicalDevice); - uint32_t queueFamilyIndices[] = { indices2.graphicsFamily.value_or(0), indices2.presentFamily.value_or(0) }; - if (indices2.graphicsFamily != indices2.presentFamily) { - swapCreateInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT; - swapCreateInfo.queueFamilyIndexCount = 2; - swapCreateInfo.pQueueFamilyIndices = queueFamilyIndices; +VkResult createDebugUtilsMessengerEXT( + VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDebugUtilsMessengerEXT* pDebugMessenger) +{ + auto func = (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr( + instance, "vkCreateDebugUtilsMessengerEXT"); + if (func != nullptr) { + return func(instance, pCreateInfo, pAllocator, pDebugMessenger); } else { - swapCreateInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; - swapCreateInfo.queueFamilyIndexCount = 0; // Optional - swapCreateInfo.pQueueFamilyIndices = nullptr; // Optional + return VK_ERROR_EXTENSION_NOT_PRESENT; + } +} + +void destroyDebugUtilsMessengerEXT(VkInstance instance, + VkDebugUtilsMessengerEXT debugMessenger, + const VkAllocationCallbacks* pAllocator) +{ + auto func = (PFN_vkDestroyDebugUtilsMessengerEXT)vkGetInstanceProcAddr( + instance, "vkDestroyDebugUtilsMessengerEXT"); + if (func != nullptr) { + func(instance, debugMessenger, pAllocator); + } +} + +void populateDebugMessengerCreateInfo( + VkDebugUtilsMessengerCreateInfoEXT& createInfo) +{ + createInfo = {}; + createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; + createInfo.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; + createInfo.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; + createInfo.pfnUserCallback = debugCallback; +} + +bool checkValidationLayerSupport() +{ + uint32_t layerCount; + vkEnumerateInstanceLayerProperties(&layerCount, nullptr); + + std::vector availableLayers(layerCount); + vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data()); + + for (const char* layerName : VALIDATION_LAYERS) { + bool layerFound = false; + + for (const auto& layerProperties : availableLayers) { + if (strcmp(layerName, layerProperties.layerName) == 0) { + layerFound = true; + break; + } + } + + if (!layerFound) { + return false; + } } - swapCreateInfo.preTransform = swapChainSupport.capabilities.currentTransform; - swapCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; - swapCreateInfo.presentMode = presentMode; - swapCreateInfo.clipped = VK_TRUE; - swapCreateInfo.oldSwapchain = VK_NULL_HANDLE; + return true; +} - if (vkCreateSwapchainKHR(VulkanDevice, &swapCreateInfo, nullptr, &VulkanSwapChain) != VK_SUCCESS) { - yolo::error("Could not create Vulkan swap chain"); - exit(1); +std::vector getRequiredExtensions() +{ + uint32_t glfwExtensionCount = 0; + const char** glfwExtensions; + glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount); + + std::vector extensions(glfwExtensions, + glfwExtensions + glfwExtensionCount); + + if constexpr (VALIDATION_LAYERS_ENABLED) { + extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); } - yolo::info("Vulkan swap chain created with {} images", imageCount); + + return extensions; +} + + + + +void setupWindow(std::string title) +{ + glfwInit(); + + // tell glfw to not use a specific api? TODO: reasearch + glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); + // disable resizing the window, this project is not configured to handle resizing + glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); + + Window = glfwCreateWindow(Width, Height, title.c_str(), nullptr, nullptr); +} + +void setupVulkan() +{ + window_create_vulkan_instance(); + window_vulkan_debugger(); + window_create_vulkan_surface(); + window_create_vulkan_physical_device(); + window_create_vulkan_logical_device(); } void setupImGui() @@ -323,7 +218,8 @@ void window_create(std::string title, int width, int height) { Width = width; Height = height; - setupGLFW(title); + setupWindow(title); + setupVulkan(); glfwSetKeyCallback(Window, glfwKeyCallback); // setupImGui(); } @@ -336,38 +232,180 @@ void window_cleanup() shutdownGLFW(); } -void window_set_title(std::string title) +void window_create_vulkan_instance() { - glfwSetWindowTitle(Window, title.c_str()); -} - -void window_set_size(int w, int h) -{ - Width = w; - Height = h; - glfwSetWindowSize(Window, Width, Height); -} - -void window_set_pos(int x, int y) { glfwSetWindowPos(Window, x, y); } - -glm::vec2 window_get_size() { return { Width, Height }; } - -void window_get_pos(int& x, int& y) { glfwGetWindowPos(Window, &x, &y); } - -// VULKAN SPECIFIC -bool window_evaluate_device(VkPhysicalDevice device, std::vector ext_needed, HW_CAPABILITY* capability) -{ - QueueFamilyIndices indices = window_get_queue_families(device); - - bool extensionsSupported = window_evaluate_device_extensions(device, ext_needed); - - bool swapChainAdequate = false; - if (extensionsSupported) { - SwapChainSupportDetails swapChainSupport = window_get_swap_chain_support(device); - swapChainAdequate = !swapChainSupport.formats.empty() && !swapChainSupport.presentModes.empty(); + if (VALIDATION_LAYERS_ENABLED && !checkValidationLayerSupport()) { + throw std::runtime_error( + "validation layers requested, but not available!"); } - return indices.isComplete() && extensionsSupported && swapChainAdequate; + VkApplicationInfo appInfo {}; + appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; + appInfo.pApplicationName = "Inferno HART"; + appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0); + appInfo.pEngineName = "No Engine"; + appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0); + appInfo.apiVersion = VK_API_VERSION_1_0; + + VkInstanceCreateInfo createInfo {}; + createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; + createInfo.pApplicationInfo = &appInfo; + + auto extensions = getRequiredExtensions(); + createInfo.enabledExtensionCount = static_cast(extensions.size()); + createInfo.ppEnabledExtensionNames = extensions.data(); + + VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo; +#ifdef VALIDATION_LAYERS_ENABLED + createInfo.enabledLayerCount = static_cast(VALIDATION_LAYERS.size()); + createInfo.ppEnabledLayerNames = VALIDATION_LAYERS.data(); + + populateDebugMessengerCreateInfo(debugCreateInfo); + createInfo.pNext = (VkDebugUtilsMessengerCreateInfoEXT*)&debugCreateInfo; +#else + createInfo.enabledLayerCount = 0; + + createInfo.pNext = nullptr; +#endif + + if (vkCreateInstance(&createInfo, nullptr, &VulkanInstance) != VK_SUCCESS) { + throw std::runtime_error("failed to create instance!"); + } + yolo::info("Vulkan instance created"); +} + +void window_vulkan_debugger() +{ + if constexpr (!VALIDATION_LAYERS_ENABLED) { + return; + } + + VkDebugUtilsMessengerCreateInfoEXT createInfo; + populateDebugMessengerCreateInfo(createInfo); + + if (createDebugUtilsMessengerEXT(VulkanInstance, &createInfo, nullptr, + &VulkanDebugMessenger) + != VK_SUCCESS) { + throw std::runtime_error("failed to set up debug messenger!"); + } +} + +void window_create_vulkan_surface() +{ + if (glfwCreateWindowSurface(VulkanInstance, Window, nullptr, &VulkanSurface) != VK_SUCCESS) { + throw std::runtime_error("failed to create window surface!"); + } + yolo::info("Vulkan surface created"); +} + +void window_create_vulkan_physical_device() +{ + uint32_t deviceCount = 0; + vkEnumeratePhysicalDevices(VulkanInstance, &deviceCount, nullptr); + + if (deviceCount == 0) { + throw std::runtime_error("failed to find GPUs with Vulkan support!"); + } + + std::vector devices(deviceCount); + vkEnumeratePhysicalDevices(VulkanInstance, &deviceCount, devices.data()); + + // std::multimap is sorted list of key-value pairs. Sorted by key. + std::multimap candidates; + + for (const auto& device : devices) { + int score = window_evaluate_device(device); + candidates.insert(std::make_pair(score, device)); + } + + // as candidates is a sorted list, the last value will always be the biggest score (first element) + if (candidates.rbegin()->first > 0) { + VkPhysicalDeviceProperties deviceProperties; + vkGetPhysicalDeviceProperties(candidates.rbegin()->second, &deviceProperties); + yolo::info("Using device: {}", deviceProperties.deviceName); + + // established the device with the best score, or the only one in the system. + VulkanPhysicalDevice = candidates.rbegin()->second; + } else { + throw std::runtime_error("failed to find a suitable GPU!"); + } +} + +void window_create_vulkan_logical_device() +{ + QueueFamilyIndices indices = window_get_queue_families(VulkanPhysicalDevice); + + std::vector queueCreateInfos; + std::set uniqueQueueFamilies = { indices.graphicsFamily.value(), indices.presentFamily.value() }; + + float queuePriority = 1.0f; + for (uint32_t queueFamily : uniqueQueueFamilies) { + VkDeviceQueueCreateInfo queueCreateInfo {}; + queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + queueCreateInfo.queueFamilyIndex = queueFamily; + queueCreateInfo.pQueuePriorities = &queuePriority; + queueCreateInfo.queueCount = 1; + queueCreateInfos.push_back(queueCreateInfo); + } + + VkPhysicalDeviceFeatures deviceFeatures {}; + + VkDeviceCreateInfo createInfo {}; + createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; + + createInfo.queueCreateInfoCount = static_cast(queueCreateInfos.size()); + createInfo.pQueueCreateInfos = queueCreateInfos.data(); + + createInfo.pEnabledFeatures = &deviceFeatures; + + createInfo.enabledExtensionCount = 0; + +#ifdef VALIDATION_LAYERS_ENABLED + createInfo.enabledLayerCount = static_cast(VALIDATION_LAYERS.size()); + createInfo.ppEnabledLayerNames = VALIDATION_LAYERS.data(); +#elif + createInfo.enabledLayerCount = 0; +#endif + + if (vkCreateDevice(VulkanPhysicalDevice, &createInfo, nullptr, &VulkanDevice) != VK_SUCCESS) { + throw std::runtime_error("failed to create logical device!"); + } + + vkGetDeviceQueue(VulkanDevice, indices.graphicsFamily.value(), 0, &VulkanGraphicsQueue); + vkGetDeviceQueue(VulkanDevice, indices.presentFamily.value(), 0, &VulkanPresentQueue); +} + +bool window_evaluate_device(VkPhysicalDevice device) +{ + int score = 0; + + VkPhysicalDeviceProperties deviceProperties; + vkGetPhysicalDeviceProperties(device, &deviceProperties); + + VkPhysicalDeviceFeatures deviceFeatures; + vkGetPhysicalDeviceFeatures(device, &deviceFeatures); + + yolo::info("Found device {}", deviceProperties.deviceName); + // Discrete GPUs have a significant performance advantage + if (deviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) { + yolo::info("Device {} is a discrete GPU", deviceProperties.deviceName); + score += 1000; + } + // We really want to favour ones with RayTracing support + + // Maximum possible size of textures affects graphics quality + score += deviceProperties.limits.maxImageDimension2D; + + // Application won't function without geometry shaders + if (!deviceFeatures.geometryShader) + return 0; + + // Ensure that the device can process the graphics commands that we need + QueueFamilyIndices indices = window_get_queue_families(device); + if (!indices.isComplete()) + return 0; + + return score; } bool window_evaluate_device_extensions(VkPhysicalDevice device, std::vector extensions) @@ -390,31 +428,32 @@ bool window_evaluate_device_extensions(VkPhysicalDevice device, std::vector queueFamilies(queueFamilyCount); vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, queueFamilies.data()); - int i = 0; + uint32_t queueFamIndex = 0; + for (const auto& queueFamily : queueFamilies) { if (queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) { - indices.graphicsFamily = i; + indices.graphicsFamily = queueFamIndex; } VkBool32 presentSupport = false; - vkGetPhysicalDeviceSurfaceSupportKHR(device, i, VulkanSurface, &presentSupport); + vkGetPhysicalDeviceSurfaceSupportKHR(device, queueFamIndex, VulkanSurface, &presentSupport); if (presentSupport) { - indices.presentFamily = i; + indices.presentFamily = queueFamIndex; } if (indices.isComplete()) { break; } - i++; + queueFamIndex++; } return indices; @@ -445,7 +484,23 @@ SwapChainSupportDetails window_get_swap_chain_support(VkPhysicalDevice device) return details; } -// END VULKAN SPECIFIC +void window_set_title(std::string title) +{ + glfwSetWindowTitle(Window, title.c_str()); +} + +void window_set_size(int w, int h) +{ + Width = w; + Height = h; + glfwSetWindowSize(Window, Width, Height); +} + +void window_set_pos(int x, int y) { glfwSetWindowPos(Window, x, y); } + +glm::vec2 window_get_size() { return { Width, Height }; } + +void window_get_pos(int& x, int& y) { glfwGetWindowPos(Window, &x, &y); } GLFWwindow* window_get_glfw_window() { return Window; } diff --git a/src/window.hpp b/src/window.hpp index 3634c68..e2adb86 100644 --- a/src/window.hpp +++ b/src/window.hpp @@ -12,9 +12,18 @@ namespace inferno::graphics { typedef void (*KeyCallback)(int key, int scan, int action, int mod); typedef void (*MouseCallback)(double x, double y); +#define VALIDATION_LAYERS_ENABLED true +#ifdef VALIDATION_LAYERS_ENABLED +const std::vector VALIDATION_LAYERS = { + "VK_LAYER_KHRONOS_validation", +}; +#endif + static VkInstance VulkanInstance; static VkPhysicalDevice VulkanPhysicalDevice = VK_NULL_HANDLE; static VkDevice VulkanDevice; +static VkDebugUtilsMessengerEXT VulkanDebugMessenger = VK_NULL_HANDLE; +static VkQueue VulkanGraphicsQueue; static VkQueue VulkanPresentQueue; static VkSurfaceKHR VulkanSurface; static VkSwapchainKHR VulkanSwapChain; @@ -24,11 +33,6 @@ enum WINDOW_MODE { WIN_MODE_FPS, }; -enum HW_CAPABILITY { - HW_CAPABILITY_VK, - HW_CAPABILITY_VK_RT, -}; - struct QueueFamilyIndices { std::optional graphicsFamily; std::optional presentFamily; @@ -48,6 +52,17 @@ struct SwapChainSupportDetails { void window_create(std::string title, int width, int height); void window_cleanup(); +void window_create_vulkan_instance(); +void window_vulkan_debugger(); +void window_create_vulkan_surface(); +void window_create_vulkan_physical_device(); +void window_create_vulkan_logical_device(); + +bool window_evaluate_device(VkPhysicalDevice device); +bool window_evaluate_device_extensions(VkPhysicalDevice device, std::vector extensions); +QueueFamilyIndices window_get_queue_families(VkPhysicalDevice device); +SwapChainSupportDetails window_get_swap_chain_support(VkPhysicalDevice device); + void window_set_title(std::string title); void window_set_size(int w, int h); @@ -55,13 +70,6 @@ void window_set_pos(int x, int y); glm::vec2 window_get_size(); void window_get_pos(int& x, int& y); -// VULKAN SPECIFIC -bool window_evaluate_device(VkPhysicalDevice device, std::vector ext_needed, HW_CAPABILITY* capability); -bool window_evaluate_device_extensions(VkPhysicalDevice device, std::vector extensions); -QueueFamilyIndices window_get_queue_families(VkPhysicalDevice device); -SwapChainSupportDetails window_get_swap_chain_support(VkPhysicalDevice device); -// END VULKAN SPECIFIC - GLFWwindow* window_get_glfw_window(); void window_set_mode(WINDOW_MODE mode);