Browse Source

Add error messages if Vulkan init failed, prevent Vulkan context freeing uninitialized device and instance.

bruvzg 5 years ago
parent
commit
996910b627

+ 18 - 9
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);
 }

+ 2 - 0
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;

+ 1 - 1
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;
 		}

+ 5 - 1
platform/android/display_server_android.cpp

@@ -360,7 +360,11 @@ Vector<String> 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() {

+ 7 - 1
platform/linuxbsd/display_server_x11.cpp

@@ -3185,7 +3185,13 @@ Vector<String> 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) {

+ 6 - 1
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);

+ 7 - 1
platform/windows/display_server_windows.cpp

@@ -3178,7 +3178,13 @@ Vector<String> 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() {