mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-11 21:58:31 +09:00
[Feat] (MG_Backend/DirectVulkan): retrieve and check device extension
This commit is contained in:
@@ -77,7 +77,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
DestroyDebugMessenger();
|
DestroyDebugMessenger();
|
||||||
|
|
||||||
DestroyInstance();
|
DestroyInstance();
|
||||||
MGLOG_D("VulkanRenderer shut down completed");
|
MGLOG_I("VulkanRenderer shut down completed");
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanRenderer::Render() {
|
void VulkanRenderer::Render() {
|
||||||
@@ -212,7 +212,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
Vector<VkPhysicalDevice> devices(deviceCount);
|
Vector<VkPhysicalDevice> devices(deviceCount);
|
||||||
vkEnumeratePhysicalDevices(m_instance, &deviceCount, devices.data());
|
vkEnumeratePhysicalDevices(m_instance, &deviceCount, devices.data());
|
||||||
for (Int i = 0; i < deviceCount; i++) {
|
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);
|
MGLOG_I("Picked physical device %d.", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,8 +224,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Bool VulkanRenderer::CheckPhysicalDeviceEligibilityAndCompare(
|
Bool VulkanRenderer::GetMoreCapablePhysicalDevice(
|
||||||
VkPhysicalDevice device, const PhysicalDevice& otherDevice, PhysicalDevice& outDevice) {
|
VkPhysicalDevice newVkDevice, const PhysicalDevice& otherDevice, PhysicalDevice& outBetterDevice) {
|
||||||
const auto deviceTypeToStr = [](VkPhysicalDeviceType type) {
|
const auto deviceTypeToStr = [](VkPhysicalDeviceType type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
|
case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
|
||||||
@@ -244,9 +244,9 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
};
|
};
|
||||||
|
|
||||||
PhysicalDevice newDevice;
|
PhysicalDevice newDevice;
|
||||||
newDevice.handle = device;
|
newDevice.handle = newVkDevice;
|
||||||
|
|
||||||
vkGetPhysicalDeviceProperties(device, &newDevice.properties);
|
vkGetPhysicalDeviceProperties(newVkDevice, &newDevice.properties);
|
||||||
const auto& deviceProperties = newDevice.properties;
|
const auto& deviceProperties = newDevice.properties;
|
||||||
auto apiVersion = deviceProperties.apiVersion;
|
auto apiVersion = deviceProperties.apiVersion;
|
||||||
MGLOG_I(" %s (Vulkan %d.%d.%d, %s)",
|
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),
|
VK_VERSION_MAJOR(apiVersion), VK_VERSION_MINOR(apiVersion), VK_VERSION_PATCH(apiVersion),
|
||||||
deviceTypeToStr(deviceProperties.deviceType));
|
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);
|
newDevice.queueFamilies.graphicsFamily = GetQueueFamilyIndex(queueFamilies, VK_QUEUE_GRAPHICS_BIT);
|
||||||
if (newDevice.queueFamilies.graphicsFamily == -1) {
|
if (newDevice.queueFamilies.graphicsFamily == -1) {
|
||||||
outDevice = otherDevice;
|
outBetterDevice = otherDevice;
|
||||||
MGLOG_I(" Ignored physical device: No graphics queue family.");
|
MGLOG_I(" Ignored physical device: No graphics queue family.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -265,7 +272,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
newDevice.queueFamilies.presentFamily =
|
newDevice.queueFamilies.presentFamily =
|
||||||
GetPresentQueueFamilyIndex(newDevice, queueFamilies, newDevice.queueFamilies.graphicsFamily);
|
GetPresentQueueFamilyIndex(newDevice, queueFamilies, newDevice.queueFamilies.graphicsFamily);
|
||||||
if (newDevice.queueFamilies.presentFamily == -1) {
|
if (newDevice.queueFamilies.presentFamily == -1) {
|
||||||
outDevice = otherDevice;
|
outBetterDevice = otherDevice;
|
||||||
MGLOG_I(" Ignored physical device: No present queue family.");
|
MGLOG_I(" Ignored physical device: No present queue family.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -273,7 +280,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
// Pick discrete GPU
|
// Pick discrete GPU
|
||||||
if (newDevice.properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU &&
|
if (newDevice.properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU &&
|
||||||
otherDevice.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.");
|
MGLOG_I(" Picked physical device: Discrete GPU.");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -281,7 +288,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
// Pick integrated GPU if no discrete GPU
|
// Pick integrated GPU if no discrete GPU
|
||||||
if (newDevice.properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU &&
|
if (newDevice.properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU &&
|
||||||
otherDevice.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: Integrated GPU and the other is not discrete.");
|
MGLOG_I(" Picked physical device: Integrated GPU and the other is not discrete.");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -289,7 +296,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
// Ignore other GPU when discrete GPU found
|
// Ignore other GPU when discrete GPU found
|
||||||
if (newDevice.properties.deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU &&
|
if (newDevice.properties.deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU &&
|
||||||
otherDevice.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.");
|
MGLOG_I(" Ignored physical device: Already picked discrete GPU.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -297,6 +304,33 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
return false;
|
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() {
|
void VulkanRenderer::CreateLogicalDeviceAndQueues() {
|
||||||
Float queuePriority = 1.0f;
|
Float queuePriority = 1.0f;
|
||||||
|
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
VkResult DestroyDebugMessenger();
|
VkResult DestroyDebugMessenger();
|
||||||
VkDebugUtilsMessengerCreateInfoEXT PopulateDebugMessengerCreateInfo();
|
VkDebugUtilsMessengerCreateInfoEXT PopulateDebugMessengerCreateInfo();
|
||||||
void PickPhysicalDevice();
|
void PickPhysicalDevice();
|
||||||
Bool CheckPhysicalDeviceEligibilityAndCompare(VkPhysicalDevice device, const PhysicalDevice& compareWithDevice, PhysicalDevice& outDevice);
|
Bool GetMoreCapablePhysicalDevice(VkPhysicalDevice newVkDevice, const PhysicalDevice& compareWithDevice, PhysicalDevice& outBetterDevice);
|
||||||
void CreateLogicalDeviceAndQueues();
|
void CreateLogicalDeviceAndQueues();
|
||||||
void CreateSurface();
|
void CreateSurface();
|
||||||
|
|
||||||
@@ -89,9 +89,13 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
|||||||
static Vector<VkQueueFamilyProperties> GetQueueFamilyFromPhysicalDevice(VkPhysicalDevice device);
|
static Vector<VkQueueFamilyProperties> GetQueueFamilyFromPhysicalDevice(VkPhysicalDevice device);
|
||||||
static Int GetQueueFamilyIndex(const Vector<VkQueueFamilyProperties>& queueFamilies, VkQueueFlagBits flag);
|
static Int GetQueueFamilyIndex(const Vector<VkQueueFamilyProperties>& queueFamilies, VkQueueFlagBits flag);
|
||||||
static Vector<VkExtensionProperties> EnumerateInstanceExtensions();
|
static Vector<VkExtensionProperties> EnumerateInstanceExtensions();
|
||||||
|
static Bool IsNecessaryDeviceExtensionSupported(VkPhysicalDevice device);
|
||||||
static constexpr const char* s_validationLayerNames[] = {
|
static constexpr const char* s_validationLayerNames[] = {
|
||||||
"VK_LAYER_KHRONOS_validation"
|
"VK_LAYER_KHRONOS_validation"
|
||||||
};
|
};
|
||||||
|
static constexpr const char* s_deviceExtensionNames[] = {
|
||||||
|
VK_KHR_SWAPCHAIN_EXTENSION_NAME
|
||||||
|
};
|
||||||
static Bool CheckValidationLayerSupport();
|
static Bool CheckValidationLayerSupport();
|
||||||
|
|
||||||
static VKAPI_ATTR VkBool32 VKAPI_CALL DebugCallback(
|
static VKAPI_ATTR VkBool32 VKAPI_CALL DebugCallback(
|
||||||
|
|||||||
Reference in New Issue
Block a user