202 lines
6.7 KiB
C++
202 lines
6.7 KiB
C++
// =============================================
|
|
// Aster: device.h
|
|
// Copyright (c) 2020-2024 Anish Bhobe
|
|
// =============================================
|
|
|
|
#pragma once
|
|
|
|
#include "context.h"
|
|
#include "global.h"
|
|
#include "physical_device.h"
|
|
#include "window.h"
|
|
|
|
#include <iterator>
|
|
#include <span>
|
|
#include <string_view>
|
|
#include <utility>
|
|
|
|
struct Queues {
|
|
vk::raii::Queue graphics{ nullptr };
|
|
vk::raii::Queue present{ nullptr };
|
|
vk::raii::Queue transfer{ nullptr };
|
|
Option<vk::raii::Queue> compute;
|
|
};
|
|
|
|
template <typename T>
|
|
struct SubmitTask;
|
|
|
|
class Device {
|
|
public:
|
|
|
|
Device(const Device &_other) = delete;
|
|
Device(Device &&_other) noexcept;
|
|
Device &operator=(const Device &_other) = delete;
|
|
Device &operator=(Device &&_other) noexcept;
|
|
|
|
Device(const std::string_view &_name, Context *_context, const PhysicalDevice &_physical_device_info, const vk::PhysicalDeviceFeatures &_enabled_features);
|
|
|
|
~Device();
|
|
|
|
template <typename T>
|
|
requires vk::isVulkanHandleType<T>::value void set_object_name(const T &_obj, const std::string_view &_name) const {
|
|
try {
|
|
device.setDebugUtilsObjectNameEXT({
|
|
.objectType = _obj.objectType,
|
|
.objectHandle = get_vk_handle(_obj),
|
|
.pObjectName = _name.data(),
|
|
});
|
|
} catch (const std::exception &err) {
|
|
WARN("Debug Utils name setting failed with "s + err.what());
|
|
}
|
|
}
|
|
|
|
//
|
|
// [[nodiscard]]
|
|
// Res<vk::CommandBuffer> alloc_temp_command_buffer(vk::CommandPool _pool) const;
|
|
//
|
|
// [[nodiscard]] Res<SubmitTask<Buffer>> upload_data(const Borrowed<Buffer>& _host_buffer, Buffer&& _staging_buffer);
|
|
// [[nodiscard]] Res<SubmitTask<Buffer>> upload_data(const Borrowed<Buffer>& _host_buffer, const std::span<u8>& _data);
|
|
// Res<> update_data(const Borrowed<Buffer>& _host_buffer, const std::span<u8>& _data) const;
|
|
|
|
// fields
|
|
PhysicalDevice physical_device;
|
|
vk::raii::Device device{ nullptr };
|
|
Queues queues;
|
|
VmaAllocator allocator;
|
|
|
|
// vk::CommandPool transfer_cmd_pool;
|
|
// vk::CommandPool graphics_cmd_pool;
|
|
|
|
std::string name;
|
|
|
|
private:
|
|
void set_name(const std::string_view &_name);
|
|
};
|
|
//
|
|
// template <typename T = void>
|
|
// struct SubmitTask {
|
|
// vk::Fence fence;
|
|
// Borrowed<Device> device{};
|
|
// T payload;
|
|
// std::vector<vk::CommandBuffer> cmd;
|
|
// vk::CommandPool pool;
|
|
//
|
|
// [[nodiscard]]
|
|
// static Res<SubmitTask<T>> create(const Borrowed<Device>& _device, T&& _payload, vk::Queue _queue, vk::CommandPool _pool, const std::vector<vk::CommandBuffer>& _cmd, const std::vector<vk::Semaphore>& _wait_on = {}, const std::vector<vk::Semaphore>& _signal_to = {}) {
|
|
//
|
|
// SubmitTask<T> task;
|
|
// if (auto res = task.submit(_device, std::forward<T>(_payload), _queue, _pool, _cmd, _wait_on, _signal_to)) {
|
|
// return std::move(task);
|
|
// } else {
|
|
// return Err::make(std::move(res.error()));
|
|
// }
|
|
// }
|
|
//
|
|
// [[nodiscard]]
|
|
// Res<> submit(const Borrowed<Device>& _device, T&& _payload, vk::Queue _queue, vk::CommandPool _pool, std::vector<vk::CommandBuffer> _cmd, std::vector<vk::Semaphore> _wait_on = {}, std::vector<vk::Semaphore> _signal_to = {}) {
|
|
// device = _device;
|
|
// auto [result, _fence] = device->device.createFence({});
|
|
// if (failed(result)) {
|
|
// return Err::make(std::fmt("Fence creation failed with %s" CODE_LOC, to_cstr(result)), result);
|
|
// }
|
|
// fence = _fence;
|
|
// payload = std::move(_payload);
|
|
// cmd = _cmd;
|
|
// pool = _pool;
|
|
//
|
|
// result = _queue.submit({
|
|
// {
|
|
// .waitSemaphoreCount = cast<u32>(_wait_on.size()),
|
|
// .pWaitSemaphores = _wait_on.data(),
|
|
// .commandBufferCount = cast<u32>(_cmd.size()),
|
|
// .pCommandBuffers = _cmd.data(),
|
|
// .signalSemaphoreCount = cast<u32>(_signal_to.size()),
|
|
// .pSignalSemaphores = _signal_to.data(),
|
|
// }
|
|
// },
|
|
// _fence);
|
|
// if (failed(result)) {
|
|
// return Err::make(std::fmt("Submit failed with %s" CODE_LOC, to_cstr(result)), result);
|
|
// }
|
|
//
|
|
// return {};
|
|
// }
|
|
//
|
|
// [[nodiscard]]
|
|
// Res<> wait_and_destroy() {
|
|
// return this->destroy();
|
|
// }
|
|
//
|
|
// [[nodiscard]]
|
|
// Res<> destroy() {
|
|
// const auto result = device->device.waitForFences({ fence }, true, max_value<u64>);
|
|
// if (failed(result)) return Err::make(std::fmt("Fence wait failed with %s" CODE_LOC, to_cstr(result)), result);
|
|
// device->device.destroyFence(fence);
|
|
// device->device.freeCommandBuffers(pool, cast<u32>(cmd.size()), cmd.data());
|
|
// return {};
|
|
// }
|
|
// };
|
|
//
|
|
// template <>
|
|
// struct SubmitTask<void> {
|
|
// vk::Fence fence;
|
|
// Borrowed<Device> device;
|
|
// std::vector<vk::CommandBuffer> cmd;
|
|
// vk::CommandPool pool;
|
|
//
|
|
// [[nodiscard]]
|
|
// static Res<SubmitTask<>> create(const Borrowed<Device>& _device, vk::Queue _queue, vk::CommandPool _pool, const std::vector<vk::CommandBuffer>& _cmd, const std::vector<vk::Semaphore>& _wait_on = {}, const vk::PipelineStageFlags& _wait_stage = vk::PipelineStageFlagBits::eBottomOfPipe, const std::vector<vk::Semaphore>& _signal_to = {}) {
|
|
//
|
|
// SubmitTask<> task;
|
|
// if (auto res = task.submit(_device, _queue, _pool, _cmd, _wait_on, _wait_stage, _signal_to)) {
|
|
// return std::move(task);
|
|
// } else {
|
|
// return Err::make(std::move(res.error()));
|
|
// }
|
|
// }
|
|
//
|
|
// [[nodiscard]]
|
|
// Res<> wait_and_destroy() {
|
|
// return this->destroy();
|
|
// }
|
|
//
|
|
// [[nodiscard]]
|
|
// Res<> destroy() {
|
|
// const auto result = device->device.waitForFences({ fence }, true, max_value<u64>);
|
|
// if (failed(result)) return Err::make(std::fmt("Fence wait failed with %s", to_cstr(result)), result);
|
|
// device->device.destroyFence(fence);
|
|
// device->device.freeCommandBuffers(pool, cast<u32>(cmd.size()), cmd.data());
|
|
// return {};
|
|
// }
|
|
//
|
|
// private:
|
|
// [[nodiscard]]
|
|
// Res<> submit(const Borrowed<Device>& _device, vk::Queue _queue, vk::CommandPool _pool, std::vector<vk::CommandBuffer> _cmd, std::vector<vk::Semaphore> _wait_on = {},
|
|
// const vk::PipelineStageFlags& _wait_stage = vk::PipelineStageFlagBits::eBottomOfPipe, std::vector<vk::Semaphore> _signal_to = {}) {
|
|
// device = _device;
|
|
// auto [result, _fence] = device->device.createFence({});
|
|
// if (failed(result)) {
|
|
// return Err::make(std::fmt("Fence creation failed with %s" CODE_LOC, to_cstr(result)), result);
|
|
// }
|
|
// fence = _fence;
|
|
// cmd = _cmd;
|
|
// pool = _pool;
|
|
// result = _queue.submit({
|
|
// vk::SubmitInfo{
|
|
// .waitSemaphoreCount = cast<u32>(_wait_on.size()),
|
|
// .pWaitSemaphores = _wait_on.data(),
|
|
// .pWaitDstStageMask = &_wait_stage,
|
|
// .commandBufferCount = cast<u32>(_cmd.size()),
|
|
// .pCommandBuffers = _cmd.data(),
|
|
// .signalSemaphoreCount = cast<u32>(_signal_to.size()),
|
|
// .pSignalSemaphores = _signal_to.data(),
|
|
// } },
|
|
// _fence);
|
|
// if (failed(result)) {
|
|
// return Err::make(std::fmt("Submit failed with %s" CODE_LOC, to_cstr(result)), result);
|
|
// }
|
|
//
|
|
// return {};
|
|
// }
|
|
// };
|
|
//
|