mirror of
https://github.com/godotengine/godot.git
synced 2026-01-03 18:11:19 +03:00
Implementing OpenXR driver
This commit is contained in:
committed by
Rémi Verschelde
parent
65bae5a341
commit
a78a9fee71
@@ -46,6 +46,8 @@
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
|
||||
#define APP_SHORT_NAME "GodotEngine"
|
||||
|
||||
VulkanHooks *VulkanContext::vulkan_hooks = nullptr;
|
||||
|
||||
VKAPI_ATTR VkBool32 VKAPI_CALL VulkanContext::_debug_messenger_callback(
|
||||
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
|
||||
VkDebugUtilsMessageTypeFlagsEXT messageType,
|
||||
@@ -695,19 +697,27 @@ Error VulkanContext::_create_instance() {
|
||||
inst_info.pNext = &dbg_report_callback_create_info;
|
||||
}
|
||||
|
||||
VkResult err = vkCreateInstance(&inst_info, nullptr, &inst);
|
||||
ERR_FAIL_COND_V_MSG(err == VK_ERROR_INCOMPATIBLE_DRIVER, ERR_CANT_CREATE,
|
||||
"Cannot find a compatible Vulkan installable client driver (ICD).\n\n"
|
||||
"vkCreateInstance Failure");
|
||||
ERR_FAIL_COND_V_MSG(err == VK_ERROR_EXTENSION_NOT_PRESENT, ERR_CANT_CREATE,
|
||||
"Cannot find a specified extension library.\n"
|
||||
"Make sure your layers path is set appropriately.\n"
|
||||
"vkCreateInstance Failure");
|
||||
ERR_FAIL_COND_V_MSG(err, ERR_CANT_CREATE,
|
||||
"vkCreateInstance failed.\n\n"
|
||||
"Do you have a compatible Vulkan installable client driver (ICD) installed?\n"
|
||||
"Please look at the Getting Started guide for additional information.\n"
|
||||
"vkCreateInstance Failure");
|
||||
VkResult err;
|
||||
|
||||
if (vulkan_hooks) {
|
||||
if (!vulkan_hooks->create_vulkan_instance(&inst_info, &inst)) {
|
||||
return ERR_CANT_CREATE;
|
||||
}
|
||||
} else {
|
||||
err = vkCreateInstance(&inst_info, nullptr, &inst);
|
||||
ERR_FAIL_COND_V_MSG(err == VK_ERROR_INCOMPATIBLE_DRIVER, ERR_CANT_CREATE,
|
||||
"Cannot find a compatible Vulkan installable client driver (ICD).\n\n"
|
||||
"vkCreateInstance Failure");
|
||||
ERR_FAIL_COND_V_MSG(err == VK_ERROR_EXTENSION_NOT_PRESENT, ERR_CANT_CREATE,
|
||||
"Cannot find a specified extension library.\n"
|
||||
"Make sure your layers path is set appropriately.\n"
|
||||
"vkCreateInstance Failure");
|
||||
ERR_FAIL_COND_V_MSG(err, ERR_CANT_CREATE,
|
||||
"vkCreateInstance failed.\n\n"
|
||||
"Do you have a compatible Vulkan installable client driver (ICD) installed?\n"
|
||||
"Please look at the Getting Started guide for additional information.\n"
|
||||
"vkCreateInstance Failure");
|
||||
}
|
||||
|
||||
inst_initialized = true;
|
||||
|
||||
@@ -820,107 +830,122 @@ Error VulkanContext::_create_physical_device(VkSurfaceKHR p_surface) {
|
||||
{ 0, nullptr },
|
||||
};
|
||||
|
||||
// TODO: At least on Linux Laptops integrated GPUs fail with Vulkan in many instances.
|
||||
// The device should really be a preference, but for now choosing a discrete GPU over the
|
||||
// integrated one is better than the default.
|
||||
|
||||
int32_t device_index = -1;
|
||||
int type_selected = -1;
|
||||
print_verbose("Vulkan devices:");
|
||||
for (uint32_t i = 0; i < gpu_count; ++i) {
|
||||
VkPhysicalDeviceProperties props;
|
||||
vkGetPhysicalDeviceProperties(physical_devices[i], &props);
|
||||
|
||||
bool present_supported = false;
|
||||
|
||||
uint32_t device_queue_family_count = 0;
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(physical_devices[i], &device_queue_family_count, nullptr);
|
||||
VkQueueFamilyProperties *device_queue_props = (VkQueueFamilyProperties *)malloc(device_queue_family_count * sizeof(VkQueueFamilyProperties));
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(physical_devices[i], &device_queue_family_count, device_queue_props);
|
||||
for (uint32_t j = 0; j < device_queue_family_count; j++) {
|
||||
VkBool32 supports;
|
||||
vkGetPhysicalDeviceSurfaceSupportKHR(physical_devices[i], j, p_surface, &supports);
|
||||
if (supports && ((device_queue_props[j].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0)) {
|
||||
present_supported = true;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
if (vulkan_hooks) {
|
||||
if (!vulkan_hooks->get_physical_device(&gpu)) {
|
||||
return ERR_CANT_CREATE;
|
||||
}
|
||||
String name = props.deviceName;
|
||||
String vendor = "Unknown";
|
||||
String dev_type;
|
||||
switch (props.deviceType) {
|
||||
case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: {
|
||||
dev_type = "Discrete";
|
||||
} break;
|
||||
case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: {
|
||||
dev_type = "Integrated";
|
||||
} break;
|
||||
case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: {
|
||||
dev_type = "Virtual";
|
||||
} break;
|
||||
case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_CPU: {
|
||||
dev_type = "CPU";
|
||||
} break;
|
||||
default: {
|
||||
dev_type = "Other";
|
||||
} break;
|
||||
}
|
||||
uint32_t vendor_idx = 0;
|
||||
while (vendor_names[vendor_idx].name != nullptr) {
|
||||
if (props.vendorID == vendor_names[vendor_idx].id) {
|
||||
vendor = vendor_names[vendor_idx].name;
|
||||
|
||||
// not really needed but nice to print the correct entry
|
||||
for (uint32_t i = 0; i < gpu_count; ++i) {
|
||||
if (physical_devices[i] == gpu) {
|
||||
device_index = i;
|
||||
break;
|
||||
}
|
||||
vendor_idx++;
|
||||
}
|
||||
free(device_queue_props);
|
||||
print_verbose(" #" + itos(i) + ": " + vendor + " " + name + " - " + (present_supported ? "Supported" : "Unsupported") + ", " + dev_type);
|
||||
} else {
|
||||
// TODO: At least on Linux Laptops integrated GPUs fail with Vulkan in many instances.
|
||||
// The device should really be a preference, but for now choosing a discrete GPU over the
|
||||
// integrated one is better than the default.
|
||||
|
||||
if (present_supported) { // Select first supported device of preferred type: Discrete > Integrated > Virtual > CPU > Other.
|
||||
int type_selected = -1;
|
||||
print_verbose("Vulkan devices:");
|
||||
for (uint32_t i = 0; i < gpu_count; ++i) {
|
||||
VkPhysicalDeviceProperties props;
|
||||
vkGetPhysicalDeviceProperties(physical_devices[i], &props);
|
||||
|
||||
bool present_supported = false;
|
||||
|
||||
uint32_t device_queue_family_count = 0;
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(physical_devices[i], &device_queue_family_count, nullptr);
|
||||
VkQueueFamilyProperties *device_queue_props = (VkQueueFamilyProperties *)malloc(device_queue_family_count * sizeof(VkQueueFamilyProperties));
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(physical_devices[i], &device_queue_family_count, device_queue_props);
|
||||
for (uint32_t j = 0; j < device_queue_family_count; j++) {
|
||||
VkBool32 supports;
|
||||
vkGetPhysicalDeviceSurfaceSupportKHR(physical_devices[i], j, p_surface, &supports);
|
||||
if (supports && ((device_queue_props[j].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0)) {
|
||||
present_supported = true;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
String name = props.deviceName;
|
||||
String vendor = "Unknown";
|
||||
String dev_type;
|
||||
switch (props.deviceType) {
|
||||
case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: {
|
||||
if (type_selected < 4) {
|
||||
type_selected = 4;
|
||||
device_index = i;
|
||||
}
|
||||
dev_type = "Discrete";
|
||||
} break;
|
||||
case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: {
|
||||
if (type_selected < 3) {
|
||||
type_selected = 3;
|
||||
device_index = i;
|
||||
}
|
||||
dev_type = "Integrated";
|
||||
} break;
|
||||
case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: {
|
||||
if (type_selected < 2) {
|
||||
type_selected = 2;
|
||||
device_index = i;
|
||||
}
|
||||
dev_type = "Virtual";
|
||||
} break;
|
||||
case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_CPU: {
|
||||
if (type_selected < 1) {
|
||||
type_selected = 1;
|
||||
device_index = i;
|
||||
}
|
||||
dev_type = "CPU";
|
||||
} break;
|
||||
default: {
|
||||
if (type_selected < 0) {
|
||||
type_selected = 0;
|
||||
device_index = i;
|
||||
}
|
||||
dev_type = "Other";
|
||||
} break;
|
||||
}
|
||||
uint32_t vendor_idx = 0;
|
||||
while (vendor_names[vendor_idx].name != nullptr) {
|
||||
if (props.vendorID == vendor_names[vendor_idx].id) {
|
||||
vendor = vendor_names[vendor_idx].name;
|
||||
break;
|
||||
}
|
||||
vendor_idx++;
|
||||
}
|
||||
free(device_queue_props);
|
||||
print_verbose(" #" + itos(i) + ": " + vendor + " " + name + " - " + (present_supported ? "Supported" : "Unsupported") + ", " + dev_type);
|
||||
|
||||
if (present_supported) { // Select first supported device of preffered type: Discrete > Integrated > Virtual > CPU > Other.
|
||||
switch (props.deviceType) {
|
||||
case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: {
|
||||
if (type_selected < 4) {
|
||||
type_selected = 4;
|
||||
device_index = i;
|
||||
}
|
||||
} break;
|
||||
case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: {
|
||||
if (type_selected < 3) {
|
||||
type_selected = 3;
|
||||
device_index = i;
|
||||
}
|
||||
} break;
|
||||
case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: {
|
||||
if (type_selected < 2) {
|
||||
type_selected = 2;
|
||||
device_index = i;
|
||||
}
|
||||
} break;
|
||||
case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_CPU: {
|
||||
if (type_selected < 1) {
|
||||
type_selected = 1;
|
||||
device_index = i;
|
||||
}
|
||||
} break;
|
||||
default: {
|
||||
if (type_selected < 0) {
|
||||
type_selected = 0;
|
||||
device_index = i;
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32_t user_device_index = Engine::get_singleton()->get_gpu_index(); // Force user selected GPU.
|
||||
if (user_device_index >= 0 && user_device_index < (int32_t)gpu_count) {
|
||||
device_index = user_device_index;
|
||||
}
|
||||
|
||||
ERR_FAIL_COND_V_MSG(device_index == -1, ERR_CANT_CREATE, "None of Vulkan devices supports both graphics and present queues.");
|
||||
|
||||
gpu = physical_devices[device_index];
|
||||
}
|
||||
|
||||
int32_t user_device_index = Engine::get_singleton()->get_gpu_index(); // Force user selected GPU.
|
||||
if (user_device_index >= 0 && user_device_index < (int32_t)gpu_count) {
|
||||
device_index = user_device_index;
|
||||
}
|
||||
|
||||
ERR_FAIL_COND_V_MSG(device_index == -1, ERR_CANT_CREATE, "None of Vulkan devices supports both graphics and present queues.");
|
||||
|
||||
gpu = physical_devices[device_index];
|
||||
free(physical_devices);
|
||||
|
||||
/* Look for device extensions */
|
||||
@@ -1148,8 +1173,14 @@ Error VulkanContext::_create_device() {
|
||||
sdevice.queueCreateInfoCount = 2;
|
||||
}
|
||||
|
||||
err = vkCreateDevice(gpu, &sdevice, nullptr, &device);
|
||||
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
|
||||
if (vulkan_hooks) {
|
||||
if (!vulkan_hooks->create_vulkan_device(&sdevice, &device)) {
|
||||
return ERR_CANT_CREATE;
|
||||
}
|
||||
} else {
|
||||
err = vkCreateDevice(gpu, &sdevice, nullptr, &device);
|
||||
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user