[PATCH 2/2] winemac.drv: Support VK_EXT_metal_surface.

Chip Davis cdavis at codeweavers.com
Fri Dec 13 10:57:25 CST 2019


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 this extension will vanish at
some point.

Signed-off-by: Chip Davis <cdavis at codeweavers.com>
---
 dlls/winemac.drv/vulkan.c | 66 +++++++++++++++++++++++++++++++++------
 1 file changed, 57 insertions(+), 9 deletions(-)

diff --git a/dlls/winemac.drv/vulkan.c b/dlls/winemac.drv/vulkan.c
index 21e93827c15..60f3dcda6af 100644
--- a/dlls/winemac.drv/vulkan.c
+++ b/dlls/winemac.drv/vulkan.c
@@ -50,6 +50,9 @@ WINE_DECLARE_DEBUG_CHANNEL(fps);
 typedef VkFlags VkMacOSSurfaceCreateFlagsMVK;
 #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
 {
     macdrv_metal_device device;
@@ -65,9 +68,18 @@ typedef struct VkMacOSSurfaceCreateInfoMVK
     const void *pView; /* NSView */
 } 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 (*pvkCreateSwapchainKHR)(VkDevice, const VkSwapchainCreateInfoKHR *, const VkAllocationCallbacks *, VkSwapchainKHR *);
 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 (*pvkDestroySurfaceKHR)(VkInstance, VkSurfaceKHR, 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)
     LOAD_FUNCPTR(vkCreateInstance)
     LOAD_FUNCPTR(vkCreateSwapchainKHR)
     LOAD_FUNCPTR(vkCreateMacOSSurfaceMVK)
+    LOAD_FUNCPTR(vkCreateMetalSurfaceEXT)
     LOAD_FUNCPTR(vkDestroyInstance)
     LOAD_FUNCPTR(vkDestroySurfaceKHR)
     LOAD_FUNCPTR(vkDestroySwapchainKHR)
@@ -159,7 +172,7 @@ static VkResult wine_vk_instance_convert_create_info(const VkInstanceCreateInfo
              */
             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
             {
@@ -239,7 +252,6 @@ static VkResult macdrv_vkCreateWin32SurfaceKHR(VkInstance instance,
         const VkAllocationCallbacks *allocator, VkSurfaceKHR *surface)
 {
     VkResult res;
-    VkMacOSSurfaceCreateInfoMVK create_info_host;
     struct wine_vk_surface *mac_surface;
     struct macdrv_win_data *data;
 
@@ -279,12 +291,26 @@ static VkResult macdrv_vkCreateWin32SurfaceKHR(VkInstance instance,
         goto err;
     }
 
-    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);
+    if (pvkCreateMetalSurfaceEXT)
+    {
+        VkMetalSurfaceCreateInfoEXT create_info_host;
+        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 = pvkCreateMacOSSurfaceMVK(instance, &create_info_host, NULL /* allocator */, &mac_surface->surface);
+        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);
+    }
     if (res != VK_SUCCESS)
     {
         ERR("Failed to create MoltenVK surface, res=%d\n", res);
@@ -341,7 +367,7 @@ static void macdrv_vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapcha
 static VkResult macdrv_vkEnumerateInstanceExtensionProperties(const char *layer_name,
         uint32_t *count, VkExtensionProperties* properties)
 {
-    unsigned int i;
+    unsigned int i, mvk_surface = -1, ext_surface = -1;
     VkResult res;
 
     TRACE("layer_name %s, count %p, properties %p\n", debugstr_a(layer_name), count, properties);
@@ -364,14 +390,36 @@ static VkResult macdrv_vkEnumerateInstanceExtensionProperties(const char *layer_
 
     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 (ext_surface != -1)
+            {
+                /* If we've already seen EXT_metal_surface, just hide this one. */
+                memcpy(properties + i, properties + i + 1, (--(*count) - i) * sizeof(VkExtensionProperties));
+                continue;
+            }
             TRACE("Substituting VK_MVK_macos_surface for VK_KHR_win32_surface\n");
 
             snprintf(properties[i].extensionName, sizeof(properties[i].extensionName),
                     VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
             properties[i].specVersion = VK_KHR_WIN32_SURFACE_SPEC_VERSION;
+            mvk_surface = i;
+        }
+        if (!strcmp(properties[i].extensionName, "VK_EXT_metal_surface"))
+        {
+            if (mvk_surface != -1)
+            {
+                /* If we've already seen MVK_macos_surface, just hide this one. */
+                memcpy(properties + i, properties + i + 1, (--(*count) - i) * sizeof(VkExtensionProperties));
+                continue;
+            }
+            TRACE("Substituting VK_EXT_metal_surface for VK_KHR_win32_surface\n");
+
+            snprintf(properties[i].extensionName, sizeof(properties[i].extensionName),
+                    VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
+            properties[i].specVersion = VK_KHR_WIN32_SURFACE_SPEC_VERSION;
+            ext_surface = i;
         }
     }
 
-- 
2.24.0




More information about the wine-devel mailing list