vulkan: Make SDL_Vulkan_GetInstanceExtensions more robust.

Now it handles NULL `count` params at the higher level, and doesn't explode if
a backend doesn't implement it.
This commit is contained in:
Ryan C. Gordon
2026-07-09 17:20:44 -04:00
parent bb74b618ac
commit e7be7d844a
10 changed files with 42 additions and 60 deletions

View File

@@ -6315,6 +6315,17 @@ void SDL_Vulkan_UnloadLibrary(void)
char const * const *SDL_Vulkan_GetInstanceExtensions(Uint32 *count)
{
Uint32 tmpcount = 0;
if (!count) {
count = &tmpcount;
}
if (!_this->Vulkan_GetInstanceExtensions) {
*count = 0;
SDL_Unsupported();
return NULL;
}
return _this->Vulkan_GetInstanceExtensions(_this, count);
}

View File

@@ -115,9 +115,7 @@ char const * const *Android_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
static const char *const extensionsForAndroid[] = {
VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_ANDROID_SURFACE_EXTENSION_NAME
};
if (count) {
*count = SDL_arraysize(extensionsForAndroid);
}
*count = SDL_arraysize(extensionsForAndroid);
return extensionsForAndroid;
}

View File

@@ -168,9 +168,7 @@ char const * const *Cocoa_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this, U
static const char *const extensionsForCocoa[] = {
VK_KHR_SURFACE_EXTENSION_NAME, VK_EXT_METAL_SURFACE_EXTENSION_NAME
};
if(count) {
*count = SDL_arraysize(extensionsForCocoa);
}
*count = SDL_arraysize(extensionsForCocoa);
return extensionsForCocoa;
}

View File

@@ -152,9 +152,7 @@ char const * const *KMSDRM_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
static const char *const extensionsForKMSDRM[] = {
VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_DISPLAY_EXTENSION_NAME
};
if (count) {
*count = SDL_arraysize(extensionsForKMSDRM);
}
*count = SDL_arraysize(extensionsForKMSDRM);
return extensionsForKMSDRM;
}

View File

@@ -179,45 +179,35 @@ void OFFSCREEN_Vulkan_UnloadLibrary(SDL_VideoDevice *_this)
char const *const *OFFSCREEN_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
Uint32 *count)
{
static const char *const returnExtensions[] = { VK_KHR_SURFACE_EXTENSION_NAME, VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME };
*count = SDL_arraysize(returnExtensions);
#if (HEADLESS_SURFACE_EXTENSION_REQUIRED_TO_LOAD == 0)
VkExtensionProperties *enumerateExtensions = NULL;
Uint32 enumerateExtensionCount = 0;
bool hasHeadlessSurfaceExtension = false;
Uint32 i;
/* In optional mode, only return VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME if it's already supported by the instance
There's probably a better way to cache the presence of the extension during OFFSCREEN_Vulkan_LoadLibrary().
But both SDL_VideoData and SDL_VideoDevice::vulkan_config seem like I'd need to touch a bunch of code to do properly.
And I want a smaller footprint for the first pass*/
if ( _this->vulkan_config.vkEnumerateInstanceExtensionProperties ) {
enumerateExtensions = SDL_Vulkan_CreateInstanceExtensionsList((PFN_vkEnumerateInstanceExtensionProperties) _this->vulkan_config.vkEnumerateInstanceExtensionProperties, &enumerateExtensionCount);
for (i = 0; i < enumerateExtensionCount; i++) {
if (SDL_strcmp(VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME, enumerateExtensions[i].extensionName) == 0) {
hasHeadlessSurfaceExtension = true;
}
}
SDL_free(enumerateExtensions);
}
if (!hasHeadlessSurfaceExtension) {
(*count)--; // assumes VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME is last
}
#endif
static const char *const returnExtensions[] = { VK_KHR_SURFACE_EXTENSION_NAME, VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME };
if (count) {
# if (HEADLESS_SURFACE_EXTENSION_REQUIRED_TO_LOAD == 0)
{
/* In optional mode, only return VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME if it's already supported by the instance
There's probably a better way to cache the presence of the extension during OFFSCREEN_Vulkan_LoadLibrary().
But both SDL_VideoData and SDL_VideoDevice::vulkan_config seem like I'd need to touch a bunch of code to do properly.
And I want a smaller footprint for the first pass*/
if ( _this->vulkan_config.vkEnumerateInstanceExtensionProperties ) {
enumerateExtensions = SDL_Vulkan_CreateInstanceExtensionsList(
(PFN_vkEnumerateInstanceExtensionProperties)
_this->vulkan_config.vkEnumerateInstanceExtensionProperties,
&enumerateExtensionCount);
for (i = 0; i < enumerateExtensionCount; i++) {
if (SDL_strcmp(VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME, enumerateExtensions[i].extensionName) == 0) {
hasHeadlessSurfaceExtension = true;
}
}
SDL_free(enumerateExtensions);
}
if ( hasHeadlessSurfaceExtension == true ) {
*count = SDL_arraysize(returnExtensions);
} else {
*count = SDL_arraysize(returnExtensions) - 1; // assumes VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME is last
}
}
# else
{
*count = SDL_arraysize(returnExtensions);
}
# endif
}
return returnExtensions;
}

View File

@@ -172,9 +172,7 @@ char const * const *UIKit_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this, U
static const char *const extensionsForUIKit[] = {
VK_KHR_SURFACE_EXTENSION_NAME, VK_EXT_METAL_SURFACE_EXTENSION_NAME
};
if(count) {
*count = SDL_arraysize(extensionsForUIKit);
}
*count = SDL_arraysize(extensionsForUIKit);
return extensionsForUIKit;
}

View File

@@ -122,9 +122,7 @@ char const * const *VIVANTE_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
static const char *const extensionsForVivante[] = {
VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_DISPLAY_EXTENSION_NAME
};
if (count) {
*count = SDL_arraysize(extensionsForVivante);
}
*count = SDL_arraysize(extensionsForVivante);
return extensionsForVivante;
}

View File

@@ -128,10 +128,7 @@ char const * const *Wayland_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME
};
if (count) {
*count = SDL_arraysize(extensionsForWayland);
}
*count = SDL_arraysize(extensionsForWayland);
return extensionsForWayland;
}

View File

@@ -115,9 +115,7 @@ char const * const *WIN_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this, Uin
static const char *const extensionsForWin32[] = {
VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WIN32_SURFACE_EXTENSION_NAME
};
if (count) {
*count = SDL_arraysize(extensionsForWin32);
}
*count = SDL_arraysize(extensionsForWin32);
return extensionsForWin32;
}

View File

@@ -166,18 +166,14 @@ char const * const *X11_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this, Uin
VK_KHR_SURFACE_EXTENSION_NAME,
VK_KHR_XCB_SURFACE_EXTENSION_NAME,
};
if(count) {
*count = SDL_arraysize(extensionsForXCB);
}
*count = SDL_arraysize(extensionsForXCB);
return extensionsForXCB;
} else {
static const char *const extensionsForXlib[] = {
VK_KHR_SURFACE_EXTENSION_NAME,
VK_KHR_XLIB_SURFACE_EXTENSION_NAME,
};
if(count) {
*count = SDL_arraysize(extensionsForXlib);
}
*count = SDL_arraysize(extensionsForXlib);
return extensionsForXlib;
}
}