Move filter Env-Var parsing to top level functions
authorCharles Giessen <charles@lunarg.com>
Tue, 1 Aug 2023 20:56:57 +0000 (14:56 -0600)
committerCharles Giessen <46324611+charles-lunarg@users.noreply.github.com>
Wed, 9 Aug 2023 19:50:28 +0000 (13:50 -0600)
The loader was querying the layer environment variable filters multiple
times during instance creation. The solution is to move the queries out
of the function that use them and do them once at the start of every
API call that needs them. That way the filters can be passed into each
function and shared.

loader/loader.c
loader/loader.h
loader/loader_environment.c
loader/loader_environment.h
loader/trampoline.c

index 00688a69629c3282ff72d5255a0a3503d45270d1..283879cafda908140b5139e4d34fea27654c6679 100644 (file)
@@ -3552,8 +3552,8 @@ VkResult loader_icd_scan(const struct loader_instance *inst, struct loader_icd_t
                          const VkInstanceCreateInfo *pCreateInfo, bool *skipped_portability_drivers) {
     VkResult res = VK_SUCCESS;
     struct loader_string_list manifest_files = {0};
-    struct loader_envvar_filter select_filter;
-    struct loader_envvar_filter disable_filter;
+    struct loader_envvar_filter select_filter = {0};
+    struct loader_envvar_filter disable_filter = {0};
     struct ICDManifestInfo *icd_details = NULL;
 
     // Set up the ICD Trampoline list so elements can be written into it.
@@ -3753,13 +3753,13 @@ VkResult get_override_layer_override_paths(struct loader_instance *inst, struct
     return VK_SUCCESS;
 }
 
-VkResult loader_scan_for_layers(struct loader_instance *inst, struct loader_layer_list *instance_layers) {
+VkResult loader_scan_for_layers(struct loader_instance *inst, struct loader_layer_list *instance_layers,
+                                const struct loader_envvar_all_filters *filters) {
     VkResult res = VK_SUCCESS;
     struct loader_layer_list settings_layers = {0};
     struct loader_layer_list regular_instance_layers = {0};
     bool override_layer_valid = false;
     char *override_paths = NULL;
-    struct loader_envvar_all_filters filters = {0};
 
     bool should_search_for_other_layers = true;
     res = get_settings_layers(inst, &settings_layers, &should_search_for_other_layers);
@@ -3775,16 +3775,6 @@ VkResult loader_scan_for_layers(struct loader_instance *inst, struct loader_laye
         goto out;
     }
 
-    // Parse the filter environment variables to determine if we have any special behavior
-    res = parse_generic_filter_environment_var(inst, VK_LAYERS_ENABLE_ENV_VAR, &filters.enable_filter);
-    if (VK_SUCCESS != res) {
-        goto out;
-    }
-    res = parse_layers_disable_filter_environment_var(inst, &filters.disable_filter);
-    if (VK_SUCCESS != res) {
-        goto out;
-    }
-
     res = loader_parse_instance_layers(inst, LOADER_DATA_FILE_MANIFEST_IMPLICIT_LAYER, NULL, &regular_instance_layers);
     if (VK_SUCCESS != res) {
         goto out;
@@ -3796,7 +3786,7 @@ VkResult loader_scan_for_layers(struct loader_instance *inst, struct loader_laye
     // Check to see if the override layer is present, and use it's override paths.
     for (uint32_t i = 0; i < regular_instance_layers.count; i++) {
         struct loader_layer_properties *prop = &regular_instance_layers.list[i];
-        if (prop->is_override && loader_implicit_layer_is_enabled(inst, &filters, prop) && prop->override_paths.count > 0) {
+        if (prop->is_override && loader_implicit_layer_is_enabled(inst, filters, prop) && prop->override_paths.count > 0) {
             res = get_override_layer_override_paths(inst, prop, &override_paths);
             if (VK_SUCCESS != res) {
                 goto out;
@@ -3813,7 +3803,7 @@ VkResult loader_scan_for_layers(struct loader_instance *inst, struct loader_laye
 
     // Verify any meta-layers in the list are valid and all the component layers are
     // actually present in the available layer list
-    res = verify_all_meta_layers(inst, &filters, &regular_instance_layers, &override_layer_valid);
+    res = verify_all_meta_layers(inst, filters, &regular_instance_layers, &override_layer_valid);
     if (VK_ERROR_OUT_OF_HOST_MEMORY == res) {
         return res;
     }
@@ -3827,7 +3817,7 @@ VkResult loader_scan_for_layers(struct loader_instance *inst, struct loader_laye
 
     // Remove disabled layers
     for (uint32_t i = 0; i < regular_instance_layers.count; ++i) {
-        if (!loader_layer_is_available(inst, &filters, &regular_instance_layers.list[i])) {
+        if (!loader_layer_is_available(inst, filters, &regular_instance_layers.list[i])) {
             loader_remove_layer_in_list(inst, &regular_instance_layers, i);
             i--;
         }
@@ -3843,14 +3833,14 @@ out:
     return res;
 }
 
-VkResult loader_scan_for_implicit_layers(struct loader_instance *inst, struct loader_layer_list *instance_layers) {
+VkResult loader_scan_for_implicit_layers(struct loader_instance *inst, struct loader_layer_list *instance_layers,
+                                         const struct loader_envvar_all_filters *layer_filters) {
     VkResult res = VK_SUCCESS;
     struct loader_layer_list settings_layers = {0};
     struct loader_layer_list regular_instance_layers = {0};
     bool override_layer_valid = false;
     char *override_paths = NULL;
     bool implicit_metalayer_present = false;
-    struct loader_envvar_all_filters filters = {0};
 
     bool should_search_for_other_layers = true;
     res = get_settings_layers(inst, &settings_layers, &should_search_for_other_layers);
@@ -3866,16 +3856,6 @@ VkResult loader_scan_for_implicit_layers(struct loader_instance *inst, struct lo
         goto out;
     }
 
-    // Parse the filter environment variables to determine if we have any special behavior
-    res = parse_generic_filter_environment_var(inst, VK_LAYERS_ENABLE_ENV_VAR, &filters.enable_filter);
-    if (VK_SUCCESS != res) {
-        goto out;
-    }
-    res = parse_layers_disable_filter_environment_var(inst, &filters.disable_filter);
-    if (VK_SUCCESS != res) {
-        goto out;
-    }
-
     res = loader_parse_instance_layers(inst, LOADER_DATA_FILE_MANIFEST_IMPLICIT_LAYER, NULL, &regular_instance_layers);
     if (VK_SUCCESS != res) {
         goto out;
@@ -3888,7 +3868,7 @@ VkResult loader_scan_for_implicit_layers(struct loader_instance *inst, struct lo
     // Each of these may require explicit layers to be enabled at this time.
     for (uint32_t i = 0; i < regular_instance_layers.count; i++) {
         struct loader_layer_properties *prop = &regular_instance_layers.list[i];
-        if (prop->is_override && loader_implicit_layer_is_enabled(inst, &filters, prop)) {
+        if (prop->is_override && loader_implicit_layer_is_enabled(inst, layer_filters, prop)) {
             override_layer_valid = true;
             res = get_override_layer_override_paths(inst, prop, &override_paths);
             if (VK_SUCCESS != res) {
@@ -3912,7 +3892,7 @@ VkResult loader_scan_for_implicit_layers(struct loader_instance *inst, struct lo
 
     // Verify any meta-layers in the list are valid and all the component layers are
     // actually present in the available layer list
-    res = verify_all_meta_layers(inst, &filters, &regular_instance_layers, &override_layer_valid);
+    res = verify_all_meta_layers(inst, layer_filters, &regular_instance_layers, &override_layer_valid);
     if (VK_ERROR_OUT_OF_HOST_MEMORY == res) {
         return res;
     }
@@ -3926,7 +3906,7 @@ VkResult loader_scan_for_implicit_layers(struct loader_instance *inst, struct lo
 
     // Remove disabled layers
     for (uint32_t i = 0; i < regular_instance_layers.count; ++i) {
-        if (!loader_implicit_layer_is_enabled(inst, &filters, &regular_instance_layers.list[i])) {
+        if (!loader_implicit_layer_is_enabled(inst, layer_filters, &regular_instance_layers.list[i])) {
             loader_remove_layer_in_list(inst, &regular_instance_layers, i);
             i--;
         }
@@ -4171,9 +4151,9 @@ void warn_if_layers_are_older_than_application(struct loader_instance *inst) {
 }
 
 VkResult loader_enable_instance_layers(struct loader_instance *inst, const VkInstanceCreateInfo *pCreateInfo,
-                                       const struct loader_layer_list *instance_layers) {
+                                       const struct loader_layer_list *instance_layers,
+                                       const struct loader_envvar_all_filters *layer_filters) {
     VkResult res = VK_SUCCESS;
-    struct loader_envvar_all_filters layers_filters = {0};
 
     assert(inst && "Cannot have null instance");
 
@@ -4191,18 +4171,8 @@ VkResult loader_enable_instance_layers(struct loader_instance *inst, const VkIns
         goto out;
     }
 
-    // Parse the filter environment variables to determine if we have any special behavior
-    res = parse_generic_filter_environment_var(inst, VK_LAYERS_ENABLE_ENV_VAR, &layers_filters.enable_filter);
-    if (VK_SUCCESS != res) {
-        goto out;
-    }
-    res = parse_layers_disable_filter_environment_var(inst, &layers_filters.disable_filter);
-    if (VK_SUCCESS != res) {
-        goto out;
-    }
-
     if (inst->settings.settings_active) {
-        res = enable_correct_layers_from_settings(inst, &layers_filters, pCreateInfo->enabledLayerCount,
+        res = enable_correct_layers_from_settings(inst, layer_filters, pCreateInfo->enabledLayerCount,
                                                   pCreateInfo->ppEnabledLayerNames, &inst->instance_layer_list,
                                                   &inst->app_activated_layer_list, &inst->expanded_activated_layer_list);
         warn_if_layers_are_older_than_application(inst);
@@ -4211,23 +4181,22 @@ VkResult loader_enable_instance_layers(struct loader_instance *inst, const VkIns
     }
 
     // Add any implicit layers first
-    res = loader_add_implicit_layers(inst, &layers_filters, &inst->app_activated_layer_list, &inst->expanded_activated_layer_list,
+    res = loader_add_implicit_layers(inst, layer_filters, &inst->app_activated_layer_list, &inst->expanded_activated_layer_list,
                                      instance_layers);
     if (res != VK_SUCCESS) {
         goto out;
     }
 
     // Add any layers specified via environment variable next
-    res = loader_add_environment_layers(inst, VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER, &layers_filters, &inst->app_activated_layer_list,
+    res = loader_add_environment_layers(inst, VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER, layer_filters, &inst->app_activated_layer_list,
                                         &inst->expanded_activated_layer_list, instance_layers);
     if (res != VK_SUCCESS) {
         goto out;
     }
 
     // Add layers specified by the application
-    res =
-        loader_add_layer_names_to_list(inst, &layers_filters, &inst->app_activated_layer_list, &inst->expanded_activated_layer_list,
-                                       pCreateInfo->enabledLayerCount, pCreateInfo->ppEnabledLayerNames, instance_layers);
+    res = loader_add_layer_names_to_list(inst, layer_filters, &inst->app_activated_layer_list, &inst->expanded_activated_layer_list,
+                                         pCreateInfo->enabledLayerCount, pCreateInfo->ppEnabledLayerNames, instance_layers);
 
     warn_if_layers_are_older_than_application(inst);
 out:
@@ -5019,12 +4988,12 @@ VkResult loader_validate_layers(const struct loader_instance *inst, const uint32
 
 VkResult loader_validate_instance_extensions(struct loader_instance *inst, const struct loader_extension_list *icd_exts,
                                              const struct loader_layer_list *instance_layers,
+                                             const struct loader_envvar_all_filters *layer_filters,
                                              const VkInstanceCreateInfo *pCreateInfo) {
     VkExtensionProperties *extension_prop;
     char *env_value;
     bool check_if_known = true;
     VkResult res = VK_SUCCESS;
-    struct loader_envvar_all_filters layers_filters = {0};
 
     struct loader_pointer_layer_list active_layers = {0};
     struct loader_pointer_layer_list expanded_layers = {0};
@@ -5044,18 +5013,8 @@ VkResult loader_validate_instance_extensions(struct loader_instance *inst, const
         goto out;
     }
 
-    // Parse the filter environment variables to determine if we have any special behavior
-    res = parse_generic_filter_environment_var(inst, VK_LAYERS_ENABLE_ENV_VAR, &layers_filters.enable_filter);
-    if (VK_SUCCESS != res) {
-        goto out;
-    }
-    res = parse_layers_disable_filter_environment_var(inst, &layers_filters.disable_filter);
-    if (VK_SUCCESS != res) {
-        goto out;
-    }
-
     if (inst->settings.settings_active) {
-        res = enable_correct_layers_from_settings(inst, &layers_filters, pCreateInfo->enabledLayerCount,
+        res = enable_correct_layers_from_settings(inst, layer_filters, pCreateInfo->enabledLayerCount,
                                                   pCreateInfo->ppEnabledLayerNames, instance_layers, &active_layers,
                                                   &expanded_layers);
         if (res != VK_SUCCESS) {
@@ -5064,17 +5023,17 @@ VkResult loader_validate_instance_extensions(struct loader_instance *inst, const
     } else {
         // Build the lists of active layers (including metalayers) and expanded layers (with metalayers resolved to their
         // components)
-        res = loader_add_implicit_layers(inst, &layers_filters, &active_layers, &expanded_layers, instance_layers);
+        res = loader_add_implicit_layers(inst, layer_filters, &active_layers, &expanded_layers, instance_layers);
         if (res != VK_SUCCESS) {
             goto out;
         }
-        res = loader_add_environment_layers(inst, VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER, &layers_filters, &active_layers,
+        res = loader_add_environment_layers(inst, VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER, layer_filters, &active_layers,
                                             &expanded_layers, instance_layers);
         if (res != VK_SUCCESS) {
             goto out;
         }
-        res = loader_add_layer_names_to_list(inst, &layers_filters, &active_layers, &expanded_layers,
-                                             pCreateInfo->enabledLayerCount, pCreateInfo->ppEnabledLayerNames, instance_layers);
+        res = loader_add_layer_names_to_list(inst, layer_filters, &active_layers, &expanded_layers, pCreateInfo->enabledLayerCount,
+                                             pCreateInfo->ppEnabledLayerNames, instance_layers);
         if (VK_SUCCESS != res) {
             goto out;
         }
@@ -6629,11 +6588,17 @@ terminator_EnumerateInstanceExtensionProperties(const VkEnumerateInstanceExtensi
     struct loader_icd_tramp_list icd_tramp_list;
     uint32_t copy_size;
     VkResult res = VK_SUCCESS;
+    struct loader_envvar_all_filters layer_filters = {0};
 
     memset(&local_ext_list, 0, sizeof(local_ext_list));
     memset(&instance_layers, 0, sizeof(instance_layers));
     memset(&icd_tramp_list, 0, sizeof(icd_tramp_list));
 
+    res = parse_layer_environment_var_filters(NULL, &layer_filters);
+    if (VK_SUCCESS != res) {
+        goto out;
+    }
+
     // Get layer libraries if needed
     if (pLayerName && strlen(pLayerName) != 0) {
         if (vk_string_validate(MaxLoaderStringLength, pLayerName) != VK_STRING_ERROR_NONE) {
@@ -6642,7 +6607,7 @@ terminator_EnumerateInstanceExtensionProperties(const VkEnumerateInstanceExtensi
             goto out;
         }
 
-        res = loader_scan_for_layers(NULL, &instance_layers);
+        res = loader_scan_for_layers(NULL, &instance_layers, &layer_filters);
         if (VK_SUCCESS != res) {
             goto out;
         }
@@ -6671,7 +6636,7 @@ terminator_EnumerateInstanceExtensionProperties(const VkEnumerateInstanceExtensi
         loader_scanned_icd_clear(NULL, &icd_tramp_list);
 
         // Append enabled implicit layers.
-        res = loader_scan_for_implicit_layers(NULL, &instance_layers);
+        res = loader_scan_for_implicit_layers(NULL, &instance_layers, &layer_filters);
         if (VK_SUCCESS != res) {
             goto out;
         }
@@ -6717,14 +6682,20 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumerateInstanceLayerProperties(const
     (void)chain;
     VkResult result = VK_SUCCESS;
     struct loader_layer_list instance_layer_list;
+    struct loader_envvar_all_filters layer_filters = {0};
 
     LOADER_PLATFORM_THREAD_ONCE(&once_init, loader_initialize);
 
     uint32_t copy_size;
 
+    result = parse_layer_environment_var_filters(NULL, &layer_filters);
+    if (VK_SUCCESS != result) {
+        goto out;
+    }
+
     // Get layer libraries
     memset(&instance_layer_list, 0, sizeof(instance_layer_list));
-    result = loader_scan_for_layers(NULL, &instance_layer_list);
+    result = loader_scan_for_layers(NULL, &instance_layer_list, &layer_filters);
     if (VK_SUCCESS != result) {
         goto out;
     }
index 3ba68af96ae97f9ff000e8781770714c24328d82..93346a9d71a088e5fcf9838f0ee4881113de3ed7 100644 (file)
@@ -91,6 +91,7 @@ VkResult loader_validate_layers(const struct loader_instance *inst, const uint32
 
 VkResult loader_validate_instance_extensions(struct loader_instance *inst, const struct loader_extension_list *icd_exts,
                                              const struct loader_layer_list *instance_layer,
+                                             const struct loader_envvar_all_filters *layer_filters,
                                              const VkInstanceCreateInfo *pCreateInfo);
 
 void loader_initialize(void);
@@ -154,8 +155,10 @@ VkResult loader_icd_scan(const struct loader_instance *inst, struct loader_icd_t
                          const VkInstanceCreateInfo *pCreateInfo, bool *skipped_portability_drivers);
 void loader_icd_destroy(struct loader_instance *ptr_inst, struct loader_icd_term *icd_term,
                         const VkAllocationCallbacks *pAllocator);
-VkResult loader_scan_for_layers(struct loader_instance *inst, struct loader_layer_list *instance_layers);
-VkResult loader_scan_for_implicit_layers(struct loader_instance *inst, struct loader_layer_list *instance_layers);
+VkResult loader_scan_for_layers(struct loader_instance *inst, struct loader_layer_list *instance_layers,
+                                const struct loader_envvar_all_filters *layer_filters);
+VkResult loader_scan_for_implicit_layers(struct loader_instance *inst, struct loader_layer_list *instance_layers,
+                                         const struct loader_envvar_all_filters *layer_filters);
 VkResult loader_get_icd_loader_instance_extensions(const struct loader_instance *inst, struct loader_icd_tramp_list *icd_tramp_list,
                                                    struct loader_extension_list *inst_exts);
 struct loader_icd_term *loader_get_icd_and_device(const void *device, struct loader_device **found_dev, uint32_t *icd_index);
@@ -169,7 +172,8 @@ void loader_remove_logical_device(struct loader_icd_term *icd_term, struct loade
 void loader_destroy_logical_device(struct loader_device *dev, const VkAllocationCallbacks *pAllocator);
 
 VkResult loader_enable_instance_layers(struct loader_instance *inst, const VkInstanceCreateInfo *pCreateInfo,
-                                       const struct loader_layer_list *instance_layers);
+                                       const struct loader_layer_list *instance_layers,
+                                       const struct loader_envvar_all_filters *layer_filters);
 
 VkResult loader_create_instance_chain(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
                                       struct loader_instance *inst, VkInstance *created_instance);
index 7038378c3d55f39146a7f1f826c7594333596614..37d489d5bdc3139d9da81f953f61c7446e628d8f 100644 (file)
@@ -367,6 +367,19 @@ out:
     return result;
 }
 
+// Parses the filter environment variables to determine if we have any special behavior
+VkResult parse_layer_environment_var_filters(const struct loader_instance *inst, struct loader_envvar_all_filters *layer_filters) {
+    VkResult res = parse_generic_filter_environment_var(inst, VK_LAYERS_ENABLE_ENV_VAR, &layer_filters->enable_filter);
+    if (VK_SUCCESS != res) {
+        return res;
+    }
+    res = parse_layers_disable_filter_environment_var(inst, &layer_filters->disable_filter);
+    if (VK_SUCCESS != res) {
+        return res;
+    }
+    return res;
+}
+
 // Check to see if the provided layer name matches any of the filter strings.
 // This will properly check against:
 //  - substrings "*string*"
index a5313fb4151021f542cbc8b04df5efe9c8ebd328..15474a3aba4b77d33a7a7a547eceb7fcd6ec4fc7 100644 (file)
@@ -47,6 +47,7 @@ VkResult parse_generic_filter_environment_var(const struct loader_instance *inst
                                               struct loader_envvar_filter *filter_struct);
 VkResult parse_layers_disable_filter_environment_var(const struct loader_instance *inst,
                                                      struct loader_envvar_disable_layers_filter *disable_struct);
+VkResult parse_layer_environment_var_filters(const struct loader_instance *inst, struct loader_envvar_all_filters *layer_filters);
 bool check_name_matches_filter_environment_var(const char *name, const struct loader_envvar_filter *filter_struct);
 VkResult loader_add_environment_layers(struct loader_instance *inst, const enum layer_type_flags type_flags,
                                        const struct loader_envvar_all_filters *filters,
index ea7ff19329626f2c9fbbcfc8c3d4b6577dc0983c..fe4acc95409de4825e7fd436d871523ea55b50e1 100644 (file)
@@ -31,6 +31,7 @@
 #include "debug_utils.h"
 #include "gpa_helper.h"
 #include "loader.h"
+#include "loader_environment.h"
 #include "log.h"
 #include "settings.h"
 #include "vk_loader_extensions.h"
@@ -187,8 +188,14 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionPropert
     loader_platform_dl_handle *libs = NULL;
     size_t lib_count = 0;
     memset(&layers, 0, sizeof(layers));
+    struct loader_envvar_all_filters layer_filters = {0};
 
-    res = loader_scan_for_implicit_layers(NULL, &layers);
+    res = parse_layer_environment_var_filters(NULL, &layer_filters);
+    if (VK_SUCCESS != res) {
+        return res;
+    }
+
+    res = loader_scan_for_implicit_layers(NULL, &layers, &layer_filters);
     if (VK_SUCCESS != res) {
         return res;
     }
@@ -287,8 +294,14 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(
     loader_platform_dl_handle *libs = NULL;
     size_t lib_count = 0;
     memset(&layers, 0, sizeof(layers));
+    struct loader_envvar_all_filters layer_filters = {0};
+
+    res = parse_layer_environment_var_filters(NULL, &layer_filters);
+    if (VK_SUCCESS != res) {
+        return res;
+    }
 
-    res = loader_scan_for_implicit_layers(NULL, &layers);
+    res = loader_scan_for_implicit_layers(NULL, &layers, &layer_filters);
     if (VK_SUCCESS != res) {
         return res;
     }
@@ -394,8 +407,14 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceVersion(uint32_t
     loader_platform_dl_handle *libs = NULL;
     size_t lib_count = 0;
     memset(&layers, 0, sizeof(layers));
+    struct loader_envvar_all_filters layer_filters = {0};
 
-    res = loader_scan_for_implicit_layers(NULL, &layers);
+    res = parse_layer_environment_var_filters(NULL, &layer_filters);
+    if (VK_SUCCESS != res) {
+        return res;
+    }
+
+    res = loader_scan_for_implicit_layers(NULL, &layers, &layer_filters);
     if (VK_SUCCESS != res) {
         return res;
     }
@@ -473,6 +492,7 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCr
     VkInstance created_instance = VK_NULL_HANDLE;
     VkResult res = VK_ERROR_INITIALIZATION_FAILED;
     VkInstanceCreateInfo ici = *pCreateInfo;
+    struct loader_envvar_all_filters layer_filters = {0};
 
     LOADER_PLATFORM_THREAD_ONCE(&once_init, loader_initialize);
 
@@ -565,11 +585,16 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCr
         }
     }
 
+    res = parse_layer_environment_var_filters(ptr_instance, &layer_filters);
+    if (VK_SUCCESS != res) {
+        goto out;
+    }
+
     // Due to implicit layers need to get layer list even if
     // enabledLayerCount == 0 and VK_INSTANCE_LAYERS is unset. For now always
     // get layer list via loader_scan_for_layers().
     memset(&ptr_instance->instance_layer_list, 0, sizeof(ptr_instance->instance_layer_list));
-    res = loader_scan_for_layers(ptr_instance, &ptr_instance->instance_layer_list);
+    res = loader_scan_for_layers(ptr_instance, &ptr_instance->instance_layer_list, &layer_filters);
     if (VK_SUCCESS != res) {
         goto out;
     }
@@ -625,7 +650,8 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCr
     if (res != VK_SUCCESS) {
         goto out;
     }
-    res = loader_validate_instance_extensions(ptr_instance, &ptr_instance->ext_list, &ptr_instance->instance_layer_list, &ici);
+    res = loader_validate_instance_extensions(ptr_instance, &ptr_instance->ext_list, &ptr_instance->instance_layer_list,
+                                              &layer_filters, &ici);
     if (res != VK_SUCCESS) {
         goto out;
     }
@@ -646,7 +672,7 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCr
     loader_platform_thread_unlock_mutex(&loader_global_instance_list_lock);
 
     // Activate any layers on instance chain
-    res = loader_enable_instance_layers(ptr_instance, &ici, &ptr_instance->instance_layer_list);
+    res = loader_enable_instance_layers(ptr_instance, &ici, &ptr_instance->instance_layer_list, &layer_filters);
     if (res != VK_SUCCESS) {
         goto out;
     }