From e61e41e9a7466526fa5fc461e74a9df2b216ab9e Mon Sep 17 00:00:00 2001 From: Peter Harris Date: Fri, 14 Feb 2025 10:28:07 +0000 Subject: [PATCH 1/3] Avoid resolving shared object entrypoints as function pointers --- generator/generate_vulkan_common.py | 24 ++++--------------- .../framework/instance_dispatch_table.hpp | 4 ++++ source_common/framework/manual_functions.cpp | 24 +++++-------------- 3 files changed, 15 insertions(+), 37 deletions(-) diff --git a/generator/generate_vulkan_common.py b/generator/generate_vulkan_common.py index ce273bb..51957bd 100755 --- a/generator/generate_vulkan_common.py +++ b/generator/generate_vulkan_common.py @@ -46,15 +46,6 @@ 'vkGetInstanceProcAddr', } -# These functions are excluded from generated intercept tables -NO_INTERCEPT_FUNCTIONS = { - # Functions exported as shared object symbols and resolved by loader - 'vkEnumerateDeviceExtensionProperties', - 'vkEnumerateDeviceLayerProperties', - 'vkEnumerateInstanceExtensionProperties', - 'vkEnumerateInstanceLayerProperties', -} - # These functions are excluded from generated dispatch tables NO_DISPATCH_FUNCTIONS = { # Functions resolved by the loader not the implementation @@ -434,7 +425,6 @@ def generate_instance_dispatch_table( continue assert command.name - if command.name in NO_INTERCEPT_OR_DISPATCH_FUNCTIONS: continue @@ -442,13 +432,12 @@ def generate_instance_dispatch_table( ttype = f'PFN_{command.name}' - if command.name not in NO_INTERCEPT_FUNCTIONS: - if plat_define: - itable_members.append(f'#if defined({plat_define})') + if plat_define: + itable_members.append(f'#if defined({plat_define})') - itable_members.append(f' ENTRY({command.name}),') - if plat_define: - itable_members.append('#endif') + itable_members.append(f' ENTRY({command.name}),') + if plat_define: + itable_members.append('#endif') if command.name not in NO_DISPATCH_FUNCTIONS: if plat_define: @@ -586,9 +575,6 @@ def generate_instance_defs( continue assert command.name - if command.name in NO_INTERCEPT_FUNCTIONS: - continue - if command.name in CUSTOM_FUNCTIONS: continue diff --git a/source_common/framework/instance_dispatch_table.hpp b/source_common/framework/instance_dispatch_table.hpp index 8114645..688fa8e 100644 --- a/source_common/framework/instance_dispatch_table.hpp +++ b/source_common/framework/instance_dispatch_table.hpp @@ -75,6 +75,10 @@ static const struct InstanceInterceptTableEntry instanceIntercepts[] = { ENTRY(vkDestroyDebugUtilsMessengerEXT), ENTRY(vkDestroyInstance), ENTRY(vkDestroySurfaceKHR), + ENTRY(vkEnumerateDeviceExtensionProperties), + ENTRY(vkEnumerateDeviceLayerProperties), + ENTRY(vkEnumerateInstanceExtensionProperties), + ENTRY(vkEnumerateInstanceLayerProperties), ENTRY(vkEnumeratePhysicalDeviceGroups), ENTRY(vkEnumeratePhysicalDeviceGroupsKHR), ENTRY(vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR), diff --git a/source_common/framework/manual_functions.cpp b/source_common/framework/manual_functions.cpp index b9b3389..751d785 100644 --- a/source_common/framework/manual_functions.cpp +++ b/source_common/framework/manual_functions.cpp @@ -67,17 +67,9 @@ struct DispatchTableEntry /** * @brief Utility macro to define a lookup for a core function. */ -#define VK_TABLE_ENTRY(func) \ - { \ - STR(func), reinterpret_cast(func) \ - } - -/** - * @brief Utility macro to define a lookup for a layer-dispatch-only function. - */ -#define VK_TABLE_ENTRYL(func) \ - { \ - STR(func), reinterpret_cast(layer_##func) \ +#define VK_TABLE_ENTRY(func) \ + { \ + STR(func), reinterpret_cast(layer_##func) \ } /* See header for documentation. */ @@ -122,11 +114,7 @@ VkLayerDeviceCreateInfo* getChainInfo(const VkDeviceCreateInfo* pCreateInfo) PFN_vkVoidFunction getFixedInstanceLayerFunction(const char* name) { static const DispatchTableEntry layerFunctions[] = { - VK_TABLE_ENTRY(vkGetInstanceProcAddr), - VK_TABLE_ENTRY(vkEnumerateDeviceLayerProperties), - VK_TABLE_ENTRY(vkEnumerateDeviceExtensionProperties), - VK_TABLE_ENTRY(vkEnumerateInstanceLayerProperties), - VK_TABLE_ENTRY(vkEnumerateInstanceExtensionProperties), + VK_TABLE_ENTRY(vkGetInstanceProcAddr) }; for (auto& function : layerFunctions) @@ -159,8 +147,7 @@ PFN_vkVoidFunction getDeviceLayerFunction(const char* name) { static const DispatchTableEntry layerFunctions[] = { VK_TABLE_ENTRY(vkGetDeviceProcAddr), - VK_TABLE_ENTRY(vkEnumerateDeviceExtensionProperties), - VK_TABLE_ENTRY(vkEnumerateDeviceLayerProperties), + }; for (auto& function : layerFunctions) @@ -667,6 +654,7 @@ VkResult layer_vkEnumerateDeviceExtensionProperties_default(VkPhysicalDevice gpu // For other cases forward to the driver to handle it assert(!pLayerName); + assert(gpu); // Hold the lock to access layer-wide global store std::unique_lock lock {g_vulkanLock}; From 16ae9893ceeecbdf01a2ef695886b21f8511f077 Mon Sep 17 00:00:00 2001 From: Peter Harris Date: Fri, 14 Feb 2025 10:51:34 +0000 Subject: [PATCH 2/3] Fix typo --- generator/generate_vulkan_common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generator/generate_vulkan_common.py b/generator/generate_vulkan_common.py index 51957bd..6b62c07 100755 --- a/generator/generate_vulkan_common.py +++ b/generator/generate_vulkan_common.py @@ -41,7 +41,7 @@ # These functions are excluded from generated intercept and dispatch tables NO_INTERCEPT_OR_DISPATCH_FUNCTIONS = { - # Functions resolved by the loaded not the implementation + # Functions resolved by the loader not the implementation 'vkGetDeviceProcAddr', 'vkGetInstanceProcAddr', } From 7594850df8706d3c11880eaf83c5f10ac434685a Mon Sep 17 00:00:00 2001 From: Peter Harris Date: Fri, 14 Feb 2025 12:21:39 +0000 Subject: [PATCH 3/3] Simplify dispatch more --- generator/generate_vulkan_common.py | 39 +++++++--------- .../framework/device_dispatch_table.hpp | 1 + .../framework/instance_dispatch_table.hpp | 1 + source_common/framework/manual_functions.cpp | 44 ++----------------- 4 files changed, 22 insertions(+), 63 deletions(-) diff --git a/generator/generate_vulkan_common.py b/generator/generate_vulkan_common.py index 6b62c07..2c4fcd4 100755 --- a/generator/generate_vulkan_common.py +++ b/generator/generate_vulkan_common.py @@ -39,19 +39,14 @@ 'vkEnumerateInstanceVersion', } -# These functions are excluded from generated intercept and dispatch tables -NO_INTERCEPT_OR_DISPATCH_FUNCTIONS = { - # Functions resolved by the loader not the implementation - 'vkGetDeviceProcAddr', - 'vkGetInstanceProcAddr', -} - # These functions are excluded from generated dispatch tables NO_DISPATCH_FUNCTIONS = { # Functions resolved by the loader not the implementation 'vkCreateDevice', 'vkCreateInstance', 'vkEnumerateInstanceExtensionProperties', + 'vkGetDeviceProcAddr', + 'vkGetInstanceProcAddr', } # These functions are excluded from generated declarations @@ -60,13 +55,13 @@ 'vkCreateInstance', 'vkDestroyDevice', 'vkDestroyInstance', - 'vkGetDeviceProcAddr', - 'vkGetInstanceProcAddr', 'vkEnumerateDeviceExtensionProperties', 'vkEnumerateDeviceLayerProperties', 'vkEnumerateInstanceExtensionProperties', 'vkEnumerateInstanceLayerProperties', 'vkGetDeviceImageMemoryRequirementsKHR', + 'vkGetDeviceProcAddr', + 'vkGetInstanceProcAddr', } # Filter out extensions from these vendors by default @@ -425,17 +420,14 @@ def generate_instance_dispatch_table( continue assert command.name - if command.name in NO_INTERCEPT_OR_DISPATCH_FUNCTIONS: - continue - plat_define = mapping.get_platform_define(command.name) - ttype = f'PFN_{command.name}' if plat_define: itable_members.append(f'#if defined({plat_define})') itable_members.append(f' ENTRY({command.name}),') + if plat_define: itable_members.append('#endif') @@ -643,25 +635,28 @@ def generate_device_dispatch_table( continue assert command.name - if command.name in NO_INTERCEPT_OR_DISPATCH_FUNCTIONS: - continue - plat_define = mapping.get_platform_define(command.name) ttype = f'PFN_{command.name}' if plat_define: itable_members.append(f'#if defined({plat_define})') - dispatch_table_members.append(f'#if defined({plat_define})') - dispatch_table_inits.append(f'#if defined({plat_define})') itable_members.append(f' ENTRY({command.name}),') - dispatch_table_members.append(f' {ttype} {command.name};') - dispatch_table_inits.append(f' ENTRY({command.name});') if plat_define: itable_members.append('#endif') - dispatch_table_members.append('#endif') - dispatch_table_inits.append('#endif') + + if command.name not in NO_DISPATCH_FUNCTIONS: + if plat_define: + dispatch_table_members.append(f'#if defined({plat_define})') + dispatch_table_inits.append(f'#if defined({plat_define})') + + dispatch_table_members.append(f' {ttype} {command.name};') + dispatch_table_inits.append(f' ENTRY({command.name});') + + if plat_define: + dispatch_table_members.append('#endif') + dispatch_table_inits.append('#endif') data = data.replace('{ITABLE_MEMBERS}', '\n'.join(itable_members)) data = data.replace('{DTABLE_MEMBERS}', '\n'.join(dispatch_table_members)) diff --git a/source_common/framework/device_dispatch_table.hpp b/source_common/framework/device_dispatch_table.hpp index d5ea701..a19c09d 100644 --- a/source_common/framework/device_dispatch_table.hpp +++ b/source_common/framework/device_dispatch_table.hpp @@ -407,6 +407,7 @@ static const struct DeviceInterceptTableEntry deviceIntercepts[] = { ENTRY(vkGetDeviceMemoryOpaqueCaptureAddress), ENTRY(vkGetDeviceMemoryOpaqueCaptureAddressKHR), ENTRY(vkGetDeviceMicromapCompatibilityEXT), + ENTRY(vkGetDeviceProcAddr), ENTRY(vkGetDeviceQueue), ENTRY(vkGetDeviceQueue2), ENTRY(vkGetEventStatus), diff --git a/source_common/framework/instance_dispatch_table.hpp b/source_common/framework/instance_dispatch_table.hpp index 688fa8e..cd35e46 100644 --- a/source_common/framework/instance_dispatch_table.hpp +++ b/source_common/framework/instance_dispatch_table.hpp @@ -88,6 +88,7 @@ static const struct InstanceInterceptTableEntry instanceIntercepts[] = { ENTRY(vkGetDisplayPlaneCapabilities2KHR), ENTRY(vkGetDisplayPlaneCapabilitiesKHR), ENTRY(vkGetDisplayPlaneSupportedDisplaysKHR), + ENTRY(vkGetInstanceProcAddr), ENTRY(vkGetPhysicalDeviceCalibrateableTimeDomainsEXT), ENTRY(vkGetPhysicalDeviceCalibrateableTimeDomainsKHR), ENTRY(vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR), diff --git a/source_common/framework/manual_functions.cpp b/source_common/framework/manual_functions.cpp index 751d785..5a35e19 100644 --- a/source_common/framework/manual_functions.cpp +++ b/source_common/framework/manual_functions.cpp @@ -110,24 +110,6 @@ VkLayerDeviceCreateInfo* getChainInfo(const VkDeviceCreateInfo* pCreateInfo) return const_cast(info); } -/* See header for documentation. */ -PFN_vkVoidFunction getFixedInstanceLayerFunction(const char* name) -{ - static const DispatchTableEntry layerFunctions[] = { - VK_TABLE_ENTRY(vkGetInstanceProcAddr) - }; - - for (auto& function : layerFunctions) - { - if (!strcmp(function.name, name)) - { - return function.function; - } - } - - return nullptr; -} - /* See header for documentation. */ PFN_vkVoidFunction getInstanceLayerFunction(const char* name) { @@ -145,19 +127,6 @@ PFN_vkVoidFunction getInstanceLayerFunction(const char* name) /* See header for documentation. */ PFN_vkVoidFunction getDeviceLayerFunction(const char* name) { - static const DispatchTableEntry layerFunctions[] = { - VK_TABLE_ENTRY(vkGetDeviceProcAddr), - - }; - - for (auto& function : layerFunctions) - { - if (!strcmp(function.name, name)) - { - return function.function; - } - } - for (auto& function : deviceIntercepts) { if (!strcmp(function.name, name)) @@ -557,16 +526,9 @@ static void enableDeviceVkExtImageCompressionControl(VkDeviceCreateInfo& createI /** See Vulkan API for documentation. */ PFN_vkVoidFunction layer_vkGetInstanceProcAddr_default(VkInstance instance, const char* pName) { - // Always expose these functions ... - PFN_vkVoidFunction layerFunction = getFixedInstanceLayerFunction(pName); - if (layerFunction) - { - return layerFunction; - } - - // Otherwise, only expose functions that the driver exposes to avoid - // changing queryable interface behavior seen by the application - layerFunction = getInstanceLayerFunction(pName); + // Only expose functions that the driver exposes to avoid changing + // queryable interface behavior seen by the application + auto layerFunction = getInstanceLayerFunction(pName); if (instance) { std::unique_lock lock {g_vulkanLock};