mirror of https://github.com/encounter/SDL.git
cocoa/uikit: Support VK_EXT_metal_surface
Uses VK_EXT_metal_surface (vkCreateMetalSurfaceEXT) when possible, otherwise falls back to the obsoleted VK_MVK_macos_surface and VK_MVK_ios_surface. Fixes #3906
This commit is contained in:
parent
b0a27cb1de
commit
df8b82f8c8
|
@ -34,12 +34,14 @@
|
|||
#define VK_USE_PLATFORM_ANDROID_KHR
|
||||
#endif
|
||||
#if SDL_VIDEO_DRIVER_COCOA
|
||||
#define VK_USE_PLATFORM_METAL_EXT
|
||||
#define VK_USE_PLATFORM_MACOS_MVK
|
||||
#endif
|
||||
#if SDL_VIDEO_DRIVER_DIRECTFB
|
||||
#define VK_USE_PLATFORM_DIRECTFB_EXT
|
||||
#endif
|
||||
#if SDL_VIDEO_DRIVER_UIKIT
|
||||
#define VK_USE_PLATFORM_METAL_EXT
|
||||
#define VK_USE_PLATFORM_IOS_MVK
|
||||
#endif
|
||||
#if SDL_VIDEO_DRIVER_WAYLAND
|
||||
|
|
|
@ -53,6 +53,7 @@ int Cocoa_Vulkan_LoadLibrary(_THIS, const char *path)
|
|||
VkExtensionProperties *extensions = NULL;
|
||||
Uint32 extensionCount = 0;
|
||||
SDL_bool hasSurfaceExtension = SDL_FALSE;
|
||||
SDL_bool hasMetalSurfaceExtension = SDL_FALSE;
|
||||
SDL_bool hasMacOSSurfaceExtension = SDL_FALSE;
|
||||
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;
|
||||
|
||||
|
@ -130,6 +131,8 @@ int Cocoa_Vulkan_LoadLibrary(_THIS, const char *path)
|
|||
for (Uint32 i = 0; i < extensionCount; i++) {
|
||||
if (SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) {
|
||||
hasSurfaceExtension = SDL_TRUE;
|
||||
} else if (SDL_strcmp(VK_EXT_METAL_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) {
|
||||
hasMetalSurfaceExtension = SDL_TRUE;
|
||||
} else if (SDL_strcmp(VK_MVK_MACOS_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) {
|
||||
hasMacOSSurfaceExtension = SDL_TRUE;
|
||||
}
|
||||
|
@ -139,9 +142,10 @@ int Cocoa_Vulkan_LoadLibrary(_THIS, const char *path)
|
|||
SDL_SetError("Installed Vulkan Portability library doesn't implement the "
|
||||
VK_KHR_SURFACE_EXTENSION_NAME " extension");
|
||||
goto fail;
|
||||
} else if (!hasMacOSSurfaceExtension) {
|
||||
} else if (!hasMetalSurfaceExtension && !hasMacOSSurfaceExtension) {
|
||||
SDL_SetError("Installed Vulkan Portability library doesn't implement the "
|
||||
VK_MVK_MACOS_SURFACE_EXTENSION_NAME "extension");
|
||||
VK_EXT_METAL_SURFACE_EXTENSION_NAME " or "
|
||||
VK_MVK_MACOS_SURFACE_EXTENSION_NAME " extensions");
|
||||
goto fail;
|
||||
}
|
||||
return 0;
|
||||
|
@ -186,11 +190,14 @@ SDL_bool Cocoa_Vulkan_CreateSurface(_THIS,
|
|||
{
|
||||
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
|
||||
(PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
|
||||
PFN_vkCreateMetalSurfaceEXT vkCreateMetalSurfaceEXT =
|
||||
(PFN_vkCreateMetalSurfaceEXT)vkGetInstanceProcAddr(
|
||||
(VkInstance)instance,
|
||||
"vkCreateMetalSurfaceEXT");
|
||||
PFN_vkCreateMacOSSurfaceMVK vkCreateMacOSSurfaceMVK =
|
||||
(PFN_vkCreateMacOSSurfaceMVK)vkGetInstanceProcAddr(
|
||||
(VkInstance)instance,
|
||||
"vkCreateMacOSSurfaceMVK");
|
||||
VkMacOSSurfaceCreateInfoMVK createInfo = {};
|
||||
VkResult result;
|
||||
SDL_MetalView metalview;
|
||||
|
||||
|
@ -199,9 +206,10 @@ SDL_bool Cocoa_Vulkan_CreateSurface(_THIS,
|
|||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (!vkCreateMacOSSurfaceMVK) {
|
||||
SDL_SetError(VK_MVK_MACOS_SURFACE_EXTENSION_NAME
|
||||
" extension is not enabled in the Vulkan instance.");
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -210,17 +218,34 @@ SDL_bool Cocoa_Vulkan_CreateSurface(_THIS,
|
|||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
|
||||
createInfo.pNext = NULL;
|
||||
createInfo.flags = 0;
|
||||
createInfo.pView = (const void *)metalview;
|
||||
result = vkCreateMacOSSurfaceMVK(instance, &createInfo,
|
||||
NULL, surface);
|
||||
if (result != VK_SUCCESS) {
|
||||
Cocoa_Metal_DestroyView(_this, metalview);
|
||||
SDL_SetError("vkCreateMacOSSurfaceMVK failed: %s",
|
||||
SDL_Vulkan_GetResultString(result));
|
||||
return SDL_FALSE;
|
||||
if (vkCreateMetalSurfaceEXT) {
|
||||
VkMetalSurfaceCreateInfoEXT createInfo = {};
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT;
|
||||
createInfo.pNext = NULL;
|
||||
createInfo.flags = 0;
|
||||
createInfo.pLayer = (__bridge const CAMetalLayer *)
|
||||
Cocoa_Metal_GetLayer(_this, metalview);
|
||||
result = vkCreateMetalSurfaceEXT(instance, &createInfo, NULL, surface);
|
||||
if (result != VK_SUCCESS) {
|
||||
Cocoa_Metal_DestroyView(_this, metalview);
|
||||
SDL_SetError("vkCreateMetalSurfaceEXT failed: %s",
|
||||
SDL_Vulkan_GetResultString(result));
|
||||
return SDL_FALSE;
|
||||
}
|
||||
} else {
|
||||
VkMacOSSurfaceCreateInfoMVK createInfo = {};
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
|
||||
createInfo.pNext = NULL;
|
||||
createInfo.flags = 0;
|
||||
createInfo.pView = (const void *)metalview;
|
||||
result = vkCreateMacOSSurfaceMVK(instance, &createInfo,
|
||||
NULL, surface);
|
||||
if (result != VK_SUCCESS) {
|
||||
Cocoa_Metal_DestroyView(_this, metalview);
|
||||
SDL_SetError("vkCreateMacOSSurfaceMVK failed: %s",
|
||||
SDL_Vulkan_GetResultString(result));
|
||||
return SDL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Unfortunately there's no SDL_Vulkan_DestroySurface function we can call
|
||||
|
|
|
@ -51,6 +51,7 @@ int UIKit_Vulkan_LoadLibrary(_THIS, const char *path)
|
|||
VkExtensionProperties *extensions = NULL;
|
||||
Uint32 extensionCount = 0;
|
||||
SDL_bool hasSurfaceExtension = SDL_FALSE;
|
||||
SDL_bool hasMetalSurfaceExtension = SDL_FALSE;
|
||||
SDL_bool hasIOSSurfaceExtension = SDL_FALSE;
|
||||
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;
|
||||
|
||||
|
@ -134,6 +135,8 @@ int UIKit_Vulkan_LoadLibrary(_THIS, const char *path)
|
|||
for (Uint32 i = 0; i < extensionCount; i++) {
|
||||
if (SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) {
|
||||
hasSurfaceExtension = SDL_TRUE;
|
||||
} else if (SDL_strcmp(VK_EXT_METAL_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) {
|
||||
hasMetalSurfaceExtension = SDL_TRUE;
|
||||
} else if (SDL_strcmp(VK_MVK_IOS_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) {
|
||||
hasIOSSurfaceExtension = SDL_TRUE;
|
||||
}
|
||||
|
@ -145,9 +148,10 @@ int UIKit_Vulkan_LoadLibrary(_THIS, const char *path)
|
|||
SDL_SetError("Installed Vulkan Portability doesn't implement the "
|
||||
VK_KHR_SURFACE_EXTENSION_NAME " extension");
|
||||
goto fail;
|
||||
} else if (!hasIOSSurfaceExtension) {
|
||||
} else if (!hasMetalSurfaceExtension && !hasIOSSurfaceExtension) {
|
||||
SDL_SetError("Installed Vulkan Portability doesn't implement the "
|
||||
VK_MVK_IOS_SURFACE_EXTENSION_NAME "extension");
|
||||
VK_EXT_METAL_SURFACE_EXTENSION_NAME " or "
|
||||
VK_MVK_IOS_SURFACE_EXTENSION_NAME " extensions");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -193,11 +197,14 @@ SDL_bool UIKit_Vulkan_CreateSurface(_THIS,
|
|||
{
|
||||
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
|
||||
(PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
|
||||
PFN_vkCreateMetalSurfaceEXT vkCreateMetalSurfaceEXT =
|
||||
(PFN_vkCreateMetalSurfaceEXT)vkGetInstanceProcAddr(
|
||||
(VkInstance)instance,
|
||||
"vkCreateMetalSurfaceEXT");
|
||||
PFN_vkCreateIOSSurfaceMVK vkCreateIOSSurfaceMVK =
|
||||
(PFN_vkCreateIOSSurfaceMVK)vkGetInstanceProcAddr(
|
||||
(VkInstance)instance,
|
||||
"vkCreateIOSSurfaceMVK");
|
||||
VkIOSSurfaceCreateInfoMVK createInfo = {};
|
||||
VkResult result;
|
||||
SDL_MetalView metalview;
|
||||
|
||||
|
@ -206,9 +213,10 @@ SDL_bool UIKit_Vulkan_CreateSurface(_THIS,
|
|||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (!vkCreateIOSSurfaceMVK) {
|
||||
SDL_SetError(VK_MVK_IOS_SURFACE_EXTENSION_NAME
|
||||
" extension is not enabled in the Vulkan instance.");
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -217,17 +225,34 @@ SDL_bool UIKit_Vulkan_CreateSurface(_THIS,
|
|||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK;
|
||||
createInfo.pNext = NULL;
|
||||
createInfo.flags = 0;
|
||||
createInfo.pView = (const void *)metalview;
|
||||
result = vkCreateIOSSurfaceMVK(instance, &createInfo,
|
||||
NULL, surface);
|
||||
if (result != VK_SUCCESS) {
|
||||
UIKit_Metal_DestroyView(_this, metalview);
|
||||
SDL_SetError("vkCreateIOSSurfaceMVK failed: %s",
|
||||
SDL_Vulkan_GetResultString(result));
|
||||
return SDL_FALSE;
|
||||
if (vkCreateMetalSurfaceEXT) {
|
||||
VkMetalSurfaceCreateInfoEXT createInfo = {};
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT;
|
||||
createInfo.pNext = NULL;
|
||||
createInfo.flags = 0;
|
||||
createInfo.pLayer = (__bridge const CAMetalLayer *)
|
||||
UIKit_Metal_GetLayer(_this, metalview);
|
||||
result = vkCreateMetalSurfaceEXT(instance, &createInfo, NULL, surface);
|
||||
if (result != VK_SUCCESS) {
|
||||
UIKit_Metal_DestroyView(_this, metalview);
|
||||
SDL_SetError("vkCreateMetalSurfaceEXT failed: %s",
|
||||
SDL_Vulkan_GetResultString(result));
|
||||
return SDL_FALSE;
|
||||
}
|
||||
} else {
|
||||
VkIOSSurfaceCreateInfoMVK createInfo = {};
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK;
|
||||
createInfo.pNext = NULL;
|
||||
createInfo.flags = 0;
|
||||
createInfo.pView = (const void *)metalview;
|
||||
result = vkCreateIOSSurfaceMVK(instance, &createInfo,
|
||||
NULL, surface);
|
||||
if (result != VK_SUCCESS) {
|
||||
UIKit_Metal_DestroyView(_this, metalview);
|
||||
SDL_SetError("vkCreateIOSSurfaceMVK failed: %s",
|
||||
SDL_Vulkan_GetResultString(result));
|
||||
return SDL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Unfortunately there's no SDL_Vulkan_DestroySurface function we can call
|
||||
|
|
Loading…
Reference in New Issue