[PATCH 3/4] winex11: vkGetInstanceProcAddr support global function loading

Roderick Colenbrander <[email protected]>
Newsgroups gmane.comp.emulators.wine.patches
Message-ID <[email protected]>
---
 dlls/winex11.drv/Makefile.in      |  1 +
 dlls/winex11.drv/vulkan.c         | 40 ++++++++++++++++++++++++++++++++++-
 dlls/winex11.drv/vulkan_private.h | 44 +++++++++++++++++++++++++++++++++++++++
 dlls/winex11.drv/vulkan_thunks.c  | 17 +++++++++++++++
 4 files changed, 101 insertions(+), 1 deletion(-)
 create mode 100644 dlls/winex11.drv/vulkan_private.h
 create mode 100644 dlls/winex11.drv/vulkan_thunks.c

diff --git a/dlls/winex11.drv/Makefile.in b/dlls/winex11.drv/Makefile.in
index 747f509b44..fc6c288d66 100644
--- a/dlls/winex11.drv/Makefile.in
+++ b/dlls/winex11.drv/Makefile.in
@@ -21,6 +21,7 @@ C_SRCS = \
 	settings.c \
 	systray.c \
 	vulkan.c \
+	vulkan_thunks.c \
 	window.c \
 	wintab.c \
 	x11drv_main.c \
diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c
index 5db3f89ec2..d3fe9c390a 100644
--- a/dlls/winex11.drv/vulkan.c
+++ b/dlls/winex11.drv/vulkan.c
@@ -22,11 +22,26 @@
 
 #include "wine/debug.h"
 #include "wine/vulkan.h"
+#include "vulkan_private.h"
 
 #ifdef SONAME_LIBVULKAN
 
 WINE_DEFAULT_DEBUG_CHANNEL(vulkan);
 
+static void *wine_vk_get_global_proc_addr(const char* name)
+{
+    int i;
+    for (i = 0; i < vk_global_dispatch_table_size; i++)
+    {
+        if (strcmp(name, vk_global_dispatch_table[i].name) == 0)
+        {
+            TRACE("Found pName=%s in global table\n", name);
+            return vk_global_dispatch_table[i].func;
+        }
+    }
+    return NULL;
+}
+
 VkResult WINAPI X11DRV_vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
         VkInstance *pInstance)
 {
@@ -41,9 +56,32 @@ VkResult WINAPI X11DRV_vkEnumerateInstanceExtensionProperties(const char *pLayer
     return VK_ERROR_OUT_OF_HOST_MEMORY;
 }
 
+/* Implementation of vkGetInstanceProcAddr. We will load any function the caller requests
+ * and which we are aware of. Hopefully we don't have to do any extension filtering, which
+ * seems to be taken care of by the loader.
+ */
 PFN_vkVoidFunction WINAPI X11DRV_vkGetInstanceProcAddr(VkInstance instance, const char* pName)
 {
-    FIXME("stub: %p, %s\n", instance, pName ? pName : "NULL");
+    void *func;
+    TRACE("%p, %s\n", instance, pName ? pName : "NULL");
+
+    /* Only global functions can be retrieved when NULL.
+     * Note: the docs are not clear if we can still query global
+     *       functions when a non-NULL instance object is passed in.
+     */
+    if (!instance)
+    {
+        func = wine_vk_get_global_proc_addr(pName);
+        if (!func)
+        {
+            TRACE("Function %s not found\n", pName);
+            return NULL;
+        }
+        return func;
+    }
+
+    /* TODO: add loading of instance and device functions. */
+    FIXME("Function %s not found\n", pName);
     return NULL;
 }
 
diff --git a/dlls/winex11.drv/vulkan_private.h b/dlls/winex11.drv/vulkan_private.h
new file mode 100644
index 0000000000..490b521a1a
--- /dev/null
+++ b/dlls/winex11.drv/vulkan_private.h
@@ -0,0 +1,44 @@
+/* X11DRV Vulkan ICD implementation
+ *
+ * Copyright 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
+ */
+
+#ifndef __WINE_VULKAN_PRIVATE_H /* __WINE_VULKAN_PRIVATE_H */
+#define __WINE_VULKAN_PRIVATE_H
+
+#ifndef __WINE_CONFIG_H
+# error You must include config.h to use this header
+#endif
+
+#ifdef SONAME_LIBVULKAN
+
+struct vulkan_func
+{
+    const char *name;
+    const char *extension;
+    void *func;
+};
+
+/* For use by vk_icdGetInstanceProcAddr / vkGetInstanceProcAddr */
+extern const struct vulkan_func vk_global_dispatch_table[] DECLSPEC_HIDDEN;
+extern const int vk_global_dispatch_table_size DECLSPEC_HIDDEN;
+
+VkResult WINAPI X11DRV_vkCreateInstance(const VkInstanceCreateInfo*, const VkAllocationCallbacks*, VkInstance*);
+VkResult WINAPI X11DRV_vkEnumerateInstanceExtensionProperties(const char*, uint32_t*, VkExtensionProperties*);
+
+#endif /* SONAME_LIBVULKAN */
+#endif /* __WINE_VULKAN_PRIVATE_H */
diff --git a/dlls/winex11.drv/vulkan_thunks.c b/dlls/winex11.drv/vulkan_thunks.c
new file mode 100644
index 0000000000..527898e06a
--- /dev/null
+++ b/dlls/winex11.drv/vulkan_thunks.c
@@ -0,0 +1,17 @@
+/* Automatically generated from Vulkan vk.xml; DO NOT EDIT! */
+
+#include "config.h"
+#include "wine/port.h"
+
+#ifdef SONAME_LIBVULKAN
+
+#include "wine/vulkan.h"
+#include "vulkan_private.h"
+
+const struct vulkan_func vk_global_dispatch_table[] = {
+    {"vkCreateInstance", NULL, &X11DRV_vkCreateInstance},
+    {"vkEnumerateInstanceExtensionProperties", NULL, &X11DRV_vkEnumerateInstanceExtensionProperties},
+};
+const int vk_global_dispatch_table_size = 2;
+
+#endif /* SONAME_LIBVULKAN */
-- 
2.13.6
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.