[PATCH v2 1/2] winevulkan: Generate a separate physical device dispatch table.
Joshua Ashton
joshua at froggi.es
Tue Mar 23 12:55:14 CDT 2021
Signed-off-by: Joshua Ashton <joshua at froggi.es>
On 3/23/21 5:42 PM, Georg Lehmann wrote:
> Signed-off-by: Georg Lehmann <dadschoorse at gmail.com>
> ---
> dlls/winevulkan/make_vulkan | 47 +++++++++++++++++++++++++++-----
> dlls/winevulkan/vulkan.c | 6 +++-
> dlls/winevulkan/vulkan_private.h | 1 +
> 3 files changed, 46 insertions(+), 8 deletions(-)
>
> diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan
> index 3ad210e4701..a4c4d16eaaa 100755
> --- a/dlls/winevulkan/make_vulkan
> +++ b/dlls/winevulkan/make_vulkan
> @@ -584,7 +584,7 @@ class VkFunction(object):
>
> def is_device_func(self):
> # If none of the other, it must be a device function
> - return not self.is_global_func() and not self.is_instance_func()
> + return not self.is_global_func() and not self.is_instance_func() and not self.is_phys_dev_func()
>
> def is_driver_func(self):
> """ Returns if function is part of Wine driver interface. """
> @@ -601,8 +601,14 @@ class VkFunction(object):
> return True
>
> def is_instance_func(self):
> - # Instance functions are passed VkInstance or VkPhysicalDevice.
> - if self.params[0].type in ["VkInstance", "VkPhysicalDevice"]:
> + # Instance functions are passed VkInstance.
> + if self.params[0].type == "VkInstance":
> + return True
> + return False
> +
> + def is_phys_dev_func(self):
> + # Physical device functions are passed VkPhysicalDevice.
> + if self.params[0].type == "VkPhysicalDevice":
> return True
> return False
>
> @@ -2270,6 +2276,14 @@ class VkGenerator(object):
> f.write(" {{\"{0}\", &{1}{0}}},\n".format(vk_func.name, prefix))
> f.write("};\n\n")
>
> + f.write("static const struct vulkan_func vk_phys_dev_dispatch_table[] =\n{\n")
> + for vk_func in self.registry.phys_dev_funcs:
> + if not vk_func.is_required():
> + continue
> +
> + f.write(" {{\"{0}\", &{1}{0}}},\n".format(vk_func.name, prefix))
> + f.write("};\n\n")
> +
> f.write("static const struct vulkan_func vk_instance_dispatch_table[] =\n{\n")
> for vk_func in self.registry.instance_funcs:
> if not vk_func.is_required():
> @@ -2292,6 +2306,20 @@ class VkGenerator(object):
> f.write(" return NULL;\n")
> f.write("}\n\n")
>
> + f.write("void *wine_vk_get_phys_dev_proc_addr(const char *name)\n")
> + f.write("{\n")
> + f.write(" unsigned int i;\n")
> + f.write(" for (i = 0; i < ARRAY_SIZE(vk_phys_dev_dispatch_table); i++)\n")
> + f.write(" {\n")
> + f.write(" if (strcmp(vk_phys_dev_dispatch_table[i].name, name) == 0)\n")
> + f.write(" {\n")
> + f.write(" TRACE(\"Found name=%s in physical device table\\n\", debugstr_a(name));\n")
> + f.write(" return vk_phys_dev_dispatch_table[i].func;\n")
> + f.write(" }\n")
> + f.write(" }\n")
> + f.write(" return NULL;\n")
> + f.write("}\n\n")
> +
> f.write("void *wine_vk_get_instance_proc_addr(const char *name)\n")
> f.write("{\n")
> f.write(" unsigned int i;\n")
> @@ -2434,7 +2462,7 @@ class VkGenerator(object):
>
> 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:
> + for vk_func in self.registry.instance_funcs + self.registry.phys_dev_funcs:
> if not vk_func.is_required():
> continue
>
> @@ -2471,7 +2499,7 @@ class VkGenerator(object):
>
> f.write("#define ALL_VK_INSTANCE_FUNCS() \\\n")
> first = True
> - for vk_func in self.registry.instance_funcs:
> + for vk_func in self.registry.instance_funcs + self.registry.phys_dev_funcs:
> if not vk_func.is_required():
> continue
>
> @@ -2635,7 +2663,7 @@ class VkGenerator(object):
> f.write("\n")
> f.write(" if (!instance) return NULL;\n\n")
> for vk_func in self.registry.funcs.values():
> - if vk_func.is_driver_func() and vk_func.is_instance_func():
> + if vk_func.is_driver_func() and (vk_func.is_instance_func() or vk_func.is_phys_dev_func()):
> f.write(' if (!strcmp(name, "{0}"))\n'.format(vk_func.name[2:]))
> f.write(' return vulkan_funcs->p_{0};\n'.format(vk_func.name))
> f.write("\n")
> @@ -2836,21 +2864,26 @@ class VkRegistry(object):
> funcs[func.name] = func
>
> # To make life easy for the code generation, separate all function
> - # calls out in the 3 types of Vulkan functions: device, global and instance.
> + # calls out in the 4 types of Vulkan functions:
> + # device, global, physical device and instance.
> device_funcs = []
> global_funcs = []
> + phys_dev_funcs = []
> instance_funcs = []
> for func in funcs.values():
> if func.is_device_func():
> device_funcs.append(func)
> elif func.is_global_func():
> global_funcs.append(func)
> + elif func.is_phys_dev_func():
> + phys_dev_funcs.append(func)
> else:
> instance_funcs.append(func)
>
> # Sort function lists by name and store them.
> self.device_funcs = sorted(device_funcs, key=lambda func: func.name)
> self.global_funcs = sorted(global_funcs, key=lambda func: func.name)
> + self.phys_dev_funcs = sorted(phys_dev_funcs, key=lambda func: func.name)
> self.instance_funcs = sorted(instance_funcs, key=lambda func: func.name)
>
> # The funcs dictionary is used as a convenient way to lookup function
> diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c
> index 971394eb9dd..87cbc3b0e4c 100644
> --- a/dlls/winevulkan/vulkan.c
> +++ b/dlls/winevulkan/vulkan.c
> @@ -1156,7 +1156,8 @@ PFN_vkVoidFunction WINAPI wine_vkGetDeviceProcAddr(VkDevice device, const char *
> * https://github.com/KhronosGroup/Vulkan-Docs/issues/655
> */
> if (device->quirks & WINEVULKAN_QUIRK_GET_DEVICE_PROC_ADDR
> - && (func = wine_vk_get_instance_proc_addr(name)))
> + && ((func = wine_vk_get_instance_proc_addr(name))
> + || (func = wine_vk_get_phys_dev_proc_addr(name))))
> {
> WARN("Returning instance function %s.\n", debugstr_a(name));
> return func;
> @@ -1219,6 +1220,9 @@ PFN_vkVoidFunction WINAPI wine_vkGetInstanceProcAddr(VkInstance instance, const
> func = wine_vk_get_instance_proc_addr(name);
> if (func) return func;
>
> + func = wine_vk_get_phys_dev_proc_addr(name);
> + if (func) return func;
> +
> /* vkGetInstanceProcAddr also loads any children of instance, so device functions as well. */
> func = wine_vk_get_device_proc_addr(name);
> if (func) return func;
> diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h
> index 4a41a15461e..322d27079ea 100644
> --- a/dlls/winevulkan/vulkan_private.h
> +++ b/dlls/winevulkan/vulkan_private.h
> @@ -232,6 +232,7 @@ static inline VkSurfaceKHR wine_surface_to_handle(struct wine_surface *surface)
> }
>
> void *wine_vk_get_device_proc_addr(const char *name) DECLSPEC_HIDDEN;
> +void *wine_vk_get_phys_dev_proc_addr(const char *name) DECLSPEC_HIDDEN;
> void *wine_vk_get_instance_proc_addr(const char *name) DECLSPEC_HIDDEN;
>
> BOOL wine_vk_device_extension_supported(const char *name) DECLSPEC_HIDDEN;
>
More information about the wine-devel
mailing list