95 lines
3.3 KiB
C++
95 lines
3.3 KiB
C++
// =============================================
|
|
// Aster: device.cpp
|
|
// Copyright (c) 2020-2024 Anish Bhobe
|
|
// =============================================
|
|
|
|
#include "device.h"
|
|
|
|
#include "context.h"
|
|
#include "window.h"
|
|
|
|
#include <map>
|
|
#include <set>
|
|
#include <vector>
|
|
|
|
Device::Device(Device &&_other) noexcept :
|
|
physical_device{ std::move(_other.physical_device) },
|
|
device{ std::exchange(_other.device, nullptr) },
|
|
allocator{ std::exchange(_other.allocator, nullptr) },
|
|
name{ std::move(_other.name) } {}
|
|
|
|
Device &Device::operator=(Device &&_other) noexcept {
|
|
if (this == &_other)
|
|
return *this;
|
|
physical_device = std::move(_other.physical_device);
|
|
device = std::exchange(_other.device, nullptr);
|
|
allocator = std::exchange(_other.allocator, nullptr);
|
|
name = std::move(_other.name);
|
|
return *this;
|
|
}
|
|
|
|
Device::Device(const std::string_view &_name, Context *_context, const PhysicalDevice &_physical_device_info, const vk::PhysicalDeviceFeatures &_enabled_features, std::set<QueueAllocation> &&_enabled_queues) :
|
|
physical_device{ _physical_device_info },
|
|
name{ _name } {
|
|
const auto &physical_device = _physical_device_info.device;
|
|
|
|
// Logical Device
|
|
std::vector queue_priority(_enabled_queues.size(), 1.0f);
|
|
std::vector<vk::DeviceQueueCreateInfo> queue_create_infos;
|
|
queue_create_infos.reserve(_enabled_queues.size());
|
|
for (auto &[family_, count_] : _enabled_queues) {
|
|
queue_create_infos.push_back({
|
|
.queueFamilyIndex = family_,
|
|
.queueCount = count_,
|
|
.pQueuePriorities = queue_priority.data(),
|
|
});
|
|
}
|
|
try {
|
|
device = physical_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("Failed to create a logical device with "s + err.what());
|
|
throw;
|
|
}
|
|
INFO("Logical Device Created!");
|
|
|
|
const VmaAllocatorCreateInfo allocator_create_info = {
|
|
.physicalDevice = *physical_device,
|
|
.device = *device,
|
|
.instance = *_context->instance,
|
|
};
|
|
|
|
allocator = nullptr;
|
|
const auto result = cast<vk::Result>(vmaCreateAllocator(&allocator_create_info, &allocator));
|
|
if (failed(result)) {
|
|
ERROR("Memory allocator creation failed with "s + vk::to_string(result));
|
|
throw std::runtime_error("Memory allocator creation failed with "s + vk::to_string(result));
|
|
}
|
|
VERBOSE("Memory Allocator Created");
|
|
|
|
INFO(fmt::format("Created Device '{}' Successfully", _name));
|
|
|
|
set_name(_name);
|
|
}
|
|
|
|
Device::~Device() {
|
|
if (allocator) {
|
|
vmaDestroyAllocator(allocator);
|
|
}
|
|
INFO("Device '" + name + "' Destroyed");
|
|
}
|
|
|
|
void Device::set_name(const std::string_view &_name) {
|
|
VERBOSE(fmt::format("Device {} -> {}", name.data(), _name.data()));
|
|
name = _name;
|
|
set_object_name(*physical_device.device, fmt::format("{} GPU", _name.data()));
|
|
set_object_name(*device, fmt::format("{} Device", _name.data()));
|
|
}
|