project-aster/aster/device.cpp

80 lines
2.9 KiB
C++

// =============================================
// Aster: device.cpp
// Copyright (c) 2020-2024 Anish Bhobe
// =============================================
#include "device.h"
Device::Device(const Context *_context, PhysicalDevice &&_physical_device, const vk::PhysicalDeviceFeatures *_enabled_features, const std::vector<QueueAllocation> &_queue_allocation, std::optional<std::string> _name) :
physical_device{ std::move(_physical_device) },
name{ std::move(_name) } {
std::vector<vk::DeviceQueueCreateInfo> queue_create_infos;
queue_create_infos.reserve(_queue_allocation.size());
u32 num_priorities = 0;
for (auto [_, count] : _queue_allocation) {
num_priorities = std::max(count, num_priorities);
}
std::vector priorities(num_priorities, 1.0f);
for (auto [family, count] : _queue_allocation) {
queue_create_infos.push_back({
.queueFamilyIndex = family,
.queueCount = count,
.pQueuePriorities = priorities.data(),
});
}
try {
device = physical_device.device.createDevice({
.queueCreateInfoCount = cast<u32>(queue_create_infos.size()),
.pQueueCreateInfos = queue_create_infos.data(),
.enabledLayerCount = _context->enable_validation_layers ? cast<u32>(_context->validation_layers.size()) : 0,
.ppEnabledLayerNames = _context->enable_validation_layers ? _context->validation_layers.data() : nullptr,
.enabledExtensionCount = cast<u32>(_context->device_extensions.size()),
.ppEnabledExtensionNames = _context->device_extensions.data(),
.pEnabledFeatures = _enabled_features,
});
} catch (const std::exception &_err) {
ERROR("Could not initialize Vulkan Device. Cause: {}", _err.what());
throw;
}
INFO("{} ({}) Initialized!", name.value_or(DEFAULT_DEVICE_NAME), physical_device.properties.deviceName.data());
VmaVulkanFunctions vma_vulkan_functions = {
.vkGetInstanceProcAddr = vk::defaultDispatchLoaderDynamic.vkGetInstanceProcAddr,
.vkGetDeviceProcAddr = vk::defaultDispatchLoaderDynamic.vkGetDeviceProcAddr,
};
const VmaAllocatorCreateInfo vma_allocator_create_info = {
.flags = 0,
.physicalDevice = physical_device.device,
.device = device,
.pVulkanFunctions = &vma_vulkan_functions,
.instance = _context->instance,
.vulkanApiVersion = ASTER_API_VERSION,
};
const auto result = cast<vk::Result>(vmaCreateAllocator(&vma_allocator_create_info, &allocator));
if (failed(result)) {
device.destroy();
auto _err = fmt::format("Memory allocator creation failed. Cause: {}", to_string(result));
ERROR("{}", _err);
throw std::runtime_error(_err);
}
VERBOSE("Memory Allocator Created");
INFO("Created '{}' Successfully", name.value_or(DEFAULT_DEVICE_NAME));
}
Device::~Device() {
if (allocator) {
vmaDestroyAllocator(allocator);
allocator = nullptr;
VERBOSE("Memory Allocator Destroyed");
}
device.destroy();
INFO("Device '{}' Destroyed", name.value_or(DEFAULT_DEVICE_NAME));
name = std::nullopt;
}