[PATCH 2/2] winevulkan: Fix surface functions if they aren't called by winevulkan.

Georg Lehmann dadschoorse at gmail.com
Tue Jan 26 06:32:24 CST 2021


Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50549
Signed-off-by: Georg Lehmann <dadschoorse at gmail.com>
---
 dlls/winemac.drv/vulkan.c        | 15 ++++++--
 dlls/winevulkan/make_vulkan      | 60 +++++++++++---------------------
 dlls/winevulkan/vulkan.c         | 45 ++++++++++++++++++++----
 dlls/winevulkan/vulkan_private.h |  3 +-
 dlls/winex11.drv/vulkan.c        | 15 ++++++--
 5 files changed, 86 insertions(+), 52 deletions(-)

diff --git a/dlls/winemac.drv/vulkan.c b/dlls/winemac.drv/vulkan.c
index 1f70059dc65..21ebcc56519 100644
--- a/dlls/winemac.drv/vulkan.c
+++ b/dlls/winemac.drv/vulkan.c
@@ -99,7 +99,7 @@ static void *macdrv_get_vk_instance_proc_addr(VkInstance instance, const char *n
 
 static inline struct wine_vk_surface *surface_from_handle(VkSurfaceKHR handle)
 {
-    return vulkan_driver_get_surface_data(handle);
+    return (struct wine_vk_surface *)(uintptr_t)handle;
 }
 
 static void *vulkan_handle;
@@ -320,7 +320,7 @@ static VkResult macdrv_vkCreateWin32SurfaceKHR(VkInstance instance,
         goto err;
     }
 
-    vulkan_driver_init_surface(*surface, mac_surface->surface, mac_surface);
+    *surface = (uintptr_t)mac_surface;
 
     release_win_data(data);
 
@@ -558,6 +558,15 @@ static VkResult macdrv_vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *
     return res;
 }
 
+static VkSurfaceKHR macdrv_wine_get_native_surface(VkSurfaceKHR surface)
+{
+    struct wine_vk_surface *mac_surface = surface_from_handle(surface);
+
+    TRACE("0x%s\n", wine_dbgstr_longlong(surface));
+
+    return mac_surface->surface;
+}
+
 static const struct vulkan_funcs vulkan_funcs =
 {
     macdrv_vkCreateInstance,
@@ -580,6 +589,8 @@ static const struct vulkan_funcs vulkan_funcs =
     macdrv_vkGetPhysicalDeviceWin32PresentationSupportKHR,
     macdrv_vkGetSwapchainImagesKHR,
     macdrv_vkQueuePresentKHR,
+
+    macdrv_wine_get_native_surface,
 };
 
 static void *macdrv_get_vk_device_proc_addr(const char *name)
diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan
index 4532fe1559a..16cd9fecf80 100755
--- a/dlls/winevulkan/make_vulkan
+++ b/dlls/winevulkan/make_vulkan
@@ -132,7 +132,7 @@ CORE_EXTENSIONS = [
 # Functions part of our winevulkan graphics driver interface.
 # DRIVER_VERSION should be bumped on any change to driver interface
 # in FUNCTION_OVERRIDES
-DRIVER_VERSION = 9
+DRIVER_VERSION = 10
 
 # Table of functions for which we have a special implementation.
 # These are regular device / instance functions for which we need
@@ -183,14 +183,14 @@ FUNCTION_OVERRIDES = {
 
     # VK_KHR_get_surface_capabilities2
     "vkGetPhysicalDeviceSurfaceCapabilities2KHR" : {"dispatch" : True, "driver" : True, "thunk" : False, "private_thunk" : True},
-    "vkGetPhysicalDeviceSurfaceFormats2KHR" : {"dispatch" : True, "driver" : True, "thunk" : True},
+    "vkGetPhysicalDeviceSurfaceFormats2KHR" : {"dispatch" : True, "driver" : True, "thunk" : False, "private_thunk" : True},
 
     # VK_KHR_win32_surface
     "vkCreateWin32SurfaceKHR" : {"dispatch" : True, "driver" : True, "thunk" : False},
     "vkGetPhysicalDeviceWin32PresentationSupportKHR" : {"dispatch" : True, "driver" : True, "thunk" : True},
 
     # VK_KHR_swapchain
-    "vkCreateSwapchainKHR" : {"dispatch" : True, "driver" : True, "thunk" : True},
+    "vkCreateSwapchainKHR" : {"dispatch" : True, "driver" : True, "thunk" : False, "private_thunk" : True},
     "vkDestroySwapchainKHR" : {"dispatch" : True, "driver" : True, "thunk" : True},
     "vkGetSwapchainImagesKHR": {"dispatch" : True, "driver" : True, "thunk" : True},
     "vkQueuePresentKHR": {"dispatch" : True, "driver" : True, "thunk" : True},
@@ -957,7 +957,7 @@ class VkHandle(object):
         if self.name == "VkDebugReportCallbackEXT":
             return "wine_debug_report_callback_from_handle({0})->debug_callback".format(name)
         if self.name == "VkSurfaceKHR":
-            return "wine_surface_from_handle({0})->base.surface".format(name)
+            return "wine_surface_from_handle({0})->surface".format(name)
 
         native_handle_name = None
 
@@ -979,12 +979,17 @@ class VkHandle(object):
             LOGGER.error("Unhandled native handle for: {0}".format(self.name))
         return None
 
+    def driver_handle(self, name):
+        """ Provide access to the handle that should be passed to the wine driver """
+
+        if self.name == "VkSurfaceKHR":
+            return "wine_surface_from_handle({0})->driver_surface".format(name)
+
+        return self.native_handle(name)
+
     def is_wrapped(self):
         return self.native_handle("test") is not None
 
-    def is_unwrapped_by_driver(self):
-        return self.name == "VkSurfaceKHR"
-
 class VkMember(object):
     def __init__(self, const=False, struct_fwd_decl=False,_type=None, pointer=None, name=None, array_len=None,
             dyn_array_len=None, optional=False, values=None):
@@ -1606,13 +1611,10 @@ class VkParam(object):
             else:
                 return "&{0}_host".format(self.name)
         else:
-            # We need to pass the native handle to the native Vulkan calls unless
-            # the wine driver unwraps the handle for us.
-            if self.is_handle() and not self.handle.is_unwrapped_by_driver():
-                native_handle = self.handle.native_handle(self.name)
-            else:
-                native_handle = None
-            return native_handle if native_handle else self.name
+            # We need to pass the native handle to the native Vulkan calls and
+            # the wine driver's handle to calls which are wrapped by the driver.
+            driver_handle = self.handle.driver_handle(self.name) if self.is_handle() else None
+            return driver_handle if driver_handle else self.name
 
 
 class VkStruct(Sequence):
@@ -2560,6 +2562,10 @@ class VkGenerator(object):
             # stuff in there. For simplicity substitute with "void *".
             pfn = pfn.replace("PFN_vkVoidFunction", "void *")
             f.write("    {0};\n".format(pfn))
+
+        f.write("\n")
+        f.write("    /* winevulkan specific functions */\n")
+        f.write("    VkSurfaceKHR (*p_wine_get_native_surface)(VkSurfaceKHR);\n")
         f.write("};\n\n")
 
         f.write("extern const struct vulkan_funcs * CDECL __wine_get_vulkan_driver(HDC hdc, UINT version);\n\n")
@@ -2593,32 +2599,6 @@ class VkGenerator(object):
         f.write("    name -= 2;\n\n")
         f.write("    return get_vulkan_driver_device_proc_addr(vulkan_funcs, name);\n}\n\n")
 
-        f.write("struct wine_surface_base\n")
-        f.write("{\n")
-        f.write("    VkSurfaceKHR surface; /* native surface */\n")
-        f.write("    void *driver_data;\n")
-        f.write("};\n\n")
-
-        f.write("static inline void vulkan_driver_init_surface(\n")
-        f.write("        VkSurfaceKHR surface, VkSurfaceKHR native_surface, void *data)\n")
-        f.write("{\n")
-        f.write("    struct wine_surface_base *object = (void *)(uintptr_t)surface;\n")
-        f.write("    object->surface = native_surface;\n")
-        f.write("    object->driver_data = data;\n")
-        f.write("};\n\n")
-
-        f.write("static inline VkSurfaceKHR vulkan_driver_get_native_surface(VkSurfaceKHR surface)\n")
-        f.write("{\n")
-        f.write("    struct wine_surface_base *object = (void *)(uintptr_t)surface;\n")
-        f.write("    return object->surface;\n")
-        f.write("};\n\n")
-
-        f.write("static inline void *vulkan_driver_get_surface_data(VkSurfaceKHR surface)\n")
-        f.write("{\n")
-        f.write("    struct wine_surface_base *object = (void *)(uintptr_t)surface;\n")
-        f.write("    return object->driver_data;\n")
-        f.write("};\n\n")
-
         f.write("#endif /* __WINE_VULKAN_DRIVER_H */\n")
 
     def generate_vulkan_spec(self, f):
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c
index 9b3064e2a44..2a503a7430d 100644
--- a/dlls/winevulkan/vulkan.c
+++ b/dlls/winevulkan/vulkan.c
@@ -1770,6 +1770,19 @@ void WINAPI wine_vkGetPrivateDataEXT(VkDevice device, VkObjectType object_type,
     device->funcs.p_vkGetPrivateDataEXT(device->device, object_type, object_handle, private_data_slot, data);
 }
 
+VkResult WINAPI wine_vkCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *create_info,
+        const VkAllocationCallbacks *allocator, VkSwapchainKHR *swapchain)
+{
+    VkSwapchainCreateInfoKHR native_info;
+
+    TRACE("%p, %p, %p, %p\n", device, create_info, allocator, swapchain);
+
+    native_info = *create_info;
+    native_info.surface = wine_surface_from_handle(create_info->surface)->driver_surface;
+
+    return thunk_vkCreateSwapchainKHR(device, &native_info, allocator, swapchain);
+}
+
 VkResult WINAPI wine_vkCreateWin32SurfaceKHR(VkInstance instance,
         const VkWin32SurfaceCreateInfoKHR *createInfo, const VkAllocationCallbacks *allocator, VkSurfaceKHR *surface)
 {
@@ -1786,18 +1799,19 @@ VkResult WINAPI wine_vkCreateWin32SurfaceKHR(VkInstance instance,
     if (!object)
         return VK_ERROR_OUT_OF_HOST_MEMORY;
 
-    *surface = wine_surface_to_handle(object);
-
-    res = instance->funcs.p_vkCreateWin32SurfaceKHR(instance->instance, createInfo, NULL, surface);
+    res = instance->funcs.p_vkCreateWin32SurfaceKHR(instance->instance, createInfo, NULL, &object->driver_surface);
 
     if (res != VK_SUCCESS)
     {
         heap_free(object);
-        *surface = VK_NULL_HANDLE;
         return res;
     }
 
-    WINE_VK_ADD_NON_DISPATCHABLE_MAPPING(instance, object, object->base.surface);
+    object->surface = vk_funcs->p_wine_get_native_surface(object->driver_surface);
+
+    WINE_VK_ADD_NON_DISPATCHABLE_MAPPING(instance, object, object->surface);
+
+    *surface = wine_surface_to_handle(object);
 
     return VK_SUCCESS;
 }
@@ -1811,12 +1825,25 @@ void WINAPI wine_vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface,
     if (!object)
         return;
 
-    instance->funcs.p_vkDestroySurfaceKHR(instance->instance, surface, NULL);
+    instance->funcs.p_vkDestroySurfaceKHR(instance->instance, object->driver_surface, NULL);
 
     WINE_VK_REMOVE_HANDLE_MAPPING(instance, object);
     heap_free(object);
 }
 
+VkResult WINAPI wine_vkGetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice phys_dev,
+        const VkPhysicalDeviceSurfaceInfo2KHR *surface_info, uint32_t *formats_count, VkSurfaceFormat2KHR *formats)
+{
+    VkPhysicalDeviceSurfaceInfo2KHR native_info;
+
+    TRACE("%p, %p, %p, %p\n", phys_dev, surface_info, formats_count, formats);
+
+    native_info = *surface_info;
+    native_info.surface = wine_surface_from_handle(surface_info->surface)->driver_surface;
+
+    return thunk_vkGetPhysicalDeviceSurfaceFormats2KHR(phys_dev, &native_info, formats_count, formats);
+}
+
 static inline void adjust_max_image_count(VkPhysicalDevice phys_dev, VkSurfaceCapabilitiesKHR* capabilities)
 {
     /* Many Windows games, for example Strange Brigade, No Man's Sky, Path of Exile
@@ -1850,11 +1877,15 @@ VkResult WINAPI wine_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice
 VkResult WINAPI wine_vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice phys_dev,
         const VkPhysicalDeviceSurfaceInfo2KHR *surface_info, VkSurfaceCapabilities2KHR *capabilities)
 {
+    VkPhysicalDeviceSurfaceInfo2KHR native_info;
     VkResult res;
 
     TRACE("%p, %p, %p\n", phys_dev, surface_info, capabilities);
 
-    res = thunk_vkGetPhysicalDeviceSurfaceCapabilities2KHR(phys_dev, surface_info, capabilities);
+    native_info = *surface_info;
+    native_info.surface = wine_surface_from_handle(surface_info->surface)->driver_surface;
+
+    res = thunk_vkGetPhysicalDeviceSurfaceCapabilities2KHR(phys_dev, &native_info, capabilities);
 
     if (res == VK_SUCCESS)
         adjust_max_image_count(phys_dev, &capabilities->surfaceCapabilities);
diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h
index bf49371e40e..4a41a15461e 100644
--- a/dlls/winevulkan/vulkan_private.h
+++ b/dlls/winevulkan/vulkan_private.h
@@ -215,7 +215,8 @@ static inline VkDebugReportCallbackEXT wine_debug_report_callback_to_handle(
 
 struct wine_surface
 {
-    struct wine_surface_base base;
+    VkSurfaceKHR surface; /* native surface */
+    VkSurfaceKHR driver_surface; /* wine driver surface */
 
     struct wine_vk_mapping mapping;
 };
diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c
index f908d3f7777..139faf6b407 100644
--- a/dlls/winex11.drv/vulkan.c
+++ b/dlls/winex11.drv/vulkan.c
@@ -99,7 +99,7 @@ static void *X11DRV_get_vk_instance_proc_addr(VkInstance instance, const char *n
 
 static inline struct wine_vk_surface *surface_from_handle(VkSurfaceKHR handle)
 {
-    return vulkan_driver_get_surface_data(handle);
+    return (struct wine_vk_surface *)(uintptr_t)handle;
 }
 
 static void *vulkan_handle;
@@ -324,7 +324,7 @@ static VkResult X11DRV_vkCreateWin32SurfaceKHR(VkInstance instance,
     XSaveContext(gdi_display, (XID)create_info->hwnd, vulkan_hwnd_context, (char *)wine_vk_surface_grab(x11_surface));
     LeaveCriticalSection(&context_section);
 
-    vulkan_driver_init_surface(*surface, x11_surface->surface, x11_surface);
+    *surface = (uintptr_t)x11_surface;
 
     TRACE("Created surface=0x%s\n", wine_dbgstr_longlong(*surface));
     return VK_SUCCESS;
@@ -601,6 +601,15 @@ static VkResult X11DRV_vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *
     return res;
 }
 
+static VkSurfaceKHR X11DRV_wine_get_native_surface(VkSurfaceKHR surface)
+{
+    struct wine_vk_surface *x11_surface = surface_from_handle(surface);
+
+    TRACE("0x%s\n", wine_dbgstr_longlong(surface));
+
+    return x11_surface->surface;
+}
+
 static const struct vulkan_funcs vulkan_funcs =
 {
     X11DRV_vkCreateInstance,
@@ -623,6 +632,8 @@ static const struct vulkan_funcs vulkan_funcs =
     X11DRV_vkGetPhysicalDeviceWin32PresentationSupportKHR,
     X11DRV_vkGetSwapchainImagesKHR,
     X11DRV_vkQueuePresentKHR,
+
+    X11DRV_wine_get_native_surface,
 };
 
 static void *X11DRV_get_vk_device_proc_addr(const char *name)
-- 
2.30.0




More information about the wine-devel mailing list