Browse Source

vulkan: SDL_Vulkan_CreateSurface now returns the usual int (0=ok, -1=error).

Fixes #10091.
Ryan C. Gordon 9 months ago
parent
commit
982feb7a65

+ 2 - 0
docs/README-migration.md

@@ -2005,6 +2005,8 @@ 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 returns an int (0=success, -1=error) instead of an SDL_bool (true=success, false=error).
+
 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.

+ 2 - 2
include/SDL3/SDL_vulkan.h

@@ -172,14 +172,14 @@ extern SDL_DECLSPEC char const* const* SDLCALL SDL_Vulkan_GetInstanceExtensions(
  *                  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.
+ * \returns 0 on success, -1 on error (check SDL_GetError() for specifics).
  *
  * \since This function is available since SDL 3.0.0.
  *
  * \sa SDL_Vulkan_GetInstanceExtensions
  * \sa SDL_Vulkan_DestroySurface
  */
-extern SDL_DECLSPEC SDL_bool SDLCALL SDL_Vulkan_CreateSurface(SDL_Window *window,
+extern SDL_DECLSPEC int SDLCALL SDL_Vulkan_CreateSurface(SDL_Window *window,
                                                           VkInstance instance,
                                                           const struct VkAllocationCallbacks *allocator,
                                                           VkSurfaceKHR* surface);

+ 1 - 1
src/dynapi/SDL_dynapi_procs.h

@@ -862,7 +862,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, const struct VkAllocationCallbacks *c, VkSurfaceKHR *d),(a,b,c,d),return)
+SDL_DYNAPI_PROC(int,SDL_Vulkan_CreateSurface,(SDL_Window *a, VkInstance b, const struct VkAllocationCallbacks *c, VkSurfaceKHR *d),(a,b,c,d),return)
 SDL_DYNAPI_PROC(void,SDL_Vulkan_DestroySurface,(VkInstance a, VkSurfaceKHR b, const struct VkAllocationCallbacks *c),(a,b,c),)
 SDL_DYNAPI_PROC(char const* const*,SDL_Vulkan_GetInstanceExtensions,(Uint32 *a),(a),return)
 SDL_DYNAPI_PROC(SDL_FunctionPointer,SDL_Vulkan_GetVkGetInstanceProcAddr,(void),(),return)

+ 1 - 1
src/render/vulkan/SDL_render_vulkan.c

@@ -1761,7 +1761,7 @@ static VkResult VULKAN_CreateDeviceResources(SDL_Renderer *renderer, SDL_Propert
     if (rendererData->surface) {
         rendererData->surface_external = SDL_TRUE;
     } else {
-        if (!device->Vulkan_CreateSurface || !device->Vulkan_CreateSurface(device, renderer->window, rendererData->instance, NULL, &rendererData->surface)) {
+        if (!device->Vulkan_CreateSurface || (device->Vulkan_CreateSurface(device, renderer->window, rendererData->instance, NULL, &rendererData->surface) < 0)) {
             VULKAN_DestroyAll(renderer);
             SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Vulkan_CreateSurface() failed.\n");
             return VK_ERROR_UNKNOWN;

+ 1 - 1
src/video/SDL_sysvideo.h

@@ -302,7 +302,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, const struct VkAllocationCallbacks *allocator, VkSurfaceKHR *surface);
+    int (*Vulkan_CreateSurface)(SDL_VideoDevice *_this, SDL_Window *window, VkInstance instance, const struct VkAllocationCallbacks *allocator, VkSurfaceKHR *surface);
     void (*Vulkan_DestroySurface)(SDL_VideoDevice *_this, VkInstance instance, VkSurfaceKHR surface, const struct VkAllocationCallbacks *allocator);
 
     /* * * */

+ 4 - 7
src/video/SDL_video.c

@@ -5462,7 +5462,7 @@ char const* const* SDL_Vulkan_GetInstanceExtensions(Uint32 *count)
     return _this->Vulkan_GetInstanceExtensions(_this, count);
 }
 
-SDL_bool SDL_Vulkan_CreateSurface(SDL_Window *window,
+int SDL_Vulkan_CreateSurface(SDL_Window *window,
                                   VkInstance instance,
                                   const struct VkAllocationCallbacks *allocator,
                                   VkSurfaceKHR *surface)
@@ -5470,18 +5470,15 @@ SDL_bool SDL_Vulkan_CreateSurface(SDL_Window *window,
     CHECK_WINDOW_MAGIC(window, SDL_FALSE);
 
     if (!(window->flags & SDL_WINDOW_VULKAN)) {
-        SDL_SetError(NOT_A_VULKAN_WINDOW);
-        return SDL_FALSE;
+        return SDL_SetError(NOT_A_VULKAN_WINDOW);
     }
 
     if (!instance) {
-        SDL_InvalidParamError("instance");
-        return SDL_FALSE;
+        return SDL_InvalidParamError("instance");
     }
 
     if (!surface) {
-        SDL_InvalidParamError("surface");
-        return SDL_FALSE;
+        return SDL_InvalidParamError("surface");
     }
 
     return _this->Vulkan_CreateSurface(_this, window, instance, allocator, surface);

+ 10 - 14
src/video/android/SDL_androidvulkan.c

@@ -122,11 +122,11 @@ char const* const* Android_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
     return extensionsForAndroid;
 }
 
-SDL_bool Android_Vulkan_CreateSurface(SDL_VideoDevice *_this,
-                                      SDL_Window *window,
-                                      VkInstance instance,
-                                      const struct VkAllocationCallbacks *allocator,
-                                      VkSurfaceKHR *surface)
+int Android_Vulkan_CreateSurface(SDL_VideoDevice *_this,
+                                 SDL_Window *window,
+                                 VkInstance instance,
+                                 const struct VkAllocationCallbacks *allocator,
+                                 VkSurfaceKHR *surface)
 {
     SDL_WindowData *windowData = window->driverdata;
     PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
@@ -139,14 +139,12 @@ SDL_bool Android_Vulkan_CreateSurface(SDL_VideoDevice *_this,
     VkResult result;
 
     if (!_this->vulkan_config.loader_handle) {
-        SDL_SetError("Vulkan is not loaded");
-        return SDL_FALSE;
+        return SDL_SetError("Vulkan is not loaded");
     }
 
     if (!vkCreateAndroidSurfaceKHR) {
-        SDL_SetError(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME
-                     " extension is not enabled in the Vulkan instance.");
-        return SDL_FALSE;
+        return SDL_SetError(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME
+                            " extension is not enabled in the Vulkan instance.");
     }
     SDL_zero(createInfo);
     createInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
@@ -155,11 +153,9 @@ SDL_bool Android_Vulkan_CreateSurface(SDL_VideoDevice *_this,
     createInfo.window = windowData->native_window;
     result = vkCreateAndroidSurfaceKHR(instance, &createInfo, allocator, surface);
     if (result != VK_SUCCESS) {
-        SDL_SetError("vkCreateAndroidSurfaceKHR failed: %s",
-                     SDL_Vulkan_GetResultString(result));
-        return SDL_FALSE;
+        return SDL_SetError("vkCreateAndroidSurfaceKHR failed: %s", SDL_Vulkan_GetResultString(result));
     }
-    return SDL_TRUE;
+    return 0;
 }
 
 void Android_Vulkan_DestroySurface(SDL_VideoDevice *_this,

+ 5 - 5
src/video/android/SDL_androidvulkan.h

@@ -38,11 +38,11 @@ int Android_Vulkan_LoadLibrary(SDL_VideoDevice *_this, const char *path);
 void Android_Vulkan_UnloadLibrary(SDL_VideoDevice *_this);
 char const* const* Android_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
                                                         Uint32 *count);
-SDL_bool Android_Vulkan_CreateSurface(SDL_VideoDevice *_this,
-                                      SDL_Window *window,
-                                      VkInstance instance,
-                                      const struct VkAllocationCallbacks *allocator,
-                                      VkSurfaceKHR *surface);
+int Android_Vulkan_CreateSurface(SDL_VideoDevice *_this,
+                                 SDL_Window *window,
+                                 VkInstance instance,
+                                 const struct VkAllocationCallbacks *allocator,
+                                 VkSurfaceKHR *surface);
 void Android_Vulkan_DestroySurface(SDL_VideoDevice *_this,
                                    VkInstance instance,
                                    VkSurfaceKHR surface,

+ 5 - 5
src/video/cocoa/SDL_cocoavulkan.h

@@ -38,11 +38,11 @@ int Cocoa_Vulkan_LoadLibrary(SDL_VideoDevice *_this, const char *path);
 void Cocoa_Vulkan_UnloadLibrary(SDL_VideoDevice *_this);
 char const* const* Cocoa_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
                                                       Uint32 *count);
-SDL_bool Cocoa_Vulkan_CreateSurface(SDL_VideoDevice *_this,
-                                    SDL_Window *window,
-                                    VkInstance instance,
-                                    const struct VkAllocationCallbacks *allocator,
-                                    VkSurfaceKHR *surface);
+int Cocoa_Vulkan_CreateSurface(SDL_VideoDevice *_this,
+                               SDL_Window *window,
+                               VkInstance instance,
+                               const struct VkAllocationCallbacks *allocator,
+                               VkSurfaceKHR *surface);
 void Cocoa_Vulkan_DestroySurface(SDL_VideoDevice *_this,
                                  VkInstance instance,
                                  VkSurfaceKHR surface,

+ 22 - 32
src/video/cocoa/SDL_cocoavulkan.m

@@ -173,18 +173,18 @@ char const* const* Cocoa_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
     return extensionsForCocoa;
 }
 
-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)
+static int Cocoa_Vulkan_CreateSurfaceViaMetalView(SDL_VideoDevice *_this,
+                                                  SDL_Window *window,
+                                                  VkInstance instance,
+                                                  const struct VkAllocationCallbacks *allocator,
+                                                  VkSurfaceKHR *surface,
+                                                  PFN_vkCreateMetalSurfaceEXT vkCreateMetalSurfaceEXT,
+                                                  PFN_vkCreateMacOSSurfaceMVK vkCreateMacOSSurfaceMVK)
 {
     VkResult result;
     SDL_MetalView metalview = Cocoa_Metal_CreateView(_this, window);
     if (metalview == NULL) {
-        return SDL_FALSE;
+        return -1;
     }
 
     if (vkCreateMetalSurfaceEXT) {
@@ -197,9 +197,7 @@ static SDL_bool Cocoa_Vulkan_CreateSurfaceViaMetalView(SDL_VideoDevice *_this,
         result = vkCreateMetalSurfaceEXT(instance, &createInfo, allocator, surface);
         if (result != VK_SUCCESS) {
             Cocoa_Metal_DestroyView(_this, metalview);
-            SDL_SetError("vkCreateMetalSurfaceEXT failed: %s",
-                         SDL_Vulkan_GetResultString(result));
-            return SDL_FALSE;
+            return SDL_SetError("vkCreateMetalSurfaceEXT failed: %s", SDL_Vulkan_GetResultString(result));;
         }
     } else {
         VkMacOSSurfaceCreateInfoMVK createInfo = {};
@@ -211,9 +209,7 @@ static SDL_bool Cocoa_Vulkan_CreateSurfaceViaMetalView(SDL_VideoDevice *_this,
                                          NULL, surface);
         if (result != VK_SUCCESS) {
             Cocoa_Metal_DestroyView(_this, metalview);
-            SDL_SetError("vkCreateMacOSSurfaceMVK failed: %s",
-                         SDL_Vulkan_GetResultString(result));
-            return SDL_FALSE;
+            return SDL_SetError("vkCreateMacOSSurfaceMVK failed: %s", SDL_Vulkan_GetResultString(result));
         }
     }
 
@@ -227,14 +223,14 @@ static SDL_bool Cocoa_Vulkan_CreateSurfaceViaMetalView(SDL_VideoDevice *_this,
      * knowledge of Metal can proceed. */
     CFBridgingRelease(metalview);
 
-    return SDL_TRUE;
+    return 0;  // success!
 }
 
-SDL_bool Cocoa_Vulkan_CreateSurface(SDL_VideoDevice *_this,
-                                    SDL_Window *window,
-                                    VkInstance instance,
-                                    const struct VkAllocationCallbacks *allocator,
-                                    VkSurfaceKHR *surface)
+int Cocoa_Vulkan_CreateSurface(SDL_VideoDevice *_this,
+                               SDL_Window *window,
+                               VkInstance instance,
+                               const struct VkAllocationCallbacks *allocator,
+                               VkSurfaceKHR *surface)
 {
     PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
         (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
@@ -249,14 +245,12 @@ SDL_bool Cocoa_Vulkan_CreateSurface(SDL_VideoDevice *_this,
     VkResult result;
 
     if (!_this->vulkan_config.loader_handle) {
-        SDL_SetError("Vulkan is not loaded");
-        return SDL_FALSE;
+        return SDL_SetError("Vulkan is not loaded");
     }
 
     if (!vkCreateMetalSurfaceEXT && !vkCreateMacOSSurfaceMVK) {
-        SDL_SetError(VK_EXT_METAL_SURFACE_EXTENSION_NAME " or " VK_MVK_MACOS_SURFACE_EXTENSION_NAME
-                                                         " extensions are not enabled in the Vulkan instance.");
-        return SDL_FALSE;
+        return SDL_SetError(VK_EXT_METAL_SURFACE_EXTENSION_NAME " or " VK_MVK_MACOS_SURFACE_EXTENSION_NAME
+                            " extensions are not enabled in the Vulkan instance.");
     }
 
     if (window->flags & SDL_WINDOW_EXTERNAL) {
@@ -274,9 +268,7 @@ SDL_bool Cocoa_Vulkan_CreateSurface(SDL_VideoDevice *_this,
                 createInfo.pLayer = (CAMetalLayer *)data.sdlContentView.layer;
                 result = vkCreateMetalSurfaceEXT(instance, &createInfo, allocator, surface);
                 if (result != VK_SUCCESS) {
-                    SDL_SetError("vkCreateMetalSurfaceEXT failed: %s",
-                                 SDL_Vulkan_GetResultString(result));
-                    return SDL_FALSE;
+                    return SDL_SetError("vkCreateMetalSurfaceEXT failed: %s", SDL_Vulkan_GetResultString(result));
                 }
             } else {
                 VkMacOSSurfaceCreateInfoMVK createInfo = {};
@@ -287,9 +279,7 @@ SDL_bool Cocoa_Vulkan_CreateSurface(SDL_VideoDevice *_this,
                 result = vkCreateMacOSSurfaceMVK(instance, &createInfo,
                                                  allocator, surface);
                 if (result != VK_SUCCESS) {
-                    SDL_SetError("vkCreateMacOSSurfaceMVK failed: %s",
-                                 SDL_Vulkan_GetResultString(result));
-                    return SDL_FALSE;
+                    return SDL_SetError("vkCreateMacOSSurfaceMVK failed: %s", SDL_Vulkan_GetResultString(result));
                 }
             }
         }
@@ -297,7 +287,7 @@ SDL_bool Cocoa_Vulkan_CreateSurface(SDL_VideoDevice *_this,
         return Cocoa_Vulkan_CreateSurfaceViaMetalView(_this, window, instance, allocator, surface, vkCreateMetalSurfaceEXT, vkCreateMacOSSurfaceMVK);
     }
 
-    return SDL_TRUE;
+    return 0;
 }
 
 void Cocoa_Vulkan_DestroySurface(SDL_VideoDevice *_this,

+ 7 - 7
src/video/kmsdrm/SDL_kmsdrmvulkan.c

@@ -158,11 +158,11 @@ char const* const* KMSDRM_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
 /* KMSDRM_Vulkan_GetInstanceExtensions(), like we do with              */
 /* VK_KHR_DISPLAY_EXTENSION_NAME, which is what we need for x-less VK. */
 /***********************************************************************/
-SDL_bool KMSDRM_Vulkan_CreateSurface(SDL_VideoDevice *_this,
-                                     SDL_Window *window,
-                                     VkInstance instance,
-                                     const struct VkAllocationCallbacks *allocator,
-                                     VkSurfaceKHR *surface)
+int KMSDRM_Vulkan_CreateSurface(SDL_VideoDevice *_this,
+                                SDL_Window *window,
+                                VkInstance instance,
+                                const struct VkAllocationCallbacks *allocator,
+                                VkSurfaceKHR *surface)
 {
     VkPhysicalDevice gpu = NULL;
     uint32_t gpu_count;
@@ -190,7 +190,7 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(SDL_VideoDevice *_this,
     VkDisplayPlaneAlphaFlagBitsKHR alpha_mode = VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR;
 
     VkResult result;
-    SDL_bool ret = SDL_FALSE;
+    SDL_bool ret = -1;
     SDL_bool valid_gpu = SDL_FALSE;
     SDL_bool mode_found = SDL_FALSE;
     SDL_bool plane_supports_display = SDL_FALSE;
@@ -483,7 +483,7 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(SDL_VideoDevice *_this,
         goto clean;
     }
 
-    ret = SDL_TRUE;
+    ret = 0;  // success!
 
 clean:
     if (physical_devices) {

+ 5 - 5
src/video/kmsdrm/SDL_kmsdrmvulkan.h

@@ -38,11 +38,11 @@ int KMSDRM_Vulkan_LoadLibrary(SDL_VideoDevice *_this, const char *path);
 void KMSDRM_Vulkan_UnloadLibrary(SDL_VideoDevice *_this);
 char const* const* KMSDRM_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
                                                        Uint32 *count);
-SDL_bool KMSDRM_Vulkan_CreateSurface(SDL_VideoDevice *_this,
-                                     SDL_Window *window,
-                                     VkInstance instance,
-                                     const struct VkAllocationCallbacks *allocator,
-                                     VkSurfaceKHR *surface);
+int KMSDRM_Vulkan_CreateSurface(SDL_VideoDevice *_this,
+                                SDL_Window *window,
+                                VkInstance instance,
+                                const struct VkAllocationCallbacks *allocator,
+                                VkSurfaceKHR *surface);
 void KMSDRM_Vulkan_DestroySurface(SDL_VideoDevice *_this,
                                   VkInstance instance,
                                   VkSurfaceKHR surface,

+ 26 - 32
src/video/offscreen/SDL_offscreenvulkan.c

@@ -214,44 +214,38 @@ char const *const *OFFSCREEN_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this
     return returnExtensions;
 }
 
-SDL_bool OFFSCREEN_Vulkan_CreateSurface(SDL_VideoDevice *_this,
-                                        SDL_Window *window,
-                                        VkInstance instance,
-                                        const struct VkAllocationCallbacks *allocator,
-                                        VkSurfaceKHR *surface)
+int OFFSCREEN_Vulkan_CreateSurface(SDL_VideoDevice *_this,
+                                   SDL_Window *window,
+                                   VkInstance instance,
+                                   const struct VkAllocationCallbacks *allocator,
+                                   VkSurfaceKHR *surface)
 {
     surface = NULL;
 
-    PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
     if (!_this->vulkan_config.loader_handle) {
-        SDL_SetError("Vulkan is not loaded");
-        return SDL_FALSE;
+        return SDL_SetError("Vulkan is not loaded");
     }
-    vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
-    {
-        PFN_vkCreateHeadlessSurfaceEXT vkCreateHeadlessSurfaceEXT =
-            (PFN_vkCreateHeadlessSurfaceEXT)vkGetInstanceProcAddr(instance,
-                                                                  "vkCreateHeadlessSurfaceEXT");
-        VkHeadlessSurfaceCreateInfoEXT createInfo;
-        VkResult result;
-        if (!vkCreateHeadlessSurfaceEXT) {
-            /*This may be surprising to the consumer when HEADLESS_SURFACE_EXTENSION_REQUIRED_TO_LOAD == 0
-                But this is the tradeoff for allowing offscreen rendering to a buffer to continue working without requiring the extension during driver load*/
-            SDL_SetError(VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME
-                         " extension is not enabled in the Vulkan instance.");
-            return SDL_FALSE;
-        }
-        SDL_zero(createInfo);
-        createInfo.sType = VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT;
-        createInfo.pNext = NULL;
-        createInfo.flags = 0;
-        result = vkCreateHeadlessSurfaceEXT(instance, &createInfo, allocator, surface);
-        if (result != VK_SUCCESS) {
-            SDL_SetError("vkCreateHeadlessSurfaceEXT failed: %s", SDL_Vulkan_GetResultString(result));
-            return SDL_FALSE;
-        }
-        return SDL_TRUE;
+
+    PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
+    PFN_vkCreateHeadlessSurfaceEXT vkCreateHeadlessSurfaceEXT =
+        (PFN_vkCreateHeadlessSurfaceEXT)vkGetInstanceProcAddr(instance, "vkCreateHeadlessSurfaceEXT");
+    VkHeadlessSurfaceCreateInfoEXT createInfo;
+    VkResult result;
+    if (!vkCreateHeadlessSurfaceEXT) {
+        /* This may be surprising to the consumer when HEADLESS_SURFACE_EXTENSION_REQUIRED_TO_LOAD == 0
+           But this is the tradeoff for allowing offscreen rendering to a buffer to continue working without requiring the extension during driver load */
+        return SDL_SetError(VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME
+                            " extension is not enabled in the Vulkan instance.");
+    }
+    SDL_zero(createInfo);
+    createInfo.sType = VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT;
+    createInfo.pNext = NULL;
+    createInfo.flags = 0;
+    result = vkCreateHeadlessSurfaceEXT(instance, &createInfo, allocator, surface);
+    if (result != VK_SUCCESS) {
+        return SDL_SetError("vkCreateHeadlessSurfaceEXT failed: %s", SDL_Vulkan_GetResultString(result));
     }
+    return 0;
 }
 
 void OFFSCREEN_Vulkan_DestroySurface(SDL_VideoDevice *_this,

+ 1 - 1
src/video/offscreen/SDL_offscreenvulkan.h

@@ -30,7 +30,7 @@
 extern int OFFSCREEN_Vulkan_LoadLibrary(SDL_VideoDevice *_this, const char *path);
 extern void OFFSCREEN_Vulkan_UnloadLibrary(SDL_VideoDevice *_this);
 extern char const *const *OFFSCREEN_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this, Uint32 *count);
-extern SDL_bool OFFSCREEN_Vulkan_CreateSurface(SDL_VideoDevice *_this, SDL_Window *window, VkInstance instance, const struct VkAllocationCallbacks *allocator, VkSurfaceKHR *surface);
+extern int OFFSCREEN_Vulkan_CreateSurface(SDL_VideoDevice *_this, SDL_Window *window, VkInstance instance, const struct VkAllocationCallbacks *allocator, VkSurfaceKHR *surface);
 extern void OFFSCREEN_Vulkan_DestroySurface(SDL_VideoDevice *_this, VkInstance instance, VkSurfaceKHR surface, const struct VkAllocationCallbacks *allocator);
 
 #endif /* SDL_VIDEO_DRIVER_OFFSCREEN && SDL_VIDEO_VULKAN */

+ 5 - 5
src/video/uikit/SDL_uikitvulkan.h

@@ -38,11 +38,11 @@ int UIKit_Vulkan_LoadLibrary(SDL_VideoDevice *_this, const char *path);
 void UIKit_Vulkan_UnloadLibrary(SDL_VideoDevice *_this);
 char const* const* UIKit_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
                                                       Uint32 *count);
-SDL_bool UIKit_Vulkan_CreateSurface(SDL_VideoDevice *_this,
-                                    SDL_Window *window,
-                                    VkInstance instance,
-                                    const struct VkAllocationCallbacks *allocator,
-                                    VkSurfaceKHR *surface);
+int UIKit_Vulkan_CreateSurface(SDL_VideoDevice *_this,
+                               SDL_Window *window,
+                               VkInstance instance,
+                               const struct VkAllocationCallbacks *allocator,
+                               VkSurfaceKHR *surface);
 void UIKit_Vulkan_DestroySurface(SDL_VideoDevice *_this,
                                  VkInstance instance,
                                  VkSurfaceKHR surface,

+ 12 - 18
src/video/uikit/SDL_uikitvulkan.m

@@ -179,11 +179,11 @@ char const* const* UIKit_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
     return extensionsForUIKit;
 }
 
-SDL_bool UIKit_Vulkan_CreateSurface(SDL_VideoDevice *_this,
-                                    SDL_Window *window,
-                                    VkInstance instance,
-                                    const struct VkAllocationCallbacks *allocator,
-                                    VkSurfaceKHR *surface)
+int UIKit_Vulkan_CreateSurface(SDL_VideoDevice *_this,
+                               SDL_Window *window,
+                               VkInstance instance,
+                               const struct VkAllocationCallbacks *allocator,
+                               VkSurfaceKHR *surface)
 {
     PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
         (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
@@ -199,19 +199,17 @@ SDL_bool UIKit_Vulkan_CreateSurface(SDL_VideoDevice *_this,
     SDL_MetalView metalview;
 
     if (!_this->vulkan_config.loader_handle) {
-        SDL_SetError("Vulkan is not loaded");
-        return SDL_FALSE;
+        return SDL_SetError("Vulkan is not loaded");
     }
 
     if (!vkCreateMetalSurfaceEXT && !vkCreateIOSSurfaceMVK) {
-        SDL_SetError(VK_EXT_METAL_SURFACE_EXTENSION_NAME " or " VK_MVK_IOS_SURFACE_EXTENSION_NAME
-                                                         " extensions are not enabled in the Vulkan instance.");
-        return SDL_FALSE;
+        return SDL_SetError(VK_EXT_METAL_SURFACE_EXTENSION_NAME " or " VK_MVK_IOS_SURFACE_EXTENSION_NAME
+                            " extensions are not enabled in the Vulkan instance.");
     }
 
     metalview = UIKit_Metal_CreateView(_this, window);
     if (metalview == NULL) {
-        return SDL_FALSE;
+        return -1;
     }
 
     if (vkCreateMetalSurfaceEXT) {
@@ -224,9 +222,7 @@ SDL_bool UIKit_Vulkan_CreateSurface(SDL_VideoDevice *_this,
         result = vkCreateMetalSurfaceEXT(instance, &createInfo, allocator, surface);
         if (result != VK_SUCCESS) {
             UIKit_Metal_DestroyView(_this, metalview);
-            SDL_SetError("vkCreateMetalSurfaceEXT failed: %s",
-                         SDL_Vulkan_GetResultString(result));
-            return SDL_FALSE;
+            return SDL_SetError("vkCreateMetalSurfaceEXT failed: %s", SDL_Vulkan_GetResultString(result));
         }
     } else {
         VkIOSSurfaceCreateInfoMVK createInfo = {};
@@ -238,9 +234,7 @@ SDL_bool UIKit_Vulkan_CreateSurface(SDL_VideoDevice *_this,
                                        allocator, surface);
         if (result != VK_SUCCESS) {
             UIKit_Metal_DestroyView(_this, metalview);
-            SDL_SetError("vkCreateIOSSurfaceMVK failed: %s",
-                         SDL_Vulkan_GetResultString(result));
-            return SDL_FALSE;
+            return SDL_SetError("vkCreateIOSSurfaceMVK failed: %s", SDL_Vulkan_GetResultString(result));
         }
     }
 
@@ -254,7 +248,7 @@ SDL_bool UIKit_Vulkan_CreateSurface(SDL_VideoDevice *_this,
      * knowledge of Metal can proceed. */
     CFBridgingRelease(metalview);
 
-    return SDL_TRUE;
+    return 0;
 }
 
 void UIKit_Vulkan_DestroySurface(SDL_VideoDevice *_this,

+ 6 - 7
src/video/vivante/SDL_vivantevulkan.c

@@ -129,15 +129,14 @@ char const* const* VIVANTE_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
     return extensionsForVivante;
 }
 
-SDL_bool VIVANTE_Vulkan_CreateSurface(SDL_VideoDevice *_this,
-                                      SDL_Window *window,
-                                      VkInstance instance,
-                                      const struct VkAllocationCallbacks *allocator,
-                                      VkSurfaceKHR *surface)
+int 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_SetError("Vulkan is not loaded");
     }
     return SDL_Vulkan_Display_CreateSurface(_this->vulkan_config.vkGetInstanceProcAddr, instance, allocator, surface);
 }

+ 5 - 5
src/video/vivante/SDL_vivantevulkan.h

@@ -37,11 +37,11 @@ int VIVANTE_Vulkan_LoadLibrary(SDL_VideoDevice *_this, const char *path);
 void VIVANTE_Vulkan_UnloadLibrary(SDL_VideoDevice *_this);
 char const* const* VIVANTE_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
                                                         Uint32 *count);
-SDL_bool VIVANTE_Vulkan_CreateSurface(SDL_VideoDevice *_this,
-                                      SDL_Window *window,
-                                      VkInstance instance,
-                                      const struct VkAllocationCallbacks *allocator,
-                                      VkSurfaceKHR *surface);
+int VIVANTE_Vulkan_CreateSurface(SDL_VideoDevice *_this,
+                                 SDL_Window *window,
+                                 VkInstance instance,
+                                 const struct VkAllocationCallbacks *allocator,
+                                 VkSurfaceKHR *surface);
 void VIVANTE_Vulkan_DestroySurface(SDL_VideoDevice *_this,
                                    VkInstance instance,
                                    VkSurfaceKHR surface,

+ 10 - 14
src/video/wayland/SDL_waylandvulkan.c

@@ -128,11 +128,11 @@ char const* const* Wayland_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
     return extensionsForWayland;
 }
 
-SDL_bool Wayland_Vulkan_CreateSurface(SDL_VideoDevice *_this,
-                                      SDL_Window *window,
-                                      VkInstance instance,
-                                      const struct VkAllocationCallbacks *allocator,
-                                      VkSurfaceKHR *surface)
+int Wayland_Vulkan_CreateSurface(SDL_VideoDevice *_this,
+                                 SDL_Window *window,
+                                 VkInstance instance,
+                                 const struct VkAllocationCallbacks *allocator,
+                                 VkSurfaceKHR *surface)
 {
     SDL_WindowData *windowData = window->driverdata;
     PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
@@ -145,14 +145,12 @@ SDL_bool Wayland_Vulkan_CreateSurface(SDL_VideoDevice *_this,
     VkResult result;
 
     if (!_this->vulkan_config.loader_handle) {
-        SDL_SetError("Vulkan is not loaded");
-        return SDL_FALSE;
+        return SDL_SetError("Vulkan is not loaded");
     }
 
     if (!vkCreateWaylandSurfaceKHR) {
-        SDL_SetError(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME
-                     " extension is not enabled in the Vulkan instance.");
-        return SDL_FALSE;
+        return SDL_SetError(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME
+                            " extension is not enabled in the Vulkan instance.");
     }
     SDL_zero(createInfo);
     createInfo.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR;
@@ -162,11 +160,9 @@ SDL_bool Wayland_Vulkan_CreateSurface(SDL_VideoDevice *_this,
     createInfo.surface = windowData->surface;
     result = vkCreateWaylandSurfaceKHR(instance, &createInfo, allocator, surface);
     if (result != VK_SUCCESS) {
-        SDL_SetError("vkCreateWaylandSurfaceKHR failed: %s",
-                     SDL_Vulkan_GetResultString(result));
-        return SDL_FALSE;
+        return SDL_SetError("vkCreateWaylandSurfaceKHR failed: %s", SDL_Vulkan_GetResultString(result));
     }
-    return SDL_TRUE;
+    return 0;
 }
 
 void Wayland_Vulkan_DestroySurface(SDL_VideoDevice *_this,

+ 1 - 1
src/video/wayland/SDL_waylandvulkan.h

@@ -37,7 +37,7 @@ int Wayland_Vulkan_LoadLibrary(SDL_VideoDevice *_this, const char *path);
 void Wayland_Vulkan_UnloadLibrary(SDL_VideoDevice *_this);
 char const* const* Wayland_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
                                                         Uint32 *count);
-SDL_bool Wayland_Vulkan_CreateSurface(SDL_VideoDevice *_this,
+int Wayland_Vulkan_CreateSurface(SDL_VideoDevice *_this,
                                       SDL_Window *window,
                                       VkInstance instance,
                                       const struct VkAllocationCallbacks *allocator,

+ 10 - 14
src/video/windows/SDL_windowsvulkan.c

@@ -120,11 +120,11 @@ char const* const* WIN_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
     return extensionsForWin32;
 }
 
-SDL_bool WIN_Vulkan_CreateSurface(SDL_VideoDevice *_this,
-                                  SDL_Window *window,
-                                  VkInstance instance,
-                                  const struct VkAllocationCallbacks *allocator,
-                                  VkSurfaceKHR *surface)
+int WIN_Vulkan_CreateSurface(SDL_VideoDevice *_this,
+                             SDL_Window *window,
+                             VkInstance instance,
+                             const struct VkAllocationCallbacks *allocator,
+                             VkSurfaceKHR *surface)
 {
     SDL_WindowData *windowData = window->driverdata;
     PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
@@ -137,14 +137,12 @@ SDL_bool WIN_Vulkan_CreateSurface(SDL_VideoDevice *_this,
     VkResult result;
 
     if (!_this->vulkan_config.loader_handle) {
-        SDL_SetError("Vulkan is not loaded");
-        return SDL_FALSE;
+        return SDL_SetError("Vulkan is not loaded");
     }
 
     if (!vkCreateWin32SurfaceKHR) {
-        SDL_SetError(VK_KHR_WIN32_SURFACE_EXTENSION_NAME
-                     " extension is not enabled in the Vulkan instance.");
-        return SDL_FALSE;
+        return SDL_SetError(VK_KHR_WIN32_SURFACE_EXTENSION_NAME
+                            " extension is not enabled in the Vulkan instance.");
     }
     createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
     createInfo.pNext = NULL;
@@ -153,11 +151,9 @@ SDL_bool WIN_Vulkan_CreateSurface(SDL_VideoDevice *_this,
     createInfo.hwnd = windowData->hwnd;
     result = vkCreateWin32SurfaceKHR(instance, &createInfo, allocator, surface);
     if (result != VK_SUCCESS) {
-        SDL_SetError("vkCreateWin32SurfaceKHR failed: %s",
-                     SDL_Vulkan_GetResultString(result));
-        return SDL_FALSE;
+        return SDL_SetError("vkCreateWin32SurfaceKHR failed: %s", SDL_Vulkan_GetResultString(result));
     }
-    return SDL_TRUE;
+    return 0;
 }
 
 void WIN_Vulkan_DestroySurface(SDL_VideoDevice *_this,

+ 5 - 5
src/video/windows/SDL_windowsvulkan.h

@@ -37,11 +37,11 @@ int WIN_Vulkan_LoadLibrary(SDL_VideoDevice *_this, const char *path);
 void WIN_Vulkan_UnloadLibrary(SDL_VideoDevice *_this);
 char const* const* WIN_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
                                                     Uint32 *count);
-SDL_bool WIN_Vulkan_CreateSurface(SDL_VideoDevice *_this,
-                                  SDL_Window *window,
-                                  VkInstance instance,
-                                  const struct VkAllocationCallbacks *allocator,
-                                  VkSurfaceKHR *surface);
+int WIN_Vulkan_CreateSurface(SDL_VideoDevice *_this,
+                             SDL_Window *window,
+                             VkInstance instance,
+                             const struct VkAllocationCallbacks *allocator,
+                             VkSurfaceKHR *surface);
 void WIN_Vulkan_DestroySurface(SDL_VideoDevice *_this,
                                VkInstance instance,
                                VkSurfaceKHR surface,

+ 13 - 21
src/video/x11/SDL_x11vulkan.c

@@ -167,18 +167,17 @@ 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)
+int X11_Vulkan_CreateSurface(SDL_VideoDevice *_this,
+                             SDL_Window *window,
+                             VkInstance instance,
+                             const struct VkAllocationCallbacks *allocator,
+                             VkSurfaceKHR *surface)
 {
     SDL_VideoData *videoData = _this->driverdata;
     SDL_WindowData *windowData = window->driverdata;
     PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
     if (!_this->vulkan_config.loader_handle) {
-        SDL_SetError("Vulkan is not loaded");
-        return SDL_FALSE;
+        return SDL_SetError("Vulkan is not loaded");
     }
     vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
     if (videoData->vulkan_xlib_xcb_library) {
@@ -188,24 +187,19 @@ SDL_bool X11_Vulkan_CreateSurface(SDL_VideoDevice *_this,
         VkXcbSurfaceCreateInfoKHR createInfo;
         VkResult result;
         if (!vkCreateXcbSurfaceKHR) {
-            SDL_SetError(VK_KHR_XCB_SURFACE_EXTENSION_NAME
-                         " extension is not enabled in the Vulkan instance.");
-            return SDL_FALSE;
+            return SDL_SetError(VK_KHR_XCB_SURFACE_EXTENSION_NAME " extension is not enabled in the Vulkan instance.");
         }
         SDL_zero(createInfo);
         createInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
         createInfo.connection = videoData->vulkan_XGetXCBConnection(videoData->display);
         if (!createInfo.connection) {
-            SDL_SetError("XGetXCBConnection failed");
-            return SDL_FALSE;
+            return SDL_SetError("XGetXCBConnection failed");
         }
         createInfo.window = (xcb_window_t)windowData->xwindow;
         result = vkCreateXcbSurfaceKHR(instance, &createInfo, allocator, surface);
         if (result != VK_SUCCESS) {
-            SDL_SetError("vkCreateXcbSurfaceKHR failed: %s", SDL_Vulkan_GetResultString(result));
-            return SDL_FALSE;
+            return SDL_SetError("vkCreateXcbSurfaceKHR failed: %s", SDL_Vulkan_GetResultString(result));
         }
-        return SDL_TRUE;
     } else {
         PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHR =
             (PFN_vkCreateXlibSurfaceKHR)vkGetInstanceProcAddr(instance,
@@ -213,9 +207,7 @@ SDL_bool X11_Vulkan_CreateSurface(SDL_VideoDevice *_this,
         VkXlibSurfaceCreateInfoKHR createInfo;
         VkResult result;
         if (!vkCreateXlibSurfaceKHR) {
-            SDL_SetError(VK_KHR_XLIB_SURFACE_EXTENSION_NAME
-                         " extension is not enabled in the Vulkan instance.");
-            return SDL_FALSE;
+            return SDL_SetError(VK_KHR_XLIB_SURFACE_EXTENSION_NAME " extension is not enabled in the Vulkan instance.");
         }
         SDL_zero(createInfo);
         createInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
@@ -223,11 +215,11 @@ SDL_bool X11_Vulkan_CreateSurface(SDL_VideoDevice *_this,
         createInfo.window = (xcb_window_t)windowData->xwindow;
         result = vkCreateXlibSurfaceKHR(instance, &createInfo, allocator, surface);
         if (result != VK_SUCCESS) {
-            SDL_SetError("vkCreateXlibSurfaceKHR failed: %s", SDL_Vulkan_GetResultString(result));
-            return SDL_FALSE;
+            return SDL_SetError("vkCreateXlibSurfaceKHR failed: %s", SDL_Vulkan_GetResultString(result));
         }
-        return SDL_TRUE;
     }
+
+    return 0;  // success!
 }
 
 void X11_Vulkan_DestroySurface(SDL_VideoDevice *_this,

+ 5 - 5
src/video/x11/SDL_x11vulkan.h

@@ -34,11 +34,11 @@ int X11_Vulkan_LoadLibrary(SDL_VideoDevice *_this, const char *path);
 void X11_Vulkan_UnloadLibrary(SDL_VideoDevice *_this);
 char const* const* X11_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
                                                     Uint32 *count);
-SDL_bool X11_Vulkan_CreateSurface(SDL_VideoDevice *_this,
-                                  SDL_Window *window,
-                                  VkInstance instance,
-                                  const struct VkAllocationCallbacks *allocator,
-                                  VkSurfaceKHR *surface);
+int X11_Vulkan_CreateSurface(SDL_VideoDevice *_this,
+                             SDL_Window *window,
+                             VkInstance instance,
+                             const struct VkAllocationCallbacks *allocator,
+                             VkSurfaceKHR *surface);
 void X11_Vulkan_DestroySurface(SDL_VideoDevice *_this,
                                VkInstance instance,
                                VkSurfaceKHR surface,

+ 1 - 4
test/testffmpeg_vulkan.c

@@ -253,10 +253,7 @@ static int createInstance(VulkanVideoContext *context)
 
 static int createSurface(VulkanVideoContext *context, SDL_Window *window)
 {
-    if (!SDL_Vulkan_CreateSurface(window,
-                                  context->instance,
-                                  NULL,
-                                  &context->surface)) {
+    if (SDL_Vulkan_CreateSurface(window, context->instance, NULL, &context->surface) < 0) {
         context->surface = VK_NULL_HANDLE;
         return -1;
     }

+ 1 - 4
test/testvulkan.c

@@ -259,10 +259,7 @@ static void loadInstanceFunctions(void)
 
 static void createSurface(void)
 {
-    if (!SDL_Vulkan_CreateSurface(vulkanContext->window,
-                                  vulkanContext->instance,
-                                  NULL,
-                                  &vulkanContext->surface)) {
+    if (SDL_Vulkan_CreateSurface(vulkanContext->window, vulkanContext->instance, NULL, &vulkanContext->surface) < 0) {
         vulkanContext->surface = VK_NULL_HANDLE;
         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_Vulkan_CreateSurface(): %s\n", SDL_GetError());
         quit(2);