// ============================================= // Aster: physical_device.h // Copyright (c) 2020-2024 Anish Bhobe // ============================================= #pragma once #include "global.h" #include "window.h" enum class QueueSupportFlagBits { eGraphics = 0b0000'0001, eTransfer = 0b0000'0010, eCompute = 0b0000'0100, ePresent = 0b0000'1000, }; using QueueSupportFlags = vk::Flags; inline std::string to_string(QueueSupportFlags queue_support) { if (! queue_support) return {}; std::string result = ""; if (queue_support & QueueSupportFlagBits::eGraphics) { result += "Graphics | "; } if (queue_support & QueueSupportFlagBits::eTransfer) { result += "Transfer | "; } if (queue_support & QueueSupportFlagBits::eCompute) { result += "Compute | "; } if (queue_support & QueueSupportFlagBits::ePresent) { result += "Present | "; } return "{ " + result.substr( 0, result.size() - 3 ) + " }"; } struct QueueFamilyInfo { u32 index; u32 count; QueueSupportFlags queue_support; [[nodiscard]] bool has_support(const QueueSupportFlags &support) const { return cast(queue_support & support); } }; struct PhysicalDevice { vk::raii::PhysicalDevice device; vk::PhysicalDeviceProperties properties; vk::PhysicalDeviceFeatures features; std::vector surface_formats; std::vector present_modes; std::vector queue_family_infos; QueueSupportFlags queue_support; PhysicalDevice(const Window *const _window, vk::raii::PhysicalDevice &&_device) : device{ std::move(_device) } { properties = device.getProperties(); features = device.getFeatures(); surface_formats = device.getSurfaceFormatsKHR(*_window->surface); present_modes = device.getSurfacePresentModesKHR(*_window->surface); queue_family_infos = get_queue_families(_window); for (auto [family, count, support] : queue_family_infos) { queue_support |= support; } } std::vector get_queue_families(const Window *_window) const; }; struct PhysicalDevices : std::vector { PhysicalDevices(const Window *const _window, const Context *_context) { auto phys_devs = vk::raii::PhysicalDevices(_context->instance); reserve(phys_devs.size()); for (auto physdev : phys_devs) { emplace_back(_window, std::move(physdev)); } } };