light/modules/renderer/backends/vk/context/device.cppm
light7734 6635d6396d
Some checks reported errors
continuous-integration/drone/push Build was killed
wip: convert from include style to module import style :D
2025-11-08 23:24:55 +03:30

145 lines
3.5 KiB
C++

export module renderer.backend.vk.device;
import memory.null_on_move;
import logger;
import debug.assertions;
import renderer.backend.vk.instance;
import renderer.frontend;
import renderer.backend.vk.library_wrapper;
import renderer.backend.vk.gpu;
import renderer.backend.vk.surface;
import std;
namespace lt::renderer::vkb {
export class Device: public IDevice
{
public:
Device(IGpu *gpu, ISurface *surface);
[[nodiscard]] auto vk() -> vk::Device &
{
return m_device;
}
[[nodiscard]] auto get_family_indices() const -> std::array<std::uint32_t, 2>
{
return { m_graphics_queue_family_index, m_present_queue_family_index };
}
private:
void initialize_physical_device();
void initialize_logical_device();
void initialize_queue_indices();
[[nodiscard]] auto find_suitable_queue_family() const -> std::uint32_t;
vkb::Gpu *m_gpu {};
vkb::Surface *m_surface {};
vk::Device m_device;
vk::Queue m_graphics_queue {};
vk::Queue m_present_queue {};
std::uint32_t m_graphics_queue_family_index = vk::constants::queue_family_ignored;
std::uint32_t m_present_queue_family_index = vk::constants::queue_family_ignored;
};
} // namespace lt::renderer::vkb
module :private;
using namespace lt::renderer;
using namespace lt::renderer::vkb;
Device::Device(IGpu *gpu, ISurface *surface)
: m_gpu(static_cast<Gpu *>(gpu))
, m_surface(static_cast<Surface *>(surface))
{
debug::ensure(m_surface->vk(), "Failed to initialize vk::Device: null vulkan surface");
initialize_queue_indices();
initialize_logical_device();
m_graphics_queue = vk::Queue(m_device, m_graphics_queue_family_index, 0u);
m_present_queue = vk::Queue(m_device, m_present_queue_family_index, 0u);
if (m_graphics_queue_family_index == m_present_queue_family_index)
{
m_device.name(m_present_queue, "graphics|present queue");
}
else
{
m_device.name(m_graphics_queue, "graphics queue");
m_device.name(m_present_queue, "present queue");
}
}
void Device::initialize_logical_device()
{
m_device = vk::Device(
m_gpu->vk(),
vk::Device::CreateInfo {
.queue_indices = std::set { m_graphics_queue_family_index, m_present_queue_family_index },
.extensions = {
vk::device_extension_names::swapchain,
vk::device_extension_names::dynamic_rendering,
vk::device_extension_names::descriptor_indexing,
},
.features = m_gpu->vk().get_features(),
.dynamic_rendering_features = m_gpu->vk().get_supported_dynamic_rendering_features(),
.descriptor_indexing_features = {
m_gpu->vk().get_supported_descriptor_indexing_features()
},
}
);
m_device.load_functions();
}
void Device::initialize_queue_indices()
{
auto properties = m_gpu->vk().get_queue_family_properties();
for (auto idx = std::uint32_t { 0u }; const auto &property : properties)
{
if (property.queue_flags & vk::QueueFlags::graphics_bit)
{
m_graphics_queue_family_index = idx;
}
if (m_gpu->vk().queue_family_supports_surface(m_surface->vk(), idx))
{
m_present_queue_family_index = idx;
}
if (m_graphics_queue_family_index != vk::constants::queue_family_ignored
&& m_present_queue_family_index != vk::constants::queue_family_ignored)
{
break;
}
++idx;
}
debug::ensure(
m_graphics_queue_family_index != vk::constants::queue_family_ignored,
"Failed to find graphics queue family"
);
debug::ensure(
m_present_queue_family_index != vk::constants::queue_family_ignored,
"Failed to find presentation queue family"
);
}