#ifndef GAMINGCORE_VULKAN_BASE_HPP #define GAMINGCORE_VULKAN_BASE_HPP #include #include #include #include #define GLFW_INCLUDE_VULKAN #include #include "core/VulkanUtility.hpp" namespace Core::Vulkan { [[maybe_unused]] constexpr u32 INVALID_QUEUE_FAMILY = 0xFFFF'FFFF; struct DeviceQueueData { u32 queueFamilyIndex = 0; float priority = 0.0f; }; class Base { VkInstance instance; #ifdef DEBUG_VULKAN VkDebugUtilsMessengerEXT debugMessenger; VkDebugReportCallbackEXT debugReportCallback; #endif VkSurfaceKHR surface; VkPhysicalDevice physicalDevice; VkDevice device; public: Base(); ~Base(); Base(const Base&) = delete; Base(Base&&) = delete; Base& operator=(const Base&) = delete; Base& operator=(Base&&) = delete; bool init(); void destroy(); PFN_vkVoidFunction getFunction(const char* name); template using PhysicalDeviceSelector = int (*)(Base&, T&); template bool findPhysicalDevice(T& data, PhysicalDeviceSelector s) { Core::Array devices; u32 c = devices.getLength(); VK_CHECK_TRUE( vkEnumeratePhysicalDevices(instance, &c, &devices[0])); int bestPoints = 0; VkPhysicalDevice best = VK_NULL_HANDLE; for(u32 i = 0; i < c; i++) { physicalDevice = devices[i]; T userData; int points = s(*this, userData); if(points > bestPoints) { bestPoints = points; best = physicalDevice; data = userData; } } physicalDevice = best; return bestPoints == 0; } void getPhysicalDeviceProperties(VkPhysicalDeviceProperties& p); u32 findQueueFamily(VkQueueFlags flags); u32 findSurfaceQueueFamily(); bool hasExtension(const char* extension); bool getSurfaceCapabilities(VkSurfaceCapabilitiesKHR& c); using SurfaceFormatSelector = int (*)(const VkSurfaceFormatKHR&); bool findSurfaceFormat( VkSurfaceFormatKHR& sf, SurfaceFormatSelector sfs); using SurfacePresentModeSelector = int (*)(VkPresentModeKHR); bool findSurfacePresentMode( VkPresentModeKHR& m, SurfacePresentModeSelector spms); bool initDevice( const List data, const List& extensions); void waitForIdle(); operator VkDevice() { return device; } operator VkSurfaceKHR() { return surface; } private: bool initInstance(); #ifdef DEBUG_VULKAN bool initDebugMessenger(); bool initDebugReportCallback(); void destroyDebugMessenger(); void destroyDebugReportCallback(); #endif bool initSurface(); }; } #endif