@@ -2165,10 +2165,24 @@ void loader_get_fullpath(const char *file, const char *in_dirs, size_t out_size,
21652165}
21662166
21672167// Verify that all component layers in a meta-layer are valid.
2168- bool verify_meta_layer_component_layers (const struct loader_instance * inst , struct loader_layer_properties * prop ,
2169- struct loader_layer_list * instance_layers ) {
2168+ // This function is potentially recursive so we pass in an array of "already checked" (length of the instance_layers->count) meta
2169+ // layers, preventing a stack overflow verifying meta layers that are each other's component layers
2170+ bool verify_meta_layer_component_layers (const struct loader_instance * inst , size_t prop_index ,
2171+ struct loader_layer_list * instance_layers , bool * already_checked_meta_layers ) {
2172+ struct loader_layer_properties * prop = & instance_layers -> list [prop_index ];
21702173 loader_api_version meta_layer_version = loader_make_version (prop -> info .specVersion );
21712174
2175+ if (NULL == already_checked_meta_layers ) {
2176+ already_checked_meta_layers = loader_stack_alloc (sizeof (bool ) * instance_layers -> count );
2177+ if (already_checked_meta_layers == NULL ) {
2178+ return false;
2179+ }
2180+ memset (already_checked_meta_layers , 0 , sizeof (bool ) * instance_layers -> count );
2181+ }
2182+
2183+ // Mark this meta layer as 'already checked', indicating which layers have already been recursed.
2184+ already_checked_meta_layers [prop_index ] = true;
2185+
21722186 for (uint32_t comp_layer = 0 ; comp_layer < prop -> component_layer_names .count ; comp_layer ++ ) {
21732187 struct loader_layer_properties * comp_prop =
21742188 loader_find_layer_property (prop -> component_layer_names .list [comp_layer ], instance_layers );
@@ -2203,22 +2217,27 @@ bool verify_meta_layer_component_layers(const struct loader_instance *inst, stru
22032217 return false;
22042218 }
22052219 if (comp_prop -> type_flags & VK_LAYER_TYPE_FLAG_META_LAYER ) {
2206- for (uint32_t sub_comp_layer = 0 ; sub_comp_layer < comp_prop -> component_layer_names .count ; sub_comp_layer ++ ) {
2207- if (!strcmp (prop -> info .layerName , comp_prop -> component_layer_names .list [sub_comp_layer ])) {
2208- loader_log (inst , VULKAN_LOADER_WARN_BIT , 0 ,
2209- "verify_meta_layer_component_layers: Recursive depedency between Meta-layer %s and Meta-layer %s. "
2210- "Skipping this layer." ,
2211- prop -> info .layerName , prop -> component_layer_names .list [comp_layer ]);
2212- return false;
2220+ size_t comp_prop_index = INT32_MAX ;
2221+ // Make sure we haven't verified this meta layer before
2222+ for (uint32_t i = 0 ; i < instance_layers -> count ; i ++ ) {
2223+ if (strcmp (comp_prop -> info .layerName , instance_layers -> list [i ].info .layerName ) == 0 ) {
2224+ comp_prop_index = i ;
22132225 }
22142226 }
2227+ if (comp_prop_index != INT32_MAX && already_checked_meta_layers [comp_prop_index ]) {
2228+ loader_log (inst , VULKAN_LOADER_WARN_BIT , 0 ,
2229+ "verify_meta_layer_component_layers: Recursive depedency between Meta-layer %s and Meta-layer %s. "
2230+ "Skipping this layer." ,
2231+ instance_layers -> list [prop_index ].info .layerName , comp_prop -> info .layerName );
2232+ return false;
2233+ }
22152234
22162235 loader_log (inst , VULKAN_LOADER_INFO_BIT , 0 ,
22172236 "verify_meta_layer_component_layers: Adding meta-layer %s which also contains meta-layer %s" ,
22182237 prop -> info .layerName , comp_prop -> info .layerName );
22192238
22202239 // Make sure if the layer is using a meta-layer in its component list that we also verify that.
2221- if (!verify_meta_layer_component_layers (inst , comp_prop , instance_layers )) {
2240+ if (!verify_meta_layer_component_layers (inst , comp_prop_index , instance_layers , already_checked_meta_layers )) {
22222241 loader_log (inst , VULKAN_LOADER_WARN_BIT , 0 ,
22232242 "Meta-layer %s component layer %s can not find all component layers."
22242243 " Skipping this layer." ,
@@ -2292,7 +2311,7 @@ VkResult verify_all_meta_layers(struct loader_instance *inst, const struct loade
22922311
22932312 // If this is a meta-layer, make sure it is valid
22942313 if (prop -> type_flags & VK_LAYER_TYPE_FLAG_META_LAYER ) {
2295- if (verify_meta_layer_component_layers (inst , prop , instance_layers )) {
2314+ if (verify_meta_layer_component_layers (inst , i , instance_layers , NULL )) {
22962315 // If any meta layer is valid, update its extension list to include the extensions from its component layers.
22972316 res = update_meta_layer_extensions_from_component_layers (inst , prop , instance_layers );
22982317 if (VK_ERROR_OUT_OF_HOST_MEMORY == res ) {
0 commit comments