Select Git revision
Renderer.cpp 2.95 KiB
#include "Renderer.hpp"
#include <algorithm>
#include <ranges>
#include <vector>
const std::vector<const char*> g_layers{
#ifdef ENGINE_VULKAN_DEBUG
"VK_LAYER_KHRONOS_validation"
#endif
};
[[nodiscard]] static auto create_instance() -> vk::UniqueInstance
{
constexpr static vk::ApplicationInfo application_info{};
const vk::InstanceCreateInfo create_info{
.pApplicationInfo = &application_info,
.enabledLayerCount = static_cast<uint32_t>(g_layers.size()),
.ppEnabledLayerNames = g_layers.data(),
};
return vk::createInstanceUnique(create_info);
}
[[nodiscard]] static auto choose_physical_device(const vk::Instance t_instance)
-> vk::PhysicalDevice
{
const auto physical_devices{ t_instance.enumeratePhysicalDevices() };
if (std::ranges::empty(physical_devices)) {
throw std::runtime_error{ "No Vulkan physical device is available." };
}
auto ranked_devices_view{
physical_devices
| std::views::transform([](vk::PhysicalDevice t_physical_device) {
switch (t_physical_device.getProperties().deviceType) {
case vk::PhysicalDeviceType::eDiscreteGpu:
return std::make_pair(t_physical_device, 2);
case vk::PhysicalDeviceType::eIntegratedGpu:
return std::make_pair(t_physical_device, 1);
default: return std::make_pair(t_physical_device, 0);
}
})
};
std::vector ranked_devices(
ranked_devices_view.begin(), ranked_devices_view.end()
);
std::ranges::sort(
ranked_devices,
std::ranges::greater{},
&std::pair<vk::PhysicalDevice, int>::second
);
return ranked_devices.front().first;
}
[[nodiscard]] static auto find_graphics_queue_family(
const vk::PhysicalDevice t_physical_device
) -> uint32_t
{
uint32_t index{};
for (const auto& properties : t_physical_device.getQueueFamilyProperties())
{
if (properties.queueFlags & vk::QueueFlagBits::eGraphics) {
return index;
}
index++;
}
throw std::runtime_error{ "Could not find graphics queue family" };
}
[[nodiscard]] static auto create_device(const vk::PhysicalDevice t_physical_device)
-> vk::UniqueDevice
{
const vk::DeviceQueueCreateInfo queue_create_info{
.queueFamilyIndex = find_graphics_queue_family(t_physical_device),
.queueCount = 1,
};
vk::DeviceCreateInfo device_create_info{
.queueCreateInfoCount = 1,
.pQueueCreateInfos = &queue_create_info,
};
return t_physical_device.createDeviceUnique(device_create_info);
}
Renderer::Renderer()
: m_instance{ create_instance() },
m_physical_device{ choose_physical_device(*m_instance) },
m_graphics_queue_family{ find_graphics_queue_family(m_physical_device) },
m_device{ create_device(m_physical_device) },
m_graphics_queue{ m_device->getQueue(m_graphics_queue_family, 0) }
{}