1/*! 2 3@page vulkan_guide Vulkan guide 4 5@tableofcontents 6 7This guide is intended to fill the gaps between the [Vulkan 8documentation](https://www.khronos.org/vulkan/) and the rest of the GLFW 9documentation and is not a replacement for either. It assumes some familiarity 10with Vulkan concepts like loaders, devices, queues and surfaces and leaves it to 11the Vulkan documentation to explain the details of Vulkan functions. 12 13To develop for Vulkan you should install an SDK for your platform, for example 14the [LunarG Vulkan SDK](https://vulkan.lunarg.com/). Apart from the headers and 15libraries, it also provides the validation layers necessary for development. 16 17The GLFW library does not need the Vulkan SDK to enable support for Vulkan. 18However, any Vulkan-specific test and example programs are built only if the 19CMake files find a Vulkan SDK. 20 21For details on a specific function in this category, see the @ref vulkan. There 22are also guides for the other areas of the GLFW API. 23 24 - @ref intro_guide 25 - @ref window_guide 26 - @ref context_guide 27 - @ref monitor_guide 28 - @ref input_guide 29 30 31@section vulkan_include Including the Vulkan and GLFW header files 32 33To include the Vulkan header, define [GLFW_INCLUDE_VULKAN](@ref build_macros) 34before including the GLFW header. 35 36@code 37#define GLFW_INCLUDE_VULKAN 38#include <GLFW/glfw3.h> 39@endcode 40 41If you instead want to include the Vulkan header from a custom location or use 42your own custom Vulkan header then do this before the GLFW header. 43 44@code 45#include <path/to/vulkan.h> 46#include <GLFW/glfw3.h> 47@endcode 48 49Unless a Vulkan header is included, either by the GLFW header or above it, any 50GLFW functions that take or return Vulkan types will not be declared. 51 52The `VK_USE_PLATFORM_*_KHR` macros do not need to be defined for the Vulkan part 53of GLFW to work. Define them only if you are using these extensions directly. 54 55 56@section vulkan_support Querying for Vulkan support 57 58If you are linking directly against the Vulkan loader then you can skip this 59section. The canonical desktop loader library exports all Vulkan core and 60Khronos extension functions, allowing them to be called directly. 61 62If you are loading the Vulkan loader dynamically instead of linking directly 63against it, you can check for the availability of a loader with @ref 64glfwVulkanSupported. 65 66@code 67if (glfwVulkanSupported()) 68{ 69 // Vulkan is available, at least for compute 70} 71@endcode 72 73This function returns `GLFW_TRUE` if the Vulkan loader was found. This check is 74performed by @ref glfwInit. 75 76If no loader was found, calling any other Vulkan related GLFW function will 77generate a @ref GLFW_API_UNAVAILABLE error. 78 79 80@subsection vulkan_proc Querying Vulkan function pointers 81 82To load any Vulkan core or extension function from the found loader, call @ref 83glfwGetInstanceProcAddress. To load functions needed for instance creation, 84pass `NULL` as the instance. 85 86@code 87PFN_vkCreateInstance pfnCreateInstance = (PFN_vkCreateInstance) 88 glfwGetInstanceProcAddress(NULL, "vkCreateInstance"); 89@endcode 90 91Once you have created an instance, you can load from it all other Vulkan core 92functions and functions from any instance extensions you enabled. 93 94@code 95PFN_vkCreateDevice pfnCreateDevice = (PFN_vkCreateDevice) 96 glfwGetInstanceProcAddress(instance, "vkCreateDevice"); 97@endcode 98 99This function in turn calls `vkGetInstanceProcAddr`. If that fails, the 100function falls back to a platform-specific query of the Vulkan loader (i.e. 101`dlsym` or `GetProcAddress`). If that also fails, the function returns `NULL`. 102For more information about `vkGetInstanceProcAddr`, see the Vulkan 103documentation. 104 105Vulkan also provides `vkGetDeviceProcAddr` for loading device-specific versions 106of Vulkan function. This function can be retrieved from an instance with @ref 107glfwGetInstanceProcAddress. 108 109@code 110PFN_vkGetDeviceProcAddr pfnGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr) 111 glfwGetInstanceProcAddress(instance, "vkGetDeviceProcAddr"); 112@endcode 113 114Device-specific functions may execute a little bit faster, due to not having to 115dispatch internally based on the device passed to them. For more information 116about `vkGetDeviceProcAddr`, see the Vulkan documentation. 117 118 119@section vulkan_ext Querying required Vulkan extensions 120 121To do anything useful with Vulkan you need to create an instance. If you want 122to use Vulkan to render to a window, you must enable the instance extensions 123GLFW requires to create Vulkan surfaces. 124 125To query the instance extensions required, call @ref 126glfwGetRequiredInstanceExtensions. 127 128@code 129uint32_t count; 130const char** extensions = glfwGetRequiredInstanceExtensions(&count); 131@endcode 132 133These extensions must all be enabled when creating instances that are going to 134be passed to @ref glfwGetPhysicalDevicePresentationSupport and @ref 135glfwCreateWindowSurface. The set of extensions will vary depending on platform 136and may also vary depending on graphics drivers and other factors. 137 138If it fails it will return `NULL` and GLFW will not be able to create Vulkan 139window surfaces. You can still use Vulkan for off-screen rendering and compute 140work. 141 142The returned array will always contain `VK_KHR_surface`, so if you don't 143require any additional extensions you can pass this list directly to the 144`VkInstanceCreateInfo` struct. 145 146@code 147VkInstanceCreateInfo ici; 148 149memset(&ici, 0, sizeof(ici)); 150ici.enabledExtensionCount = count; 151ici.ppEnabledExtensionNames = extensions; 152... 153@endcode 154 155Additional extensions may be required by future versions of GLFW. You should 156check whether any extensions you wish to enable are already in the returned 157array, as it is an error to specify an extension more than once in the 158`VkInstanceCreateInfo` struct. 159 160 161@section vulkan_present Querying for Vulkan presentation support 162 163Not every queue family of every Vulkan device can present images to surfaces. 164To check whether a specific queue family of a physical device supports image 165presentation without first having to create a window and surface, call @ref 166glfwGetPhysicalDevicePresentationSupport. 167 168@code 169if (glfwGetPhysicalDevicePresentationSupport(instance, physical_device, queue_family_index)) 170{ 171 // Queue family supports image presentation 172} 173@endcode 174 175The `VK_KHR_surface` extension additionally provides the 176`vkGetPhysicalDeviceSurfaceSupportKHR` function, which performs the same test on 177an existing Vulkan surface. 178 179 180@section vulkan_window Creating the window 181 182Unless you will be using OpenGL or OpenGL ES with the same window as Vulkan, 183there is no need to create a context. You can disable context creation with the 184[GLFW_CLIENT_API](@ref window_hints_ctx) hint. 185 186@code 187glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); 188GLFWwindow* window = glfwCreateWindow(640, 480, "Window Title", NULL, NULL); 189@endcode 190 191See @ref context_less for more information. 192 193 194@section vulkan_surface Creating a Vulkan window surface 195 196You can create a Vulkan surface (as defined by the `VK_KHR_surface` extension) 197for a GLFW window with @ref glfwCreateWindowSurface. 198 199@code 200VkSurfaceKHR surface; 201VkResult err = glfwCreateWindowSurface(instance, window, NULL, &surface); 202if (err) 203{ 204 // Window surface creation failed 205} 206@endcode 207 208It is your responsibility to destroy the surface. GLFW does not destroy it for 209you. Call `vkDestroySurfaceKHR` function from the same extension to destroy it. 210 211*/ 212