#include "aster/constants.h" #include "aster/context.h" #include "aster/device.h" #include "aster/glfw_context.h" #include "aster/physical_device.h" #include "aster/window.h" #include "aster/global.h" #include "aster/swapchain.h" constexpr QueueSupportFlags REQUIRED_QUEUE_SUPPORT = QueueSupportFlags{} | QueueSupportFlagBits::eGraphics | QueueSupportFlagBits::eCompute | QueueSupportFlagBits::ePresent | QueueSupportFlagBits::eTransfer; [[nodiscard]] bool isSuitableDevice(const PhysicalDevice *physicalDevice) { const bool hasAllRequiredQueues = std::ranges::any_of(physicalDevice->m_QueueFamilies, [](const auto &queueFamilyProp) { return (queueFamilyProp.m_Support & REQUIRED_QUEUE_SUPPORT) == REQUIRED_QUEUE_SUPPORT; }); const bool isNotCpu = physicalDevice->m_DeviceProperties.deviceType != vk::PhysicalDeviceType::eCpu; const bool hasPresentMode = !physicalDevice->m_PresentModes.empty(); const bool hasSurfaceFormat = !physicalDevice->m_SurfaceFormats.empty(); return hasSurfaceFormat && hasPresentMode && isNotCpu && hasAllRequiredQueues; } PhysicalDevice findSuitableDevice(const PhysicalDevices &physicalDevices) { for (auto &physicalDevice : physicalDevices) { if (isSuitableDevice(&physicalDevice)) { return physicalDevice; } } ERROR("No suitable GPU available on the system.") THEN_ABORT(vk::Result::eErrorUnknown); } QueueAllocation findAppropriateQueueAllocation(const PhysicalDevice *physicalDevice) { for (auto &queueFamilyInfo : physicalDevice->m_QueueFamilies) { if ((queueFamilyInfo.m_Support & REQUIRED_QUEUE_SUPPORT) == REQUIRED_QUEUE_SUPPORT) { return { .m_Family = queueFamilyInfo.m_Index, .m_Count = queueFamilyInfo.m_Count, }; } } ERROR("No suitable queue family on the GPU.") THEN_ABORT(vk::Result::eErrorUnknown); } int main(int, char **) { MIN_LOG_LEVEL(Logger::LogType::eDebug); GlfwContext glfwContext = {}; Context context = {"Aster", VERSION}; Window window = {"Aster1", &context, {640, 480}}; PhysicalDevices physicalDevices = {&window, &context}; PhysicalDevice deviceToUse = findSuitableDevice(physicalDevices); INFO("Using {} as the primary device.", deviceToUse.m_DeviceProperties.deviceName.data()); vk::PhysicalDeviceFeatures features = {}; QueueAllocation queueAllocation = findAppropriateQueueAllocation(&deviceToUse); Device device = {&context, &deviceToUse, &features, {queueAllocation}, "Primary Device"}; Swapchain swapchain = {&window, &device, "Primary Chain"}; while (window.Poll()) { } return 0; }