From 813a9504737445987d327f91e360fa96081a0619 Mon Sep 17 00:00:00 2001 From: Charles Giessen Date: Wed, 20 Nov 2024 18:12:48 -0600 Subject: [PATCH] Log what caused each layer to be enabled Adds information about how each layer was enabled, useful for debugging when you are not sure *what* caused a layer to be enabled (in-application API, different environment variables, vkconfig, implicit layer, etc). --- loader/loader.c | 37 ++++++++++++++++++++++++++++++++++++- loader/loader_common.h | 11 +++++++++++ loader/loader_environment.c | 2 ++ loader/settings.c | 5 +++++ 4 files changed, 54 insertions(+), 1 deletion(-) diff --git a/loader/loader.c b/loader/loader.c index 2a287c9db..32c56fe00 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -81,6 +81,7 @@ struct activated_layer_info { char *manifest; char *library; bool is_implicit; + enum loader_layer_enabled_by_what enabled_by_what; char *disable_env; char *enable_name_env; char *enable_value_env; @@ -142,6 +143,29 @@ bool loader_check_version_meets_required(loader_api_version required, loader_api (version.major == required.major && version.minor == required.minor && version.patch >= required.patch); } +const char *get_enabled_by_what_str(enum loader_layer_enabled_by_what enabled_by_what) { + switch (enabled_by_what) { + default: + assert(true && "Shouldn't reach this"); + "Unknown"; + case (ENABLED_BY_WHAT_UNSET): + assert(true && "Shouldn't reach this"); + return "Unknown"; + case (ENABLED_BY_WHAT_LOADER_SETTINGS_FILE): + return "Loader Settings File (Vulkan Configurator)"; + case (ENABLED_BY_WHAT_IMPLICIT_LAYER): + return "Implicit Layer"; + case (ENABLED_BY_WHAT_VK_INSTANCE_LAYERS): + return "Environment Variable VK_INSTANCE_LAYERS"; + case (ENABLED_BY_WHAT_VK_LOADER_LAYERS_ENABLE): + return "Environment Variable VK_LOADER_LAYERS_ENABLE"; + case (ENABLED_BY_WHAT_IN_APPLICATION_API): + return "By the Application"; + case (ENABLED_BY_WHAT_META_LAYER): + return "Meta Layer (Vulkan Configurator)"; + } +} + // Wrapper around opendir so that the dirent_on_windows gets the instance it needs // while linux opendir & readdir does not DIR *loader_opendir(const struct loader_instance *instance, const char *name) { @@ -980,6 +1004,7 @@ VkResult loader_add_layer_names_to_list(const struct loader_instance *inst, cons // If not a meta-layer, simply add it. if (0 == (layer_prop->type_flags & VK_LAYER_TYPE_FLAG_META_LAYER)) { + layer_prop->enabled_by_what = ENABLED_BY_WHAT_IN_APPLICATION_API; err = loader_add_layer_properties_to_list(inst, output_list, layer_prop); if (err == VK_ERROR_OUT_OF_HOST_MEMORY) return err; err = loader_add_layer_properties_to_list(inst, expanded_output_list, layer_prop); @@ -1090,7 +1115,7 @@ VkResult loader_add_implicit_layer(const struct loader_instance *inst, struct lo if (loader_find_layer_name_in_list(&prop->info.layerName[0], target_list)) { return result; } - + prop->enabled_by_what = ENABLED_BY_WHAT_IMPLICIT_LAYER; result = loader_add_layer_properties_to_list(inst, target_list, prop); if (result == VK_ERROR_OUT_OF_HOST_MEMORY) return result; if (NULL != expanded_target_list) { @@ -1135,17 +1160,20 @@ VkResult loader_add_meta_layer(const struct loader_instance *inst, const struct // If the component layer is itself an implicit layer, we need to do the implicit layer enable // checks if (0 == (search_prop->type_flags & VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER)) { + search_prop->enabled_by_what = ENABLED_BY_WHAT_META_LAYER; result = loader_add_implicit_layer(inst, search_prop, filters, target_list, expanded_target_list, source_list); if (result == VK_ERROR_OUT_OF_HOST_MEMORY) return result; } else { if (0 != (search_prop->type_flags & VK_LAYER_TYPE_FLAG_META_LAYER)) { bool found_layers_in_component_meta_layer = true; + search_prop->enabled_by_what = ENABLED_BY_WHAT_META_LAYER; result = loader_add_meta_layer(inst, filters, search_prop, target_list, expanded_target_list, source_list, &found_layers_in_component_meta_layer); if (result == VK_ERROR_OUT_OF_HOST_MEMORY) return result; if (!found_layers_in_component_meta_layer) found_all_component_layers = false; } else if (!loader_find_layer_name_in_list(&search_prop->info.layerName[0], target_list)) { // Make sure the layer isn't already in the output_list, skip adding it if it is. + search_prop->enabled_by_what = ENABLED_BY_WHAT_META_LAYER; result = loader_add_layer_properties_to_list(inst, target_list, search_prop); if (result == VK_ERROR_OUT_OF_HOST_MEMORY) return result; if (NULL != expanded_target_list) { @@ -1164,6 +1192,7 @@ VkResult loader_add_meta_layer(const struct loader_instance *inst, const struct // Add this layer to the overall target list (not the expanded one) if (found_all_component_layers) { + prop->enabled_by_what = ENABLED_BY_WHAT_META_LAYER; result = loader_add_layer_properties_to_list(inst, target_list, prop); if (result == VK_ERROR_OUT_OF_HOST_MEMORY) return result; // Write the result to out_found_all_component_layers in case this function is being recursed @@ -4706,6 +4735,7 @@ VkResult loader_create_instance_chain(const VkInstanceCreateInfo *pCreateInfo, c activated_layers[num_activated_layers].manifest = layer_prop->manifest_file_name; activated_layers[num_activated_layers].library = layer_prop->lib_name; activated_layers[num_activated_layers].is_implicit = !(layer_prop->type_flags & VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER); + activated_layers[num_activated_layers].enabled_by_what = layer_prop->enabled_by_what; if (activated_layers[num_activated_layers].is_implicit) { activated_layers[num_activated_layers].disable_env = layer_prop->disable_env_var.name; activated_layers[num_activated_layers].enable_name_env = layer_prop->enable_env_var.name; @@ -4821,6 +4851,8 @@ VkResult loader_create_instance_chain(const VkInstanceCreateInfo *pCreateInfo, c loader_log(inst, VULKAN_LOADER_LAYER_BIT, 0, " %s", activated_layers[index].name); loader_log(inst, VULKAN_LOADER_LAYER_BIT, 0, " Type: %s", activated_layers[index].is_implicit ? "Implicit" : "Explicit"); + loader_log(inst, VULKAN_LOADER_LAYER_BIT, 0, " Enabled By: %s", + get_enabled_by_what_str(activated_layers[index].enabled_by_what)); if (activated_layers[index].is_implicit) { loader_log(inst, VULKAN_LOADER_LAYER_BIT, 0, " Disable Env Var: %s", activated_layers[index].disable_env); @@ -5055,6 +5087,7 @@ VkResult loader_create_device_chain(const VkPhysicalDevice pd, const VkDeviceCre activated_layers[num_activated_layers].manifest = layer_prop->manifest_file_name; activated_layers[num_activated_layers].library = layer_prop->lib_name; activated_layers[num_activated_layers].is_implicit = !(layer_prop->type_flags & VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER); + activated_layers[num_activated_layers].enabled_by_what = layer_prop->enabled_by_what; if (activated_layers[num_activated_layers].is_implicit) { activated_layers[num_activated_layers].disable_env = layer_prop->disable_env_var.name; } @@ -5089,6 +5122,8 @@ VkResult loader_create_device_chain(const VkPhysicalDevice pd, const VkDeviceCre loader_log(inst, VULKAN_LOADER_LAYER_BIT, 0, " %s", activated_layers[index].name); loader_log(inst, VULKAN_LOADER_LAYER_BIT, 0, " Type: %s", activated_layers[index].is_implicit ? "Implicit" : "Explicit"); + loader_log(inst, VULKAN_LOADER_LAYER_BIT, 0, " Enabled By: %s", + get_enabled_by_what_str(activated_layers[index].enabled_by_what)); if (activated_layers[index].is_implicit) { loader_log(inst, VULKAN_LOADER_LAYER_BIT, 0, " Disable Env Var: %s", activated_layers[index].disable_env); diff --git a/loader/loader_common.h b/loader/loader_common.h index 37b7d23d6..c879ca10a 100644 --- a/loader/loader_common.h +++ b/loader/loader_common.h @@ -163,6 +163,16 @@ enum layer_type_flags { VK_LAYER_TYPE_FLAG_META_LAYER = 0x4, // If not set, indicates standard layer }; +enum loader_layer_enabled_by_what { + ENABLED_BY_WHAT_UNSET, // default value indicates this field hasn't been filled in + ENABLED_BY_WHAT_LOADER_SETTINGS_FILE, + ENABLED_BY_WHAT_IMPLICIT_LAYER, + ENABLED_BY_WHAT_VK_INSTANCE_LAYERS, + ENABLED_BY_WHAT_VK_LOADER_LAYERS_ENABLE, + ENABLED_BY_WHAT_IN_APPLICATION_API, + ENABLED_BY_WHAT_META_LAYER, +}; + struct loader_layer_properties { VkLayerProperties info; enum layer_type_flags type_flags; @@ -172,6 +182,7 @@ struct loader_layer_properties { char *manifest_file_name; char *lib_name; enum loader_layer_library_status lib_status; + enum loader_layer_enabled_by_what enabled_by_what; loader_platform_dl_handle lib_handle; struct loader_layer_functions functions; struct loader_extension_list instance_extension_list; diff --git a/loader/loader_environment.c b/loader/loader_environment.c index 073953234..4f9133ecd 100644 --- a/loader/loader_environment.c +++ b/loader/loader_environment.c @@ -480,6 +480,7 @@ VkResult loader_add_environment_layers(struct loader_instance *inst, const enum // Only add it if it doesn't already appear in the layer list if (!loader_find_layer_name_in_list(source_prop->info.layerName, target_list)) { if (0 == (source_prop->type_flags & VK_LAYER_TYPE_FLAG_META_LAYER)) { + source_prop->enabled_by_what = ENABLED_BY_WHAT_VK_INSTANCE_LAYERS; res = loader_add_layer_properties_to_list(inst, target_list, source_prop); if (res == VK_ERROR_OUT_OF_HOST_MEMORY) goto out; res = loader_add_layer_properties_to_list(inst, expanded_target_list, source_prop); @@ -546,6 +547,7 @@ VkResult loader_add_environment_layers(struct loader_instance *inst, const enum // If not a meta-layer, simply add it. if (0 == (source_prop->type_flags & VK_LAYER_TYPE_FLAG_META_LAYER)) { + source_prop->enabled_by_what = ENABLED_BY_WHAT_VK_LOADER_LAYERS_ENABLE; res = loader_add_layer_properties_to_list(inst, target_list, source_prop); if (res == VK_ERROR_OUT_OF_HOST_MEMORY) goto out; res = loader_add_layer_properties_to_list(inst, expanded_target_list, source_prop); diff --git a/loader/settings.c b/loader/settings.c index 376c9e25f..7222df15d 100644 --- a/loader/settings.c +++ b/loader/settings.c @@ -774,6 +774,7 @@ VkResult enable_correct_layers_from_settings(const struct loader_instance* inst, // Force enable it based on settings if (props->settings_control_value == LOADER_SETTINGS_LAYER_CONTROL_ON) { enable_layer = true; + props->enabled_by_what = ENABLED_BY_WHAT_LOADER_SETTINGS_FILE; } else { // Check if disable filter needs to skip the layer if ((filters->disable_filter.disable_all || filters->disable_filter.disable_all_implicit || @@ -785,6 +786,7 @@ VkResult enable_correct_layers_from_settings(const struct loader_instance* inst, // Check the enable filter if (!enable_layer && check_name_matches_filter_environment_var(props->info.layerName, &filters->enable_filter)) { enable_layer = true; + props->enabled_by_what = ENABLED_BY_WHAT_VK_LOADER_LAYERS_ENABLE; } // First look for the old-fashion layers forced on with VK_INSTANCE_LAYERS @@ -799,6 +801,7 @@ VkResult enable_correct_layers_from_settings(const struct loader_instance* inst, char* next = loader_get_next_path(instance_layers_env_iter); if (0 == strcmp(instance_layers_env_iter, props->info.layerName)) { enable_layer = true; + props->enabled_by_what = ENABLED_BY_WHAT_VK_INSTANCE_LAYERS; break; } instance_layers_env_iter = next; @@ -810,6 +813,7 @@ VkResult enable_correct_layers_from_settings(const struct loader_instance* inst, for (uint32_t j = 0; j < app_enabled_name_count; j++) { if (strcmp(props->info.layerName, app_enabled_names[j]) == 0) { enable_layer = true; + props->enabled_by_what = ENABLED_BY_WHAT_IN_APPLICATION_API; break; } } @@ -819,6 +823,7 @@ VkResult enable_correct_layers_from_settings(const struct loader_instance* inst, if (!enable_layer && (0 == (props->type_flags & VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER)) && loader_implicit_layer_is_enabled(inst, filters, props)) { enable_layer = true; + props->enabled_by_what = ENABLED_BY_WHAT_IMPLICIT_LAYER; } if (enable_layer) {