You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
		
		
		
		
		
			
		
			
				
					
					
						
							236 lines
						
					
					
						
							8.4 KiB
						
					
					
				
			
		
		
	
	
							236 lines
						
					
					
						
							8.4 KiB
						
					
					
				| /*! | |
| 
 | |
| @page vulkan_guide Vulkan guide | |
|   | |
| @tableofcontents | |
| 
 | |
| This guide is intended to fill the gaps between the [Vulkan | |
| documentation](https://www.khronos.org/vulkan/) and the rest of the GLFW | |
| documentation and is not a replacement for either.  It assumes some familiarity | |
| with Vulkan concepts like loaders, devices, queues and surfaces and leaves it to | |
| the Vulkan documentation to explain the details of Vulkan functions. | |
| 
 | |
| To develop for Vulkan you should install an SDK for your platform, for example | |
| the [LunarG Vulkan SDK](https://vulkan.lunarg.com/) for Windows and Linux or | |
| [MoltenVK](https://moltengl.com/moltenvk/) for macOS.  Apart from headers and | |
| link libraries, they should also provide the validation layers necessary for | |
| development. | |
| 
 | |
| The GLFW library does not need the Vulkan SDK to enable support for Vulkan. | |
| However, any Vulkan-specific test and example programs are built only if the | |
| CMake files find a Vulkan SDK. | |
| 
 | |
| @macos Because MoltenVK is typically not installed system-wide, you will need to | |
| point CMake to it using the `CMAKE_FRAMEWORK_PATH` variable when configuring the | |
| GLFW source tree.  Set this variable to the `MoltenVK/macOS` subdirectory of the | |
| SDK, either on the command-line or in the CMake GUI. | |
| 
 | |
| For details on a specific function in this category, see the @ref vulkan.  There | |
| are also guides for the other areas of the GLFW API. | |
| 
 | |
|  - @ref intro_guide | |
|  - @ref window_guide | |
|  - @ref context_guide | |
|  - @ref monitor_guide | |
|  - @ref input_guide | |
| 
 | |
| 
 | |
| @section vulkan_loader Linking against the Vulkan loader | |
| 
 | |
| By default, GLFW will look for the Vulkan loader on demand at runtime via its | |
| standard name (`vulkan-1.dll` on Windows, `libvulkan.so.1` on Linux and other | |
| Unix-like systems and `libMoltenVK.dylib` on macOS).  This means that GLFW does | |
| not need to be linked against the loader.  However, it also means that if you | |
| are using the static library form of the Vulkan loader GLFW will either fail to | |
| find it or (worse) use the wrong one. | |
| 
 | |
| The @ref GLFW_VULKAN_STATIC CMake option makes GLFW link directly against the | |
| static library form.  Not linking against the Vulkan loader will then be | |
| a compile-time error. | |
| 
 | |
| @macos When using the static library form of MoltenVK (i.e. `MetalVK.framework` | |
| and not `libMoltenVK.dylib`) you must also link against its dependencies: the | |
| `Cocoa`, `Metal` and `QuartzCore` system frameworks and the `libc++` library. | |
| 
 | |
| 
 | |
| @section vulkan_include Including the Vulkan and GLFW header files | |
| 
 | |
| To include the Vulkan header, define @ref GLFW_INCLUDE_VULKAN before including | |
| the GLFW header. | |
| 
 | |
| @code | |
| #define GLFW_INCLUDE_VULKAN | |
| #include <GLFW/glfw3.h> | |
| @endcode | |
| 
 | |
| If you instead want to include the Vulkan header from a custom location or use | |
| your own custom Vulkan header then do this before the GLFW header. | |
| 
 | |
| @code | |
| #include <path/to/vulkan.h> | |
| #include <GLFW/glfw3.h> | |
| @endcode | |
| 
 | |
| Unless a Vulkan header is included, either by the GLFW header or above it, any | |
| GLFW functions that take or return Vulkan types will not be declared. | |
| 
 | |
| The `VK_USE_PLATFORM_*_KHR` macros do not need to be defined for the Vulkan part | |
| of GLFW to work.  Define them only if you are using these extensions directly. | |
| 
 | |
| 
 | |
| @section vulkan_support Querying for Vulkan support | |
| 
 | |
| If you are linking directly against the Vulkan loader then you can skip this | |
| section.  The canonical desktop loader library exports all Vulkan core and | |
| Khronos extension functions, allowing them to be called directly. | |
| 
 | |
| If you are loading the Vulkan loader dynamically instead of linking directly | |
| against it, you can check for the availability of a loader and ICD with @ref | |
| glfwVulkanSupported. | |
| 
 | |
| @code | |
| if (glfwVulkanSupported()) | |
| { | |
|     // Vulkan is available, at least for compute | |
| } | |
| @endcode | |
| 
 | |
| This function returns `GLFW_TRUE` if the Vulkan loader and any minimally | |
| functional ICD was found. | |
| 
 | |
| If if one or both were not found, calling any other Vulkan related GLFW function | |
| will generate a @ref GLFW_API_UNAVAILABLE error. | |
| 
 | |
| 
 | |
| @subsection vulkan_proc Querying Vulkan function pointers | |
| 
 | |
| To load any Vulkan core or extension function from the found loader, call @ref | |
| glfwGetInstanceProcAddress.  To load functions needed for instance creation, | |
| pass `NULL` as the instance. | |
| 
 | |
| @code | |
| PFN_vkCreateInstance pfnCreateInstance = (PFN_vkCreateInstance) | |
|     glfwGetInstanceProcAddress(NULL, "vkCreateInstance"); | |
| @endcode | |
| 
 | |
| Once you have created an instance, you can load from it all other Vulkan core | |
| functions and functions from any instance extensions you enabled. | |
| 
 | |
| @code | |
| PFN_vkCreateDevice pfnCreateDevice = (PFN_vkCreateDevice) | |
|     glfwGetInstanceProcAddress(instance, "vkCreateDevice"); | |
| @endcode | |
| 
 | |
| This function in turn calls `vkGetInstanceProcAddr`.  If that fails, the | |
| function falls back to a platform-specific query of the Vulkan loader (i.e. | |
| `dlsym` or `GetProcAddress`).  If that also fails, the function returns `NULL`. | |
| For more information about `vkGetInstanceProcAddr`, see the Vulkan | |
| documentation. | |
| 
 | |
| Vulkan also provides `vkGetDeviceProcAddr` for loading device-specific versions | |
| of Vulkan function.  This function can be retrieved from an instance with @ref | |
| glfwGetInstanceProcAddress. | |
| 
 | |
| @code | |
| PFN_vkGetDeviceProcAddr pfnGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr) | |
|     glfwGetInstanceProcAddress(instance, "vkGetDeviceProcAddr"); | |
| @endcode | |
| 
 | |
| Device-specific functions may execute a little bit faster, due to not having to | |
| dispatch internally based on the device passed to them.  For more information | |
| about `vkGetDeviceProcAddr`, see the Vulkan documentation. | |
| 
 | |
| 
 | |
| @section vulkan_ext Querying required Vulkan extensions | |
| 
 | |
| To do anything useful with Vulkan you need to create an instance.  If you want | |
| to use Vulkan to render to a window, you must enable the instance extensions | |
| GLFW requires to create Vulkan surfaces. | |
| 
 | |
| To query the instance extensions required, call @ref | |
| glfwGetRequiredInstanceExtensions. | |
| 
 | |
| @code | |
| uint32_t count; | |
| const char** extensions = glfwGetRequiredInstanceExtensions(&count); | |
| @endcode | |
| 
 | |
| These extensions must all be enabled when creating instances that are going to | |
| be passed to @ref glfwGetPhysicalDevicePresentationSupport and @ref | |
| glfwCreateWindowSurface.  The set of extensions will vary depending on platform | |
| and may also vary depending on graphics drivers and other factors. | |
| 
 | |
| If it fails it will return `NULL` and GLFW will not be able to create Vulkan | |
| window surfaces.  You can still use Vulkan for off-screen rendering and compute | |
| work. | |
| 
 | |
| The returned array will always contain `VK_KHR_surface`, so if you don't | |
| require any additional extensions you can pass this list directly to the | |
| `VkInstanceCreateInfo` struct. | |
| 
 | |
| @code | |
| VkInstanceCreateInfo ici; | |
| 
 | |
| memset(&ici, 0, sizeof(ici)); | |
| ici.enabledExtensionCount = count; | |
| ici.ppEnabledExtensionNames = extensions; | |
| ... | |
| @endcode | |
| 
 | |
| Additional extensions may be required by future versions of GLFW.  You should | |
| check whether any extensions you wish to enable are already in the returned | |
| array, as it is an error to specify an extension more than once in the | |
| `VkInstanceCreateInfo` struct.  | |
| 
 | |
| 
 | |
| @section vulkan_present Querying for Vulkan presentation support | |
| 
 | |
| Not every queue family of every Vulkan device can present images to surfaces. | |
| To check whether a specific queue family of a physical device supports image | |
| presentation without first having to create a window and surface, call @ref | |
| glfwGetPhysicalDevicePresentationSupport. | |
| 
 | |
| @code | |
| if (glfwGetPhysicalDevicePresentationSupport(instance, physical_device, queue_family_index)) | |
| { | |
|     // Queue family supports image presentation | |
| } | |
| @endcode | |
| 
 | |
| The `VK_KHR_surface` extension additionally provides the  | |
| `vkGetPhysicalDeviceSurfaceSupportKHR` function, which performs the same test on | |
| an existing Vulkan surface. | |
| 
 | |
| 
 | |
| @section vulkan_window Creating the window | |
| 
 | |
| Unless you will be using OpenGL or OpenGL ES with the same window as Vulkan, | |
| there is no need to create a context.  You can disable context creation with the | |
| [GLFW_CLIENT_API](@ref GLFW_CLIENT_API_hint) hint. | |
| 
 | |
| @code | |
| glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); | |
| GLFWwindow* window = glfwCreateWindow(640, 480, "Window Title", NULL, NULL); | |
| @endcode | |
| 
 | |
| See @ref context_less for more information. | |
| 
 | |
| 
 | |
| @section vulkan_surface Creating a Vulkan window surface | |
| 
 | |
| You can create a Vulkan surface (as defined by the `VK_KHR_surface` extension) | |
| for a GLFW window with @ref glfwCreateWindowSurface. | |
| 
 | |
| @code | |
| VkSurfaceKHR surface; | |
| VkResult err = glfwCreateWindowSurface(instance, window, NULL, &surface); | |
| if (err) | |
| { | |
|     // Window surface creation failed | |
| } | |
| @endcode | |
| 
 | |
| 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. | |
| 
 | |
| */
 | |
| 
 |