project-aster/aster_core/physical_device.h

85 lines
2.3 KiB
C++

// =============================================
// 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<QueueSupportFlagBits>;
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<bool>(queue_support & support);
}
};
struct PhysicalDevice {
vk::raii::PhysicalDevice device;
vk::PhysicalDeviceProperties properties;
vk::PhysicalDeviceFeatures features;
std::vector<vk::SurfaceFormatKHR> surface_formats;
std::vector<vk::PresentModeKHR> present_modes;
std::vector<QueueFamilyInfo> 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<QueueFamilyInfo> get_queue_families(const Window *_window) const;
};
struct PhysicalDevices : std::vector<PhysicalDevice> {
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));
}
}
};