SDL: vulkan: SDL_Vulkan_CreateSurface now accepts an app-provided allocator.

From 2f92807087f49c830481cc5689ae53cb7cdb42e2 Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Mon, 6 Nov 2023 13:30:56 -0500
Subject: [PATCH] vulkan: SDL_Vulkan_CreateSurface now accepts an app-provided
 allocator.

Fixes #3638.
---
 docs/README-migration.md              |  2 ++
 include/SDL3/SDL_vulkan.h             |  7 +++++++
 src/dynapi/SDL_dynapi_procs.h         |  2 +-
 src/video/SDL_sysvideo.h              |  2 +-
 src/video/SDL_video.c                 |  3 ++-
 src/video/SDL_vulkan_internal.h       |  1 +
 src/video/SDL_vulkan_utils.c          |  3 ++-
 src/video/android/SDL_androidvulkan.c |  4 ++--
 src/video/android/SDL_androidvulkan.h |  1 +
 src/video/cocoa/SDL_cocoavulkan.h     |  1 +
 src/video/cocoa/SDL_cocoavulkan.m     | 10 ++++++----
 src/video/kmsdrm/SDL_kmsdrmvulkan.c   |  3 ++-
 src/video/kmsdrm/SDL_kmsdrmvulkan.h   |  1 +
 src/video/uikit/SDL_uikitvulkan.h     |  1 +
 src/video/vivante/SDL_vivantevulkan.c |  3 ++-
 src/video/vivante/SDL_vivantevulkan.h |  1 +
 src/video/wayland/SDL_waylandvulkan.c |  4 ++--
 src/video/wayland/SDL_waylandvulkan.h |  1 +
 src/video/windows/SDL_windowsvulkan.c |  4 ++--
 src/video/windows/SDL_windowsvulkan.h |  1 +
 src/video/x11/SDL_x11vulkan.c         |  7 +++----
 src/video/x11/SDL_x11vulkan.h         |  1 +
 test/testvulkan.c                     |  1 +
 23 files changed, 44 insertions(+), 20 deletions(-)

diff --git a/docs/README-migration.md b/docs/README-migration.md
index ab156c3e6545..7ddd7fb90e64 100644
--- a/docs/README-migration.md
+++ b/docs/README-migration.md
@@ -1312,4 +1312,6 @@ SDL_Vulkan_GetInstanceExtensions() no longer takes a window parameter, and no lo
 
 SDL_Vulkan_GetVkGetInstanceProcAddr() now returns `SDL_FunctionPointer` instead of `void *`, and should be cast to PFN_vkGetInstanceProcAddr.
 
+SDL_Vulkan_CreateSurface() now takes a VkAllocationCallbacks pointer as its third parameter. If you don't have an allocator to supply, pass a NULL here to use the system default allocator (SDL2 always used the system default allocator here).
+
 SDL_Vulkan_GetDrawableSize() has been removed. SDL_GetWindowSizeInPixels() can be used in its place.
diff --git a/include/SDL3/SDL_vulkan.h b/include/SDL3/SDL_vulkan.h
index 3b58efb55f65..6d84e655ca98 100644
--- a/include/SDL3/SDL_vulkan.h
+++ b/include/SDL3/SDL_vulkan.h
@@ -51,6 +51,7 @@ extern "C" {
 
 VK_DEFINE_HANDLE(VkInstance)
 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR)
+struct VkAllocationCallbacks;
 
 #endif /* !NO_SDL_VULKAN_TYPEDEFS */
 
@@ -165,8 +166,13 @@ extern DECLSPEC char const* const* SDLCALL SDL_Vulkan_GetInstanceExtensions(Uint
  * `instance` must have been created with extensions returned by
  * SDL_Vulkan_GetInstanceExtensions() enabled.
  *
+ * If `allocator` is NULL, Vulkan will use the system default allocator.
+ * This argument is passed directly to Vulkan and isn't used by SDL itself.
+ *
  * \param window The window to which to attach the Vulkan surface
  * \param instance The Vulkan instance handle
+ * \param allocator A VkAllocationCallbacks struct, which lets the app
+ *                  set the allocator that creates the surface. Can be NULL.
  * \param surface A pointer to a VkSurfaceKHR handle to output the newly
  *                created surface
  * \returns SDL_TRUE on success, SDL_FALSE on error.
@@ -177,6 +183,7 @@ extern DECLSPEC char const* const* SDLCALL SDL_Vulkan_GetInstanceExtensions(Uint
  */
 extern DECLSPEC SDL_bool SDLCALL SDL_Vulkan_CreateSurface(SDL_Window *window,
                                                           VkInstance instance,
+                                                          const struct VkAllocationCallbacks *allocator,
                                                           VkSurfaceKHR* surface);
 
 /* @} *//* Vulkan support functions */
diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
index 48a999e32c71..048aba36fef7 100644
--- a/src/dynapi/SDL_dynapi_procs.h
+++ b/src/dynapi/SDL_dynapi_procs.h
@@ -719,7 +719,7 @@ SDL_DYNAPI_PROC(int,SDL_UpdateTexture,(SDL_Texture *a, const SDL_Rect *b, const
 SDL_DYNAPI_PROC(int,SDL_UpdateWindowSurface,(SDL_Window *a),(a),return)
 SDL_DYNAPI_PROC(int,SDL_UpdateWindowSurfaceRects,(SDL_Window *a, const SDL_Rect *b, int c),(a,b,c),return)
 SDL_DYNAPI_PROC(int,SDL_UpdateYUVTexture,(SDL_Texture *a, const SDL_Rect *b, const Uint8 *c, int d, const Uint8 *e, int f, const Uint8 *g, int h),(a,b,c,d,e,f,g,h),return)
-SDL_DYNAPI_PROC(SDL_bool,SDL_Vulkan_CreateSurface,(SDL_Window *a, VkInstance b, VkSurfaceKHR *c),(a,b,c),return)
+SDL_DYNAPI_PROC(SDL_bool,SDL_Vulkan_CreateSurface,(SDL_Window *a, VkInstance b, const struct VkAllocationCallbacks *c, VkSurfaceKHR *d),(a,b,c,d),return)
 SDL_DYNAPI_PROC(char const* const*,SDL_Vulkan_GetInstanceExtensions,(Uint32 *a),(a),return)
 SDL_DYNAPI_PROC(SDL_FunctionPointer,SDL_Vulkan_GetVkGetInstanceProcAddr,(void),(),return)
 SDL_DYNAPI_PROC(int,SDL_Vulkan_LoadLibrary,(const char *a),(a),return)
diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h
index 40ca81942280..b318d75db0b7 100644
--- a/src/video/SDL_sysvideo.h
+++ b/src/video/SDL_sysvideo.h
@@ -291,7 +291,7 @@ struct SDL_VideoDevice
     int (*Vulkan_LoadLibrary)(SDL_VideoDevice *_this, const char *path);
     void (*Vulkan_UnloadLibrary)(SDL_VideoDevice *_this);
     char const* const* (*Vulkan_GetInstanceExtensions)(SDL_VideoDevice *_this, Uint32 *count);
-    SDL_bool (*Vulkan_CreateSurface)(SDL_VideoDevice *_this, SDL_Window *window, VkInstance instance, VkSurfaceKHR *surface);
+    SDL_bool (*Vulkan_CreateSurface)(SDL_VideoDevice *_this, SDL_Window *window, VkInstance instance, const struct VkAllocationCallbacks *allocator, VkSurfaceKHR *surface);
 
     /* * * */
     /*
diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c
index 232d0a037998..665009100de2 100644
--- a/src/video/SDL_video.c
+++ b/src/video/SDL_video.c
@@ -5147,6 +5147,7 @@ char const* const* SDL_Vulkan_GetInstanceExtensions(Uint32 *count)
 
 SDL_bool SDL_Vulkan_CreateSurface(SDL_Window *window,
                                   VkInstance instance,
+                                  const struct VkAllocationCallbacks *allocator,
                                   VkSurfaceKHR *surface)
 {
     CHECK_WINDOW_MAGIC(window, SDL_FALSE);
@@ -5166,7 +5167,7 @@ SDL_bool SDL_Vulkan_CreateSurface(SDL_Window *window,
         return SDL_FALSE;
     }
 
-    return _this->Vulkan_CreateSurface(_this, window, instance, surface);
+    return _this->Vulkan_CreateSurface(_this, window, instance, allocator, surface);
 }
 
 SDL_MetalView SDL_Metal_CreateView(SDL_Window *window)
diff --git a/src/video/SDL_vulkan_internal.h b/src/video/SDL_vulkan_internal.h
index 74452134bd52..4d749fa6324f 100644
--- a/src/video/SDL_vulkan_internal.h
+++ b/src/video/SDL_vulkan_internal.h
@@ -69,6 +69,7 @@ extern VkExtensionProperties *SDL_Vulkan_CreateInstanceExtensionsList(
  * extension. */
 extern SDL_bool SDL_Vulkan_Display_CreateSurface(void *vkGetInstanceProcAddr,
                                                  VkInstance instance,
+                                                 const struct VkAllocationCallbacks *allocator,
                                                  VkSurfaceKHR *surface);
 #else
 
diff --git a/src/video/SDL_vulkan_utils.c b/src/video/SDL_vulkan_utils.c
index 5ce81a7b0804..e44275a9c3b6 100644
--- a/src/video/SDL_vulkan_utils.c
+++ b/src/video/SDL_vulkan_utils.c
@@ -177,6 +177,7 @@ static const VkDisplayPlaneAlphaFlagBitsKHR alphaModes[4] = {
 
 SDL_bool SDL_Vulkan_Display_CreateSurface(void *vkGetInstanceProcAddr_,
                                           VkInstance instance,
+                                          const struct VkAllocationCallbacks *allocator,
                                           VkSurfaceKHR *surface)
 {
     PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
@@ -459,7 +460,7 @@ SDL_bool SDL_Vulkan_Display_CreateSurface(void *vkGetInstanceProcAddr_,
     createInfo.transform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
     createInfo.globalAlpha = 1.0f;
 
-    result = vkCreateDisplayPlaneSurfaceKHR(instance, &createInfo, NULL, surface);
+    result = vkCreateDisplayPlaneSurfaceKHR(instance, &createInfo, allocator, surface);
     if (result != VK_SUCCESS) {
         SDL_SetError("vkCreateDisplayPlaneSurfaceKHR failed: %s", SDL_Vulkan_GetResultString(result));
         return SDL_FALSE;
diff --git a/src/video/android/SDL_androidvulkan.c b/src/video/android/SDL_androidvulkan.c
index d47d422a9714..85f044f48bdf 100644
--- a/src/video/android/SDL_androidvulkan.c
+++ b/src/video/android/SDL_androidvulkan.c
@@ -126,6 +126,7 @@ char const* const* Android_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
 SDL_bool Android_Vulkan_CreateSurface(SDL_VideoDevice *_this,
                                       SDL_Window *window,
                                       VkInstance instance,
+                                      const struct VkAllocationCallbacks *allocator,
                                       VkSurfaceKHR *surface)
 {
     SDL_WindowData *windowData = window->driverdata;
@@ -153,8 +154,7 @@ SDL_bool Android_Vulkan_CreateSurface(SDL_VideoDevice *_this,
     createInfo.pNext = NULL;
     createInfo.flags = 0;
     createInfo.window = windowData->native_window;
-    result = vkCreateAndroidSurfaceKHR(instance, &createInfo,
-                                       NULL, surface);
+    result = vkCreateAndroidSurfaceKHR(instance, &createInfo, allocator, surface);
     if (result != VK_SUCCESS) {
         SDL_SetError("vkCreateAndroidSurfaceKHR failed: %s",
                      SDL_Vulkan_GetResultString(result));
diff --git a/src/video/android/SDL_androidvulkan.h b/src/video/android/SDL_androidvulkan.h
index e538ca917a2e..d477ad106fc2 100644
--- a/src/video/android/SDL_androidvulkan.h
+++ b/src/video/android/SDL_androidvulkan.h
@@ -41,6 +41,7 @@ char const* const* Android_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
 SDL_bool Android_Vulkan_CreateSurface(SDL_VideoDevice *_this,
                                       SDL_Window *window,
                                       VkInstance instance,
+                                      const struct VkAllocationCallbacks *allocator,
                                       VkSurfaceKHR *surface);
 
 #endif
diff --git a/src/video/cocoa/SDL_cocoavulkan.h b/src/video/cocoa/SDL_cocoavulkan.h
index 155dac30888b..fdc4a7e69f5f 100644
--- a/src/video/cocoa/SDL_cocoavulkan.h
+++ b/src/video/cocoa/SDL_cocoavulkan.h
@@ -41,6 +41,7 @@ char const* const* Cocoa_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
 SDL_bool Cocoa_Vulkan_CreateSurface(SDL_VideoDevice *_this,
                                     SDL_Window *window,
                                     VkInstance instance,
+                                    const struct VkAllocationCallbacks *allocator,
                                     VkSurfaceKHR *surface);
 
 #endif
diff --git a/src/video/cocoa/SDL_cocoavulkan.m b/src/video/cocoa/SDL_cocoavulkan.m
index 55d1f352fb0d..d5d3cb88da69 100644
--- a/src/video/cocoa/SDL_cocoavulkan.m
+++ b/src/video/cocoa/SDL_cocoavulkan.m
@@ -178,6 +178,7 @@ void Cocoa_Vulkan_UnloadLibrary(SDL_VideoDevice *_this)
 static SDL_bool Cocoa_Vulkan_CreateSurfaceViaMetalView(SDL_VideoDevice *_this,
                                                        SDL_Window *window,
                                                        VkInstance instance,
+                                                       const struct VkAllocationCallbacks *allocator,
                                                        VkSurfaceKHR *surface,
                                                        PFN_vkCreateMetalSurfaceEXT vkCreateMetalSurfaceEXT,
                                                        PFN_vkCreateMacOSSurfaceMVK vkCreateMacOSSurfaceMVK)
@@ -195,7 +196,7 @@ static SDL_bool Cocoa_Vulkan_CreateSurfaceViaMetalView(SDL_VideoDevice *_this,
         createInfo.flags = 0;
         createInfo.pLayer = (__bridge const CAMetalLayer *)
             Cocoa_Metal_GetLayer(_this, metalview);
-        result = vkCreateMetalSurfaceEXT(instance, &createInfo, NULL, surface);
+        result = vkCreateMetalSurfaceEXT(instance, &createInfo, allocator, surface);
         if (result != VK_SUCCESS) {
             Cocoa_Metal_DestroyView(_this, metalview);
             SDL_SetError("vkCreateMetalSurfaceEXT failed: %s",
@@ -231,6 +232,7 @@ static SDL_bool Cocoa_Vulkan_CreateSurfaceViaMetalView(SDL_VideoDevice *_this,
 SDL_bool Cocoa_Vulkan_CreateSurface(SDL_VideoDevice *_this,
                                     SDL_Window *window,
                                     VkInstance instance,
+                                    const struct VkAllocationCallbacks *allocator,
                                     VkSurfaceKHR *surface)
 {
     PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
@@ -269,7 +271,7 @@ SDL_bool Cocoa_Vulkan_CreateSurface(SDL_VideoDevice *_this,
                 createInfo.pNext = NULL;
                 createInfo.flags = 0;
                 createInfo.pLayer = (CAMetalLayer *)data.sdlContentView.layer;
-                result = vkCreateMetalSurfaceEXT(instance, &createInfo, NULL, surface);
+                result = vkCreateMetalSurfaceEXT(instance, &createInfo, allocator, surface);
                 if (result != VK_SUCCESS) {
                     SDL_SetError("vkCreateMetalSurfaceEXT failed: %s",
                                  SDL_Vulkan_GetResultString(result));
@@ -282,7 +284,7 @@ SDL_bool Cocoa_Vulkan_CreateSurface(SDL_VideoDevice *_this,
                 createInfo.flags = 0;
                 createInfo.pView = (__bridge const void *)data.sdlContentView;
                 result = vkCreateMacOSSurfaceMVK(instance, &createInfo,
-                                                 NULL, surface);
+                                                 allocator, surface);
                 if (result != VK_SUCCESS) {
                     SDL_SetError("vkCreateMacOSSurfaceMVK failed: %s",
                                  SDL_Vulkan_GetResultString(result));
@@ -291,7 +293,7 @@ SDL_bool Cocoa_Vulkan_CreateSurface(SDL_VideoDevice *_this,
             }
         }
     } else {
-        return Cocoa_Vulkan_CreateSurfaceViaMetalView(_this, window, instance, surface, vkCreateMetalSurfaceEXT, vkCreateMacOSSurfaceMVK);
+        return Cocoa_Vulkan_CreateSurfaceViaMetalView(_this, window, instance, allocator, surface, vkCreateMetalSurfaceEXT, vkCreateMacOSSurfaceMVK);
     }
 
     return SDL_TRUE;
diff --git a/src/video/kmsdrm/SDL_kmsdrmvulkan.c b/src/video/kmsdrm/SDL_kmsdrmvulkan.c
index fba00b6585cd..20b6516e3541 100644
--- a/src/video/kmsdrm/SDL_kmsdrmvulkan.c
+++ b/src/video/kmsdrm/SDL_kmsdrmvulkan.c
@@ -163,6 +163,7 @@ char const* const* KMSDRM_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
 SDL_bool KMSDRM_Vulkan_CreateSurface(SDL_VideoDevice *_this,
                                      SDL_Window *window,
                                      VkInstance instance,
+                                     const struct VkAllocationCallbacks *allocator,
                                      VkSurfaceKHR *surface)
 {
     VkPhysicalDevice gpu = NULL;
@@ -476,7 +477,7 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(SDL_VideoDevice *_this,
     display_plane_surface_create_info.alphaMode = alpha_mode;
     result = vkCreateDisplayPlaneSurfaceKHR(instance,
                                             &display_plane_surface_create_info,
-                                            NULL,
+                                            allocator,
                                             surface);
     if (result != VK_SUCCESS) {
         SDL_SetError("vkCreateDisplayPlaneSurfaceKHR failed: %s",
diff --git a/src/video/kmsdrm/SDL_kmsdrmvulkan.h b/src/video/kmsdrm/SDL_kmsdrmvulkan.h
index 7db828d93a52..5b327197d666 100644
--- a/src/video/kmsdrm/SDL_kmsdrmvulkan.h
+++ b/src/video/kmsdrm/SDL_kmsdrmvulkan.h
@@ -41,6 +41,7 @@ char const* const* KMSDRM_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
 SDL_bool KMSDRM_Vulkan_CreateSurface(SDL_VideoDevice *_this,
                                      SDL_Window *window,
                                      VkInstance instance,
+                                     const struct VkAllocationCallbacks *allocator,
                                      VkSurfaceKHR *surface);
 
 #endif
diff --git a/src/video/uikit/SDL_uikitvulkan.h b/src/video/uikit/SDL_uikitvulkan.h
index 432edda9460d..540ccca46871 100644
--- a/src/video/uikit/SDL_uikitvulkan.h
+++ b/src/video/uikit/SDL_uikitvulkan.h
@@ -41,6 +41,7 @@ char const* const* UIKit_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
 SDL_bool UIKit_Vulkan_CreateSurface(SDL_VideoDevice *_this,
                                     SDL_Window *window,
                                     VkInstance instance,
+                                    const struct VkAllocationCallbacks *allocator,
                                     VkSurfaceKHR *surface);
 
 #endif
diff --git a/src/video/vivante/SDL_vivantevulkan.c b/src/video/vivante/SDL_vivantevulkan.c
index d5a30e79e96e..9244bf0b256b 100644
--- a/src/video/vivante/SDL_vivantevulkan.c
+++ b/src/video/vivante/SDL_vivantevulkan.c
@@ -133,13 +133,14 @@ char const* const* VIVANTE_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
 SDL_bool VIVANTE_Vulkan_CreateSurface(SDL_VideoDevice *_this,
                                       SDL_Window *window,
                                       VkInstance instance,
+                                      const struct VkAllocationCallbacks *allocator,
                                       VkSurfaceKHR *surface)
 {
     if (!_this->vulkan_config.loader_handle) {
         SDL_SetError("Vulkan is not loaded");
         return SDL_FALSE;
     }
-    return SDL_Vulkan_Display_CreateSurface(_this->vulkan_config.vkGetInstanceProcAddr, instance, surface);
+    return SDL_Vulkan_Display_CreateSurface(_this->vulkan_config.vkGetInstanceProcAddr, instance, allocator, surface);
 }
 
 #endif
diff --git a/src/video/vivante/SDL_vivantevulkan.h b/src/video/vivante/SDL_vivantevulkan.h
index b39fd2b9f0af..5a0fa9133a4d 100644
--- a/src/video/vivante/SDL_vivantevulkan.h
+++ b/src/video/vivante/SDL_vivantevulkan.h
@@ -40,6 +40,7 @@ char const* const* VIVANTE_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
 SDL_bool VIVANTE_Vulkan_CreateSurface(SDL_VideoDevice *_this,
                                       SDL_Window *window,
                                       VkInstance instance,
+                                      const struct VkAllocationCallbacks *allocator,
                                       VkSurfaceKHR *surface);
 
 #endif
diff --git a/src/video/wayland/SDL_waylandvulkan.c b/src/video/wayland/SDL_waylandvulkan.c
index b07aaf95e895..99a9cd13e40f 100644
--- a/src/video/wayland/SDL_waylandvulkan.c
+++ b/src/video/wayland/SDL_waylandvulkan.c
@@ -134,6 +134,7 @@ char const* const* Wayland_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
 SDL_bool Wayland_Vulkan_CreateSurface(SDL_VideoDevice *_this,
                                       SDL_Window *window,
                                       VkInstance instance,
+                                      const struct VkAllocationCallbacks *allocator,
                                       VkSurfaceKHR *surface)
 {
     SDL_WindowData *windowData = window->driverdata;
@@ -162,8 +163,7 @@ SDL_bool Wayland_Vulkan_CreateSurface(SDL_VideoDevice *_this,
     createInfo.flags = 0;
     createInfo.display = windowData->waylandData->display;
     createInfo.surface = windowData->surface;
-    result = vkCreateWaylandSurfaceKHR(instance, &createInfo,
-                                       NULL, surface);
+    result = vkCreateWaylandSurfaceKHR(instance, &createInfo, allocator, surface);
     if (result != VK_SUCCESS) {
         SDL_SetError("vkCreateWaylandSurfaceKHR failed: %s",
                      SDL_Vulkan_GetResultString(result));
diff --git a/src/video/wayland/SDL_waylandvulkan.h b/src/video/wayland/SDL_waylandvulkan.h
index ebcd4c1c5656..c3ba76dc2c25 100644
--- a/src/video/wayland/SDL_waylandvulkan.h
+++ b/src/video/wayland/SDL_waylandvulkan.h
@@ -41,6 +41,7 @@ char const* const* Wayland_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
 SDL_bool Wayland_Vulkan_CreateSurface(SDL_VideoDevice *_this,
                                       SDL_Window *window,
                                       VkInstance instance,
+                                      const struct VkAllocationCallbacks *allocator,
                                       VkSurfaceKHR *surface);
 
 #endif
diff --git a/src/video/windows/SDL_windowsvulkan.c b/src/video/windows/SDL_windowsvulkan.c
index 79b64ffd8f77..e2e2a39a60c6 100644
--- a/src/video/windows/SDL_windowsvulkan.c
+++ b/src/video/windows/SDL_windowsvulkan.c
@@ -125,6 +125,7 @@ char const* const* WIN_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
 SDL_bool WIN_Vulkan_CreateSurface(SDL_VideoDevice *_this,
                                   SDL_Window *window,
                                   VkInstance instance,
+                                  const struct VkAllocationCallbacks *allocator,
                                   VkSurfaceKHR *surface)
 {
     SDL_WindowData *windowData = window->driverdata;
@@ -152,8 +153,7 @@ SDL_bool WIN_Vulkan_CreateSurface(SDL_VideoDevice *_this,
     createInfo.flags = 0;
     createInfo.hinstance = windowData->hinstance;
     createInfo.hwnd = windowData->hwnd;
-    result = vkCreateWin32SurfaceKHR(instance, &createInfo,
-                                     NULL, surface);
+    result = vkCreateWin32SurfaceKHR(instance, &createInfo, allocator, surface);
     if (result != VK_SUCCESS) {
         SDL_SetError("vkCreateWin32SurfaceKHR failed: %s",
                      SDL_Vulkan_GetResultString(result));
diff --git a/src/video/windows/SDL_windowsvulkan.h b/src/video/windows/SDL_windowsvulkan.h
index 0fffcbf4278c..95e6c12ae4a5 100644
--- a/src/video/windows/SDL_windowsvulkan.h
+++ b/src/video/windows/SDL_windowsvulkan.h
@@ -41,6 +41,7 @@ char const* const* WIN_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
 SDL_bool WIN_Vulkan_CreateSurface(SDL_VideoDevice *_this,
                                   SDL_Window *window,
                                   VkInstance instance,
+                                  const struct VkAllocationCallbacks *allocator,
                                   VkSurfaceKHR *surface);
 
 #endif
diff --git a/src/video/x11/SDL_x11vulkan.c b/src/video/x11/SDL_x11vulkan.c
index 7eea5a34bba8..a5aa38b9a2e1 100644
--- a/src/video/x11/SDL_x11vulkan.c
+++ b/src/video/x11/SDL_x11vulkan.c
@@ -170,6 +170,7 @@ char const* const* X11_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
 SDL_bool X11_Vulkan_CreateSurface(SDL_VideoDevice *_this,
                                   SDL_Window *window,
                                   VkInstance instance,
+                                  const struct VkAllocationCallbacks *allocator,
                                   VkSurfaceKHR *surface)
 {
     SDL_VideoData *videoData = _this->driverdata;
@@ -199,8 +200,7 @@ SDL_bool X11_Vulkan_CreateSurface(SDL_VideoDevice *_this,
             return SDL_FALSE;
         }
         createInfo.window = (xcb_window_t)windowData->xwindow;
-        result = vkCreateXcbSurfaceKHR(instance, &createInfo,
-                                       NULL, surface);
+        result = vkCreateXcbSurfaceKHR(instance, &createInfo, allocator, surface);
         if (result != VK_SUCCESS) {
             SDL_SetError("vkCreateXcbSurfaceKHR failed: %s", SDL_Vulkan_GetResultString(result));
             return SDL_FALSE;
@@ -221,8 +221,7 @@ SDL_bool X11_Vulkan_CreateSurface(SDL_VideoDevice *_this,
         createInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
         createInfo.dpy = videoData->display;
         createInfo.window = (xcb_window_t)windowData->xwindow;
-        result = vkCreateXlibSurfaceKHR(instance, &createInfo,
-                                        NULL, surface);
+        result = vkCreateXlibSurfaceKHR(instance, &createInfo, allocator, surface);
         if (result != VK_SUCCESS) {
             SDL_SetError("vkCreateXlibSurfaceKHR failed: %s", SDL_Vulkan_GetResultString(result));
             return SDL_FALSE;
diff --git a/src/video/x11/SDL_x11vulkan.h b/src/video/x11/SDL_x11vulkan.h
index acaf5d65cbc6..e26727e5505a 100644
--- a/src/video/x11/SDL_x11vulkan.h
+++ b/src/video/x11/SDL_x11vulkan.h
@@ -37,6 +37,7 @@ char const* const* X11_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
 SDL_bool X11_Vulkan_CreateSurface(SDL_VideoDevice *_this,
                                   SDL_Window *window,
                                   VkInstance instance,
+                                  const struct VkAllocationCallbacks *allocator,
                                   VkSurfaceKHR *surface);
 
 #endif
diff --git a/test/testvulkan.c b/test/testvulkan.c
index e13e3ace8421..4555f8705a2e 100644
--- a/test/testvulkan.c
+++ b/test/testvulkan.c
@@ -261,6 +261,7 @@ static void createSurface(void)
 {
     if (!SDL_Vulkan_CreateSurface(vulkanContext->window,
                                   vulkanContext->instance,
+                                  NULL,
                                   &vulkanContext->surface)) {
         vulkanContext->surface = VK_NULL_HANDLE;
         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_Vulkan_CreateSurface(): %s\n", SDL_GetError());