mirror of
https://github.com/glfw/glfw.git
synced 2026-09-22 08:50:15 +00:00
Add basic Vulkan support
Added GLFW_INCLUDE_VULKAN. Added glfwVulkanSupported, glfwGetRequiredInstanceExtensions, glfwGetInstanceProcAddress, glfwGetPhysicalDevicePresentationSupport and glfwCreateWindowSurface. Added port of LunarG SDK tri example.
This commit is contained in:
+185
@@ -0,0 +1,185 @@
|
||||
/*!
|
||||
|
||||
@page vulkan Vulkan guide
|
||||
|
||||
@tableofcontents
|
||||
|
||||
This guide is intended to fill the gaps between the Vulkan documentation and the
|
||||
rest of the GLFW documentation and is not a replacement for either.
|
||||
|
||||
To develop for Vulkan you should install an SDK for your platform, for example
|
||||
the [LunarG Vulkan SDK](http://lunarg.com/vulkan-sdk/). Apart from the headers
|
||||
and libraries, it also provides the validation layers necessary for development.
|
||||
|
||||
GLFW itself does not need a Vulkan SDK to enable support for Vulkan. However,
|
||||
any Vulkan-specific test and example programs are built only if the CMake files
|
||||
find the LunarG SDK.
|
||||
|
||||
|
||||
@section vulkan_include Including the Vulkan and GLFW header files
|
||||
|
||||
To include the Vulkan header, define `GLFW_INCLUDE_VULKAN` before including the
|
||||
GLFW header.
|
||||
|
||||
@code
|
||||
#define GLFW_INCLUDE_VULKAN
|
||||
#include <GLFW/glfw3.h>
|
||||
@endcode
|
||||
|
||||
If you want to include the Vulkan header from a custom location or use your own
|
||||
custom Vulkan header then you need to include them before the GLFW header.
|
||||
|
||||
@code
|
||||
#include <custom/path/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 use 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.
|
||||
|
||||
|
||||
@section vulkan_support Querying for Vulkan support
|
||||
|
||||
If you are loading the Vulkan loader dynamically instead of linking directly
|
||||
against it, you can check for the availability of a loader with @ref
|
||||
glfwVulkanSupported.
|
||||
|
||||
@code
|
||||
if (glfwVulkanSupported())
|
||||
{
|
||||
// Vulkan is available, at least for compute
|
||||
}
|
||||
@endcode
|
||||
|
||||
This function returns `GLFW_TRUE` if the Vulkan loader was found. This check is
|
||||
performed by @ref glfwInit.
|
||||
|
||||
If no loader was 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.
|
||||
|
||||
@code
|
||||
PFN_vkCreateDevice pfnCreateDevice = (PFN_vkCreateDevice)
|
||||
glfwGetInstanceProcAddress(instance, "vkCreateDevice");
|
||||
@endcode
|
||||
|
||||
This is equivalent to calling `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
|
||||
int 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 Vulkan window surface creation will not be
|
||||
possible. You may 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 Vulkan queue family of every 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 also 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 in addition to Vulkan, there is no
|
||||
need to create a context for that window. You can disable context creation by
|
||||
setting the [GLFW_CLIENT_API](@ref window_hints_ctx) hint to `GLFW_NO_API`.
|
||||
|
||||
@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.
|
||||
|
||||
*/
|
||||
Reference in New Issue
Block a user