From 4d20399bfc9173c6da834e737648502a8cc5b7b5 Mon Sep 17 00:00:00 2001 From: Charles Giessen Date: Mon, 23 Jun 2025 13:51:57 -0500 Subject: [PATCH] Cleanup command extension checking of device functions Remove some TODO's about needing the detailed dependency info of a command. Commands from extensions are available if any of the extensions they come from are enabled. The extensions themselves have complex requirements for enabling, but because the loader tries to do basic validation, it should only check that the primary extensions are available. This is so that the loader doesn't replicate all of the complicated dependency checking logic that already present in the Validation Layer. --- loader/generated/vk_loader_extensions.c | 8 ++--- .../generators/loader_extension_generator.py | 33 +++++-------------- 2 files changed, 13 insertions(+), 28 deletions(-) diff --git a/loader/generated/vk_loader_extensions.c b/loader/generated/vk_loader_extensions.c index 1afd2efa9..dc80940a8 100644 --- a/loader/generated/vk_loader_extensions.c +++ b/loader/generated/vk_loader_extensions.c @@ -1627,7 +1627,7 @@ void init_extension_device_proc_terminator_dispatch(struct loader_device *dev) { // ---- VK_KHR_swapchain extension commands if (dev->driver_extensions.khr_swapchain_enabled) dispatch->CreateSwapchainKHR = (PFN_vkCreateSwapchainKHR)gpda(dev->icd_device, "vkCreateSwapchainKHR"); - if (dev->driver_extensions.khr_swapchain_enabled) + if (dev->driver_extensions.khr_swapchain_enabled || dev->driver_extensions.khr_device_group_enabled) dispatch->GetDeviceGroupSurfacePresentModesKHR = (PFN_vkGetDeviceGroupSurfacePresentModesKHR)gpda(dev->icd_device, "vkGetDeviceGroupSurfacePresentModesKHR"); // ---- VK_KHR_display_swapchain extension commands @@ -1660,7 +1660,7 @@ void init_extension_device_proc_terminator_dispatch(struct loader_device *dev) { #if defined(VK_USE_PLATFORM_WIN32_KHR) // ---- VK_EXT_full_screen_exclusive extension commands - if (dev->driver_extensions.ext_full_screen_exclusive_enabled && (dev->driver_extensions.khr_device_group_enabled || dev->driver_extensions.version_1_1_enabled)) + if (dev->driver_extensions.ext_full_screen_exclusive_enabled) dispatch->GetDeviceGroupSurfacePresentModes2EXT = (PFN_vkGetDeviceGroupSurfacePresentModes2EXT)gpda(dev->icd_device, "vkGetDeviceGroupSurfacePresentModes2EXT"); #endif // VK_USE_PLATFORM_WIN32_KHR } @@ -13648,7 +13648,7 @@ PFN_vkVoidFunction get_extension_device_proc_terminator(struct loader_device *de } if (!strcmp(name, "GetDeviceGroupSurfacePresentModesKHR")) { *found_name = true; - return dev->driver_extensions.khr_swapchain_enabled ? + return dev->driver_extensions.khr_swapchain_enabled || dev->driver_extensions.khr_device_group_enabled ? (PFN_vkVoidFunction)terminator_GetDeviceGroupSurfacePresentModesKHR : NULL; } // ---- VK_KHR_display_swapchain extension commands @@ -13713,7 +13713,7 @@ PFN_vkVoidFunction get_extension_device_proc_terminator(struct loader_device *de // ---- VK_EXT_full_screen_exclusive extension commands if (!strcmp(name, "GetDeviceGroupSurfacePresentModes2EXT")) { *found_name = true; - return (dev->driver_extensions.ext_full_screen_exclusive_enabled && (dev->driver_extensions.khr_device_group_enabled || dev->driver_extensions.version_1_1_enabled)) ? + return dev->driver_extensions.ext_full_screen_exclusive_enabled ? (PFN_vkVoidFunction)terminator_GetDeviceGroupSurfacePresentModes2EXT : NULL; } #endif // VK_USE_PLATFORM_WIN32_KHR diff --git a/scripts/generators/loader_extension_generator.py b/scripts/generators/loader_extension_generator.py index 3b7e77442..7d3f2543b 100644 --- a/scripts/generators/loader_extension_generator.py +++ b/scripts/generators/loader_extension_generator.py @@ -249,16 +249,6 @@ def print_vk_layer_dispatch_table(self, out): self.OutputLayerInstanceDispatchTable(out) self.OutputLayerDeviceDispatchTable(out) - # Convert an XML dependency expression to a C expression, taking a callback to replace extension names - # See https://registry.khronos.org/vulkan/specs/1.4/registry.html#depends-expressions - @staticmethod - def ConvertDependencyExpression(expr, replace_func): - # '(' and ')' can pass through unchanged - expr = re.sub(',', ' || ', expr) - expr = re.sub(r'\+', ' && ', expr) - expr = re.sub(r'\w+', lambda match: replace_func(match.group()), expr) - return expr - def DescribeBlock(self, command, current_block, out, custom_commands_string = ' commands', indent = ' '): effective_version_name = APISpecific.getEffectiveVersionName(self.targetApiName, command.version) if command.extensions != current_block and effective_version_name != current_block: @@ -664,14 +654,11 @@ def InitDeviceFunctionTerminatorDispatchTable(self, out): out.append(f'#if defined({command.protect})\n') current_block = self.DescribeBlock(command, current_block, out) - if command.name == 'vkGetDeviceGroupSurfacePresentModes2EXT': # command.extensions[0].depends in [x for x in self.vk.commands.values() if x.device]: - # Hardcode the dependency expression as vulkan_object.py doesn't expose this information - dep_expr = self.ConvertDependencyExpression('VK_KHR_device_group,VK_VERSION_1_1', lambda ext_name: f'dev->driver_extensions.{ext_name[3:].lower()}_enabled') - out.append(f' if (dev->driver_extensions.{command.extensions[0][3:].lower()}_enabled && ({dep_expr}))\n') - out.append(f' dispatch->{command.name[2:]} = (PFN_{(command.name)})gpda(dev->icd_device, "{(command.name)}");\n') - else: - out.append(f' if (dev->driver_extensions.{command.extensions[0][3:].lower()}_enabled)\n') - out.append(f' dispatch->{command.name[2:]} = (PFN_{(command.name)})gpda(dev->icd_device, "{(command.name)}");\n') + enable_extension_expressions = [] + for ext in command.extensions: + enable_extension_expressions.append(f'dev->driver_extensions.{ext[3:].lower()}_enabled') + out.append(f' if ({" || ".join(enable_extension_expressions)})\n') + out.append(f' dispatch->{command.name[2:]} = (PFN_{(command.name)})gpda(dev->icd_device, "{(command.name)}");\n') if command.protect is not None: out.append(f'#endif // {command.protect}\n') @@ -1304,12 +1291,10 @@ def DeviceExtensionGetTerminator(self, out): out.append(f' if (!strcmp(name, "{command.name[2:]}")) {{\n') out.append(' *found_name = true;\n') - if command.name == 'vkGetDeviceGroupSurfacePresentModes2EXT': # command.extensions[0].depends in [x for x in self.vk.commands.values() if x.device]: - # Hardcode the dependency expression as vulkan_object.py doesn't expose this information - dep_expr = self.ConvertDependencyExpression('VK_KHR_device_group,VK_VERSION_1_1', lambda ext_name: f'dev->driver_extensions.{ext_name[3:].lower()}_enabled') - out.append(f' return (dev->driver_extensions.{command.extensions[0][3:].lower()}_enabled && ({dep_expr})) ?\n') - else: - out.append(f' return dev->driver_extensions.{command.extensions[0][3:].lower()}_enabled ?\n') + enable_extension_expressions = [] + for ext in command.extensions: + enable_extension_expressions.append(f'dev->driver_extensions.{ext[3:].lower()}_enabled') + out.append(f' return {" || ".join(enable_extension_expressions)} ?\n') out.append(f' (PFN_vkVoidFunction)terminator_{(command.name[2:])} : NULL;\n') out.append(' }\n')