Add SDL_Vulkan_GetPresentationSupport

This commit is contained in:
Ethan Lee 2024-07-11 12:58:28 -04:00
parent 186fec2560
commit 1993ef664e
15 changed files with 167 additions and 0 deletions

View File

@ -51,6 +51,7 @@ extern "C" {
#endif
VK_DEFINE_HANDLE(VkInstance)
VK_DEFINE_HANDLE(VkPhysicalDevice)
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR)
struct VkAllocationCallbacks;
@ -211,6 +212,25 @@ extern SDL_DECLSPEC void SDLCALL SDL_Vulkan_DestroySurface(VkInstance instance,
VkSurfaceKHR surface,
const struct VkAllocationCallbacks *allocator);
/**
* Query support for presentation via a given physical device and queue family.
*
* The `instance` must have been created with extensions returned by
* SDL_Vulkan_GetInstanceExtensions() enabled.
*
* \param instance the Vulkan instance handle.
* \param physicalDevice a valid Vulkan physical device handle.
* \param queueFamilyIndex a valid queue family index for the given physical device.
* \returns SDL_TRUE if supported, SDL_FALSE if unsupported or an error occurred.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_Vulkan_GetInstanceExtensions
*/
extern SDL_DECLSPEC SDL_bool SDLCALL SDL_Vulkan_GetPresentationSupport(VkInstance instance,
VkPhysicalDevice physicalDevice,
Uint32 queueFamilyIndex);
/* @} *//* Vulkan support functions */
/* Ends C function definitions when using C++ */

View File

@ -1045,6 +1045,7 @@ SDL3_0.0.0 {
SDL_wcsnstr;
SDL_wcsstr;
SDL_wcstol;
SDL_Vulkan_GetPresentationSupport;
# extra symbols go here (don't modify this line)
local: *;
};

View File

@ -1070,3 +1070,4 @@
#define SDL_wcsnstr SDL_wcsnstr_REAL
#define SDL_wcsstr SDL_wcsstr_REAL
#define SDL_wcstol SDL_wcstol_REAL
#define SDL_Vulkan_GetPresentationSupport SDL_Vulkan_GetPresentationSupport_REAL

View File

@ -1076,3 +1076,4 @@ SDL_DYNAPI_PROC(size_t,SDL_wcsnlen,(const wchar_t *a, size_t b),(a,b),return)
SDL_DYNAPI_PROC(wchar_t*,SDL_wcsnstr,(const wchar_t *a, const wchar_t *b, size_t c),(a,b,c),return)
SDL_DYNAPI_PROC(wchar_t*,SDL_wcsstr,(const wchar_t *a, const wchar_t *b),(a,b),return)
SDL_DYNAPI_PROC(long,SDL_wcstol,(const wchar_t *a, wchar_t **b, int c),(a,b,c),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_Vulkan_GetPresentationSupport,(VkInstance a, VkPhysicalDevice b, Uint32 c),(a,b,c),return)

View File

@ -304,6 +304,7 @@ struct SDL_VideoDevice
char const* const* (*Vulkan_GetInstanceExtensions)(SDL_VideoDevice *_this, Uint32 *count);
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);
SDL_bool (*Vulkan_GetPresentationSupport)(SDL_VideoDevice *_this, VkInstance instance, VkPhysicalDevice physicalDevice, Uint32 queueFamilyIndex);
/* * * */
/*

View File

@ -5526,6 +5526,24 @@ void SDL_Vulkan_DestroySurface(VkInstance instance,
}
}
SDL_bool SDL_Vulkan_GetPresentationSupport(VkInstance instance,
VkPhysicalDevice physicalDevice,
Uint32 queueFamilyIndex)
{
if (_this && instance && physicalDevice) {
if (_this->Vulkan_GetPresentationSupport) {
return _this->Vulkan_GetPresentationSupport(_this, instance, physicalDevice, queueFamilyIndex);
}
/* If the backend does not have this function then it does not have a
* WSI function to query it; in other words it's not necessary to check
* as it is always supported.
*/
return SDL_TRUE;
}
return SDL_FALSE;
}
SDL_MetalView SDL_Metal_CreateView(SDL_Window *window)
{
CHECK_WINDOW_MAGIC(window, NULL);

View File

@ -519,6 +519,7 @@ static SDL_VideoDevice *Wayland_CreateDevice(void)
device->Vulkan_GetInstanceExtensions = Wayland_Vulkan_GetInstanceExtensions;
device->Vulkan_CreateSurface = Wayland_Vulkan_CreateSurface;
device->Vulkan_DestroySurface = Wayland_Vulkan_DestroySurface;
device->Vulkan_GetPresentationSupport = Wayland_Vulkan_GetPresentationSupport;
#endif
device->free = Wayland_DeleteDevice;

View File

@ -175,4 +175,32 @@ void Wayland_Vulkan_DestroySurface(SDL_VideoDevice *_this,
}
}
SDL_bool Wayland_Vulkan_GetPresentationSupport(SDL_VideoDevice *_this,
VkInstance instance,
VkPhysicalDevice physicalDevice,
Uint32 queueFamilyIndex)
{
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
(PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR vkGetPhysicalDeviceWaylandPresentationSupportKHR =
(PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)vkGetInstanceProcAddr(
instance,
"vkGetPhysicalDeviceWaylandPresentationSupportKHR");
if (!_this->vulkan_config.loader_handle) {
SDL_SetError("Vulkan is not loaded");
return SDL_FALSE;
}
if (!vkGetPhysicalDeviceWaylandPresentationSupportKHR) {
SDL_SetError(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME
" extension is not enabled in the Vulkan instance.");
return SDL_FALSE;
}
return vkGetPhysicalDeviceWaylandPresentationSupportKHR(physicalDevice,
queueFamilyIndex,
_this->driverdata->display);
}
#endif

View File

@ -46,6 +46,10 @@ void Wayland_Vulkan_DestroySurface(SDL_VideoDevice *_this,
VkInstance instance,
VkSurfaceKHR surface,
const struct VkAllocationCallbacks *allocator);
SDL_bool Wayland_Vulkan_GetPresentationSupport(SDL_VideoDevice *_this,
VkInstance instance,
VkPhysicalDevice physicalDevice,
Uint32 queueFamilyIndex);
#endif

View File

@ -263,6 +263,7 @@ static SDL_VideoDevice *WIN_CreateDevice(void)
device->Vulkan_GetInstanceExtensions = WIN_Vulkan_GetInstanceExtensions;
device->Vulkan_CreateSurface = WIN_Vulkan_CreateSurface;
device->Vulkan_DestroySurface = WIN_Vulkan_DestroySurface;
device->Vulkan_GetPresentationSupport = WIN_Vulkan_GetPresentationSupport;
#endif
#if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)

View File

@ -166,4 +166,31 @@ void WIN_Vulkan_DestroySurface(SDL_VideoDevice *_this,
}
}
SDL_bool WIN_Vulkan_GetPresentationSupport(SDL_VideoDevice *_this,
VkInstance instance,
VkPhysicalDevice physicalDevice,
Uint32 queueFamilyIndex)
{
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
(PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR vkGetPhysicalDeviceWin32PresentationSupportKHR =
(PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)vkGetInstanceProcAddr(
instance,
"vkGetPhysicalDeviceWin32PresentationSupportKHR");
if (!_this->vulkan_config.loader_handle) {
SDL_SetError("Vulkan is not loaded");
return SDL_FALSE;
}
if (!vkGetPhysicalDeviceWin32PresentationSupportKHR) {
SDL_SetError(VK_KHR_WIN32_SURFACE_EXTENSION_NAME
" extension is not enabled in the Vulkan instance.");
return SDL_FALSE;
}
return vkGetPhysicalDeviceWin32PresentationSupportKHR(physicalDevice,
queueFamilyIndex);
}
#endif

View File

@ -46,6 +46,10 @@ void WIN_Vulkan_DestroySurface(SDL_VideoDevice *_this,
VkInstance instance,
VkSurfaceKHR surface,
const struct VkAllocationCallbacks *allocator);
SDL_bool WIN_Vulkan_GetPresentationSupport(SDL_VideoDevice *_this,
VkInstance instance,
VkPhysicalDevice physicalDevice,
Uint32 queueFamilyIndex);
#endif

View File

@ -280,6 +280,7 @@ static SDL_VideoDevice *X11_CreateDevice(void)
device->Vulkan_GetInstanceExtensions = X11_Vulkan_GetInstanceExtensions;
device->Vulkan_CreateSurface = X11_Vulkan_CreateSurface;
device->Vulkan_DestroySurface = X11_Vulkan_DestroySurface;
device->Vulkan_GetPresentationSupport = X11_Vulkan_GetPresentationSupport;
#endif
#ifdef SDL_USE_LIBDBUS

View File

@ -232,4 +232,59 @@ void X11_Vulkan_DestroySurface(SDL_VideoDevice *_this,
}
}
SDL_bool X11_Vulkan_GetPresentationSupport(SDL_VideoDevice *_this,
VkInstance instance,
VkPhysicalDevice physicalDevice,
Uint32 queueFamilyIndex)
{
SDL_VideoData *videoData = _this->driverdata;
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
const char *forced_visual_id;
VisualID visualid;
if (!_this->vulkan_config.loader_handle) {
return SDL_SetError("Vulkan is not loaded");
}
vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
forced_visual_id = SDL_GetHint(SDL_HINT_VIDEO_X11_WINDOW_VISUALID);
if (forced_visual_id) {
visualid = SDL_strtol(forced_visual_id, NULL, 0);
} else {
visualid = X11_XVisualIDFromVisual(DefaultVisual(videoData->display, DefaultScreen(videoData->display)));
}
if (videoData->vulkan_xlib_xcb_library) {
PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR vkGetPhysicalDeviceXcbPresentationSupportKHR =
(PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)vkGetInstanceProcAddr(
instance,
"vkGetPhysicalDeviceXcbPresentationSupportKHR");
if (!vkGetPhysicalDeviceXcbPresentationSupportKHR) {
SDL_SetError(VK_KHR_XCB_SURFACE_EXTENSION_NAME " extension is not enabled in the Vulkan instance.");
return SDL_FALSE;
}
return vkGetPhysicalDeviceXcbPresentationSupportKHR(physicalDevice,
queueFamilyIndex,
videoData->vulkan_XGetXCBConnection(videoData->display),
visualid);
} else {
PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR vkGetPhysicalDeviceXlibPresentationSupportKHR =
(PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)vkGetInstanceProcAddr(
instance,
"vkGetPhysicalDeviceXlibPresentationSupportKHR");
if (!vkGetPhysicalDeviceXlibPresentationSupportKHR) {
SDL_SetError(VK_KHR_XLIB_SURFACE_EXTENSION_NAME " extension is not enabled in the Vulkan instance.");
return SDL_FALSE;
}
return vkGetPhysicalDeviceXlibPresentationSupportKHR(physicalDevice,
queueFamilyIndex,
videoData->display,
visualid);
}
}
#endif

View File

@ -43,6 +43,10 @@ void X11_Vulkan_DestroySurface(SDL_VideoDevice *_this,
VkInstance instance,
VkSurfaceKHR surface,
const struct VkAllocationCallbacks *allocator);
SDL_bool X11_Vulkan_GetPresentationSupport(SDL_VideoDevice *_this,
VkInstance instance,
VkPhysicalDevice physicalDevice,
Uint32 queueFamilyIndex);
#endif