VKAPI_ATTR VkResult VKAPI_CALL CreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkInstance *pInstance) { VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO); assert(chain_info->u.pLayerInfo); PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr; PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance)fpGetInstanceProcAddr(NULL, "vkCreateInstance"); if (fpCreateInstance == NULL) { return VK_ERROR_INITIALIZATION_FAILED; } // Advance the link info for the next element on the chain chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext; VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance); if (result != VK_SUCCESS) { return result; } instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(*pInstance), instance_layer_data_map); instance_data->instance = *pInstance; layer_init_instance_dispatch_table(*pInstance, &instance_data->dispatch_table, fpGetInstanceProcAddr); instance_data->instance = *pInstance; instance_data->report_data = debug_report_create_instance(&instance_data->dispatch_table, *pInstance, pCreateInfo->enabledExtensionCount, pCreateInfo->ppEnabledExtensionNames); // Set up temporary debug callbacks to output messages at CreateInstance-time if (!layer_copy_tmp_callbacks(pCreateInfo->pNext, &instance_data->num_tmp_callbacks, &instance_data->tmp_dbg_create_infos, &instance_data->tmp_callbacks)) { if (instance_data->num_tmp_callbacks > 0) { if (layer_enable_tmp_callbacks(instance_data->report_data, instance_data->num_tmp_callbacks, instance_data->tmp_dbg_create_infos, instance_data->tmp_callbacks)) { layer_free_tmp_callbacks(instance_data->tmp_dbg_create_infos, instance_data->tmp_callbacks); instance_data->num_tmp_callbacks = 0; } } } initUniqueObjects(instance_data, pAllocator); InstanceExtensionWhitelist(pCreateInfo, *pInstance); // Disable and free tmp callbacks, no longer necessary if (instance_data->num_tmp_callbacks > 0) { layer_disable_tmp_callbacks(instance_data->report_data, instance_data->num_tmp_callbacks, instance_data->tmp_callbacks); layer_free_tmp_callbacks(instance_data->tmp_dbg_create_infos, instance_data->tmp_callbacks); instance_data->num_tmp_callbacks = 0; } return result; }
VKAPI_ATTR void VKAPI_CALL DestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) { dispatch_key key = get_dispatch_key(instance); layer_data *my_data = get_my_data_ptr(key, layer_data_map); VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table; // Enable the temporary callback(s) here to catch cleanup issues: bool callback_setup = false; if (my_data->num_tmp_callbacks > 0) { if (!layer_enable_tmp_callbacks(my_data->report_data, my_data->num_tmp_callbacks, my_data->tmp_dbg_create_infos, my_data->tmp_callbacks)) { callback_setup = true; } } startWriteObject(my_data, instance); pTable->DestroyInstance(instance, pAllocator); finishWriteObject(my_data, instance); // Disable and cleanup the temporary callback(s): if (callback_setup) { layer_disable_tmp_callbacks(my_data->report_data, my_data->num_tmp_callbacks, my_data->tmp_callbacks); } if (my_data->num_tmp_callbacks > 0) { layer_free_tmp_callbacks(my_data->tmp_dbg_create_infos, my_data->tmp_callbacks); my_data->num_tmp_callbacks = 0; } // Clean up logging callback, if any while (my_data->logging_callback.size() > 0) { VkDebugReportCallbackEXT callback = my_data->logging_callback.back(); layer_destroy_msg_callback(my_data->report_data, callback, pAllocator); my_data->logging_callback.pop_back(); } layer_debug_report_destroy_instance(my_data->report_data); delete my_data->instance_dispatch_table; layer_data_map.erase(key); }