[PATCH 1/3] winevulkan: Load instance functions.

Roderick Colenbrander thunderbird2k at gmail.com
Fri Mar 2 00:13:35 CST 2018


Signed-off-by: Roderick Colenbrander <thunderbird2k at gmail.com>
---
 dlls/winevulkan/make_vulkan      | 32 ++++++++++++++++++++++++++++----
 dlls/winevulkan/vulkan.c         |  9 +++++++++
 dlls/winevulkan/vulkan_private.h |  1 +
 dlls/winevulkan/vulkan_thunks.h  | 29 +++++++++++++++++++++++++++++
 dlls/winex11.drv/vulkan.c        |  6 ++++--
 5 files changed, 71 insertions(+), 6 deletions(-)

diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan
index 6c6cf2ea3c..5657b70c4c 100755
--- a/dlls/winevulkan/make_vulkan
+++ b/dlls/winevulkan/make_vulkan
@@ -1035,17 +1035,41 @@ class VkGenerator(object):
         # Generate prototypes for device and instance functions requiring a custom implementation.
         f.write("/* Functions for which we have custom implementations outside of the thunks. */\n")
         for vk_func in self.registry.funcs.values():
+            if not vk_func.is_required() or vk_func.is_global_func() or vk_func.needs_thunk():
+                continue
+
+            f.write("{0};\n".format(vk_func.prototype("WINAPI", prefix="wine_", postfix="DECLSPEC_HIDDEN")))
+        f.write("\n")
+
+        f.write("/* For use by vkInstance and children */\n")
+        f.write("struct vulkan_instance_funcs\n{\n")
+        for vk_func in self.registry.instance_funcs:
             if not vk_func.is_required():
                 continue
 
-            if vk_func.is_global_func():
+            if not vk_func.needs_dispatch() or vk_func.is_driver_func():
+                LOGGER.debug("skipping {0} in vulkan_instance_funcs".format(vk_func.name))
                 continue
 
-            if vk_func.needs_thunk():
+            f.write("    {0};\n".format(vk_func.pfn(conv=False)))
+        f.write("};\n\n")
+
+        f.write("#define ALL_VK_INSTANCE_FUNCS() \\\n")
+        first = True
+        for vk_func in self.registry.instance_funcs:
+            if not vk_func.is_required():
                 continue
 
-            f.write("{0};\n".format(vk_func.prototype("WINAPI", prefix="wine_", postfix="DECLSPEC_HIDDEN")))
-        f.write("\n")
+            if not vk_func.needs_dispatch() or vk_func.is_driver_func():
+                LOGGER.debug("skipping {0} in ALL_VK_INSTANCE_FUNCS".format(vk_func.name))
+                continue
+
+            if first:
+                f.write("    USE_VK_FUNC({0})".format(vk_func.name))
+                first = False
+            else:
+                f.write("\\\n    USE_VK_FUNC({0})".format(vk_func.name))
+        f.write("\n\n")
 
         f.write("#endif /* __WINE_VULKAN_THUNKS_H */\n")
 
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c
index 85836bdd42..0f48d971e2 100644
--- a/dlls/winevulkan/vulkan.c
+++ b/dlls/winevulkan/vulkan.c
@@ -99,6 +99,15 @@ static VkResult WINAPI wine_vkCreateInstance(const VkInstanceCreateInfo *create_
         goto err;
     }
 
+    /* Load all instance functions we are aware of. Note the loader takes care
+     * of any filtering for extensions which were not requested, but which the
+     * ICD may support.
+     */
+#define USE_VK_FUNC(name) \
+    object->funcs.p_##name = (void*)vk_funcs->p_vkGetInstanceProcAddr(object->instance, #name);
+    ALL_VK_INSTANCE_FUNCS()
+#undef USE_VK_FUNC
+
     *instance = object;
     TRACE("Done, instance=%p native_instance=%p\n", object, object->instance);
     return VK_SUCCESS;
diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h
index 5688137833..16aa0ce55c 100644
--- a/dlls/winevulkan/vulkan_private.h
+++ b/dlls/winevulkan/vulkan_private.h
@@ -51,6 +51,7 @@ struct wine_vk_base
 struct VkInstance_T
 {
     struct wine_vk_base base;
+    struct vulkan_instance_funcs funcs;
     VkInstance instance; /* native instance */
 };
 
diff --git a/dlls/winevulkan/vulkan_thunks.h b/dlls/winevulkan/vulkan_thunks.h
index 969bf125f9..087fa17d0e 100644
--- a/dlls/winevulkan/vulkan_thunks.h
+++ b/dlls/winevulkan/vulkan_thunks.h
@@ -9,4 +9,33 @@ void *wine_vk_get_instance_proc_addr(const char *name) DECLSPEC_HIDDEN;
 /* Functions for which we have custom implementations outside of the thunks. */
 void WINAPI wine_vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) DECLSPEC_HIDDEN;
 
+/* For use by vkInstance and children */
+struct vulkan_instance_funcs
+{
+    VkResult (*p_vkCreateDevice)(VkPhysicalDevice, const VkDeviceCreateInfo *, const VkAllocationCallbacks *, VkDevice *);
+    VkResult (*p_vkEnumerateDeviceExtensionProperties)(VkPhysicalDevice, const char *, uint32_t *, VkExtensionProperties *);
+    VkResult (*p_vkEnumerateDeviceLayerProperties)(VkPhysicalDevice, uint32_t *, VkLayerProperties *);
+    VkResult (*p_vkEnumeratePhysicalDevices)(VkInstance, uint32_t *, VkPhysicalDevice *);
+    void (*p_vkGetPhysicalDeviceFeatures)(VkPhysicalDevice, VkPhysicalDeviceFeatures *);
+    void (*p_vkGetPhysicalDeviceFormatProperties)(VkPhysicalDevice, VkFormat, VkFormatProperties *);
+    VkResult (*p_vkGetPhysicalDeviceImageFormatProperties)(VkPhysicalDevice, VkFormat, VkImageType, VkImageTiling, VkImageUsageFlags, VkImageCreateFlags, VkImageFormatProperties *);
+    void (*p_vkGetPhysicalDeviceMemoryProperties)(VkPhysicalDevice, VkPhysicalDeviceMemoryProperties *);
+    void (*p_vkGetPhysicalDeviceProperties)(VkPhysicalDevice, VkPhysicalDeviceProperties *);
+    void (*p_vkGetPhysicalDeviceQueueFamilyProperties)(VkPhysicalDevice, uint32_t *, VkQueueFamilyProperties *);
+    void (*p_vkGetPhysicalDeviceSparseImageFormatProperties)(VkPhysicalDevice, VkFormat, VkImageType, VkSampleCountFlagBits, VkImageUsageFlags, VkImageTiling, uint32_t *, VkSparseImageFormatProperties *);
+};
+
+#define ALL_VK_INSTANCE_FUNCS() \
+    USE_VK_FUNC(vkCreateDevice)\
+    USE_VK_FUNC(vkEnumerateDeviceExtensionProperties)\
+    USE_VK_FUNC(vkEnumerateDeviceLayerProperties)\
+    USE_VK_FUNC(vkEnumeratePhysicalDevices)\
+    USE_VK_FUNC(vkGetPhysicalDeviceFeatures)\
+    USE_VK_FUNC(vkGetPhysicalDeviceFormatProperties)\
+    USE_VK_FUNC(vkGetPhysicalDeviceImageFormatProperties)\
+    USE_VK_FUNC(vkGetPhysicalDeviceMemoryProperties)\
+    USE_VK_FUNC(vkGetPhysicalDeviceProperties)\
+    USE_VK_FUNC(vkGetPhysicalDeviceQueueFamilyProperties)\
+    USE_VK_FUNC(vkGetPhysicalDeviceSparseImageFormatProperties)
+
 #endif /* __WINE_VULKAN_THUNKS_H */
diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c
index adc3da35e4..c3fed9e58a 100644
--- a/dlls/winex11.drv/vulkan.c
+++ b/dlls/winex11.drv/vulkan.c
@@ -36,6 +36,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(vulkan);
 
 static VkResult (*pvkCreateInstance)(const VkInstanceCreateInfo *, const VkAllocationCallbacks *, VkInstance *);
 static void (*pvkDestroyInstance)(VkInstance, const VkAllocationCallbacks *);
+static void * (*pvkGetInstanceProcAddr)(VkInstance, const char *);
 
 static BOOL wine_vk_init(void)
 {
@@ -50,6 +51,7 @@ static BOOL wine_vk_init(void)
 #define LOAD_FUNCPTR(f) if((p##f = wine_dlsym(vulkan_handle, #f, NULL, 0)) == NULL) return FALSE;
 LOAD_FUNCPTR(vkCreateInstance)
 LOAD_FUNCPTR(vkDestroyInstance)
+LOAD_FUNCPTR(vkGetInstanceProcAddr)
 #undef LOAD_FUNCPTR
 
     return TRUE;
@@ -116,8 +118,8 @@ static VkResult X11DRV_vkEnumerateInstanceExtensionProperties(const char *layer_
 
 static void * X11DRV_vkGetInstanceProcAddr(VkInstance instance, const char *name)
 {
-    FIXME("stub: %p, %s\n", instance, debugstr_a(name));
-    return NULL;
+    TRACE("%p, %s\n", instance, debugstr_a(name));
+    return pvkGetInstanceProcAddr(instance, name);
 }
 
 static const struct vulkan_funcs vulkan_funcs =
-- 
2.14.3




More information about the wine-devel mailing list