mirror of
https://github.com/glfw/glfw.git
synced 2024-11-14 14:33:52 +00:00
ab3bfb4205
GLFW now checks for the libvulkan.1.dylib loader instead of what is now the ICD. This removes checking for libMoltenVK.dylib to avoid cryptic errors. This unfortunately also breaks compatibility with the standalone MoltenVK SDK. This also removes support for the static loader library as that is not present in the LunarG SDK. Related to #870.
239 lines
8.2 KiB
Plaintext
239 lines
8.2 KiB
Plaintext
/*!
|
|
|
|
@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 download the [LunarG Vulkan
|
|
SDK](https://vulkan.lunarg.com/) for your platform. Apart from headers and link
|
|
libraries, they 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.
|
|
|
|
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 `libvulkan.1.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 Because the Vulkan loader and ICD are not installed globally on macOS,
|
|
you need to set up the application bundle according to the LunarG SDK
|
|
documentation. To help the GLFW CMake files find the SDK, you can set the
|
|
`VULKAN_SDK` environment variable.
|
|
|
|
@code{.sh}
|
|
env VULKAN_SDK=/example/path/to/vulkansdk-macos cmake .
|
|
@endcode
|
|
|
|
|
|
@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.
|
|
|
|
If successful the returned array will always include `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
|
|
|
|
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.
|
|
|
|
*/
|