aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Young <marky@lunarg.com>2017-05-04 12:16:35 -0600
committerMark Young <marky@lunarg.com>2017-05-09 11:01:03 -0600
commitc5bd152da9aebd7b3a073bddbdf78dcd7dce5a86 (patch)
treedd0a217a46d238d5570fa31e8c802a0ed0cb6278
parent3d876c1544ba6325720a64c248e8eb0214e55d6e (diff)
downloadusermoji-c5bd152da9aebd7b3a073bddbdf78dcd7dce5a86.tar.xz
loader: Fix layer Enumerate bug
This fixes a bug found by Timothee Besset regarding calling vkEnumerateDeviceLayerProperties when no layers are present. This resulted in a negative number being filled into a uint32_t which caused an invalid number of layers to be returned. Now that we have meta-layers implemented instead of hard-coded, I created two lists: an application provided list of layers, and an expanded list of layers (where meta-layers are broken up into their component layers). The former is used when working with the enumerate calls, but the later is used internally for final layer activation. Change-Id: If723fdfb5acb1dc57923282d2c641c582870ad1c
-rw-r--r--layers/linux/VkLayer_standard_validation.json2
-rw-r--r--layers/windows/VkLayer_standard_validation.json2
-rw-r--r--loader/loader.c175
-rw-r--r--loader/loader.h21
-rw-r--r--loader/trampoline.c76
5 files changed, 182 insertions, 94 deletions
diff --git a/layers/linux/VkLayer_standard_validation.json b/layers/linux/VkLayer_standard_validation.json
index f8f775db..9fee3627 100644
--- a/layers/linux/VkLayer_standard_validation.json
+++ b/layers/linux/VkLayer_standard_validation.json
@@ -3,7 +3,7 @@
"layer": {
"name": "VK_LAYER_LUNARG_standard_validation",
"type": "GLOBAL",
- "api_version": "1.0.49",
+ "api_version": "1.0.48",
"implementation_version": "1",
"description": "LunarG Standard Validation",
"component_layers": [
diff --git a/layers/windows/VkLayer_standard_validation.json b/layers/windows/VkLayer_standard_validation.json
index f8f775db..9fee3627 100644
--- a/layers/windows/VkLayer_standard_validation.json
+++ b/layers/windows/VkLayer_standard_validation.json
@@ -3,7 +3,7 @@
"layer": {
"name": "VK_LAYER_LUNARG_standard_validation",
"type": "GLOBAL",
- "api_version": "1.0.49",
+ "api_version": "1.0.48",
"implementation_version": "1",
"description": "LunarG Standard Validation",
"component_layers": [
diff --git a/loader/loader.c b/loader/loader.c
index bc81a759..c07424fc 100644
--- a/loader/loader.c
+++ b/loader/loader.c
@@ -936,34 +936,57 @@ VkResult loader_add_to_dev_ext_list(const struct loader_instance *inst, struct l
// Prototype of loader_add_meta_layer function since we use it in the loader_add_implicit_layer, but can also
// call loader_add_implicit_layer from loader_add_meta_layer.
bool loader_add_meta_layer(const struct loader_instance *inst, const struct loader_layer_properties *prop,
- struct loader_layer_list *target_list, const struct loader_layer_list *source_list);
+ struct loader_layer_list *target_list, struct loader_layer_list *expanded_target_list,
+ const struct loader_layer_list *source_list);
+
+// Search the given layer list for a list matching the given VkLayerProperties
+bool has_vk_layer_property(const VkLayerProperties *vk_layer_prop, const struct loader_layer_list *list) {
+ for (uint32_t i = 0; i < list->count; i++) {
+ if (strcmp(vk_layer_prop->layerName, list->list[i].info.layerName) == 0) return true;
+ }
+ return false;
+}
+
+// Search the given layer list for a layer matching the given name
+bool has_layer_name(const char *name, const struct loader_layer_list *list) {
+ for (uint32_t i = 0; i < list->count; i++) {
+ if (strcmp(name, list->list[i].info.layerName) == 0) return true;
+ }
+ return false;
+}
// Search the given search_list for any layers in the props list. Add these to the
// output layer_list. Don't add duplicates to the output layer_list.
static VkResult loader_add_layer_names_to_list(const struct loader_instance *inst, struct loader_layer_list *output_list,
- uint32_t name_count, const char *const *names,
- const struct loader_layer_list *search_list) {
+ struct loader_layer_list *expanded_output_list, uint32_t name_count,
+ const char *const *names, const struct loader_layer_list *source_list) {
struct loader_layer_properties *layer_prop;
VkResult err = VK_SUCCESS;
for (uint32_t i = 0; i < name_count; i++) {
- const char *search_target = names[i];
- layer_prop = loader_get_layer_property(search_target, search_list);
+ const char *source_name = names[i];
+ layer_prop = loader_get_layer_property(source_name, source_list);
if (NULL == layer_prop) {
loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
"loader_add_layer_names_to_list: Unable to find layer"
" %s",
- search_target);
+ source_name);
err = VK_ERROR_LAYER_NOT_PRESENT;
continue;
}
// If not a meta-layer, simply add it.
if (0 == (layer_prop->type_flags & VK_LAYER_TYPE_FLAG_META_LAYER)) {
- err = loader_add_to_layer_list(inst, output_list, 1, layer_prop);
+ if (!has_vk_layer_property(&layer_prop->info, output_list)) {
+ loader_add_to_layer_list(inst, output_list, 1, layer_prop);
+ }
+ if (!has_vk_layer_property(&layer_prop->info, expanded_output_list)) {
+ loader_add_to_layer_list(inst, expanded_output_list, 1, layer_prop);
+ }
} else {
- if (!loader_add_meta_layer(inst, layer_prop, output_list, search_list)) {
- err = VK_ERROR_LAYER_NOT_PRESENT;
+ if (!has_vk_layer_property(&layer_prop->info, output_list) ||
+ !has_vk_layer_property(&layer_prop->info, expanded_output_list)) {
+ loader_add_meta_layer(inst, layer_prop, output_list, expanded_output_list, source_list);
}
}
}
@@ -994,22 +1017,6 @@ void loader_destroy_layer_list(const struct loader_instance *inst, struct loader
layer_list->capacity = 0;
}
-// Search the given layer list for a list matching the given VkLayerProperties
-bool has_vk_layer_property(const VkLayerProperties *vk_layer_prop, const struct loader_layer_list *list) {
- for (uint32_t i = 0; i < list->count; i++) {
- if (strcmp(vk_layer_prop->layerName, list->list[i].info.layerName) == 0) return true;
- }
- return false;
-}
-
-// Search the given layer list for a layer matching the given name
-bool has_layer_name(const char *name, const struct loader_layer_list *list) {
- for (uint32_t i = 0; i < list->count; i++) {
- if (strcmp(name, list->list[i].info.layerName) == 0) return true;
- }
- return false;
-}
-
// Append non-duplicate layer properties defined in prop_list to the given layer_info list
VkResult loader_add_to_layer_list(const struct loader_instance *inst, struct loader_layer_list *list, uint32_t prop_list_count,
const struct loader_layer_properties *props) {
@@ -1054,7 +1061,8 @@ VkResult loader_add_to_layer_list(const struct loader_instance *inst, struct loa
// Check the individual implicit layer for the enable/disable environment variable settings. Only add it after
// every check has passed indicating it should be used.
static void loader_add_implicit_layer(const struct loader_instance *inst, const struct loader_layer_properties *prop,
- struct loader_layer_list *target_list, const struct loader_layer_list *source_list) {
+ struct loader_layer_list *target_list, struct loader_layer_list *expanded_target_list,
+ const struct loader_layer_list *source_list) {
bool enable = false;
char *env_value = NULL;
@@ -1080,16 +1088,25 @@ static void loader_add_implicit_layer(const struct loader_instance *inst, const
if (enable) {
// If not a meta-layer, simply add it.
if (0 == (prop->type_flags & VK_LAYER_TYPE_FLAG_META_LAYER)) {
- loader_add_to_layer_list(inst, target_list, 1, prop);
+ if (!has_vk_layer_property(&prop->info, target_list)) {
+ loader_add_to_layer_list(inst, target_list, 1, prop);
+ }
+ if (NULL != expanded_target_list && !has_vk_layer_property(&prop->info, expanded_target_list)) {
+ loader_add_to_layer_list(inst, expanded_target_list, 1, prop);
+ }
} else {
- loader_add_meta_layer(inst, prop, target_list, source_list);
+ if (!has_vk_layer_property(&prop->info, target_list) ||
+ (NULL != expanded_target_list && !has_vk_layer_property(&prop->info, expanded_target_list))) {
+ loader_add_meta_layer(inst, prop, target_list, expanded_target_list, source_list);
+ }
}
}
}
// Add the component layers of a meta-layer to the active list of layers
bool loader_add_meta_layer(const struct loader_instance *inst, const struct loader_layer_properties *prop,
- struct loader_layer_list *target_list, const struct loader_layer_list *source_list) {
+ struct loader_layer_list *target_list, struct loader_layer_list *expanded_target_list,
+ const struct loader_layer_list *source_list) {
bool found = true;
// We need to add all the individual component layers
@@ -1099,15 +1116,19 @@ bool loader_add_meta_layer(const struct loader_instance *inst, const struct load
loader_get_layer_property(prop->component_layer_names[comp_layer], source_list);
if (search_prop != NULL) {
found_comp = true;
- if (has_vk_layer_property(&search_prop->info, target_list)) {
- break;
- }
- // If the component layer is itself an implicit layer, check before adding,
- // otherwise, just add
+
+ // 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)) {
- loader_add_implicit_layer(inst, search_prop, target_list, source_list);
+ loader_add_implicit_layer(inst, search_prop, target_list, expanded_target_list, source_list);
} else {
- loader_add_to_layer_list(inst, target_list, 1, search_prop);
+ // Otherwise, just make sure it hasn't already been added to either list before we add it
+ if (!has_vk_layer_property(&search_prop->info, target_list)) {
+ loader_add_to_layer_list(inst, target_list, 1, search_prop);
+ }
+ if (NULL != expanded_target_list && !has_vk_layer_property(&search_prop->info, expanded_target_list)) {
+ loader_add_to_layer_list(inst, expanded_target_list, 1, search_prop);
+ }
}
}
if (!found_comp) {
@@ -1125,22 +1146,24 @@ bool loader_add_meta_layer(const struct loader_instance *inst, const struct load
// that matches the given type. Add all matching layers to the target_list.
// Do not add if found loader_layer_properties is already on the target_list.
void loader_find_layer_name_add_list(const struct loader_instance *inst, const char *name, const enum layer_type_flags type_flags,
- const struct loader_layer_list *source_list, struct loader_layer_list *target_list) {
+ const struct loader_layer_list *source_list, struct loader_layer_list *target_list,
+ struct loader_layer_list *expanded_target_list) {
bool found = false;
for (uint32_t i = 0; i < source_list->count; i++) {
struct loader_layer_properties *source_prop = &source_list->list[i];
if (0 == strcmp(source_prop->info.layerName, name) && (source_prop->type_flags & type_flags) == type_flags) {
- // If already, there, keep going.
- if (has_vk_layer_property(&source_prop->info, target_list)) {
- continue;
- }
// If not a meta-layer, simply add it.
if (0 == (source_prop->type_flags & VK_LAYER_TYPE_FLAG_META_LAYER)) {
- if (VK_SUCCESS == loader_add_to_layer_list(inst, target_list, 1, source_prop)) {
+ if (!has_vk_layer_property(&source_prop->info, target_list) &&
+ VK_SUCCESS == loader_add_to_layer_list(inst, target_list, 1, source_prop)) {
+ found = true;
+ }
+ if (!has_vk_layer_property(&source_prop->info, expanded_target_list) &&
+ VK_SUCCESS == loader_add_to_layer_list(inst, expanded_target_list, 1, source_prop)) {
found = true;
}
} else {
- found = loader_add_meta_layer(inst, source_prop, target_list, source_list);
+ found = loader_add_meta_layer(inst, source_prop, target_list, expanded_target_list, source_list);
}
}
}
@@ -1272,8 +1295,11 @@ void loader_destroy_logical_device(const struct loader_instance *inst, struct lo
if (pAllocator) {
dev->alloc_callbacks = *pAllocator;
}
- if (NULL != dev->activated_layer_list.list) {
- loader_deactivate_layers(inst, dev, &dev->activated_layer_list);
+ if (NULL != dev->expanded_activated_layer_list.list) {
+ loader_deactivate_layers(inst, dev, &dev->expanded_activated_layer_list);
+ }
+ if (NULL != dev->app_activated_layer_list.list) {
+ loader_destroy_layer_list(inst, dev, &dev->app_activated_layer_list);
}
loader_device_heap_free(dev, dev);
}
@@ -1996,6 +2022,7 @@ static bool verify_meta_layer_comp_layers(const struct loader_instance *inst, st
// Verify that all meta-layers in a layer list are valid.
static void verify_all_meta_layers(const struct loader_instance *inst, struct loader_layer_list *instance_layers) {
+ bool has_layers_at_start = instance_layers->count > 0;
for (uint32_t i = 0; i < instance_layers->count; i++) {
struct loader_layer_properties *prop = &instance_layers->list[i];
@@ -3699,8 +3726,8 @@ static bool loader_check_icds_for_phys_dev_ext_address(struct loader_instance *i
}
static bool loader_check_layer_list_for_phys_dev_ext_address(struct loader_instance *inst, const char *funcName) {
- struct loader_layer_properties *layer_prop_list = inst->activated_layer_list.list;
- for (uint32_t layer = 0; layer < inst->activated_layer_list.count; ++layer) {
+ struct loader_layer_properties *layer_prop_list = inst->expanded_activated_layer_list.list;
+ for (uint32_t layer = 0; layer < inst->expanded_activated_layer_list.count; ++layer) {
// If this layer supports the vk_layerGetPhysicalDeviceProcAddr, then call
// it and see if it returns a valid pointer for this function name.
if (layer_prop_list[layer].interface_version > 1) {
@@ -3881,8 +3908,8 @@ bool loader_phys_dev_ext_gpa(struct loader_instance *inst, const char *funcName,
// Now, search for the first layer attached and query using it to get
// the first entry point.
- for (i = 0; i < inst->activated_layer_list.count; i++) {
- struct loader_layer_properties *layer_prop = &inst->activated_layer_list.list[i];
+ for (i = 0; i < inst->expanded_activated_layer_list.count; i++) {
+ struct loader_layer_properties *layer_prop = &inst->expanded_activated_layer_list.list[i];
if (layer_prop->interface_version > 1 && NULL != layer_prop->functions.get_physical_device_proc_addr) {
inst->disp->phys_dev_ext[idx] =
(PFN_PhysDevExt)layer_prop->functions.get_physical_device_proc_addr((VkInstance)inst, funcName);
@@ -3956,11 +3983,12 @@ void loader_deactivate_layers(const struct loader_instance *instance, struct loa
// Go through the search_list and find any layers which match type. If layer
// type match is found in then add it to ext_list.
static void loader_add_implicit_layers(const struct loader_instance *inst, struct loader_layer_list *target_list,
+ struct loader_layer_list *expanded_target_list,
const struct loader_layer_list *source_list) {
for (uint32_t src_layer = 0; src_layer < source_list->count; src_layer++) {
const struct loader_layer_properties *prop = &source_list->list[src_layer];
if (0 == (prop->type_flags & VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER)) {
- loader_add_implicit_layer(inst, prop, target_list, source_list);
+ loader_add_implicit_layer(inst, prop, target_list, expanded_target_list, source_list);
}
}
}
@@ -3968,7 +3996,8 @@ static void loader_add_implicit_layers(const struct loader_instance *inst, struc
// Get the layer name(s) from the env_name environment variable. If layer is found in
// search_list then add it to layer_list. But only add it to layer_list if type_flags matches.
static void loader_add_env_layers(struct loader_instance *inst, const enum layer_type_flags type_flags, const char *env_name,
- struct loader_layer_list *target_list, const struct loader_layer_list *source_list) {
+ struct loader_layer_list *target_list, struct loader_layer_list *expanded_target_list,
+ const struct loader_layer_list *source_list) {
char *next, *name;
char *layer_env = loader_secure_getenv(env_name, inst);
if (layer_env == NULL) {
@@ -3982,7 +4011,7 @@ static void loader_add_env_layers(struct loader_instance *inst, const enum layer
while (name && *name) {
next = loader_get_next_path(name);
- loader_find_layer_name_add_list(inst, name, type_flags, source_list, target_list);
+ loader_find_layer_name_add_list(inst, name, type_flags, source_list, target_list, expanded_target_list);
name = next;
}
@@ -4001,23 +4030,30 @@ VkResult loader_enable_instance_layers(struct loader_instance *inst, const VkIns
assert(inst && "Cannot have null instance");
- if (!loader_init_layer_list(inst, &inst->activated_layer_list)) {
+ if (!loader_init_layer_list(inst, &inst->app_activated_layer_list)) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "loader_enable_instance_layers: Failed to initialize"
+ " application version of the layer list");
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+
+ if (!loader_init_layer_list(inst, &inst->expanded_activated_layer_list)) {
loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
"loader_enable_instance_layers: Failed to initialize"
- " the layer list");
+ " expanded version of the layer list");
return VK_ERROR_OUT_OF_HOST_MEMORY;
}
// Add any implicit layers first
- loader_add_implicit_layers(inst, &inst->activated_layer_list, instance_layers);
+ loader_add_implicit_layers(inst, &inst->app_activated_layer_list, &inst->expanded_activated_layer_list, instance_layers);
// Add any layers specified via environment variable next
- loader_add_env_layers(inst, VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER, "VK_INSTANCE_LAYERS", &inst->activated_layer_list,
- instance_layers);
+ loader_add_env_layers(inst, VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER, "VK_INSTANCE_LAYERS", &inst->app_activated_layer_list,
+ &inst->expanded_activated_layer_list, instance_layers);
// Add layers specified by the application
- err = loader_add_layer_names_to_list(inst, &inst->activated_layer_list, pCreateInfo->enabledLayerCount,
- pCreateInfo->ppEnabledLayerNames, instance_layers);
+ err = loader_add_layer_names_to_list(inst, &inst->app_activated_layer_list, &inst->expanded_activated_layer_list,
+ pCreateInfo->enabledLayerCount, pCreateInfo->ppEnabledLayerNames, instance_layers);
return err;
}
@@ -4082,14 +4118,14 @@ VkResult loader_create_instance_chain(const VkInstanceCreateInfo *pCreateInfo, c
memcpy(&loader_create_info, pCreateInfo, sizeof(VkInstanceCreateInfo));
- if (inst->activated_layer_list.count > 0) {
+ if (inst->expanded_activated_layer_list.count > 0) {
chain_info.u.pLayerInfo = NULL;
chain_info.pNext = pCreateInfo->pNext;
chain_info.sType = VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO;
chain_info.function = VK_LAYER_LINK_INFO;
loader_create_info.pNext = &chain_info;
- layer_instance_link_info = loader_stack_alloc(sizeof(VkLayerInstanceLink) * inst->activated_layer_list.count);
+ layer_instance_link_info = loader_stack_alloc(sizeof(VkLayerInstanceLink) * inst->expanded_activated_layer_list.count);
if (!layer_instance_link_info) {
loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
"loader_create_instance_chain: Failed to alloc Instance"
@@ -4098,8 +4134,8 @@ VkResult loader_create_instance_chain(const VkInstanceCreateInfo *pCreateInfo, c
}
// Create instance chain of enabled layers
- for (int32_t i = inst->activated_layer_list.count - 1; i >= 0; i--) {
- struct loader_layer_properties *layer_prop = &inst->activated_layer_list.list[i];
+ for (int32_t i = inst->expanded_activated_layer_list.count - 1; i >= 0; i--) {
+ struct loader_layer_properties *layer_prop = &inst->expanded_activated_layer_list.list[i];
loader_platform_dl_handle lib_handle;
lib_handle = loader_open_layer_lib(inst, "instance", layer_prop);
@@ -4279,7 +4315,7 @@ VkResult loader_create_device_chain(const struct loader_physical_device_tramp *p
}
}
- layer_device_link_info = loader_stack_alloc(sizeof(VkLayerDeviceLink) * dev->activated_layer_list.count);
+ layer_device_link_info = loader_stack_alloc(sizeof(VkLayerDeviceLink) * dev->expanded_activated_layer_list.count);
if (!layer_device_link_info) {
loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
"loader_create_device_chain: Failed to alloc Device objects"
@@ -4287,7 +4323,7 @@ VkResult loader_create_device_chain(const struct loader_physical_device_tramp *p
return VK_ERROR_OUT_OF_HOST_MEMORY;
}
- if (dev->activated_layer_list.count > 0) {
+ if (dev->expanded_activated_layer_list.count > 0) {
chain_info.sType = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO;
chain_info.function = VK_LAYER_LINK_INFO;
chain_info.u.pLayerInfo = NULL;
@@ -4295,8 +4331,8 @@ VkResult loader_create_device_chain(const struct loader_physical_device_tramp *p
loader_create_info.pNext = &chain_info;
// Create instance chain of enabled layers
- for (int32_t i = dev->activated_layer_list.count - 1; i >= 0; i--) {
- struct loader_layer_properties *layer_prop = &dev->activated_layer_list.list[i];
+ for (int32_t i = dev->expanded_activated_layer_list.count - 1; i >= 0; i--) {
+ struct loader_layer_properties *layer_prop = &dev->expanded_activated_layer_list.list[i];
loader_platform_dl_handle lib_handle;
bool functions_in_interface = false;
@@ -5308,7 +5344,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumerateDeviceExtensionProperties(VkP
goto out;
}
- loader_add_implicit_layers(icd_term->this_instance, &implicit_layer_list, &icd_term->this_instance->instance_layer_list);
+ loader_add_implicit_layers(icd_term->this_instance, &implicit_layer_list, NULL, &icd_term->this_instance->instance_layer_list);
// We need to determine which implicit layers are active, and then add their extensions. This can't be cached as
// it depends on results of environment variables (which can change).
if (pProperties != NULL) {
@@ -5325,7 +5361,8 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumerateDeviceExtensionProperties(VkP
goto out;
}
- loader_add_implicit_layers(icd_term->this_instance, &implicit_layer_list, &icd_term->this_instance->instance_layer_list);
+ loader_add_implicit_layers(icd_term->this_instance, &implicit_layer_list, NULL,
+ &icd_term->this_instance->instance_layer_list);
for (uint32_t i = 0; i < implicit_layer_list.count; i++) {
for (uint32_t j = 0; j < implicit_layer_list.list[i].device_extension_list.count; j++) {
diff --git a/loader/loader.h b/loader/loader.h
index 28390753..2c65923d 100644
--- a/loader/loader.h
+++ b/loader/loader.h
@@ -180,7 +180,13 @@ struct loader_device {
VkDevice icd_device; // device object from the icd
struct loader_physical_device_term *phys_dev_term;
- struct loader_layer_list activated_layer_list;
+ // List of activated layers.
+ // app_ is the version based on exactly what the application asked for.
+ // This is what must be returned to the application on Enumerate calls.
+ // expanded_ is the version based on expanding meta-layers into their
+ // individual component layers. This is what is used internally.
+ struct loader_layer_list app_activated_layer_list;
+ struct loader_layer_list expanded_activated_layer_list;
VkAllocationCallbacks alloc_callbacks;
@@ -250,7 +256,15 @@ struct loader_instance {
struct loader_msg_callback_map_entry *icd_msg_callback_map;
struct loader_layer_list instance_layer_list;
- struct loader_layer_list activated_layer_list;
+
+ // List of activated layers.
+ // app_ is the version based on exactly what the application asked for.
+ // This is what must be returned to the application on Enumerate calls.
+ // expanded_ is the version based on expanding meta-layers into their
+ // individual component layers. This is what is used internally.
+ struct loader_layer_list app_activated_layer_list;
+ struct loader_layer_list expanded_activated_layer_list;
+
VkInstance instance; // layers/ICD instance returned to trampoline
struct loader_extension_list ext_list; // icds and loaders extensions
@@ -420,7 +434,8 @@ bool loader_find_layer_name_array(const char *name, uint32_t layer_count, const
VkResult loader_add_to_layer_list(const struct loader_instance *inst, struct loader_layer_list *list, uint32_t prop_list_count,
const struct loader_layer_properties *props);
void loader_find_layer_name_add_list(const struct loader_instance *inst, const char *name, const enum layer_type_flags type_flags,
- const struct loader_layer_list *search_list, struct loader_layer_list *found_list);
+ const struct loader_layer_list *source_list, struct loader_layer_list *target_list,
+ struct loader_layer_list *expanded_target_list);
void loader_scanned_icd_clear(const struct loader_instance *inst, struct loader_icd_tramp_list *icd_tramp_list);
VkResult loader_icd_scan(const struct loader_instance *inst, struct loader_icd_tramp_list *icd_tramp_list);
void loader_layer_scan(const struct loader_instance *inst, struct loader_layer_list *instance_layers);
diff --git a/loader/trampoline.c b/loader/trampoline.c
index d65ebc41..1afe4455 100644
--- a/loader/trampoline.c
+++ b/loader/trampoline.c
@@ -361,7 +361,12 @@ out:
util_FreeDebugReportCreateInfos(pAllocator, ptr_instance->tmp_dbg_create_infos, ptr_instance->tmp_callbacks);
}
- loader_deactivate_layers(ptr_instance, NULL, &ptr_instance->activated_layer_list);
+ if (NULL != ptr_instance->expanded_activated_layer_list.list) {
+ loader_deactivate_layers(ptr_instance, NULL, &ptr_instance->expanded_activated_layer_list);
+ }
+ if (NULL != ptr_instance->app_activated_layer_list.list) {
+ loader_destroy_layer_list(ptr_instance, NULL, &ptr_instance->app_activated_layer_list);
+ }
loader_delete_layer_properties(ptr_instance, &ptr_instance->instance_layer_list);
loader_scanned_icd_clear(ptr_instance, &ptr_instance->icd_tramp_list);
@@ -411,7 +416,12 @@ LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyInstance(VkInstance instance,
disp->DestroyInstance(instance, pAllocator);
- loader_deactivate_layers(ptr_instance, NULL, &ptr_instance->activated_layer_list);
+ if (NULL != ptr_instance->expanded_activated_layer_list.list) {
+ loader_deactivate_layers(ptr_instance, NULL, &ptr_instance->expanded_activated_layer_list);
+ }
+ if (NULL != ptr_instance->app_activated_layer_list.list) {
+ loader_destroy_layer_list(ptr_instance, NULL, &ptr_instance->app_activated_layer_list);
+ }
if (ptr_instance->phys_devs_tramp) {
for (uint32_t i = 0; i < ptr_instance->phys_dev_count_tramp; i++) {
@@ -574,7 +584,7 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice phy
}
// Make sure requested extensions to be enabled are supported
- res = loader_validate_device_extensions(phys_dev, &inst->activated_layer_list, &icd_exts, pCreateInfo);
+ res = loader_validate_device_extensions(phys_dev, &inst->expanded_activated_layer_list, &icd_exts, pCreateInfo);
if (res != VK_SUCCESS) {
loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0, "vkCreateDevice: Failed to validate extensions in list");
goto out;
@@ -586,21 +596,47 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice phy
goto out;
}
- // Copy the instance layer list into the device
- dev->activated_layer_list.capacity = inst->activated_layer_list.capacity;
- dev->activated_layer_list.count = inst->activated_layer_list.count;
- dev->activated_layer_list.list =
- loader_device_heap_alloc(dev, inst->activated_layer_list.capacity, VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
- if (dev->activated_layer_list.list == NULL) {
- loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
- "vkCreateDevice: Failed to allocate activated layer"
- "list of size %d.",
- inst->activated_layer_list.capacity);
- res = VK_ERROR_OUT_OF_HOST_MEMORY;
- goto out;
+ // Copy the application enabled instance layer list into the device
+ if (NULL != inst->app_activated_layer_list.list) {
+ dev->app_activated_layer_list.capacity = inst->app_activated_layer_list.capacity;
+ dev->app_activated_layer_list.count = inst->app_activated_layer_list.count;
+ dev->app_activated_layer_list.list =
+ loader_device_heap_alloc(dev, inst->app_activated_layer_list.capacity, VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
+ if (dev->app_activated_layer_list.list == NULL) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "vkCreateDevice: Failed to allocate application activated layer list of size %d.",
+ inst->app_activated_layer_list.capacity);
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ memcpy(dev->app_activated_layer_list.list, inst->app_activated_layer_list.list,
+ sizeof(*dev->app_activated_layer_list.list) * dev->app_activated_layer_list.count);
+ } else {
+ dev->app_activated_layer_list.capacity = 0;
+ dev->app_activated_layer_list.count = 0;
+ dev->app_activated_layer_list.list = NULL;
+ }
+
+ // Copy the expanded enabled instance layer list into the device
+ if (NULL != inst->expanded_activated_layer_list.list) {
+ dev->expanded_activated_layer_list.capacity = inst->expanded_activated_layer_list.capacity;
+ dev->expanded_activated_layer_list.count = inst->expanded_activated_layer_list.count;
+ dev->expanded_activated_layer_list.list =
+ loader_device_heap_alloc(dev, inst->expanded_activated_layer_list.capacity, VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
+ if (dev->expanded_activated_layer_list.list == NULL) {
+ loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+ "vkCreateDevice: Failed to allocate expanded activated layer list of size %d.",
+ inst->expanded_activated_layer_list.capacity);
+ res = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto out;
+ }
+ memcpy(dev->expanded_activated_layer_list.list, inst->expanded_activated_layer_list.list,
+ sizeof(*dev->expanded_activated_layer_list.list) * dev->expanded_activated_layer_list.count);
+ } else {
+ dev->expanded_activated_layer_list.capacity = 0;
+ dev->expanded_activated_layer_list.count = 0;
+ dev->expanded_activated_layer_list.list = NULL;
}
- memcpy(dev->activated_layer_list.list, inst->activated_layer_list.list,
- sizeof(*dev->activated_layer_list.list) * dev->activated_layer_list.count);
res = loader_create_device_chain(phys_dev, pCreateInfo, pAllocator, inst, dev);
if (res != VK_SUCCESS) {
@@ -738,13 +774,13 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(Vk
phys_dev = (struct loader_physical_device_tramp *)physicalDevice;
const struct loader_instance *inst = phys_dev->this_instance;
- uint32_t count = inst->activated_layer_list.count;
- if (pProperties == NULL) {
+ uint32_t count = inst->app_activated_layer_list.count;
+ if (count == 0 || pProperties == NULL) {
*pPropertyCount = count;
loader_platform_thread_unlock_mutex(&loader_lock);
return VK_SUCCESS;
}
- enabled_layers = (struct loader_layer_list *)&inst->activated_layer_list;
+ enabled_layers = (struct loader_layer_list *)&inst->app_activated_layer_list;
copy_size = (*pPropertyCount < count) ? *pPropertyCount : count;
for (uint32_t i = 0; i < copy_size; i++) {