diff options
Diffstat (limited to 'loader')
| -rw-r--r-- | loader/debug_report.c | 108 | ||||
| -rw-r--r-- | loader/debug_report.h | 21 | ||||
| -rw-r--r-- | loader/loader.h | 4 | ||||
| -rw-r--r-- | loader/trampoline.c | 111 |
4 files changed, 208 insertions, 36 deletions
diff --git a/loader/debug_report.c b/loader/debug_report.c index 7da370ce..3f49aa8c 100644 --- a/loader/debug_report.c +++ b/loader/debug_report.c @@ -156,6 +156,114 @@ void util_DestroyDebugReportCallback(struct loader_instance *inst, } } +// This utility (used by vkInstanceCreateInfo(), looks at a pNext chain. It +// counts any VkDebugReportCallbackCreateInfoEXT structs that it finds. It +// then allocates array that can hold that many structs, as well as that many +// VkDebugReportCallbackEXT handles. It then copies each +// VkDebugReportCallbackCreateInfoEXT, and initializes each handle. +VkResult +util_CopyDebugReportCreateInfos(const void *pChain, + const VkAllocationCallbacks *pAllocator, + uint32_t *num_callbacks, + VkDebugReportCallbackCreateInfoEXT **infos, + VkDebugReportCallbackEXT **callbacks) +{ + uint32_t n = *num_callbacks = 0; + + // NOTE: The loader is not using pAllocator, and so this function doesn't + // either. + + const void *pNext = pChain; + while (pNext) { + // 1st, count the number VkDebugReportCallbackCreateInfoEXT: + if (((VkDebugReportCallbackCreateInfoEXT *)pNext)->sType == + VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT) { + n++; + } + pNext = (void *)((VkDebugReportCallbackCreateInfoEXT *)pNext)->pNext; + } + if (n == 0) { + return VK_SUCCESS; + } + + // 2nd, allocate memory for each VkDebugReportCallbackCreateInfoEXT: + VkDebugReportCallbackCreateInfoEXT *pInfos = + *infos = ((VkDebugReportCallbackCreateInfoEXT *) + malloc(n * sizeof(VkDebugReportCallbackCreateInfoEXT))); + if (!pInfos) { + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + // 3rd, allocate memory for a unique handle for each callback: + VkDebugReportCallbackEXT *pCallbacks = + *callbacks = ((VkDebugReportCallbackEXT *) + malloc(n * sizeof(VkDebugReportCallbackEXT))); + if (!pCallbacks) { + free(pInfos); + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + // 4th, copy each VkDebugReportCallbackCreateInfoEXT for use by + // vkDestroyInstance, and assign a unique handle to each callback (just + // use the address of the copied VkDebugReportCallbackCreateInfoEXT): + pNext = pChain; + while (pNext) { + if (((VkInstanceCreateInfo *)pNext)->sType == + VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT) { + memcpy(pInfos, pNext, + sizeof(VkDebugReportCallbackCreateInfoEXT)); + *pCallbacks++ = (VkDebugReportCallbackEXT)pInfos++; + } + pNext = (void *)((VkInstanceCreateInfo *)pNext)->pNext; + } + + *num_callbacks = n; + return VK_SUCCESS; +} + +void util_FreeDebugReportCreateInfos(const VkAllocationCallbacks *pAllocator, + VkDebugReportCallbackCreateInfoEXT *infos, + VkDebugReportCallbackEXT *callbacks) +{ + free(infos); + free(callbacks); +} + +VkResult +util_CreateDebugReportCallbacks(struct loader_instance *inst, + const VkAllocationCallbacks *pAllocator, + uint32_t num_callbacks, + VkDebugReportCallbackCreateInfoEXT *infos, + VkDebugReportCallbackEXT *callbacks) +{ + VkResult rtn; + for (uint32_t i = 0 ; i < num_callbacks ; i++) { + rtn = util_CreateDebugReportCallback(inst, + &infos[i], + pAllocator, + callbacks[i]); + if (rtn != VK_SUCCESS) { + for (uint32_t j = 0 ; j < i ; j++) { + util_DestroyDebugReportCallback(inst, + callbacks[j], + pAllocator); + } + return rtn; + } + } + return rtn; +} + +void util_DestroyDebugReportCallbacks(struct loader_instance *inst, + const VkAllocationCallbacks *pAllocator, + uint32_t num_callbacks, + VkDebugReportCallbackEXT *callbacks) +{ + for (uint32_t i = 0 ; i < num_callbacks ; i++) { + util_DestroyDebugReportCallback(inst, + callbacks[i], + pAllocator); + } +} + static VKAPI_ATTR void VKAPI_CALL debug_report_DestroyDebugReportCallback(VkInstance instance, VkDebugReportCallbackEXT callback, diff --git a/loader/debug_report.h b/loader/debug_report.h index baac021e..72a31e53 100644 --- a/loader/debug_report.h +++ b/loader/debug_report.h @@ -142,6 +142,27 @@ void util_DestroyDebugReportCallback(struct loader_instance *inst, VkDebugReportCallbackEXT callback, const VkAllocationCallbacks *pAllocator); +VkResult +util_CopyDebugReportCreateInfos(const void *pChain, + const VkAllocationCallbacks *pAllocator, + uint32_t *num_callbacks, + VkDebugReportCallbackCreateInfoEXT **infos, + VkDebugReportCallbackEXT **callbacks); +void util_FreeDebugReportCreateInfos(const VkAllocationCallbacks *pAllocator, + VkDebugReportCallbackCreateInfoEXT *infos, + VkDebugReportCallbackEXT *callbacks); +VkResult +util_CreateDebugReportCallbacks(struct loader_instance *inst, + const VkAllocationCallbacks *pAllocator, + uint32_t num_callbacks, + VkDebugReportCallbackCreateInfoEXT *infos, + VkDebugReportCallbackEXT *callbacks); + +void util_DestroyDebugReportCallbacks(struct loader_instance *inst, + const VkAllocationCallbacks *pAllocator, + uint32_t num_callbacks, + VkDebugReportCallbackEXT *callbacks); + VkBool32 util_DebugReportMessage(const struct loader_instance *inst, VkFlags msgFlags, VkDebugReportObjectTypeEXT objectType, diff --git a/loader/loader.h b/loader/loader.h index 244066c0..8a0d4cc8 100644 --- a/loader/loader.h +++ b/loader/loader.h @@ -293,7 +293,9 @@ struct loader_instance { bool debug_report_enabled; VkLayerDbgFunctionNode *DbgFunctionHead; - VkDebugReportCallbackCreateInfoEXT debugReportCreateInfo; + uint32_t num_tmp_callbacks; + VkDebugReportCallbackCreateInfoEXT *tmp_dbg_create_infos; + VkDebugReportCallbackEXT *tmp_callbacks; VkAllocationCallbacks alloc_callbacks; diff --git a/loader/trampoline.c b/loader/trampoline.c index 9c9a879c..260fd340 100644 --- a/loader/trampoline.c +++ b/loader/trampoline.c @@ -242,8 +242,6 @@ vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo, struct loader_instance *ptr_instance = NULL; VkInstance created_instance = VK_NULL_HANDLE; VkResult res = VK_ERROR_INITIALIZATION_FAILED; - VkDebugReportCallbackEXT instance_callback = VK_NULL_HANDLE; - void *pNext = (void *)pCreateInfo->pNext; loader_platform_thread_once(&once_init, loader_initialize); @@ -273,26 +271,38 @@ vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo, #endif /* - * Look for a debug report create info structure - * and setup a callback if found. + * Look for one or more debug report create info structures + * and setup a callback(s) for each one found. */ - while (pNext) { - if (((VkInstanceCreateInfo *)pNext)->sType == - VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT) { - // Use this pNext so that vkCreateInstance has a callback that can - // be used to log messages. Make a copy for use by - // vkDestroyInstance as well. - memcpy(&ptr_instance->debugReportCreateInfo, pNext, - sizeof(VkDebugReportCallbackCreateInfoEXT)); - instance_callback = (VkDebugReportCallbackEXT)ptr_instance; - if (util_CreateDebugReportCallback(ptr_instance, pNext, NULL, - instance_callback)) { - loader_heap_free(ptr_instance, ptr_instance); - loader_platform_thread_unlock_mutex(&loader_lock); - return VK_ERROR_OUT_OF_HOST_MEMORY; - } + ptr_instance->num_tmp_callbacks = 0; + ptr_instance->tmp_dbg_create_infos = NULL; + ptr_instance->tmp_callbacks = NULL; + if (util_CopyDebugReportCreateInfos(pCreateInfo->pNext, + pAllocator, + &ptr_instance->num_tmp_callbacks, + &ptr_instance->tmp_dbg_create_infos, + &ptr_instance->tmp_callbacks)) { + // One or more were found, but allocation failed. Therefore, clean up + // and fail this function: + loader_heap_free(ptr_instance, ptr_instance); + loader_platform_thread_unlock_mutex(&loader_lock); + return VK_ERROR_OUT_OF_HOST_MEMORY; + } else if (ptr_instance->num_tmp_callbacks > 0) { + // Setup the temporary callback(s) here to catch early issues: + if (util_CreateDebugReportCallbacks(ptr_instance, + pAllocator, + ptr_instance->num_tmp_callbacks, + ptr_instance->tmp_dbg_create_infos, + ptr_instance->tmp_callbacks)) { + // Failure of setting up one or more of the callback. Therefore, + // clean up and fail this function: + util_FreeDebugReportCreateInfos(pAllocator, + ptr_instance->tmp_dbg_create_infos, + ptr_instance->tmp_callbacks); + loader_heap_free(ptr_instance, ptr_instance); + loader_platform_thread_unlock_mutex(&loader_lock); + return VK_ERROR_OUT_OF_HOST_MEMORY; } - pNext = (void *)((VkInstanceCreateInfo *)pNext)->pNext; } /* Due to implicit layers need to get layer list even if @@ -312,8 +322,13 @@ vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo, pCreateInfo->ppEnabledLayerNames, &ptr_instance->instance_layer_list); if (res != VK_SUCCESS) { - util_DestroyDebugReportCallback(ptr_instance, instance_callback, - NULL); + util_DestroyDebugReportCallbacks(ptr_instance, + pAllocator, + ptr_instance->num_tmp_callbacks, + ptr_instance->tmp_callbacks); + util_FreeDebugReportCreateInfos(pAllocator, + ptr_instance->tmp_dbg_create_infos, + ptr_instance->tmp_callbacks); loader_heap_free(ptr_instance, ptr_instance); loader_platform_thread_unlock_mutex(&loader_lock); return res; @@ -359,7 +374,13 @@ vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo, loader_destroy_generic_list( ptr_instance, (struct loader_generic_list *)&ptr_instance->ext_list); - util_DestroyDebugReportCallback(ptr_instance, instance_callback, NULL); + util_DestroyDebugReportCallbacks(ptr_instance, + pAllocator, + ptr_instance->num_tmp_callbacks, + ptr_instance->tmp_callbacks); + util_FreeDebugReportCreateInfos(pAllocator, + ptr_instance->tmp_dbg_create_infos, + ptr_instance->tmp_callbacks); loader_platform_thread_unlock_mutex(&loader_lock); loader_heap_free(ptr_instance, ptr_instance); return res; @@ -380,7 +401,13 @@ vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo, loader_destroy_generic_list( ptr_instance, (struct loader_generic_list *)&ptr_instance->ext_list); - util_DestroyDebugReportCallback(ptr_instance, instance_callback, NULL); + util_DestroyDebugReportCallbacks(ptr_instance, + pAllocator, + ptr_instance->num_tmp_callbacks, + ptr_instance->tmp_callbacks); + util_FreeDebugReportCreateInfos(pAllocator, + ptr_instance->tmp_dbg_create_infos, + ptr_instance->tmp_callbacks); loader_platform_thread_unlock_mutex(&loader_lock); loader_heap_free(ptr_instance, ptr_instance); return VK_ERROR_OUT_OF_HOST_MEMORY; @@ -405,7 +432,13 @@ vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo, ptr_instance, (struct loader_generic_list *)&ptr_instance->ext_list); loader.instances = ptr_instance->next; - util_DestroyDebugReportCallback(ptr_instance, instance_callback, NULL); + util_DestroyDebugReportCallbacks(ptr_instance, + pAllocator, + ptr_instance->num_tmp_callbacks, + ptr_instance->tmp_callbacks); + util_FreeDebugReportCreateInfos(pAllocator, + ptr_instance->tmp_dbg_create_infos, + ptr_instance->tmp_callbacks); loader_platform_thread_unlock_mutex(&loader_lock); loader_heap_free(ptr_instance, ptr_instance->disp); loader_heap_free(ptr_instance, ptr_instance); @@ -434,7 +467,10 @@ vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo, } /* Remove temporary debug_report callback */ - util_DestroyDebugReportCallback(ptr_instance, instance_callback, NULL); + util_DestroyDebugReportCallbacks(ptr_instance, + pAllocator, + ptr_instance->num_tmp_callbacks, + ptr_instance->tmp_callbacks); loader_unexpand_inst_layer_names(ptr_instance, saved_layer_count, saved_layer_names, saved_layer_ptr, pCreateInfo); @@ -447,7 +483,6 @@ vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) { const VkLayerInstanceDispatchTable *disp; struct loader_instance *ptr_instance = NULL; - VkDebugReportCallbackEXT instance_callback = VK_NULL_HANDLE; bool callback_setup = false; disp = loader_get_instance_dispatch(instance); @@ -456,13 +491,13 @@ vkDestroyInstance(VkInstance instance, ptr_instance = loader_get_instance(instance); - if (ptr_instance->debugReportCreateInfo.sType == - VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT) { - // Setup a temporary callback here to catch cleanup issues: - instance_callback = (VkDebugReportCallbackEXT)ptr_instance; - if (!util_CreateDebugReportCallback(ptr_instance, - &ptr_instance->debugReportCreateInfo, - NULL, instance_callback)) { + if (ptr_instance->num_tmp_callbacks > 0) { + // Setup the temporary callback(s) here to catch cleanup issues: + if (!util_CreateDebugReportCallbacks(ptr_instance, + pAllocator, + ptr_instance->num_tmp_callbacks, + ptr_instance->tmp_dbg_create_infos, + ptr_instance->tmp_callbacks)) { callback_setup = true; } } @@ -473,7 +508,13 @@ vkDestroyInstance(VkInstance instance, if (ptr_instance->phys_devs) loader_heap_free(ptr_instance, ptr_instance->phys_devs); if (callback_setup) { - util_DestroyDebugReportCallback(ptr_instance, instance_callback, NULL); + util_DestroyDebugReportCallbacks(ptr_instance, + pAllocator, + ptr_instance->num_tmp_callbacks, + ptr_instance->tmp_callbacks); + util_FreeDebugReportCreateInfos(pAllocator, + ptr_instance->tmp_dbg_create_infos, + ptr_instance->tmp_callbacks); } loader_heap_free(ptr_instance, ptr_instance->disp); loader_heap_free(ptr_instance, ptr_instance); |
