From eff07c0407e59de88de971647015a2b77f0f6842 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Sat, 23 Jan 2021 13:28:21 -0600 Subject: [PATCH] vulkan: Add generators for instance trampoline functions ANV needs these because we have a different dispatch table for each hardware generation and Vulkan requires that the device entrypoints returned from vkGetInstanceProcAddr work regardless of which device they're used with. Reviewed-by: Lionel Landwerlin Reviewed-by: Bas Nieuwenhuizen Part-of: --- src/vulkan/util/vk_device.h | 3 + src/vulkan/util/vk_dispatch_table_gen.py | 81 ++++++++++++++++++++++++ src/vulkan/util/vk_instance.h | 3 + src/vulkan/util/vk_object.c | 3 +- src/vulkan/util/vk_object.h | 2 + src/vulkan/util/vk_physical_device.h | 3 + 6 files changed, 94 insertions(+), 1 deletion(-) diff --git a/src/vulkan/util/vk_device.h b/src/vulkan/util/vk_device.h index 9fb1c4ed7f3..a888f36357e 100644 --- a/src/vulkan/util/vk_device.h +++ b/src/vulkan/util/vk_device.h @@ -49,6 +49,9 @@ struct vk_device { #endif }; +VK_DEFINE_HANDLE_CASTS(vk_device, base, VkDevice, + VK_OBJECT_TYPE_DEVICE) + VkResult MUST_CHECK vk_device_init(struct vk_device *device, struct vk_physical_device *physical_device, diff --git a/src/vulkan/util/vk_dispatch_table_gen.py b/src/vulkan/util/vk_dispatch_table_gen.py index f1561bc2610..849f617562d 100644 --- a/src/vulkan/util/vk_dispatch_table_gen.py +++ b/src/vulkan/util/vk_dispatch_table_gen.py @@ -144,6 +144,9 @@ vk_device_dispatch_table_get_if_supported( const struct vk_instance_extension_table *instance_exts, const struct vk_device_extension_table *device_exts); +extern struct vk_physical_device_dispatch_table vk_physical_device_trampolines; +extern struct vk_device_dispatch_table vk_device_trampolines; + #ifdef __cplusplus } #endif @@ -154,7 +157,11 @@ vk_device_dispatch_table_get_if_supported( TEMPLATE_C = Template(COPYRIGHT + """\ /* This file generated from ${filename}, don't edit directly. */ +#include "vk_device.h" #include "vk_dispatch_table.h" +#include "vk_instance.h" +#include "vk_object.h" +#include "vk_physical_device.h" #include "util/macros.h" #include "string.h" @@ -468,6 +475,80 @@ vk_device_dispatch_table_get_if_supported( return vk_device_dispatch_table_get_for_entry_index(table, entry_index); } + +% for e in physical_device_entrypoints: + % if e.alias: + <% continue %> + % endif + % if e.guard is not None: +#ifdef ${e.guard} + % endif +static ${e.return_type} +${e.prefixed_name('vk_tramp')}(${e.decl_params()}) +{ + <% assert e.params[0].type == 'VkPhysicalDevice' %> + VK_FROM_HANDLE(vk_physical_device, vk_physical_device, ${e.params[0].name}); + return vk_physical_device->dispatch_table.${e.name}(${e.call_params()}); +} + % if e.guard is not None: +#endif + % endif +% endfor + +struct vk_physical_device_dispatch_table vk_physical_device_trampolines = { +% for e in physical_device_entrypoints: + % if e.alias: + <% continue %> + % endif + % if e.guard is not None: +#ifdef ${e.guard} + % endif + .${e.name} = ${e.prefixed_name('vk_tramp')}, + % if e.guard is not None: +#endif + % endif +% endfor +}; + +% for e in device_entrypoints: + % if e.alias: + <% continue %> + % endif + % if e.guard is not None: +#ifdef ${e.guard} + % endif +static ${e.return_type} +${e.prefixed_name('vk_tramp')}(${e.decl_params()}) +{ + % if e.params[0].type == 'VkDevice': + VK_FROM_HANDLE(vk_device, vk_device, ${e.params[0].name}); + return vk_device->dispatch_table.${e.name}(${e.call_params()}); + % elif e.params[0].type in ('VkCommandBuffer', 'VkQueue'): + struct vk_object_base *vk_object = (struct vk_object_base *)${e.params[0].name}; + return vk_object->device->dispatch_table.${e.name}(${e.call_params()}); + % else: + assert(!"Unhandled device child trampoline case: ${e.params[0].type}"); + % endif +} + % if e.guard is not None: +#endif + % endif +% endfor + +struct vk_device_dispatch_table vk_device_trampolines = { +% for e in device_entrypoints: + % if e.alias: + <% continue %> + % endif + % if e.guard is not None: +#ifdef ${e.guard} + % endif + .${e.name} = ${e.prefixed_name('vk_tramp')}, + % if e.guard is not None: +#endif + % endif +% endfor +}; """, output_encoding='utf-8') U32_MASK = 2**32 - 1 diff --git a/src/vulkan/util/vk_instance.h b/src/vulkan/util/vk_instance.h index 8704a76c3b7..3e13464fcec 100644 --- a/src/vulkan/util/vk_instance.h +++ b/src/vulkan/util/vk_instance.h @@ -49,6 +49,9 @@ struct vk_instance { struct vk_instance_dispatch_table dispatch_table; }; +VK_DEFINE_HANDLE_CASTS(vk_instance, base, VkInstance, + VK_OBJECT_TYPE_INSTANCE) + VkResult MUST_CHECK vk_instance_init(struct vk_instance *instance, const struct vk_instance_extension_table *supported_extensions, diff --git a/src/vulkan/util/vk_object.c b/src/vulkan/util/vk_object.c index 291ef1f33c4..191811fd2a8 100644 --- a/src/vulkan/util/vk_object.c +++ b/src/vulkan/util/vk_object.c @@ -29,12 +29,13 @@ #include "util/ralloc.h" void -vk_object_base_init(UNUSED struct vk_device *device, +vk_object_base_init(struct vk_device *device, struct vk_object_base *base, UNUSED VkObjectType obj_type) { base->_loader_data.loaderMagic = ICD_LOADER_MAGIC; base->type = obj_type; + base->device = device; util_sparse_array_init(&base->private_data, sizeof(uint64_t), 8); } diff --git a/src/vulkan/util/vk_object.h b/src/vulkan/util/vk_object.h index ee957b77aac..27d8d2949e9 100644 --- a/src/vulkan/util/vk_object.h +++ b/src/vulkan/util/vk_object.h @@ -42,6 +42,8 @@ struct vk_object_base { VK_LOADER_DATA _loader_data; VkObjectType type; + struct vk_device *device; + /* For VK_EXT_private_data */ struct util_sparse_array private_data; }; diff --git a/src/vulkan/util/vk_physical_device.h b/src/vulkan/util/vk_physical_device.h index a490a6642a7..fea39ae9d17 100644 --- a/src/vulkan/util/vk_physical_device.h +++ b/src/vulkan/util/vk_physical_device.h @@ -40,6 +40,9 @@ struct vk_physical_device { struct vk_physical_device_dispatch_table dispatch_table; }; +VK_DEFINE_HANDLE_CASTS(vk_physical_device, base, VkPhysicalDevice, + VK_OBJECT_TYPE_PHYSICAL_DEVICE) + VkResult MUST_CHECK vk_physical_device_init(struct vk_physical_device *physical_device, struct vk_instance *instance,