|
1
|
1 /*
|
|
|
2 Simple DirectMedia Layer
|
|
|
3 Copyright (C) 2017, Mark Callow
|
|
|
4
|
|
|
5 This software is provided 'as-is', without any express or implied
|
|
|
6 warranty. In no event will the authors be held liable for any damages
|
|
|
7 arising from the use of this software.
|
|
|
8
|
|
|
9 Permission is granted to anyone to use this software for any purpose,
|
|
|
10 including commercial applications, and to alter it and redistribute it
|
|
|
11 freely, subject to the following restrictions:
|
|
|
12
|
|
|
13 1. The origin of this software must not be misrepresented; you must not
|
|
|
14 claim that you wrote the original software. If you use this software
|
|
|
15 in a product, an acknowledgment in the product documentation would be
|
|
|
16 appreciated but is not required.
|
|
|
17 2. Altered source versions must be plainly marked as such, and must not be
|
|
|
18 misrepresented as being the original software.
|
|
|
19 3. This notice may not be removed or altered from any source distribution.
|
|
|
20 */
|
|
|
21
|
|
|
22 /**
|
|
|
23 * # CategoryVulkan
|
|
|
24 *
|
|
|
25 * Functions for creating Vulkan surfaces on SDL windows.
|
|
|
26 *
|
|
|
27 * For the most part, Vulkan operates independent of SDL, but it benefits from
|
|
|
28 * a little support during setup.
|
|
|
29 *
|
|
|
30 * Use SDL_Vulkan_GetInstanceExtensions() to get platform-specific bits for
|
|
|
31 * creating a VkInstance, then SDL_Vulkan_GetVkGetInstanceProcAddr() to get
|
|
|
32 * the appropriate function for querying Vulkan entry points. Then
|
|
|
33 * SDL_Vulkan_CreateSurface() will get you the final pieces you need to
|
|
|
34 * prepare for rendering into an SDL_Window with Vulkan.
|
|
|
35 *
|
|
|
36 * Unlike OpenGL, most of the details of "context" creation and window buffer
|
|
|
37 * swapping are handled by the Vulkan API directly, so SDL doesn't provide
|
|
|
38 * Vulkan equivalents of SDL_GL_SwapWindow(), etc; they aren't necessary.
|
|
|
39 */
|
|
|
40
|
|
|
41 #ifndef SDL_vulkan_h_
|
|
|
42 #define SDL_vulkan_h_
|
|
|
43
|
|
|
44 #include <SDL3/SDL_stdinc.h>
|
|
|
45 #include <SDL3/SDL_error.h>
|
|
|
46 #include <SDL3/SDL_video.h>
|
|
|
47
|
|
|
48 #include <SDL3/SDL_begin_code.h>
|
|
|
49 /* Set up for C function definitions, even when using C++ */
|
|
|
50 #ifdef __cplusplus
|
|
|
51 extern "C" {
|
|
|
52 #endif
|
|
|
53
|
|
|
54 /* Avoid including vulkan_core.h, don't define VkInstance if it's already included */
|
|
|
55 #ifdef VULKAN_CORE_H_
|
|
|
56 #define NO_SDL_VULKAN_TYPEDEFS
|
|
|
57 #endif
|
|
|
58 #ifndef NO_SDL_VULKAN_TYPEDEFS
|
|
|
59 #define VK_DEFINE_HANDLE(object) typedef struct object##_T* object;
|
|
|
60
|
|
|
61 #if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__)) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__) || (defined(__riscv) && __riscv_xlen == 64)
|
|
|
62 #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object;
|
|
|
63 #else
|
|
|
64 #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object;
|
|
|
65 #endif
|
|
|
66
|
|
|
67 VK_DEFINE_HANDLE(VkInstance)
|
|
|
68 VK_DEFINE_HANDLE(VkPhysicalDevice)
|
|
|
69 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR)
|
|
|
70 struct VkAllocationCallbacks;
|
|
|
71
|
|
|
72 /* Make sure to undef to avoid issues in case of later vulkan include */
|
|
|
73 #undef VK_DEFINE_HANDLE
|
|
|
74 #undef VK_DEFINE_NON_DISPATCHABLE_HANDLE
|
|
|
75
|
|
|
76 #endif /* !NO_SDL_VULKAN_TYPEDEFS */
|
|
|
77
|
|
|
78 /**
|
|
|
79 * \name Vulkan support functions
|
|
|
80 */
|
|
|
81 /* @{ */
|
|
|
82
|
|
|
83 /**
|
|
|
84 * Dynamically load the Vulkan loader library.
|
|
|
85 *
|
|
|
86 * This should be called after initializing the video driver, but before
|
|
|
87 * creating any Vulkan windows. If no Vulkan loader library is loaded, the
|
|
|
88 * default library will be loaded upon creation of the first Vulkan window.
|
|
|
89 *
|
|
|
90 * SDL keeps a counter of how many times this function has been successfully
|
|
|
91 * called, so it is safe to call this function multiple times, so long as it
|
|
|
92 * is eventually paired with an equivalent number of calls to
|
|
|
93 * SDL_Vulkan_UnloadLibrary. The `path` argument is ignored unless there is no
|
|
|
94 * library currently loaded, and and the library isn't actually unloaded until
|
|
|
95 * there have been an equivalent number of calls to SDL_Vulkan_UnloadLibrary.
|
|
|
96 *
|
|
|
97 * It is fairly common for Vulkan applications to link with libvulkan instead
|
|
|
98 * of explicitly loading it at run time. This will work with SDL provided the
|
|
|
99 * application links to a dynamic library and both it and SDL use the same
|
|
|
100 * search path.
|
|
|
101 *
|
|
|
102 * If you specify a non-NULL `path`, an application should retrieve all of the
|
|
|
103 * Vulkan functions it uses from the dynamic library using
|
|
|
104 * SDL_Vulkan_GetVkGetInstanceProcAddr unless you can guarantee `path` points
|
|
|
105 * to the same vulkan loader library the application linked to.
|
|
|
106 *
|
|
|
107 * On Apple devices, if `path` is NULL, SDL will attempt to find the
|
|
|
108 * `vkGetInstanceProcAddr` address within all the Mach-O images of the current
|
|
|
109 * process. This is because it is fairly common for Vulkan applications to
|
|
|
110 * link with libvulkan (and historically MoltenVK was provided as a static
|
|
|
111 * library). If it is not found, on macOS, SDL will attempt to load
|
|
|
112 * `vulkan.framework/vulkan`, `libvulkan.1.dylib`,
|
|
|
113 * `MoltenVK.framework/MoltenVK`, and `libMoltenVK.dylib`, in that order. On
|
|
|
114 * iOS, SDL will attempt to load `libMoltenVK.dylib`. Applications using a
|
|
|
115 * dynamic framework or .dylib must ensure it is included in its application
|
|
|
116 * bundle.
|
|
|
117 *
|
|
|
118 * On non-Apple devices, application linking with a static libvulkan is not
|
|
|
119 * supported. Either do not link to the Vulkan loader or link to a dynamic
|
|
|
120 * library version.
|
|
|
121 *
|
|
|
122 * \param path the platform dependent Vulkan loader library name or NULL.
|
|
|
123 * \returns true on success or false on failure; call SDL_GetError() for more
|
|
|
124 * information.
|
|
|
125 *
|
|
|
126 * \threadsafety This function is not thread safe.
|
|
|
127 *
|
|
|
128 * \since This function is available since SDL 3.2.0.
|
|
|
129 *
|
|
|
130 * \sa SDL_Vulkan_GetVkGetInstanceProcAddr
|
|
|
131 * \sa SDL_Vulkan_UnloadLibrary
|
|
|
132 */
|
|
|
133 extern SDL_DECLSPEC bool SDLCALL SDL_Vulkan_LoadLibrary(const char *path);
|
|
|
134
|
|
|
135 /**
|
|
|
136 * Get the address of the `vkGetInstanceProcAddr` function.
|
|
|
137 *
|
|
|
138 * This should be called after either calling SDL_Vulkan_LoadLibrary() or
|
|
|
139 * creating an SDL_Window with the `SDL_WINDOW_VULKAN` flag.
|
|
|
140 *
|
|
|
141 * The actual type of the returned function pointer is
|
|
|
142 * PFN_vkGetInstanceProcAddr, but that isn't available because the Vulkan
|
|
|
143 * headers are not included here. You should cast the return value of this
|
|
|
144 * function to that type, e.g.
|
|
|
145 *
|
|
|
146 * `vkGetInstanceProcAddr =
|
|
|
147 * (PFN_vkGetInstanceProcAddr)SDL_Vulkan_GetVkGetInstanceProcAddr();`
|
|
|
148 *
|
|
|
149 * \returns the function pointer for `vkGetInstanceProcAddr` or NULL on
|
|
|
150 * failure; call SDL_GetError() for more information.
|
|
|
151 *
|
|
|
152 * \since This function is available since SDL 3.2.0.
|
|
|
153 */
|
|
|
154 extern SDL_DECLSPEC SDL_FunctionPointer SDLCALL SDL_Vulkan_GetVkGetInstanceProcAddr(void);
|
|
|
155
|
|
|
156 /**
|
|
|
157 * Unload the Vulkan library previously loaded by SDL_Vulkan_LoadLibrary().
|
|
|
158 *
|
|
|
159 * SDL keeps a counter of how many times this function has been called, so it
|
|
|
160 * is safe to call this function multiple times, so long as it is paired with
|
|
|
161 * an equivalent number of calls to SDL_Vulkan_LoadLibrary. The library isn't
|
|
|
162 * actually unloaded until there have been an equivalent number of calls to
|
|
|
163 * SDL_Vulkan_UnloadLibrary.
|
|
|
164 *
|
|
|
165 * Once the library has actually been unloaded, if any Vulkan instances
|
|
|
166 * remain, they will likely crash the program. Clean up any existing Vulkan
|
|
|
167 * resources, and destroy appropriate windows, renderers and GPU devices
|
|
|
168 * before calling this function.
|
|
|
169 *
|
|
|
170 * \threadsafety This function is not thread safe.
|
|
|
171 *
|
|
|
172 * \since This function is available since SDL 3.2.0.
|
|
|
173 *
|
|
|
174 * \sa SDL_Vulkan_LoadLibrary
|
|
|
175 */
|
|
|
176 extern SDL_DECLSPEC void SDLCALL SDL_Vulkan_UnloadLibrary(void);
|
|
|
177
|
|
|
178 /**
|
|
|
179 * Get the Vulkan instance extensions needed for vkCreateInstance.
|
|
|
180 *
|
|
|
181 * This should be called after either calling SDL_Vulkan_LoadLibrary() or
|
|
|
182 * creating an SDL_Window with the `SDL_WINDOW_VULKAN` flag.
|
|
|
183 *
|
|
|
184 * On return, the variable pointed to by `count` will be set to the number of
|
|
|
185 * elements returned, suitable for using with
|
|
|
186 * VkInstanceCreateInfo::enabledExtensionCount, and the returned array can be
|
|
|
187 * used with VkInstanceCreateInfo::ppEnabledExtensionNames, for calling
|
|
|
188 * Vulkan's vkCreateInstance API.
|
|
|
189 *
|
|
|
190 * You should not free the returned array; it is owned by SDL.
|
|
|
191 *
|
|
|
192 * \param count a pointer filled in with the number of extensions returned.
|
|
|
193 * \returns an array of extension name strings on success, NULL on failure;
|
|
|
194 * call SDL_GetError() for more information.
|
|
|
195 *
|
|
|
196 * \since This function is available since SDL 3.2.0.
|
|
|
197 *
|
|
|
198 * \sa SDL_Vulkan_CreateSurface
|
|
|
199 */
|
|
|
200 extern SDL_DECLSPEC char const * const * SDLCALL SDL_Vulkan_GetInstanceExtensions(Uint32 *count);
|
|
|
201
|
|
|
202 /**
|
|
|
203 * Create a Vulkan rendering surface for a window.
|
|
|
204 *
|
|
|
205 * The `window` must have been created with the `SDL_WINDOW_VULKAN` flag and
|
|
|
206 * `instance` must have been created with extensions returned by
|
|
|
207 * SDL_Vulkan_GetInstanceExtensions() enabled.
|
|
|
208 *
|
|
|
209 * If `allocator` is NULL, Vulkan will use the system default allocator. This
|
|
|
210 * argument is passed directly to Vulkan and isn't used by SDL itself.
|
|
|
211 *
|
|
|
212 * \param window the window to which to attach the Vulkan surface.
|
|
|
213 * \param instance the Vulkan instance handle.
|
|
|
214 * \param allocator a VkAllocationCallbacks struct, which lets the app set the
|
|
|
215 * allocator that creates the surface. Can be NULL.
|
|
|
216 * \param surface a pointer to a VkSurfaceKHR handle to output the newly
|
|
|
217 * created surface.
|
|
|
218 * \returns true on success or false on failure; call SDL_GetError() for more
|
|
|
219 * information.
|
|
|
220 *
|
|
|
221 * \since This function is available since SDL 3.2.0.
|
|
|
222 *
|
|
|
223 * \sa SDL_Vulkan_GetInstanceExtensions
|
|
|
224 * \sa SDL_Vulkan_DestroySurface
|
|
|
225 */
|
|
|
226 extern SDL_DECLSPEC bool SDLCALL SDL_Vulkan_CreateSurface(SDL_Window *window,
|
|
|
227 VkInstance instance,
|
|
|
228 const struct VkAllocationCallbacks *allocator,
|
|
|
229 VkSurfaceKHR *surface);
|
|
|
230
|
|
|
231 /**
|
|
|
232 * Destroy the Vulkan rendering surface of a window.
|
|
|
233 *
|
|
|
234 * This should be called before SDL_DestroyWindow, if SDL_Vulkan_CreateSurface
|
|
|
235 * was called after SDL_CreateWindow.
|
|
|
236 *
|
|
|
237 * The `instance` must have been created with extensions returned by
|
|
|
238 * SDL_Vulkan_GetInstanceExtensions() enabled and `surface` must have been
|
|
|
239 * created successfully by an SDL_Vulkan_CreateSurface() call.
|
|
|
240 *
|
|
|
241 * If `allocator` is NULL, Vulkan will use the system default allocator. This
|
|
|
242 * argument is passed directly to Vulkan and isn't used by SDL itself.
|
|
|
243 *
|
|
|
244 * \param instance the Vulkan instance handle.
|
|
|
245 * \param surface vkSurfaceKHR handle to destroy.
|
|
|
246 * \param allocator a VkAllocationCallbacks struct, which lets the app set the
|
|
|
247 * allocator that destroys the surface. Can be NULL.
|
|
|
248 *
|
|
|
249 * \since This function is available since SDL 3.2.0.
|
|
|
250 *
|
|
|
251 * \sa SDL_Vulkan_GetInstanceExtensions
|
|
|
252 * \sa SDL_Vulkan_CreateSurface
|
|
|
253 */
|
|
|
254 extern SDL_DECLSPEC void SDLCALL SDL_Vulkan_DestroySurface(VkInstance instance,
|
|
|
255 VkSurfaceKHR surface,
|
|
|
256 const struct VkAllocationCallbacks *allocator);
|
|
|
257
|
|
|
258 /**
|
|
|
259 * Query support for presentation via a given physical device and queue
|
|
|
260 * family.
|
|
|
261 *
|
|
|
262 * The `instance` must have been created with extensions returned by
|
|
|
263 * SDL_Vulkan_GetInstanceExtensions() enabled.
|
|
|
264 *
|
|
|
265 * \param instance the Vulkan instance handle.
|
|
|
266 * \param physicalDevice a valid Vulkan physical device handle.
|
|
|
267 * \param queueFamilyIndex a valid queue family index for the given physical
|
|
|
268 * device.
|
|
|
269 * \returns true if supported, false if unsupported or an error occurred.
|
|
|
270 *
|
|
|
271 * \since This function is available since SDL 3.2.0.
|
|
|
272 *
|
|
|
273 * \sa SDL_Vulkan_GetInstanceExtensions
|
|
|
274 */
|
|
|
275 extern SDL_DECLSPEC bool SDLCALL SDL_Vulkan_GetPresentationSupport(VkInstance instance,
|
|
|
276 VkPhysicalDevice physicalDevice,
|
|
|
277 Uint32 queueFamilyIndex);
|
|
|
278
|
|
|
279 /* @} *//* Vulkan support functions */
|
|
|
280
|
|
|
281 /* Ends C function definitions when using C++ */
|
|
|
282 #ifdef __cplusplus
|
|
|
283 }
|
|
|
284 #endif
|
|
|
285 #include <SDL3/SDL_close_code.h>
|
|
|
286
|
|
|
287 #endif /* SDL_vulkan_h_ */
|