80 lines
2.9 KiB
C++
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;
|
|
} |