From 8a8eefa0d8b9a256df1b4540a8a7c158a75eca07 Mon Sep 17 00:00:00 2001 From: Corentin Wallez Date: Tue, 30 Jan 2018 13:25:17 -0500 Subject: [PATCH] Fail Vulkan surface creation if window has context OpenGL / OpenGL ES cannot share presentation on a window with Vulkan. This adds an error to `glfwCreateWindowSurface` when it is called on a window without the GLFW_CLIENT_API hint set to GLFW_NO_API. This prevents undefined bahevior and hard to debug crashes. Fixes #1194. Closes #1205. --- README.md | 3 +++ docs/vulkan.dox | 4 ++++ include/GLFW/glfw3.h | 7 ++++++- src/vulkan.c | 7 +++++++ 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8568686a..6ad0b9ef 100644 --- a/README.md +++ b/README.md @@ -178,6 +178,8 @@ information on what to include when reporting a bug. - Added `GLFW_OSMESA_CONTEXT_API` for creating OpenGL contexts with [OSMesa](https://www.mesa3d.org/osmesa.html) (#281) - Added `GenerateMappings.cmake` script for updating gamepad mappings +- Made `glfwCreateWindowSurface` emit an error when the window has a context + (#1194,#1205) - Deprecated window parameter of clipboard string functions - Deprecated charmods callback - Removed `GLFW_USE_RETINA` compile-time option @@ -442,6 +444,7 @@ skills. - Ricardo Vieira - Nicholas Vitovitch - Simon Voordouw + - Corentin Wallez - Torsten Walluhn - Patrick Walton - Xo Wang diff --git a/docs/vulkan.dox b/docs/vulkan.dox index 8c198bef..e57e6dff 100644 --- a/docs/vulkan.dox +++ b/docs/vulkan.dox @@ -230,6 +230,10 @@ if (err) } @endcode +If an OpenGL or OpenGL ES context was created on the window, the context has +ownership of the presentation on the window and a Vulkan surface cannot be +created. + It is your responsibility to destroy the surface. GLFW does not destroy it for you. Call `vkDestroySurfaceKHR` function from the same extension to destroy it. diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index dbb1429e..9cfde197 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -5441,6 +5441,11 @@ GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhys * glfwGetRequiredInstanceExtensions to check what instance extensions are * required. * + * The window surface cannot be shared with another API so the window must + * have been created with the [client api hint](@ref GLFW_CLIENT_API_attrib) + * set to `GLFW_NO_API` otherwise it generates a @ref GLFW_INVALID_VALUE error + * and returns `VK_ERROR_NATIVE_WINDOW_IN_USE_KHR`. + * * The window surface must be destroyed before the specified Vulkan instance. * It is the responsibility of the caller to destroy the window surface. GLFW * does not destroy it for you. Call `vkDestroySurfaceKHR` to destroy the @@ -5456,7 +5461,7 @@ GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhys * [error](@ref error_handling) occurred. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR. + * GLFW_API_UNAVAILABLE, @ref GLFW_PLATFORM_ERROR and @ref GLFW_INVALID_VALUE * * @remark If an error occurs before the creation call is made, GLFW returns * the Vulkan error code most appropriate for the error. Appropriate use of diff --git a/src/vulkan.c b/src/vulkan.c index 1fd15fad..ab45c9b3 100644 --- a/src/vulkan.c +++ b/src/vulkan.c @@ -317,6 +317,13 @@ GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, return VK_ERROR_EXTENSION_NOT_PRESENT; } + if (window->context.client != GLFW_NO_API) + { + _glfwInputError(GLFW_INVALID_VALUE, + "Vulkan: Window surface creation requires the window to have the client API set to GLFW_NO_API"); + return VK_ERROR_NATIVE_WINDOW_IN_USE_KHR; + } + return _glfwPlatformCreateWindowSurface(instance, window, allocator, surface); }