Commit 1eba86fc authored by Chip Davis's avatar Chip Davis Committed by Alexandre Julliard

winemac.drv: Support VK_EXT_metal_surface.

Prefer it to VK_MVK_macos_surface when present. MoltenVK has deprecated VK_MVK_macos_surface in favor of VK_EXT_metal_surface. It's likely that the former extension will vanish at some point. Signed-off-by: 's avatarChip Davis <cdavis@codeweavers.com> Signed-off-by: 's avatarKen Thomases <ken@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent 606424bb
...@@ -50,6 +50,9 @@ WINE_DECLARE_DEBUG_CHANNEL(fps); ...@@ -50,6 +50,9 @@ WINE_DECLARE_DEBUG_CHANNEL(fps);
typedef VkFlags VkMacOSSurfaceCreateFlagsMVK; typedef VkFlags VkMacOSSurfaceCreateFlagsMVK;
#define VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK 1000123000 #define VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK 1000123000
typedef VkFlags VkMetalSurfaceCreateFlagsEXT;
#define VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT 1000217000
struct wine_vk_surface struct wine_vk_surface
{ {
macdrv_metal_device device; macdrv_metal_device device;
...@@ -65,9 +68,18 @@ typedef struct VkMacOSSurfaceCreateInfoMVK ...@@ -65,9 +68,18 @@ typedef struct VkMacOSSurfaceCreateInfoMVK
const void *pView; /* NSView */ const void *pView; /* NSView */
} VkMacOSSurfaceCreateInfoMVK; } VkMacOSSurfaceCreateInfoMVK;
typedef struct VkMetalSurfaceCreateInfoEXT
{
VkStructureType sType;
const void *pNext;
VkMetalSurfaceCreateFlagsEXT flags;
const void *pLayer; /* CAMetalLayer */
} VkMetalSurfaceCreateInfoEXT;
static VkResult (*pvkCreateInstance)(const VkInstanceCreateInfo *, const VkAllocationCallbacks *, VkInstance *); static VkResult (*pvkCreateInstance)(const VkInstanceCreateInfo *, const VkAllocationCallbacks *, VkInstance *);
static VkResult (*pvkCreateSwapchainKHR)(VkDevice, const VkSwapchainCreateInfoKHR *, const VkAllocationCallbacks *, VkSwapchainKHR *); static VkResult (*pvkCreateSwapchainKHR)(VkDevice, const VkSwapchainCreateInfoKHR *, const VkAllocationCallbacks *, VkSwapchainKHR *);
static VkResult (*pvkCreateMacOSSurfaceMVK)(VkInstance, const VkMacOSSurfaceCreateInfoMVK*, const VkAllocationCallbacks *, VkSurfaceKHR *); static VkResult (*pvkCreateMacOSSurfaceMVK)(VkInstance, const VkMacOSSurfaceCreateInfoMVK*, const VkAllocationCallbacks *, VkSurfaceKHR *);
static VkResult (*pvkCreateMetalSurfaceEXT)(VkInstance, const VkMetalSurfaceCreateInfoEXT*, const VkAllocationCallbacks *, VkSurfaceKHR *);
static void (*pvkDestroyInstance)(VkInstance, const VkAllocationCallbacks *); static void (*pvkDestroyInstance)(VkInstance, const VkAllocationCallbacks *);
static void (*pvkDestroySurfaceKHR)(VkInstance, VkSurfaceKHR, const VkAllocationCallbacks *); static void (*pvkDestroySurfaceKHR)(VkInstance, VkSurfaceKHR, const VkAllocationCallbacks *);
static void (*pvkDestroySwapchainKHR)(VkDevice, VkSwapchainKHR, const VkAllocationCallbacks *); static void (*pvkDestroySwapchainKHR)(VkDevice, VkSwapchainKHR, const VkAllocationCallbacks *);
...@@ -103,6 +115,7 @@ static BOOL WINAPI wine_vk_init(INIT_ONCE *once, void *param, void **context) ...@@ -103,6 +115,7 @@ static BOOL WINAPI wine_vk_init(INIT_ONCE *once, void *param, void **context)
LOAD_FUNCPTR(vkCreateInstance) LOAD_FUNCPTR(vkCreateInstance)
LOAD_FUNCPTR(vkCreateSwapchainKHR) LOAD_FUNCPTR(vkCreateSwapchainKHR)
LOAD_FUNCPTR(vkCreateMacOSSurfaceMVK) LOAD_FUNCPTR(vkCreateMacOSSurfaceMVK)
LOAD_FUNCPTR(vkCreateMetalSurfaceEXT)
LOAD_FUNCPTR(vkDestroyInstance) LOAD_FUNCPTR(vkDestroyInstance)
LOAD_FUNCPTR(vkDestroySurfaceKHR) LOAD_FUNCPTR(vkDestroySurfaceKHR)
LOAD_FUNCPTR(vkDestroySwapchainKHR) LOAD_FUNCPTR(vkDestroySwapchainKHR)
...@@ -159,7 +172,7 @@ static VkResult wine_vk_instance_convert_create_info(const VkInstanceCreateInfo ...@@ -159,7 +172,7 @@ static VkResult wine_vk_instance_convert_create_info(const VkInstanceCreateInfo
*/ */
if (!strcmp(src->ppEnabledExtensionNames[i], "VK_KHR_win32_surface")) if (!strcmp(src->ppEnabledExtensionNames[i], "VK_KHR_win32_surface"))
{ {
enabled_extensions[i] = "VK_MVK_macos_surface"; enabled_extensions[i] = pvkCreateMetalSurfaceEXT ? "VK_EXT_metal_surface" : "VK_MVK_macos_surface";
} }
else else
{ {
...@@ -239,7 +252,6 @@ static VkResult macdrv_vkCreateWin32SurfaceKHR(VkInstance instance, ...@@ -239,7 +252,6 @@ static VkResult macdrv_vkCreateWin32SurfaceKHR(VkInstance instance,
const VkAllocationCallbacks *allocator, VkSurfaceKHR *surface) const VkAllocationCallbacks *allocator, VkSurfaceKHR *surface)
{ {
VkResult res; VkResult res;
VkMacOSSurfaceCreateInfoMVK create_info_host;
struct wine_vk_surface *mac_surface; struct wine_vk_surface *mac_surface;
struct macdrv_win_data *data; struct macdrv_win_data *data;
...@@ -279,12 +291,26 @@ static VkResult macdrv_vkCreateWin32SurfaceKHR(VkInstance instance, ...@@ -279,12 +291,26 @@ static VkResult macdrv_vkCreateWin32SurfaceKHR(VkInstance instance,
goto err; goto err;
} }
create_info_host.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK; if (pvkCreateMetalSurfaceEXT)
create_info_host.pNext = NULL; {
create_info_host.flags = 0; /* reserved */ VkMetalSurfaceCreateInfoEXT create_info_host;
create_info_host.pView = macdrv_view_get_metal_layer(mac_surface->view); create_info_host.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT;
create_info_host.pNext = NULL;
create_info_host.flags = 0; /* reserved */
create_info_host.pLayer = macdrv_view_get_metal_layer(mac_surface->view);
res = pvkCreateMetalSurfaceEXT(instance, &create_info_host, NULL /* allocator */, &mac_surface->surface);
}
else
{
VkMacOSSurfaceCreateInfoMVK create_info_host;
create_info_host.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
create_info_host.pNext = NULL;
create_info_host.flags = 0; /* reserved */
create_info_host.pView = macdrv_view_get_metal_layer(mac_surface->view);
res = pvkCreateMacOSSurfaceMVK(instance, &create_info_host, NULL /* allocator */, &mac_surface->surface); res = pvkCreateMacOSSurfaceMVK(instance, &create_info_host, NULL /* allocator */, &mac_surface->surface);
}
if (res != VK_SUCCESS) if (res != VK_SUCCESS)
{ {
ERR("Failed to create MoltenVK surface, res=%d\n", res); ERR("Failed to create MoltenVK surface, res=%d\n", res);
...@@ -342,6 +368,7 @@ static VkResult macdrv_vkEnumerateInstanceExtensionProperties(const char *layer_ ...@@ -342,6 +368,7 @@ static VkResult macdrv_vkEnumerateInstanceExtensionProperties(const char *layer_
uint32_t *count, VkExtensionProperties* properties) uint32_t *count, VkExtensionProperties* properties)
{ {
unsigned int i; unsigned int i;
BOOL seen_surface = FALSE;
VkResult res; VkResult res;
TRACE("layer_name %s, count %p, properties %p\n", debugstr_a(layer_name), count, properties); TRACE("layer_name %s, count %p, properties %p\n", debugstr_a(layer_name), count, properties);
...@@ -353,8 +380,9 @@ static VkResult macdrv_vkEnumerateInstanceExtensionProperties(const char *layer_ ...@@ -353,8 +380,9 @@ static VkResult macdrv_vkEnumerateInstanceExtensionProperties(const char *layer_
return VK_ERROR_LAYER_NOT_PRESENT; return VK_ERROR_LAYER_NOT_PRESENT;
} }
/* We will return the same number of instance extensions reported by the host back to /* We will return at most the same number of instance extensions reported by the host back to
* winevulkan. Along the way we may replace MoltenVK extensions with their win32 equivalents. * winevulkan. Along the way we may replace MoltenVK extensions with their win32 equivalents,
* or remove redundant extensions outright.
* Winevulkan will perform more detailed filtering as it knows whether it has thunks * Winevulkan will perform more detailed filtering as it knows whether it has thunks
* for a particular extension. * for a particular extension.
*/ */
...@@ -364,14 +392,24 @@ static VkResult macdrv_vkEnumerateInstanceExtensionProperties(const char *layer_ ...@@ -364,14 +392,24 @@ static VkResult macdrv_vkEnumerateInstanceExtensionProperties(const char *layer_
for (i = 0; i < *count; i++) for (i = 0; i < *count; i++)
{ {
/* For now the only MoltenVK extension we need to fixup. Long-term we may need an array. */ /* For now the only MoltenVK extensions we need to fixup. Long-term we may need an array. */
if (!strcmp(properties[i].extensionName, "VK_MVK_macos_surface")) if (!strcmp(properties[i].extensionName, "VK_MVK_macos_surface") ||
!strcmp(properties[i].extensionName, "VK_EXT_metal_surface"))
{ {
TRACE("Substituting VK_MVK_macos_surface for VK_KHR_win32_surface\n"); if (seen_surface)
{
/* If we've already seen a surface extension, just hide this one. */
memmove(properties + i, properties + i + 1, (*count - i - 1) * sizeof(*properties));
--*count;
--i;
continue;
}
TRACE("Substituting %s for VK_KHR_win32_surface\n", properties[i].extensionName);
snprintf(properties[i].extensionName, sizeof(properties[i].extensionName), snprintf(properties[i].extensionName, sizeof(properties[i].extensionName),
VK_KHR_WIN32_SURFACE_EXTENSION_NAME); VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
properties[i].specVersion = VK_KHR_WIN32_SURFACE_SPEC_VERSION; properties[i].specVersion = VK_KHR_WIN32_SURFACE_SPEC_VERSION;
seen_surface = TRUE;
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment