[Feat] (MG_Backend/DirectVulkan): retrieve and check device extension

This commit is contained in:
2026-02-12 11:08:57 +08:00
parent 99bc2e121b
commit ba7bf87ee0
2 changed files with 51 additions and 13 deletions
@@ -77,7 +77,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
DestroyDebugMessenger();
DestroyInstance();
MGLOG_D("VulkanRenderer shut down completed");
MGLOG_I("VulkanRenderer shut down completed");
}
void VulkanRenderer::Render() {
@@ -212,7 +212,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
Vector<VkPhysicalDevice> devices(deviceCount);
vkEnumeratePhysicalDevices(m_instance, &deviceCount, devices.data());
for (Int i = 0; i < deviceCount; i++) {
if (CheckPhysicalDeviceEligibilityAndCompare(devices[i], m_physicalDevice, m_physicalDevice))
if (GetMoreCapablePhysicalDevice(devices[i], m_physicalDevice, m_physicalDevice))
MGLOG_I("Picked physical device %d.", i);
}
@@ -224,8 +224,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
}
}
Bool VulkanRenderer::CheckPhysicalDeviceEligibilityAndCompare(
VkPhysicalDevice device, const PhysicalDevice& otherDevice, PhysicalDevice& outDevice) {
Bool VulkanRenderer::GetMoreCapablePhysicalDevice(
VkPhysicalDevice newVkDevice, const PhysicalDevice& otherDevice, PhysicalDevice& outBetterDevice) {
const auto deviceTypeToStr = [](VkPhysicalDeviceType type) {
switch (type) {
case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
@@ -244,9 +244,9 @@ namespace MobileGL::MG_Backend::DirectVulkan {
};
PhysicalDevice newDevice;
newDevice.handle = device;
newDevice.handle = newVkDevice;
vkGetPhysicalDeviceProperties(device, &newDevice.properties);
vkGetPhysicalDeviceProperties(newVkDevice, &newDevice.properties);
const auto& deviceProperties = newDevice.properties;
auto apiVersion = deviceProperties.apiVersion;
MGLOG_I(" %s (Vulkan %d.%d.%d, %s)",
@@ -254,10 +254,17 @@ namespace MobileGL::MG_Backend::DirectVulkan {
VK_VERSION_MAJOR(apiVersion), VK_VERSION_MINOR(apiVersion), VK_VERSION_PATCH(apiVersion),
deviceTypeToStr(deviceProperties.deviceType));
Vector<VkQueueFamilyProperties> queueFamilies = GetQueueFamilyFromPhysicalDevice(device);
Bool deviceExtSupported = IsNecessaryDeviceExtensionSupported(newVkDevice);
if (!deviceExtSupported) {
outBetterDevice = otherDevice;
MGLOG_I(" Ignored physical device: Some of the required device extension not supported on this device.");
return false;
}
Vector<VkQueueFamilyProperties> queueFamilies = GetQueueFamilyFromPhysicalDevice(newVkDevice);
newDevice.queueFamilies.graphicsFamily = GetQueueFamilyIndex(queueFamilies, VK_QUEUE_GRAPHICS_BIT);
if (newDevice.queueFamilies.graphicsFamily == -1) {
outDevice = otherDevice;
outBetterDevice = otherDevice;
MGLOG_I(" Ignored physical device: No graphics queue family.");
return false;
}
@@ -265,7 +272,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
newDevice.queueFamilies.presentFamily =
GetPresentQueueFamilyIndex(newDevice, queueFamilies, newDevice.queueFamilies.graphicsFamily);
if (newDevice.queueFamilies.presentFamily == -1) {
outDevice = otherDevice;
outBetterDevice = otherDevice;
MGLOG_I(" Ignored physical device: No present queue family.");
return false;
}
@@ -273,7 +280,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
// Pick discrete GPU
if (newDevice.properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU &&
otherDevice.properties.deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) {
outDevice = newDevice;
outBetterDevice = newDevice;
MGLOG_I(" Picked physical device: Discrete GPU.");
return true;
}
@@ -281,7 +288,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
// Pick integrated GPU if no discrete GPU
if (newDevice.properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU &&
otherDevice.properties.deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) {
outDevice = newDevice;
outBetterDevice = newDevice;
MGLOG_I(" Picked physical device: Integrated GPU and the other is not discrete.");
return true;
}
@@ -289,7 +296,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
// Ignore other GPU when discrete GPU found
if (newDevice.properties.deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU &&
otherDevice.properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) {
outDevice = newDevice;
outBetterDevice = newDevice;
MGLOG_I(" Ignored physical device: Already picked discrete GPU.");
return false;
}
@@ -297,6 +304,33 @@ namespace MobileGL::MG_Backend::DirectVulkan {
return false;
}
Bool VulkanRenderer::IsNecessaryDeviceExtensionSupported(VkPhysicalDevice device) {
Uint32 extensionCount = 0;
vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, nullptr);
std::vector<VkExtensionProperties> availableExtensions(extensionCount);
vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, availableExtensions.data());
MGLOG_I("Got %u Vulkan device extensions: ", extensionCount);
for (auto& extension : availableExtensions) {
MGLOG_I(" %s (r.%u)", extension.extensionName, extension.specVersion);
}
for (SizeT i = 0; i < std::size(s_deviceExtensionNames); ++i) {
Bool found = false;
for (const auto& extension : availableExtensions) {
if (strcmp(extension.extensionName, s_deviceExtensionNames[i]) == 0) {
found = true;
break;
}
}
if (!found)
return false;
}
return true;
}
void VulkanRenderer::CreateLogicalDeviceAndQueues() {
Float queuePriority = 1.0f;
@@ -80,7 +80,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
VkResult DestroyDebugMessenger();
VkDebugUtilsMessengerCreateInfoEXT PopulateDebugMessengerCreateInfo();
void PickPhysicalDevice();
Bool CheckPhysicalDeviceEligibilityAndCompare(VkPhysicalDevice device, const PhysicalDevice& compareWithDevice, PhysicalDevice& outDevice);
Bool GetMoreCapablePhysicalDevice(VkPhysicalDevice newVkDevice, const PhysicalDevice& compareWithDevice, PhysicalDevice& outBetterDevice);
void CreateLogicalDeviceAndQueues();
void CreateSurface();
@@ -89,9 +89,13 @@ namespace MobileGL::MG_Backend::DirectVulkan {
static Vector<VkQueueFamilyProperties> GetQueueFamilyFromPhysicalDevice(VkPhysicalDevice device);
static Int GetQueueFamilyIndex(const Vector<VkQueueFamilyProperties>& queueFamilies, VkQueueFlagBits flag);
static Vector<VkExtensionProperties> EnumerateInstanceExtensions();
static Bool IsNecessaryDeviceExtensionSupported(VkPhysicalDevice device);
static constexpr const char* s_validationLayerNames[] = {
"VK_LAYER_KHRONOS_validation"
};
static constexpr const char* s_deviceExtensionNames[] = {
VK_KHR_SWAPCHAIN_EXTENSION_NAME
};
static Bool CheckValidationLayerSupport();
static VKAPI_ATTR VkBool32 VKAPI_CALL DebugCallback(