From 5a751a674574e597364058861ef3f4c192d1fcde Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Wed, 11 Feb 2026 14:35:37 +0800 Subject: [PATCH] [Feat] (MG_Backend/DirectVulkan): pick vkPhysicalDevice --- .../DirectVulkan/Renderer/VulkanRenderer.cpp | 77 ++++++++++++++++++- .../DirectVulkan/Renderer/VulkanRenderer.h | 6 +- 2 files changed, 79 insertions(+), 4 deletions(-) diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp index 4820f9a3..43fdf349 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp @@ -60,6 +60,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { void VulkanRenderer::Initialize() { CreateInstance(); + PickPhysicalDevice(); MGLOG_D("VulkanRenderer initialized"); } @@ -80,8 +81,8 @@ namespace MobileGL::MG_Backend::DirectVulkan { } void VulkanRenderer::CreateInstance() { - m_extensions = EnumerateExtensions(); - MGLOG_I("Got %d Vulkan extensions: ", m_extensions.size()); + m_extensions = EnumerateInstanceExtensions(); + MGLOG_I("Got %d Vulkan instance extensions: ", m_extensions.size()); for (auto& extension : m_extensions) { MGLOG_I(" %s (r.%u)", extension.extensionName, extension.specVersion); } @@ -189,7 +190,77 @@ namespace MobileGL::MG_Backend::DirectVulkan { return createInfo; } - Vector VulkanRenderer::EnumerateExtensions() { + void VulkanRenderer::PickPhysicalDevice() { + Uint32 deviceCount = 0; + vkEnumeratePhysicalDevices(m_instance, &deviceCount, nullptr); + if (deviceCount == 0) { + MGLOG_E("No physical devices supporting Vulkan found."); + } else { + MGLOG_I("Found %d physical device(s).", deviceCount); + } + + auto deviceTypeToStr = [](VkPhysicalDeviceType type) { + switch (type) { + case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: + return "INTEGRATED_GPU"; + case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: + return "DISCRETE_GPU"; + case VK_PHYSICAL_DEVICE_TYPE_CPU: + return "CPU"; + case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: + return "VIRTUAL_GPU"; + case VK_PHYSICAL_DEVICE_TYPE_OTHER: + return "OTHER"; + default: + return "UNKNOWN"; + } + }; + + Vector devices(deviceCount); + vkEnumeratePhysicalDevices(m_instance, &deviceCount, devices.data()); + for (const auto& device : devices) { + VkPhysicalDeviceProperties deviceProperties; + vkGetPhysicalDeviceProperties(device, &deviceProperties); + auto apiVersion = deviceProperties.apiVersion; + MGLOG_I(" %s (Vulkan %d.%d.%d, %s)", + deviceProperties.deviceName, + VK_VERSION_MAJOR(apiVersion), VK_VERSION_MINOR(apiVersion), VK_VERSION_PATCH(apiVersion), + deviceTypeToStr(deviceProperties.deviceType)); + // TODO: Properly check device eligibility + if (m_physicalDevice == VK_NULL_HANDLE && deviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) { + m_physicalDevice = device; + MGLOG_I("Physical device picked."); + } + + if (m_physicalDevice == VK_NULL_HANDLE && CheckDeviceEligible(device)) { + m_physicalDevice = device; + MGLOG_I("Physical device picked."); + } + } + + MOBILEGL_ASSERT(!devices.empty(), "No physical devices found."); + if (m_physicalDevice == VK_NULL_HANDLE) { + m_physicalDevice = devices[0]; + MGLOG_I("No suitable physical device picked yet, defaulting to device 0."); + } + } + + Bool VulkanRenderer::CheckDeviceEligible(VkPhysicalDevice device) { + Uint32 queueFamilyCount = 0; + vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, nullptr); + + Vector queueFamilies(queueFamilyCount); + vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, queueFamilies.data()); + + for (const auto& queueFamily : queueFamilies) { + if (queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) { + return true; + } + } + return false; + } + + Vector VulkanRenderer::EnumerateInstanceExtensions() { Uint32 extensionCount = 0; VK_VERIFY(vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr)); Vector extensions(extensionCount); diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.h b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.h index 5eb5247b..b763f328 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.h +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.h @@ -51,13 +51,17 @@ namespace MobileGL::MG_Backend::DirectVulkan { Vector m_extensions; VkInstance m_instance = VK_NULL_HANDLE; VkDebugUtilsMessengerEXT m_debugMessenger = VK_NULL_HANDLE; + VkPhysicalDevice m_physicalDevice = VK_NULL_HANDLE; void CreateInstance(); void DestroyInstance(); VkResult SetupDebugMessenger(); VkResult DestroyDebugMessenger(); VkDebugUtilsMessengerCreateInfoEXT PopulateDebugMessengerCreateInfo(); - static Vector EnumerateExtensions(); + void PickPhysicalDevice(); + static Bool CheckDeviceEligible(VkPhysicalDevice device); + + static Vector EnumerateInstanceExtensions(); static constexpr const char* s_validationLayerNames[] = { "VK_LAYER_KHRONOS_validation" };