From a8c02e7b5d514eef09db4ab3e8096773c5391b22 Mon Sep 17 00:00:00 2001 From: Daniel Rakos Date: Mon, 31 Aug 2026 14:16:09 +0200 Subject: [PATCH] loader: Remove limit on number of ID filters --- loader/loader.c | 14 +++++++------- loader/loader.h | 14 +++++++------- loader/loader_common.h | 2 +- loader/loader_environment.c | 20 ++++++++++++-------- loader/loader_environment.h | 1 + loader/trampoline.c | 28 +++++++++++++++++----------- 6 files changed, 45 insertions(+), 34 deletions(-) diff --git a/loader/loader.c b/loader/loader.c index eb753f6a6..7a547fd37 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -8277,13 +8277,13 @@ VkResult get_device_driver_id(VkPhysicalDevice physicalDevice, VkDriverId *drive return VK_SUCCESS; } -VkResult loader_filter_enumerated_physical_device(const struct loader_instance *inst, - const struct loader_envvar_id_filter *device_id_filter, - const struct loader_envvar_id_filter *vendor_id_filter, - const struct loader_envvar_id_filter *driver_id_filter, - const uint32_t in_PhysicalDeviceCount, - const VkPhysicalDevice *in_pPhysicalDevices, uint32_t *out_pPhysicalDeviceCount, - VkPhysicalDevice *out_pPhysicalDevices) { +VkResult loader_filter_enumerated_physical_devices(const struct loader_instance *inst, + const struct loader_envvar_id_filter *device_id_filter, + const struct loader_envvar_id_filter *vendor_id_filter, + const struct loader_envvar_id_filter *driver_id_filter, + const uint32_t in_PhysicalDeviceCount, + const VkPhysicalDevice *in_pPhysicalDevices, uint32_t *out_pPhysicalDeviceCount, + VkPhysicalDevice *out_pPhysicalDevices) { uint32_t filtered_physical_device_count = 0; for (uint32_t i = 0; i < in_PhysicalDeviceCount; i++) { VkPhysicalDeviceProperties dev_props = {0}; diff --git a/loader/loader.h b/loader/loader.h index ceb8db8cc..0db8f223c 100644 --- a/loader/loader.h +++ b/loader/loader.h @@ -248,13 +248,13 @@ bool loader_check_version_meets_required(loader_api_version required, loader_api // Helper that returns true if the string passed in path ends in .json bool is_json(const char *path, size_t len); -VkResult loader_filter_enumerated_physical_device(const struct loader_instance *inst, - const struct loader_envvar_id_filter *device_id_filter, - const struct loader_envvar_id_filter *vendor_id_filter, - const struct loader_envvar_id_filter *driver_id_filter, - const uint32_t in_PhysicalDeviceCount, - const VkPhysicalDevice *in_pPhysicalDevices, uint32_t *out_pPhysicalDeviceCount, - VkPhysicalDevice *out_pPhysicalDevices); +VkResult loader_filter_enumerated_physical_devices(const struct loader_instance *inst, + const struct loader_envvar_id_filter *device_id_filter, + const struct loader_envvar_id_filter *vendor_id_filter, + const struct loader_envvar_id_filter *driver_id_filter, + const uint32_t in_PhysicalDeviceCount, + const VkPhysicalDevice *in_pPhysicalDevices, uint32_t *out_pPhysicalDeviceCount, + VkPhysicalDevice *out_pPhysicalDevices); VkResult loader_filter_enumerated_physical_device_groups( const struct loader_instance *inst, const struct loader_envvar_id_filter *device_id_filter, diff --git a/loader/loader_common.h b/loader/loader_common.h index aa1458810..65617481c 100644 --- a/loader/loader_common.h +++ b/loader/loader_common.h @@ -553,5 +553,5 @@ struct loader_envvar_id_filter_value { struct loader_envvar_id_filter { uint32_t count; - struct loader_envvar_id_filter_value filters[MAX_ADDITIONAL_FILTERS]; + struct loader_envvar_id_filter_value *filters; }; diff --git a/loader/loader_environment.c b/loader/loader_environment.c index 709747149..bdda1a0cc 100644 --- a/loader/loader_environment.c +++ b/loader/loader_environment.c @@ -577,24 +577,22 @@ void parse_id_filter_environment_var(const struct loader_instance *inst, const c goto out; } // Allocate a separate string since scan_for_next_comma modifies the original string + uint32_t num_commas = 0; parsing_string = loader_stack_alloc(env_var_len + 1); for (uint32_t iii = 0; iii < env_var_len; ++iii) { + if (env_var_value[iii] == ',') { + num_commas++; + } parsing_string[iii] = (char)tolower((unsigned char)env_var_value[iii]); } parsing_string[env_var_len] = '\0'; + filter_struct->filters = (struct loader_envvar_id_filter_value *)loader_instance_heap_alloc( + inst, (num_commas + 1) * sizeof(struct loader_envvar_id_filter_value), VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); filter_struct->count = 0; char *context = NULL; char *token = thread_safe_strtok(parsing_string, ",", &context); while (NULL != token) { - if (filter_struct->count >= MAX_ADDITIONAL_FILTERS) { - loader_log(inst, VULKAN_LOADER_WARN_BIT, 0, - "parse_id_filter_environment_var: Exceeded maximum number of filters (%d) for env var '%s'. " - "Remaining entries will be ignored.", - MAX_ADDITIONAL_FILTERS, env_var_name); - break; - } - struct loader_envvar_id_filter_value *filter_value = &filter_struct->filters[filter_struct->count]; char *pEnd; @@ -624,3 +622,9 @@ bool check_id_matches_filter_environment_var(const uint32_t id, const struct loa } return false; } + +void free_id_filters(const struct loader_instance *inst, struct loader_envvar_id_filter *filter_struct) { + if (filter_struct != NULL && filter_struct->filters != NULL) { + loader_instance_heap_free(inst, filter_struct->filters); + } +} diff --git a/loader/loader_environment.h b/loader/loader_environment.h index 319e85d8b..b339a53bb 100644 --- a/loader/loader_environment.h +++ b/loader/loader_environment.h @@ -58,3 +58,4 @@ VkResult loader_add_environment_layers(struct loader_instance *inst, const char void parse_id_filter_environment_var(const struct loader_instance *inst, const char *env_var_name, struct loader_envvar_id_filter *filter_struct); bool check_id_matches_filter_environment_var(const uint32_t id, const struct loader_envvar_id_filter *filter_struct); +void free_id_filters(const struct loader_instance *inst, struct loader_envvar_id_filter *filter_struct); diff --git a/loader/trampoline.c b/loader/trampoline.c index 0a1dc7d0b..5fe35d21f 100644 --- a/loader/trampoline.c +++ b/loader/trampoline.c @@ -874,6 +874,10 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDevices(VkInstan VkResult res = VK_SUCCESS; struct loader_instance *inst; + struct loader_envvar_id_filter device_id_filter = {0, NULL}; + struct loader_envvar_id_filter vendor_id_filter = {0, NULL}; + struct loader_envvar_id_filter driver_id_filter = {0, NULL}; + loader_platform_thread_lock_mutex(&loader_lock); inst = loader_get_instance(instance); @@ -891,10 +895,6 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDevices(VkInstan goto out; } - struct loader_envvar_id_filter device_id_filter; - struct loader_envvar_id_filter vendor_id_filter; - struct loader_envvar_id_filter driver_id_filter; - parse_id_filter_environment_var(inst, VK_DEVICE_ID_FILTER_ENV_VAR, &device_id_filter); parse_id_filter_environment_var(inst, VK_VENDOR_ID_FILTER_ENV_VAR, &vendor_id_filter); parse_id_filter_environment_var(inst, VK_DRIVER_ID_FILTER_ENV_VAR, &driver_id_filter); @@ -915,9 +915,9 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDevices(VkInstan goto out; } - res = loader_filter_enumerated_physical_device(inst, &device_id_filter, &vendor_id_filter, &driver_id_filter, - physical_device_count, physical_devices, pPhysicalDeviceCount, - pPhysicalDevices); + res = loader_filter_enumerated_physical_devices(inst, &device_id_filter, &vendor_id_filter, &driver_id_filter, + physical_device_count, physical_devices, pPhysicalDeviceCount, + pPhysicalDevices); } if (NULL != pPhysicalDevices && (VK_SUCCESS == res || VK_INCOMPLETE == res)) { @@ -932,6 +932,9 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDevices(VkInstan } out: + free_id_filters(inst, &device_id_filter); + free_id_filters(inst, &vendor_id_filter); + free_id_filters(inst, &driver_id_filter); loader_platform_thread_unlock_mutex(&loader_lock); @@ -2634,6 +2637,10 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDeviceGroups( VkResult res = VK_SUCCESS; struct loader_instance *inst = NULL; + struct loader_envvar_id_filter device_id_filter = {0, NULL}; + struct loader_envvar_id_filter vendor_id_filter = {0, NULL}; + struct loader_envvar_id_filter driver_id_filter = {0, NULL}; + loader_platform_thread_lock_mutex(&loader_lock); inst = loader_get_instance(instance); @@ -2651,10 +2658,6 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDeviceGroups( goto out; } - struct loader_envvar_id_filter device_id_filter; - struct loader_envvar_id_filter vendor_id_filter; - struct loader_envvar_id_filter driver_id_filter; - parse_id_filter_environment_var(inst, VK_DEVICE_ID_FILTER_ENV_VAR, &device_id_filter); parse_id_filter_environment_var(inst, VK_VENDOR_ID_FILTER_ENV_VAR, &vendor_id_filter); parse_id_filter_environment_var(inst, VK_DRIVER_ID_FILTER_ENV_VAR, &driver_id_filter); @@ -2694,6 +2697,9 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDeviceGroups( } out: + free_id_filters(inst, &device_id_filter); + free_id_filters(inst, &vendor_id_filter); + free_id_filters(inst, &driver_id_filter); loader_platform_thread_unlock_mutex(&loader_lock); return res;