From 996910b62706774792bde4934e23ef5bde37fc32 Mon Sep 17 00:00:00 2001 From: bruvzg <7645683+bruvzg@users.noreply.github.com> Date: Mon, 13 Jul 2020 19:24:04 +0300 Subject: [PATCH] Add error messages if Vulkan init failed, prevent Vulkan context freeing uninitialized device and instance. --- drivers/vulkan/vulkan_context.cpp | 27 ++++++++++++++------- drivers/vulkan/vulkan_context.h | 2 ++ main/main.cpp | 2 +- platform/android/display_server_android.cpp | 6 ++++- platform/linuxbsd/display_server_x11.cpp | 8 +++++- platform/osx/display_server_osx.mm | 7 +++++- platform/windows/display_server_windows.cpp | 8 +++++- 7 files changed, 46 insertions(+), 14 deletions(-) diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp index a8a29aaeeaf..e064a4ad6a0 100644 --- a/drivers/vulkan/vulkan_context.cpp +++ b/drivers/vulkan/vulkan_context.cpp @@ -344,6 +344,8 @@ Error VulkanContext::_create_physical_device() { "Please look at the Getting Started guide for additional information.\n" "vkCreateInstance Failure"); + inst_initialized = true; + /* Make initial call to query gpu_count, then second call for gpu info*/ err = vkEnumeratePhysicalDevices(inst, &gpu_count, nullptr); ERR_FAIL_COND_V(err, ERR_CANT_CREATE); @@ -1133,6 +1135,7 @@ Error VulkanContext::initialize() { return err; } + device_initialized = true; return OK; } @@ -1584,15 +1587,21 @@ VulkanContext::~VulkanContext() { if (queue_props) { free(queue_props); } - for (uint32_t i = 0; i < FRAME_LAG; i++) { - vkDestroyFence(device, fences[i], nullptr); - vkDestroySemaphore(device, image_acquired_semaphores[i], nullptr); - vkDestroySemaphore(device, draw_complete_semaphores[i], nullptr); - if (separate_present_queue) { - vkDestroySemaphore(device, image_ownership_semaphores[i], nullptr); + if (device_initialized) { + for (uint32_t i = 0; i < FRAME_LAG; i++) { + vkDestroyFence(device, fences[i], nullptr); + vkDestroySemaphore(device, image_acquired_semaphores[i], nullptr); + vkDestroySemaphore(device, draw_complete_semaphores[i], nullptr); + if (separate_present_queue) { + vkDestroySemaphore(device, image_ownership_semaphores[i], nullptr); + } } + if (inst_initialized) { + DestroyDebugUtilsMessengerEXT(inst, dbg_messenger, nullptr); + } + vkDestroyDevice(device, nullptr); + } + if (inst_initialized) { + vkDestroyInstance(inst, nullptr); } - DestroyDebugUtilsMessengerEXT(inst, dbg_messenger, nullptr); - vkDestroyDevice(device, nullptr); - vkDestroyInstance(inst, nullptr); } diff --git a/drivers/vulkan/vulkan_context.h b/drivers/vulkan/vulkan_context.h index 3f4cfac1233..9ebea42ecb6 100644 --- a/drivers/vulkan/vulkan_context.h +++ b/drivers/vulkan/vulkan_context.h @@ -53,6 +53,8 @@ class VulkanContext { uint32_t queue_family_count; VkQueueFamilyProperties *queue_props; VkDevice device; + bool device_initialized = false; + bool inst_initialized = false; //present bool queues_initialized; diff --git a/main/main.cpp b/main/main.cpp index 4fbbc21f410..bb4751c61dd 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1298,7 +1298,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) { } } - if (!display_server) { + if (!display_server || err != OK) { ERR_PRINT("Unable to create DisplayServer, all display drivers failed."); return err; } diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp index 1436d832dec..1fb0d7ef603 100644 --- a/platform/android/display_server_android.cpp +++ b/platform/android/display_server_android.cpp @@ -360,7 +360,11 @@ Vector DisplayServerAndroid::get_rendering_drivers_func() { } DisplayServer *DisplayServerAndroid::create_func(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) { - return memnew(DisplayServerAndroid(p_rendering_driver, p_mode, p_flags, p_resolution, r_error)); + DisplayServer *ds = memnew(DisplayServerAndroid(p_rendering_driver, p_mode, p_flags, p_resolution, r_error)); + if (r_error != OK) { + ds->alert("Your video card driver does not support any of the supported Vulkan versions.", "Unable to initialize Video driver"); + } + return ds; } void DisplayServerAndroid::register_android_driver() { diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp index c9b951f4d96..21b3bcec309 100644 --- a/platform/linuxbsd/display_server_x11.cpp +++ b/platform/linuxbsd/display_server_x11.cpp @@ -3185,7 +3185,13 @@ Vector DisplayServerX11::get_rendering_drivers_func() { } DisplayServer *DisplayServerX11::create_func(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) { - return memnew(DisplayServerX11(p_rendering_driver, p_mode, p_flags, p_resolution, r_error)); + DisplayServer *ds = memnew(DisplayServerX11(p_rendering_driver, p_mode, p_flags, p_resolution, r_error)); + if (r_error != OK) { + ds->alert("Your video card driver does not support any of the supported Vulkan versions.\n" + "Please update your drivers or if you have a very old or integrated GPU upgrade it.", + "Unable to initialize Video driver"); + } + return ds; } DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect) { diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm index 07ecd5d2c6a..4793591b541 100644 --- a/platform/osx/display_server_osx.mm +++ b/platform/osx/display_server_osx.mm @@ -3456,7 +3456,11 @@ ObjectID DisplayServerOSX::window_get_attached_instance_id(WindowID p_window) co } DisplayServer *DisplayServerOSX::create_func(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) { - return memnew(DisplayServerOSX(p_rendering_driver, p_mode, p_flags, p_resolution, r_error)); + DisplayServer *ds = memnew(DisplayServerOSX(p_rendering_driver, p_mode, p_flags, p_resolution, r_error)); + if (r_error != OK) { + ds->alert("Your video card driver does not support any of the supported Metal versions.", "Unable to initialize Video driver"); + } + return ds; } DisplayServerOSX::WindowID DisplayServerOSX::_create_window(WindowMode p_mode, const Rect2i &p_rect) { @@ -3745,6 +3749,7 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode screen_get_position(0).x + (screen_get_size(0).width - p_resolution.width) / 2, screen_get_position(0).y + (screen_get_size(0).height - p_resolution.height) / 2); WindowID main_window = _create_window(p_mode, Rect2i(window_position, p_resolution)); + ERR_FAIL_COND(main_window == INVALID_WINDOW_ID); for (int i = 0; i < WINDOW_FLAG_MAX; i++) { if (p_flags & (1 << i)) { window_set_flag(WindowFlags(i), true, main_window); diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index 103e858d97a..3eba0934b1b 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -3178,7 +3178,13 @@ Vector DisplayServerWindows::get_rendering_drivers_func() { } DisplayServer *DisplayServerWindows::create_func(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) { - return memnew(DisplayServerWindows(p_rendering_driver, p_mode, p_flags, p_resolution, r_error)); + DisplayServer *ds = memnew(DisplayServerWindows(p_rendering_driver, p_mode, p_flags, p_resolution, r_error)); + if (r_error != OK) { + ds->alert("Your video card driver does not support any of the supported Vulkan versions.\n" + "Please update your drivers or if you have a very old or integrated GPU upgrade it.", + "Unable to initialize Video driver"); + } + return ds; } void DisplayServerWindows::register_windows_driver() {