diff --git a/engine/include/nova/render/render_device.h b/engine/include/nova/render/render_device.h index c53480d..73e8cd8 100644 --- a/engine/include/nova/render/render_device.h +++ b/engine/include/nova/render/render_device.h @@ -13,6 +13,7 @@ namespace Nova { struct NOVA_API RenderDevice { + static constexpr u32 AUTO = static_cast(-1); enum class Vendor { UNKNOWN = 0, INTEL = 0x8086, AMD = 0x1002, NVIDIA = 0x10de }; enum class Type { OTHER = 0, INTEGRATED = 1, DISCRETE = 2, VIRTUAL = 3, CPU = 4 }; diff --git a/engine/src/drivers/vulkan/render_driver.cpp b/engine/src/drivers/vulkan/render_driver.cpp index 3ecf1dd..9238f53 100644 --- a/engine/src/drivers/vulkan/render_driver.cpp +++ b/engine/src/drivers/vulkan/render_driver.cpp @@ -72,17 +72,24 @@ const RenderDevice& VulkanRenderDriver::get_device(const u32 index) const { return m_devices[index]; } -void VulkanRenderDriver::create_device(const u32 index) { +void VulkanRenderDriver::create_device(u32 index) { NOVA_AUTO_TRACE(); - NOVA_ASSERT(index < m_devices.size()); NOVA_ASSERT(!m_device); + if (index == RenderDevice::AUTO) { + index = _pick_device(); + } else { + NOVA_ASSERT(index < m_devices.size()); + } + + NOVA_LOG("Using device: {}", m_devices[index].name); m_physical_device = static_cast(m_devices[index].handle); - std::vector queues; _check_device_extensions(); _check_device_features(); // TODO: Check device capabilities + + std::vector queues; _init_queues(queues); _init_device(queues); } @@ -228,6 +235,43 @@ void VulkanRenderDriver::_init_hardware() { NOVA_LOG("Found device: {}", properties.deviceName); } + + if (m_devices.empty()) { + throw std::runtime_error("No devices found"); + } +} + +u32 VulkanRenderDriver::_pick_device() const { + NOVA_AUTO_TRACE(); + + u32 best_index = 0; + u32 best_score = 0; + + for (u32 i = 0; i < m_devices.size(); i++) { + u32 score = 0; + switch (m_devices[i].type) { + case RenderDevice::Type::DISCRETE: + score += 4; + break; + case RenderDevice::Type::INTEGRATED: + score += 3; + break; + case RenderDevice::Type::VIRTUAL: + score += 2; + break; + case RenderDevice::Type::CPU: + score += 1; + break; + default: + break; + } + if (score > best_score) { + best_index = i; + best_score = score; + } + } + + return best_index; } void VulkanRenderDriver::_check_device_extensions() { diff --git a/engine/src/drivers/vulkan/render_driver.h b/engine/src/drivers/vulkan/render_driver.h index df26bd3..dd74b18 100644 --- a/engine/src/drivers/vulkan/render_driver.h +++ b/engine/src/drivers/vulkan/render_driver.h @@ -43,6 +43,7 @@ namespace Nova { void _init_instance(); void _init_hardware(); + u32 _pick_device() const; void _check_device_extensions(); void _check_device_features(); void _init_queues(std::vector& queues) const;