[PATCH v3 05/10] winevulkan: Define vulkan driver interface.

Roderick Colenbrander thunderbird2k at gmail.com
Mon Feb 26 01:14:30 CST 2018


Signed-off-by: Roderick Colenbrander <thunderbird2k at gmail.com>
---
 dlls/gdi32/Makefile.in       |  3 ++-
 dlls/gdi32/dibdrv/dc.c       |  2 ++
 dlls/gdi32/driver.c          |  6 +++++
 dlls/gdi32/enhmfdrv/dc.c     |  1 +
 dlls/gdi32/enhmfdrv/init.c   |  1 +
 dlls/gdi32/freetype.c        |  1 +
 dlls/gdi32/gdi32.spec        |  3 +++
 dlls/gdi32/mfdrv/init.c      |  1 +
 dlls/gdi32/path.c            |  1 +
 dlls/gdi32/vulkan.c          | 41 ++++++++++++++++++++++++++++++
 dlls/wineandroid.drv/init.c  |  1 +
 dlls/winemac.drv/gdi.c       |  1 +
 dlls/wineps.drv/init.c       |  1 +
 dlls/winevulkan/Makefile.in  |  1 +
 dlls/winevulkan/vulkan.c     | 25 ++++++++++++++++--
 dlls/winevulkan/vulkan.py    | 60 ++++++++++++++++++++++++++++++++++++++++++++
 dlls/winex11.drv/init.c      |  1 +
 dlls/winex11.drv/xrender.c   |  1 +
 include/wine/gdi_driver.h    |  5 +++-
 include/wine/vulkan_driver.h | 23 +++++++++++++++++
 20 files changed, 175 insertions(+), 4 deletions(-)
 create mode 100644 dlls/gdi32/vulkan.c
 create mode 100644 include/wine/vulkan_driver.h

diff --git a/dlls/gdi32/Makefile.in b/dlls/gdi32/Makefile.in
index a0f76d23bb..9e5464de2d 100644
--- a/dlls/gdi32/Makefile.in
+++ b/dlls/gdi32/Makefile.in
@@ -46,7 +46,8 @@ C_SRCS = \
 	pen.c \
 	printdrv.c \
 	region.c \
-	vertical.c
+	vertical.c \
+	vulkan.c
 
 RC_SRCS = gdi32.rc
 
diff --git a/dlls/gdi32/dibdrv/dc.c b/dlls/gdi32/dibdrv/dc.c
index 2447093921..78f4b7a396 100644
--- a/dlls/gdi32/dibdrv/dc.c
+++ b/dlls/gdi32/dibdrv/dc.c
@@ -520,6 +520,7 @@ const struct gdi_dc_funcs dib_driver =
     NULL,                               /* pUnrealizePalette */
     NULL,                               /* pWidenPath */
     dibdrv_wine_get_wgl_driver,         /* wine_get_wgl_driver */
+    NULL,                               /* wine_get_vulkan_driver */
     GDI_PRIORITY_DIB_DRV                /* priority */
 };
 
@@ -1146,5 +1147,6 @@ static const struct gdi_dc_funcs window_driver =
     NULL,                               /* pUnrealizePalette */
     NULL,                               /* pWidenPath */
     windrv_wine_get_wgl_driver,         /* wine_get_wgl_driver */
+    NULL,                               /* wine_get_vulkan_driver */
     GDI_PRIORITY_DIB_DRV + 10           /* priority */
 };
diff --git a/dlls/gdi32/driver.c b/dlls/gdi32/driver.c
index 6a3975a531..fcf016b578 100644
--- a/dlls/gdi32/driver.c
+++ b/dlls/gdi32/driver.c
@@ -681,6 +681,11 @@ static struct opengl_funcs *nulldrv_wine_get_wgl_driver( PHYSDEV dev, UINT versi
     return (void *)-1;
 }
 
+static const struct vulkan_funcs *nulldrv_wine_get_vulkan_driver( PHYSDEV dev, UINT version )
+{
+    return NULL;
+}
+
 const struct gdi_dc_funcs null_driver =
 {
     nulldrv_AbortDoc,                   /* pAbortDoc */
@@ -810,6 +815,7 @@ const struct gdi_dc_funcs null_driver =
     nulldrv_UnrealizePalette,           /* pUnrealizePalette */
     nulldrv_WidenPath,                  /* pWidenPath */
     nulldrv_wine_get_wgl_driver,        /* wine_get_wgl_driver */
+    nulldrv_wine_get_vulkan_driver,     /* wine_get_vulkan_driver */
 
     GDI_PRIORITY_NULL_DRV               /* priority */
 };
diff --git a/dlls/gdi32/enhmfdrv/dc.c b/dlls/gdi32/enhmfdrv/dc.c
index 37180fec9e..99a089f1a2 100644
--- a/dlls/gdi32/enhmfdrv/dc.c
+++ b/dlls/gdi32/enhmfdrv/dc.c
@@ -950,5 +950,6 @@ static const struct gdi_dc_funcs emfpath_driver =
     NULL,                               /* pUnrealizePalette */
     NULL,                               /* pWidenPath */
     NULL,                               /* wine_get_wgl_driver */
+    NULL,                               /* wine_get_vulkan_driver */
     GDI_PRIORITY_PATH_DRV + 1           /* priority */
 };
diff --git a/dlls/gdi32/enhmfdrv/init.c b/dlls/gdi32/enhmfdrv/init.c
index 6f9a95632c..35803bcc33 100644
--- a/dlls/gdi32/enhmfdrv/init.c
+++ b/dlls/gdi32/enhmfdrv/init.c
@@ -163,6 +163,7 @@ static const struct gdi_dc_funcs emfdrv_driver =
     NULL,                            /* pUnrealizePalette */
     EMFDRV_WidenPath,                /* pWidenPath */
     NULL,                            /* wine_get_wgl_driver */
+    NULL,                            /* wine_get_vulkan_driver */
     GDI_PRIORITY_GRAPHICS_DRV        /* priority */
 };
 
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index 383314794a..37ca6dc5cc 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -8902,6 +8902,7 @@ static const struct gdi_dc_funcs freetype_funcs =
     NULL,                               /* pUnrealizePalette */
     NULL,                               /* pWidenPath */
     NULL,                               /* wine_get_wgl_driver */
+    NULL,                               /* wine_get_vulkan_driver */
     GDI_PRIORITY_FONT_DRV               /* priority */
 };
 
diff --git a/dlls/gdi32/gdi32.spec b/dlls/gdi32/gdi32.spec
index 7792731b9e..2400a51038 100644
--- a/dlls/gdi32/gdi32.spec
+++ b/dlls/gdi32/gdi32.spec
@@ -524,3 +524,6 @@
 
 # OpenGL
 @ cdecl __wine_get_wgl_driver(long long)
+
+# Vulkan
+@ cdecl __wine_get_vulkan_driver(long long)
diff --git a/dlls/gdi32/mfdrv/init.c b/dlls/gdi32/mfdrv/init.c
index 50f8ba3b4e..d766d025e5 100644
--- a/dlls/gdi32/mfdrv/init.c
+++ b/dlls/gdi32/mfdrv/init.c
@@ -226,6 +226,7 @@ static const struct gdi_dc_funcs MFDRV_Funcs =
     NULL,                            /* pUnrealizePalette */
     MFDRV_WidenPath,                 /* pWidenPath */
     NULL,                            /* wine_get_wgl_driver */
+    NULL,                            /* wine_get_vulkan_driver */
     GDI_PRIORITY_GRAPHICS_DRV        /* priority */
 };
 
diff --git a/dlls/gdi32/path.c b/dlls/gdi32/path.c
index 51334b28b4..41cab60515 100644
--- a/dlls/gdi32/path.c
+++ b/dlls/gdi32/path.c
@@ -2245,5 +2245,6 @@ const struct gdi_dc_funcs path_driver =
     NULL,                               /* pUnrealizePalette */
     NULL,                               /* pWidenPath */
     NULL,                               /* wine_get_wgl_driver */
+    NULL,                               /* wine_get_vulkan_driver */
     GDI_PRIORITY_PATH_DRV               /* priority */
 };
diff --git a/dlls/gdi32/vulkan.c b/dlls/gdi32/vulkan.c
new file mode 100644
index 0000000000..6358417974
--- /dev/null
+++ b/dlls/gdi32/vulkan.c
@@ -0,0 +1,41 @@
+/*
+ * Vulkan display driver loading
+ *
+ * Copyright (c) 2017 Roderick Colenbrander
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include "gdi_private.h"
+
+/***********************************************************************
+ *      __wine_get_vulkan_driver  (GDI32.@)
+ */
+const struct vulkan_funcs * CDECL __wine_get_vulkan_driver(HDC hdc, UINT version)
+{
+    const struct vulkan_funcs *ret = NULL;
+    DC * dc = get_dc_ptr(hdc);
+
+    if (dc)
+    {
+        PHYSDEV physdev = GET_DC_PHYSDEV(dc, wine_get_vulkan_driver);
+        ret = physdev->funcs->wine_get_vulkan_driver(physdev, version);
+        release_dc_ptr(dc);
+    }
+    return ret;
+}
diff --git a/dlls/wineandroid.drv/init.c b/dlls/wineandroid.drv/init.c
index 47ef4a2a86..0dd3e5e686 100644
--- a/dlls/wineandroid.drv/init.c
+++ b/dlls/wineandroid.drv/init.c
@@ -453,6 +453,7 @@ static const struct gdi_dc_funcs android_drv_funcs =
     NULL,                               /* pUnrealizePalette */
     NULL,                               /* pWidenPath */
     ANDROID_wine_get_wgl_driver,        /* wine_get_wgl_driver */
+    NULL,                               /* wine_get_vulkan_driver */
     GDI_PRIORITY_GRAPHICS_DRV           /* priority */
 };
 
diff --git a/dlls/winemac.drv/gdi.c b/dlls/winemac.drv/gdi.c
index 896016bfb2..1f9ac8be41 100644
--- a/dlls/winemac.drv/gdi.c
+++ b/dlls/winemac.drv/gdi.c
@@ -418,6 +418,7 @@ static const struct gdi_dc_funcs macdrv_funcs =
     NULL,                                   /* pUnrealizePalette */
     NULL,                                   /* pWidenPath */
     macdrv_wine_get_wgl_driver,             /* wine_get_wgl_driver */
+    NULL,                                   /* wine_get_vulkan_driver */
     GDI_PRIORITY_GRAPHICS_DRV               /* priority */
 };
 
diff --git a/dlls/wineps.drv/init.c b/dlls/wineps.drv/init.c
index 5b328798cc..2eb03b836c 100644
--- a/dlls/wineps.drv/init.c
+++ b/dlls/wineps.drv/init.c
@@ -908,6 +908,7 @@ static const struct gdi_dc_funcs psdrv_funcs =
     NULL,                               /* pUnrealizePalette */
     NULL,                               /* pWidenPath */
     NULL,                               /* wine_get_wgl_driver */
+    NULL,                               /* wine_get_vulkan_driver */
     GDI_PRIORITY_GRAPHICS_DRV           /* priority */
 };
 
diff --git a/dlls/winevulkan/Makefile.in b/dlls/winevulkan/Makefile.in
index 0bffb487e2..859c731c6e 100644
--- a/dlls/winevulkan/Makefile.in
+++ b/dlls/winevulkan/Makefile.in
@@ -1,4 +1,5 @@
 MODULE    = winevulkan.dll
+IMPORTS   = user32 gdi32
 
 C_SRCS = \
 	vulkan.c
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c
index ef2e287646..ef98f03e37 100644
--- a/dlls/winevulkan/vulkan.c
+++ b/dlls/winevulkan/vulkan.c
@@ -21,9 +21,11 @@
 
 #include "windef.h"
 #include "winbase.h"
+#include "winuser.h"
 
 #include "wine/debug.h"
 #include "wine/vulkan.h"
+#include "wine/vulkan_driver.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(vulkan);
 
@@ -46,6 +48,26 @@ struct vulkan_func
 
 static void *wine_vk_get_global_proc_addr(const char *name);
 
+static const struct vulkan_funcs *vk_funcs = NULL;
+
+static BOOL wine_vk_init(HINSTANCE hinst)
+{
+    HDC hdc = GetDC(0);
+
+    vk_funcs =  __wine_get_vulkan_driver(hdc, WINE_VULKAN_DRIVER_VERSION);
+    if (!vk_funcs)
+    {
+        ERR("Failed to load Wine graphics driver supporting Vulkan.\n");
+        ReleaseDC(0, hdc);
+        return FALSE;
+    }
+
+    DisableThreadLibraryCalls(hinst);
+
+    ReleaseDC(0, hdc);
+    return TRUE;
+}
+
 static VkResult WINAPI wine_vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
         VkInstance *pInstance)
 {
@@ -121,8 +143,7 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved)
     switch(reason)
     {
         case DLL_PROCESS_ATTACH:
-            DisableThreadLibraryCalls(hinst);
-            break;
+            return wine_vk_init(hinst);
 
         case DLL_THREAD_ATTACH:
             break;
diff --git a/dlls/winevulkan/vulkan.py b/dlls/winevulkan/vulkan.py
index 80ad9fcee4..b786354168 100755
--- a/dlls/winevulkan/vulkan.py
+++ b/dlls/winevulkan/vulkan.py
@@ -69,6 +69,27 @@ WINE_VULKAN_THUNKS_C = "vulkan_thunks.c"
 WINE_VULKAN_THUNKS_H = "vulkan_thunks.h"
 
 
+# Functions part of our winevulkan graphics driver interface.
+# DRIVER_VERSION should be bumped on any change to driver interface
+# in FUNCTION_OVERRIDES
+DRIVER_VERSION = 1
+
+# Table of functions for which we have a special implementation.
+# This are regular device / instance functions for which we need
+# to more work compared to a regular thunk  or because they are
+# part of the driver interface.
+# - driver sets whether the api is part of the driver interface.
+FUNCTION_OVERRIDES = {
+    # Global functions
+    "vkCreateInstance" : {"driver" : True},
+    "vkEnumerateInstanceExtensionProperties" : {"driver" : True},
+    "vkGetInstanceProcAddr": {"driver" : True},
+
+    # Instance functions
+    "vkDestroyInstance" : {"driver" : True},
+}
+
+
 class VkBaseType(object):
     def __init__(self, name, _type, requires=None):
         """ Vulkan base type class.
@@ -235,6 +256,10 @@ class VkFunction(object):
         self.type = _type
         self.params = params
 
+        # For some functions we need some extra metadata from FUNCTION_OVERRIDES.
+        func_info = FUNCTION_OVERRIDES.get(self.name, None)
+        self.driver = func_info["driver"] if func_info is not None else False
+
         # Required is set while parsing which APIs and types are required
         # and is used by the code generation.
         self.required = False
@@ -257,6 +282,10 @@ class VkFunction(object):
         # If none of the other, it must be a device function
         return not self.is_global_func() and not self.is_instance_func()
 
+    def is_driver_func(self):
+        """ Returns if function is part of Wine driver interface. """
+        return self.driver
+
     def is_global_func(self):
         # Treat vkGetInstanceProcAddr as a global function as it
         # can operate with NULL for vkInstance.
@@ -904,6 +933,34 @@ class VkGenerator(object):
 
         f.write("#endif /* __WINE_VULKAN_H */\n")
 
+    def generate_vulkan_driver_h(self, f):
+        f.write("/* Automatically generated from Vulkan vk.xml; DO NOT EDIT! */\n\n")
+        f.write("#ifndef __WINE_VULKAN_DRIVER_H\n")
+        f.write("#define __WINE_VULKAN_DRIVER_H\n\n")
+
+        f.write("/* Wine internal vulkan driver version, needs to be bumped upon vulkan_funcs changes. */\n")
+        f.write("#define WINE_VULKAN_DRIVER_VERSION {0}\n\n".format(DRIVER_VERSION))
+
+        f.write("struct vulkan_funcs\n{\n")
+        f.write("    /* Vulkan global functions. This are the only calls at this point a graphics driver\n")
+        f.write("     * needs to provide. Other function calls will be provided indirectly by dispatch\n")
+        f.write("     * tables part of dispatchable Vulkan objects such as VkInstance or vkDevice.\n")
+        f.write("     */\n")
+
+        for vk_func in self.registry.funcs.values():
+            if not vk_func.is_required() or not vk_func.is_driver_func():
+                continue
+
+            pfn = vk_func.pfn()
+            # Avoid PFN_vkVoidFunction in driver interface as Vulkan likes to put calling convention
+            # stuff in there. For simplicity substitute with "void *".
+            pfn = pfn.replace("PFN_vkVoidFunction", "void *")
+            f.write("    {0};\n".format(pfn))
+        f.write("};\n\n")
+
+        f.write("extern const struct vulkan_funcs * CDECL __wine_get_vulkan_driver(HDC hdc, UINT version);\n\n")
+        f.write("#endif /* __WINE_VULKAN_DRIVER_H */\n")
+
 
 class VkRegistry(object):
     def __init__(self, reg_filename):
@@ -1187,5 +1244,8 @@ def main():
     with open(WINE_VULKAN_H, "w") as f:
         generator.generate_vulkan_h(f)
 
+    with open(WINE_VULKAN_DRIVER_H, "w") as f:
+        generator.generate_vulkan_driver_h(f)
+
 if __name__ == "__main__":
     main()
diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c
index e1eb3f84d3..24ed656405 100644
--- a/dlls/winex11.drv/init.c
+++ b/dlls/winex11.drv/init.c
@@ -475,6 +475,7 @@ static const struct gdi_dc_funcs x11drv_funcs =
     X11DRV_UnrealizePalette,            /* pUnrealizePalette */
     NULL,                               /* pWidenPath */
     X11DRV_wine_get_wgl_driver,         /* wine_get_wgl_driver */
+    NULL,                               /* wine_get_vulkan_driver */
     GDI_PRIORITY_GRAPHICS_DRV           /* priority */
 };
 
diff --git a/dlls/winex11.drv/xrender.c b/dlls/winex11.drv/xrender.c
index b9b7c4f325..4d04741435 100644
--- a/dlls/winex11.drv/xrender.c
+++ b/dlls/winex11.drv/xrender.c
@@ -2284,6 +2284,7 @@ static const struct gdi_dc_funcs xrender_funcs =
     NULL,                               /* pUnrealizePalette */
     NULL,                               /* pWidenPath */
     NULL,                               /* wine_get_wgl_driver */
+    NULL,                               /* wine_get_vulkan_driver */
     GDI_PRIORITY_GRAPHICS_DRV + 10      /* priority */
 };
 
diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h
index 32d17f7dce..4693235cae 100644
--- a/include/wine/gdi_driver.h
+++ b/include/wine/gdi_driver.h
@@ -25,6 +25,7 @@
 
 struct gdi_dc_funcs;
 struct opengl_funcs;
+struct vulkan_funcs;
 
 typedef struct gdi_physdev
 {
@@ -191,13 +192,14 @@ struct gdi_dc_funcs
     BOOL     (*pUnrealizePalette)(HPALETTE);
     BOOL     (*pWidenPath)(PHYSDEV);
     struct opengl_funcs * (*wine_get_wgl_driver)(PHYSDEV,UINT);
+    const struct vulkan_funcs * (*wine_get_vulkan_driver)(PHYSDEV,UINT);
 
     /* priority order for the driver on the stack */
     UINT       priority;
 };
 
 /* increment this when you change the DC function table */
-#define WINE_GDI_DRIVER_VERSION 47
+#define WINE_GDI_DRIVER_VERSION 48
 
 #define GDI_PRIORITY_NULL_DRV        0  /* null driver */
 #define GDI_PRIORITY_FONT_DRV      100  /* any font driver */
@@ -280,5 +282,6 @@ extern void CDECL __wine_set_visible_region( HDC hdc, HRGN hrgn, const RECT *vis
                                              const RECT *device_rect, struct window_surface *surface );
 extern void CDECL __wine_set_display_driver( HMODULE module );
 extern struct opengl_funcs * CDECL __wine_get_wgl_driver( HDC hdc, UINT version );
+extern const struct vulkan_funcs * CDECL __wine_get_vulkan_driver( HDC hdc, UINT version );
 
 #endif /* __WINE_WINE_GDI_DRIVER_H */
diff --git a/include/wine/vulkan_driver.h b/include/wine/vulkan_driver.h
new file mode 100644
index 0000000000..568a2128c3
--- /dev/null
+++ b/include/wine/vulkan_driver.h
@@ -0,0 +1,23 @@
+/* Automatically generated from Vulkan vk.xml; DO NOT EDIT! */
+
+#ifndef __WINE_VULKAN_DRIVER_H
+#define __WINE_VULKAN_DRIVER_H
+
+/* Wine internal vulkan driver version, needs to be bumped upon vulkan_funcs changes. */
+#define WINE_VULKAN_DRIVER_VERSION 1
+
+struct vulkan_funcs
+{
+    /* Vulkan global functions. This are the only calls at this point a graphics driver
+     * needs to provide. Other function calls will be provided indirectly by dispatch
+     * tables part of dispatchable Vulkan objects such as VkInstance or vkDevice.
+     */
+    VkResult (*p_vkCreateInstance)(const VkInstanceCreateInfo *, const VkAllocationCallbacks *, VkInstance *);
+    void (*p_vkDestroyInstance)(VkInstance, const VkAllocationCallbacks *);
+    VkResult (*p_vkEnumerateInstanceExtensionProperties)(const char *, uint32_t *, VkExtensionProperties *);
+    void * (*p_vkGetInstanceProcAddr)(VkInstance, const char *);
+};
+
+extern const struct vulkan_funcs * CDECL __wine_get_vulkan_driver(HDC hdc, UINT version);
+
+#endif /* __WINE_VULKAN_DRIVER_H */
-- 
2.14.3




More information about the wine-devel mailing list